All files / src/contexts SandboxContext.tsx

100% Statements 16/16
100% Branches 8/8
100% Functions 5/5
100% Lines 16/16

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75                                          2x           2x 35x 35x   35x 8x       35x 34x 27x       35x               35x             2x 37x 37x     3x               34x        
/**
 * Sandbox Context
 * Provides sandbox mode state and toggle functionality throughout the app
 */
 
import React, { createContext, useContext, useEffect, ReactNode } from 'react';
import { useSandboxStatus, useToggleSandbox } from '../hooks/useSandbox';
 
interface SandboxContextType {
  /** Whether the app is currently in sandbox/test mode */
  isSandbox: boolean;
  /** Whether sandbox mode is available for this business */
  sandboxEnabled: boolean;
  /** Whether the sandbox status is loading */
  isLoading: boolean;
  /** Toggle between live and sandbox mode */
  toggleSandbox: (enableSandbox: boolean) => Promise<void>;
  /** Whether a toggle operation is in progress */
  isToggling: boolean;
}
 
const SandboxContext = createContext<SandboxContextType | undefined>(undefined);
 
interface SandboxProviderProps {
  children: ReactNode;
}
 
export const SandboxProvider: React.FC<SandboxProviderProps> = ({ children }) => {
  const { data: status, isLoading } = useSandboxStatus();
  const toggleMutation = useToggleSandbox();
 
  const toggleSandbox = async (enableSandbox: boolean) => {
    await toggleMutation.mutateAsync(enableSandbox);
  };
 
  // Store sandbox mode in localStorage for persistence across tabs
  useEffect(() => {
    if (status?.sandbox_mode !== undefined) {
      localStorage.setItem('sandbox_mode', String(status.sandbox_mode));
    }
  }, [status?.sandbox_mode]);
 
  const value: SandboxContextType = {
    isSandbox: status?.sandbox_mode ?? false,
    sandboxEnabled: status?.sandbox_enabled ?? false,
    isLoading,
    toggleSandbox,
    isToggling: toggleMutation.isPending,
  };
 
  return (
    <SandboxContext.Provider value={value}>
      {children}
    </SandboxContext.Provider>
  );
};
 
export const useSandbox = (): SandboxContextType => {
  const context = useContext(SandboxContext);
  if (context === undefined) {
    // Return default values when used outside SandboxProvider
    // This happens for platform admins who don't have sandbox mode
    return {
      isSandbox: false,
      sandboxEnabled: false,
      isLoading: false,
      toggleSandbox: async () => {},
      isToggling: false,
    };
  }
  return context;
};
 
export default SandboxContext;