sms-extension-1777874553/client/src/context/BusinessContext.jsx

98 lines
3.4 KiB
JavaScript

/* eslint-disable react-refresh/only-export-components */
import { createContext, useContext, useState, useEffect, useCallback } from 'react';
import apiClient from '../api/client';
import { getRuntimeCompanyId } from '../utils/runtimeContext';
const BusinessContext = createContext(null);
const SESSION_KEY = 'sms_active_business';
export function BusinessProvider({ children }) {
const [activeBusiness, setActiveBusinessState] = useState(null);
const [hasGlobalSms, setHasGlobalSms] = useState(false);
const [isSetupComplete, setIsSetupComplete] = useState(false);
const [loading, setLoading] = useState(true);
const updateReadyState = useCallback((activeProfile) => {
const hasProfile = !!activeProfile;
setHasGlobalSms(hasProfile);
const p = activeProfile?.provider || {};
const nextIsSetupComplete = hasProfile && !!p.providerName && !!p.senderId && !!p.dltEntityId;
setIsSetupComplete(nextIsSetupComplete);
return nextIsSetupComplete;
}, []);
// On mount: rehydrate from sessionStorage and refresh from API
useEffect(() => {
async function rehydrate() {
const stored = sessionStorage.getItem(SESSION_KEY);
if (!stored) { setLoading(false); return; }
try {
const { businessId, companyId } = JSON.parse(stored);
const runtimeCompanyId = getRuntimeCompanyId();
if (runtimeCompanyId && companyId && runtimeCompanyId !== companyId) {
throw new Error('Stored business belongs to a different company context');
}
const [bizRes, smsRes] = await Promise.all([
apiClient.get(`/api/businesses/${businessId}`),
apiClient.get(`/api/businesses/${businessId}/global-sms/active`).catch(() => ({ data: {} }))
]);
setActiveBusinessState(bizRes.data);
updateReadyState(smsRes.data?.activeProfile);
sessionStorage.setItem(SESSION_KEY, JSON.stringify({
businessId,
companyId: runtimeCompanyId || companyId || '',
}));
} catch {
// Business no longer exists — clear stale session
sessionStorage.removeItem(SESSION_KEY);
setActiveBusinessState(null);
setHasGlobalSms(false);
setIsSetupComplete(false);
} finally {
setLoading(false);
}
}
rehydrate();
}, [updateReadyState]);
const setActiveBusiness = useCallback(async (business) => {
setActiveBusinessState(business);
sessionStorage.setItem(SESSION_KEY, JSON.stringify({
businessId: business.businessId,
companyId: getRuntimeCompanyId(),
}));
try {
const smsRes = await apiClient.get(`/api/businesses/${business.businessId}/global-sms/active`);
return updateReadyState(smsRes.data?.activeProfile);
} catch {
setHasGlobalSms(false);
setIsSetupComplete(false);
return false;
}
}, [updateReadyState]);
const clearBusiness = useCallback(() => {
setActiveBusinessState(null);
setHasGlobalSms(false);
setIsSetupComplete(false);
sessionStorage.removeItem(SESSION_KEY);
}, []);
const activeBusinessId = activeBusiness?.businessId || null;
return (
<BusinessContext.Provider value={{
activeBusiness, activeBusinessId, setActiveBusiness, clearBusiness, loading, hasGlobalSms, setHasGlobalSms, isSetupComplete, setIsSetupComplete
}}>
{children}
</BusinessContext.Provider>
);
}
export function useBusiness() {
return useContext(BusinessContext);
}