/** * usePayrollSettings — React hook for fetching org payroll settings * and returning the correct TaxJurisdiction plugin instance. * * Usage: * const { jurisdiction, settings, loading, error } = usePayrollSettings(); * if (jurisdiction) { * console.log(jurisdiction.name, jurisdiction.currency); * } */ import { useState, useEffect, useCallback } from "react"; import { getTaxJurisdiction } from "@/lib/payroll"; import { fetchPayrollSettings } from "@/lib/supabase/payroll-settings-actions"; import type { PayrollSettings } from "@/lib/payroll-settings-types"; import type { TaxJurisdiction } from "@/lib/payroll/types"; interface UsePayrollSettingsReturn { settings: PayrollSettings | null; jurisdiction: TaxJurisdiction | null; loading: boolean; error: string | null; refetch: () => void; } export function usePayrollSettings(): UsePayrollSettingsReturn { const [settings, setSettings] = useState(null); const [jurisdiction, setJurisdiction] = useState(null); const [loading, setLoading] = useState(true); const [error, setError] = useState(null); const fetchSettings = useCallback(() => { setLoading(true); setError(null); fetchPayrollSettings() .then((s) => { setSettings(s); if (s) { // Build the appropriate TaxJurisdiction plugin const opts: Record = {}; if (s.country_code === "US" && s.state_code) { opts.stateTaxRate = s.state_tax_rate ?? 0; opts.stateName = s.state_name ?? s.state_code; } if (s.country_code === "SG") { opts.isCPRorSC = s.is_singapore_citizen_or_pr ?? true; } if (!s.is_natively_supported) { opts.flatIncomeTaxRate = s.flat_income_tax_rate ?? 0.2; opts.employerPensionRate = s.employer_pension_rate ?? 0; opts.employerTaxRate = s.employer_tax_rate ?? 0; opts.displayName = s.country_name; opts.currency = s.currency; opts.countryCode = s.country_code; opts.taxFreeAllowance = s.tax_free_allowance ?? 0; } const j = getTaxJurisdiction(s.country_code, opts); setJurisdiction(j); } else { setJurisdiction(null); } }) .catch((e: Error) => { setError(e.message || "Failed to load payroll settings"); setSettings(null); setJurisdiction(null); }) .finally(() => setLoading(false)); }, []); useEffect(() => { fetchSettings(); }, [fetchSettings]); return { settings, jurisdiction, loading, error, refetch: fetchSettings }; }