import { useCallback, useState, ReactNode, useMemo } from 'react'; import { createContext, useContextSelector } from 'use-context-selector'; export interface ProposeChangesDecision { approved: boolean; user_reason?: string; } interface UIContextProps { isMobileSidebarOpen: boolean; setIsMobileSidebarOpen: React.Dispatch>; isLoginModalOpen: boolean; setIsLoginModalOpen: React.Dispatch>; isRateLimitModalOpen: boolean; setIsRateLimitModalOpen: React.Dispatch>; isUpgradeModalOpen: boolean; setIsUpgradeModalOpen: React.Dispatch>; isWorkflowsModalOpen: boolean; setIsWorkflowsModalOpen: React.Dispatch>; isSettingsModalOpen: boolean; setIsSettingsModalOpen: React.Dispatch>; isConfirmDeleteModalOpen: boolean; setIsConfirmDeleteModalOpen: React.Dispatch>; confirmDeleteConversationName: string | null; setConfirmDeleteConversationName: React.Dispatch>; confirmDeleteConversationId: string | null; setConfirmDeleteConversationId: React.Dispatch>; // Propose Changes modal isProposeChangesModalOpen: boolean; setIsProposeChangesModalOpen: React.Dispatch>; proposeChangesRequest: any | null; setProposeChangesRequest: React.Dispatch>; openProposeChanges: (request: any) => Promise; resolveProposeChanges: (decision: ProposeChangesDecision) => void; } const defaultContextValue: UIContextProps = { isMobileSidebarOpen: false, setIsMobileSidebarOpen: () => {}, isLoginModalOpen: false, setIsLoginModalOpen: () => {}, isRateLimitModalOpen: false, setIsRateLimitModalOpen: () => {}, isUpgradeModalOpen: false, setIsUpgradeModalOpen: () => {}, isWorkflowsModalOpen: false, setIsWorkflowsModalOpen: () => {}, isSettingsModalOpen: false, setIsSettingsModalOpen: () => {}, isConfirmDeleteModalOpen: false, setIsConfirmDeleteModalOpen: () => {}, confirmDeleteConversationName: null, setConfirmDeleteConversationName: () => {}, confirmDeleteConversationId: null, setConfirmDeleteConversationId: () => {}, isProposeChangesModalOpen: false, setIsProposeChangesModalOpen: () => {}, proposeChangesRequest: null, setProposeChangesRequest: () => {}, openProposeChanges: async () => ({ approved: false }), resolveProposeChanges: () => {}, }; const UIContext = createContext(defaultContextValue); interface UIProviderProps { children: ReactNode; } export const UIProvider = ({ children }: UIProviderProps): JSX.Element => { const [isMobileSidebarOpen, setIsMobileSidebarOpen] = useState(false); const [isLoginModalOpen, setIsLoginModalOpen] = useState(false); const [isRateLimitModalOpen, setIsRateLimitModalOpen] = useState(false); const [isUpgradeModalOpen, setIsUpgradeModalOpen] = useState(false); const [isWorkflowsModalOpen, setIsWorkflowsModalOpen] = useState(false); const [isSettingsModalOpen, setIsSettingsModalOpen] = useState(false); const [isConfirmDeleteModalOpen, setIsConfirmDeleteModalOpen] = useState(false); const [confirmDeleteConversationName, setConfirmDeleteConversationName] = useState(null); const [confirmDeleteConversationId, setConfirmDeleteConversationId] = useState(null); const [isProposeChangesModalOpen, setIsProposeChangesModalOpen] = useState(false); const [proposeChangesRequest, setProposeChangesRequest] = useState(null); const [resolver, setResolver] = useState<((value: ProposeChangesDecision) => void) | null>(null); const openProposeChanges = useCallback((request: any) => { setProposeChangesRequest(request); setIsProposeChangesModalOpen(true); return new Promise((resolve) => { setResolver(() => resolve); }); }, []); const resolveProposeChanges = useCallback((decision: ProposeChangesDecision) => { if (resolver) { resolver(decision); setResolver(null); } setIsProposeChangesModalOpen(false); setProposeChangesRequest(null); }, [resolver]); const contextValue = useMemo(() => ({ isMobileSidebarOpen, setIsMobileSidebarOpen, isLoginModalOpen, setIsLoginModalOpen, isRateLimitModalOpen, setIsRateLimitModalOpen, isUpgradeModalOpen, setIsUpgradeModalOpen, isWorkflowsModalOpen, setIsWorkflowsModalOpen, isSettingsModalOpen, setIsSettingsModalOpen, isConfirmDeleteModalOpen, setIsConfirmDeleteModalOpen, confirmDeleteConversationName, setConfirmDeleteConversationName, confirmDeleteConversationId, setConfirmDeleteConversationId, isProposeChangesModalOpen, setIsProposeChangesModalOpen, proposeChangesRequest, setProposeChangesRequest, openProposeChanges, resolveProposeChanges, }), [ isMobileSidebarOpen, isLoginModalOpen, isRateLimitModalOpen, isUpgradeModalOpen, isWorkflowsModalOpen, isSettingsModalOpen, isConfirmDeleteModalOpen, confirmDeleteConversationName, confirmDeleteConversationId, isProposeChangesModalOpen, proposeChangesRequest, openProposeChanges, resolveProposeChanges, ]); return ( {children} ); }; // Selector Hook export const useUISelector = (selector: (state: UIContextProps) => T): T => { return useContextSelector(UIContext, selector); }; export const useIsMobileSidebarOpen = () => { return useUISelector(state => state.isMobileSidebarOpen); }; export const useIsLoginModalOpen = () => { return useUISelector(state => state.isLoginModalOpen); }; export const useIsRateLimitModalOpen = () => { return useUISelector(state => state.isRateLimitModalOpen); }; export const useIsUpgradeModalOpen = () => { return useUISelector(state => state.isUpgradeModalOpen); }; export const useIsWorkflowsModalOpen = () => { return useUISelector(state => state.isWorkflowsModalOpen); }; export const useIsSettingsModalOpen = () => { return useUISelector(state => state.isSettingsModalOpen); }; export const useIsConfirmDeleteModalOpen = () => { return useUISelector(state => state.isConfirmDeleteModalOpen); }; export const useConfirmDeleteConversationName = () => { return useUISelector(state => state.confirmDeleteConversationName); }; export const useConfirmDeleteConversationId = () => { return useUISelector(state => state.confirmDeleteConversationId); }; // Individual Selector Hooks for Setter Functions export const useSetIsMobileSidebarOpen = () => { return useUISelector(state => state.setIsMobileSidebarOpen); }; export const useSetIsLoginModalOpen = () => { return useUISelector(state => state.setIsLoginModalOpen); }; export const useSetIsRateLimitModalOpen = () => { return useUISelector(state => state.setIsRateLimitModalOpen); }; export const useSetIsUpgradeModalOpen = () => { return useUISelector(state => state.setIsUpgradeModalOpen); }; export const useSetIsWorkflowsModalOpen = () => { return useUISelector(state => state.setIsWorkflowsModalOpen); }; export const useSetIsSettingsModalOpen = () => { return useUISelector(state => state.setIsSettingsModalOpen); }; export const useSetIsConfirmDeleteModalOpen = () => { return useUISelector(state => state.setIsConfirmDeleteModalOpen); }; export const useSetConfirmDeleteConversationName = () => { return useUISelector(state => state.setConfirmDeleteConversationName); }; export const useSetConfirmDeleteConversationId = () => { return useUISelector(state => state.setConfirmDeleteConversationId); }; export const useIsProposeChangesModalOpen = () => { return useUISelector(state => state.isProposeChangesModalOpen); }; export const useSetIsProposeChangesModalOpen = () => { return useUISelector(state => state.setIsProposeChangesModalOpen); }; export const useProposeChangesRequest = () => { return useUISelector(state => state.proposeChangesRequest); }; export const useSetProposeChangesRequest = () => { return useUISelector(state => state.setProposeChangesRequest); }; export const useOpenProposeChanges = () => { return useUISelector(state => state.openProposeChanges); };