import { useMemo, useState, useEffect, ReactNode } from 'react'; import { useNavigate } from 'react-router-dom'; import { useTranslation } from '@repo/core-i18n'; import { BaseEntity, BaseRemoteDataServices } from '@repo/core-api/data-services'; import { ConfigSlice, ModuleConfigEntity, SinglePageFormState, SinglePageModalState } from '../entities/entity'; import { EnterpriseConfigContext, EnterpriseDataServiceContext, EnterpriseSelectionContext, EnterpriseNavigationContext, EnterpriseModalContext, EnterpriseTranslationContext, } from '../hooks/use-module.context'; import { defaultPrivileges } from '../constant/default-privilege'; export interface EnterpriseModuleProviderProps { children: ReactNode; config: ModuleConfigEntity; dataServices: BaseRemoteDataServices; } export function EnterpriseModuleProvider(props: EnterpriseModuleProviderProps) { const { children, config, dataServices } = props; const navigate = useNavigate(); // --------------------------------------------------------------------------- // 1. Config Slice (Static) // --------------------------------------------------------------------------- const configSlice: ConfigSlice = useMemo(() => { return { config, // FIXME => IMPLEMENT PRIVILEGE privileges: defaultPrivileges, }; }, [config]); // --------------------------------------------------------------------------- // 1b. Translation Slice (Dedicated context — decoupled from config) // --------------------------------------------------------------------------- const namespaces = useMemo(() => [config.translationNamespace, 'common'], [config.translationNamespace]); const { t } = useTranslation(namespaces); const translationSlice = useMemo(() => ({ t: t as (key: string, options?: Record) => string }), [t]); // Set document title — uses explicit tabTitle or falls back to translation key 'title' useEffect(() => { const title = config.tabTitle || t('title'); if (title) { document.title = title; } }, [config.tabTitle, t]); // --------------------------------------------------------------------------- // 2. Data Service Slice (Stable refs) // --------------------------------------------------------------------------- const dataServiceSlice = useMemo(() => { return { dataServices, privilege: undefined }; }, [dataServices]); // --------------------------------------------------------------------------- // 3. Selection Slice (Dynamic state) // --------------------------------------------------------------------------- const [selectedRows, setSelectedRows] = useState([]); const [metaData, setMetaData] = useState(null); const [filterData, setFilterData] = useState(null); const selectionSlice = useMemo( () => ({ selectedRows, setSelectedRows, metaData, setMetaData, filterData, setFilterData, }), [selectedRows, metaData, filterData], ); // --------------------------------------------------------------------------- // 4. Modal Slice (For Single Page mode) // --------------------------------------------------------------------------- const [formState, setFormState] = useState({ open: false, formType: 'CREATE' }); const [detailState, setDetailState] = useState({ open: false }); const modalSlice = useMemo( () => ({ formState, setFormState, detailState, setDetailState }), [formState, detailState], ); // --------------------------------------------------------------------------- // 5. Navigation Slice // --------------------------------------------------------------------------- const navigationSlice = useMemo(() => { const isSingle = config.moduleCategory === 'SINGLE_PAGE'; return { navigateToIndex: () => { if (isSingle) { setFormState({ open: false, formType: 'CREATE' }); setDetailState({ open: false }); } else { navigate(`${config.webUrl}/index`); } }, navigateToCreate: () => { if (isSingle) { setFormState({ open: true, formType: 'DUPLICATE' }); } else { navigate(`${config.webUrl}/create`); } }, navigateToEdit: (id: string) => { if (isSingle) { setFormState({ open: true, formType: 'EDIT', dataId: id }); } else { navigate(`${config.webUrl}/edit/${id}`); } }, navigateToDetail: (id: string) => { if (isSingle) { setDetailState({ open: true, dataId: id }); } else { navigate(`${config.webUrl}/detail/${id}`); } }, navigateToDuplicate: (id: string) => { if (isSingle) { setFormState({ open: true, formType: 'DUPLICATE', dataId: id }); } else { navigate(`${config.webUrl}/duplicate/${id}`); } }, }; }, [config.moduleCategory, config.webUrl, navigate]); // --------------------------------------------------------------------------- // Render // --------------------------------------------------------------------------- const { ALLOW_VIEW } = configSlice.privileges; useEffect(() => { if (!ALLOW_VIEW) navigate('/403', { replace: true }); }, [ALLOW_VIEW, navigate]); if (!ALLOW_VIEW) { return null; } return ( {children} ); }