diff --git a/app/page.tsx b/app/page.tsx index f787bce..b7cbbb5 100644 --- a/app/page.tsx +++ b/app/page.tsx @@ -46,8 +46,10 @@ export default function Dashboard() { const [comparisonSection, setComparisonSection] = useState>("inflation"); const [comparisonCurrencies, setComparisonCurrencies] = useState("all"); const [focusCurrency, setFocusCurrency] = useState("all"); - const [globalMacroSlide, setGlobalMacroSlide] = useState<"mon"|"infl"|"cro"|"empl">("mon"); - const [macroSyncEnabled, setMacroSyncEnabled] = useState(false); + const [globalMacroSlide, setGlobalMacroSlide] = useState<"mon"|"infl"|"cro"|"empl">("mon"); + const [globalCardTab, setGlobalCardTab] = useState<"overview"|"mispricing"|"focus">("overview"); + const [globalSignauxSlide, setGlobalSignauxSlide] = useState<"ois"|"cot"|"sent">("ois"); + const [macroSyncEnabled, setMacroSyncEnabled] = useState(false); // ── Sentiment multi-paires Myfxbook → {CCY: {longPct, shortPct, pair}} ────── // Pour chaque devise, on calcule le % "long CCY" en moyenne pondérée (par volume) @@ -585,6 +587,10 @@ export default function Dashboard() { macroSection={macroSection} syncMacroSlide={macroSyncEnabled ? globalMacroSlide : undefined} onMacroSlideChange={macroSyncEnabled ? setGlobalMacroSlide : undefined} + syncCardTab={macroSyncEnabled ? globalCardTab : undefined} + onCardTabChange={macroSyncEnabled ? (setGlobalCardTab as (id: "overview"|"mispricing"|"focus") => void) : undefined} + syncSignauxSlide={macroSyncEnabled ? globalSignauxSlide : undefined} + onSignauxSlideChange={macroSyncEnabled ? setGlobalSignauxSlide : undefined} /> ))} diff --git a/components/CurrencyCard.tsx b/components/CurrencyCard.tsx index 76fca96..ac29b6b 100644 --- a/components/CurrencyCard.tsx +++ b/components/CurrencyCard.tsx @@ -58,6 +58,10 @@ interface Props { macroSection?: MacroSection; syncMacroSlide?: "mon" | "infl" | "cro" | "empl"; onMacroSlideChange?: (id: "mon" | "infl" | "cro" | "empl") => void; + syncCardTab?: "overview" | "mispricing" | "focus"; + onCardTabChange?: (id: "overview" | "mispricing" | "focus") => void; + syncSignauxSlide?: "ois" | "cot" | "sent"; + onSignauxSlideChange?: (id: "ois" | "cot" | "sent") => void; } type Tab = "overview" | "mispricing" | "focus"; @@ -600,6 +604,7 @@ function OISEnhancedBlock({ ratePath }: { ratePath: CBRatePath }) { export default function CurrencyCard({ currency, expectations, yields, sentiment, cot, ratePath, onDivergenceUpdate, calEvents, macroSection, syncMacroSlide, onMacroSlideChange, + syncCardTab, onCardTabChange, syncSignauxSlide, onSignauxSlideChange, }: Props) { const meta = CURRENCY_META[currency]; @@ -636,6 +641,8 @@ export default function CurrencyCard({ const prevSyncMacroRef = useRef(syncMacroSlide ?? "mon"); const [signauxSlide, setSignauxSlide] = useState("ois"); const [signauxSlideDir, setSignauxSlideDir] = useState<1|-1>(1); + const prevSyncCardTabRef = useRef(syncCardTab ?? "overview"); + const prevSyncSignauxSlideRef = useRef(syncSignauxSlide ?? "ois"); // ── Data fetch ─────────────────────────────────────────────────────────────── const load = useCallback(async () => { @@ -924,13 +931,36 @@ export default function CurrencyCard({ } }, [syncMacroSlide]); + // Sync tab principal depuis une autre carte + useEffect(() => { + if (syncCardTab === undefined) return; + const prev = prevSyncCardTabRef.current; + if (syncCardTab !== prev) { + setActiveTab(syncCardTab); + prevSyncCardTabRef.current = syncCardTab; + } + }, [syncCardTab]); + + // Sync sous-slide Signaux depuis une autre carte + useEffect(() => { + if (syncSignauxSlide === undefined) return; + const order: SignauxSlide[] = ["ois", "cot", "sent"]; + const prev = prevSyncSignauxSlideRef.current; + if (syncSignauxSlide !== prev) { + setSignauxSlideDir(order.indexOf(syncSignauxSlide) >= order.indexOf(prev) ? 1 : -1); + setSignauxSlide(syncSignauxSlide); + prevSyncSignauxSlideRef.current = syncSignauxSlide; + } + }, [syncSignauxSlide]); + const goToSignauxSlide = useCallback((id: SignauxSlide) => { const order: SignauxSlide[] = ["ois", "cot", "sent"]; setSignauxSlide(prev => { setSignauxSlideDir(order.indexOf(id) >= order.indexOf(prev) ? 1 : -1); return id; }); - }, []); + onSignauxSlideChange?.(id); + }, [onSignauxSlideChange]); // ── Recent published events for this currency (last 72h, non-low impact) ───── const recentEvents = useMemo(() => { @@ -1234,7 +1264,7 @@ export default function CurrencyCard({ {TABS.map((t) => (