spb/countryatlas
Public
TypeScript 57%
Python 38.6%
JavaScript 3.6%
CSS 0.6%
1'use client';2import { createContext, useCallback, useContext, useMemo, useState, type ReactNode } from 'react';3import type { FormatSpec, ObservationStatus, Provenance } from '@/lib/types';45/** Indicator description the sheet needs (built from a MetricValue or an IndicatorCard). */6export interface ProvenanceIndicator extends FormatSpec {7 slug: string;8 name: string;9 methodology?: string | null;10 description?: string | null;11}1213/** The value being explained (a MetricValue or a SeriesValue reduced to what the sheet shows). */14export interface ProvenanceValue {15 value: number | null;16 formatted?: string | null;17 period: string | null;18 year?: number | null;19 unit?: string | null;20 is_estimate?: boolean;21 is_forecast?: boolean;22 status?: ObservationStatus | string | null;23 provenance: Provenance | null;24}2526export interface ProvenancePayload {27 indicator: ProvenanceIndicator;28 value: ProvenanceValue | null;29 country?: { id: string; slug: string | null; name: string; flag?: string | null } | null;30 /** Override download link; defaults to the country CSV, else the indicator CSV. */31 downloadHref?: string;32 /** Optional data-quality facts for the series (badges are derived when absent). */33 quality?: {34 badges?: Array<'fresh' | 'historical' | 'sparse' | 'limited-coverage' | 'stale' | 'flagged' | 'forecast'>;35 firstYear?: number | null;36 latestYear?: number | null;37 points?: number | null;38 missingYears?: number | null;39 continuityPct?: number | null;40 coveragePct?: number | null;41 referenceYear?: number | null;42 } | null;43}4445interface Ctx {46 payload: ProvenancePayload | null;47 open: (p: ProvenancePayload) => void;48 close: () => void;49}5051const ProvenanceCtx = createContext<Ctx | null>(null);5253export function ProvenanceProvider({ children }: { children: ReactNode }) {54 const [payload, setPayload] = useState<ProvenancePayload | null>(null);55 const open = useCallback((p: ProvenancePayload) => setPayload(p), []);56 const close = useCallback(() => setPayload(null), []);57 const value = useMemo(() => ({ payload, open, close }), [payload, open, close]);58 return <ProvenanceCtx.Provider value={value}>{children}</ProvenanceCtx.Provider>;59}6061export function useProvenance(): Ctx {62 const ctx = useContext(ProvenanceCtx);63 if (!ctx) return { payload: null, open: () => {}, close: () => {} };64 return ctx;65}66