import { createContext, useContext, useMemo, type ReactNode } from "react"; import { create } from "zustand"; export type PeekPayload = | { kind: "payer"; payerId: string } | { kind: "rule"; rule: string }; interface DrillState { stack: PeekPayload[]; openPeek: (p: PeekPayload) => void; closeTop: () => void; closeAll: () => void; } // One zustand store per provider instance (factory) so multiple // providers (e.g. in tests) don't share state. function makeStore() { return create((set) => ({ stack: [], openPeek: (p) => set((s) => ({ // Cap at 2 levels total: one drawer + one peek. When called and // the stack already has one peek, replace it. stack: s.stack.length >= 1 ? [p] : [p], })), closeTop: () => set((s) => ({ stack: s.stack.slice(0, -1) })), closeAll: () => set({ stack: [] }), })); } type StoreApi = ReturnType; const Ctx = createContext(null); export function DrillStackProvider({ children }: { children: ReactNode }) { // useMemo so the store instance is stable across renders. const store = useMemo(makeStore, []); return {children}; } export function useDrillStack() { const store = useContext(Ctx); if (!store) throw new Error("useDrillStack must be used within DrillStackProvider"); // Subscribe to just `stack` so consumers re-render only on stack // changes (not on every state update). const stack = store((s) => s.stack); return { stack, openPeek: store.getState().openPeek, closeTop: store.getState().closeTop, closeAll: store.getState().closeAll, }; }