context.tsx1.2 KBView on GitHub
'use client';

import { createContext, useContext } from 'react';
import type { DashboardRow } from '../types/dashboard';

export interface ResolvedSource {
  rows: DashboardRow[];
  isLoading: boolean;
  error?: unknown;
}

/** Map of source name → resolved rows, provided once at the dashboard root. */
const SourcesContext = createContext<Record<string, ResolvedSource>>({});
export const SourcesProvider = SourcesContext.Provider;
export function useSources() {
  return useContext(SourcesContext);
}

/**
 * Repeater scope — the current row, the team aggregate to compare against, and
 * the binding name used in `{{<as>.field}}` templates. Undefined outside a
 * repeater.
 */
export interface RepeaterScope {
  row: DashboardRow;
  team: DashboardRow;
  as: string;
}

const ScopeContext = createContext<RepeaterScope | null>(null);
export const ScopeProvider = ScopeContext.Provider;
export function useScope() {
  return useContext(ScopeContext);
}

/** Interpolation scope object: `{ [as]: row, team, row }`. */
export function templateScope(scope: RepeaterScope | null): Record<string, unknown> {
  if (!scope) return {};
  return { [scope.as]: scope.row, row: scope.row, team: scope.team };
}