refactor: integrate Zustand store into EnterpriseModuleProvider and update module configurations to use store-based state management

This commit is contained in:
Firman Ramdhani
2026-07-20 14:09:46 +07:00
parent d089c40707
commit dd18787ee7
11 changed files with 116 additions and 37 deletions
@@ -4,7 +4,7 @@ import { ModuleConfigEntity } from '@repo/ui/foundations';
* Core configuration and constants for the Full Page module.
* Used across Domain, Data, and Presentation layers.
*/
export const FullPageModuleConfig: ModuleConfigEntity = {
export const fullPageModuleConfig: ModuleConfigEntity = {
/** Unique identifier for permissions, caching, and i18n */
moduleKey: 'EXAMPLE_FULL_PAGE',
@@ -21,6 +21,5 @@ export const FullPageModuleConfig: ModuleConfigEntity = {
moduleCategory: 'FULL_PAGE',
/** */
// moduleType: 'MASTER_DATA',
moduleType: 'TRANSACTION',
moduleType: 'MASTER_DATA',
} as const;
@@ -2,9 +2,10 @@ import { lazy } from 'react';
import { Navigate, Route, Routes } from 'react-router-dom';
import { EnterpriseModuleProvider } from '@repo/ui/foundations';
import { registerModuleNamespace } from '@repo/core-i18n';
import { FullPageModuleConfig } from '../../domain/constants';
import { fullPageModuleConfig } from '../../domain/constants';
import { fullPageDataService } from '../../domain/factories';
import { FullPageEntity } from '../../domain/entities';
import { fullPageStore } from '../store';
import fullPageId from '../languages/id/full-page.json';
import fullPageEn from '../languages/en/full-page.json';
@@ -18,7 +19,7 @@ const DetailPage = lazy(() => import('../pages/full-page.page.detail'));
// ---------------------------------------------------------------------------
// Called once at import time — safe, idempotent, outside React render cycle.
// The namespace 'full-page' must match config.translationNamespace.
registerModuleNamespace(FullPageModuleConfig.translationNamespace, {
registerModuleNamespace(fullPageModuleConfig.translationNamespace, {
id: fullPageId,
en: fullPageEn,
});
@@ -28,14 +29,18 @@ registerModuleNamespace(FullPageModuleConfig.translationNamespace, {
// ---------------------------------------------------------------------------
export default function FullPageModule() {
return (
<EnterpriseModuleProvider<FullPageEntity> config={FullPageModuleConfig} dataServices={fullPageDataService}>
<EnterpriseModuleProvider<FullPageEntity>
config={fullPageModuleConfig}
dataServices={fullPageDataService}
store={fullPageStore}
>
<Routes>
<Route path="/index" element={<IndexPage />} />
<Route path="/detail/:dataId" element={<DetailPage />} />
<Route path="/edit/:dataId" element={<FormPage formPageType="edit" />} />
<Route path="/duplicate/:dataId" element={<FormPage formPageType="duplicate" />} />
<Route path="/create" element={<FormPage formPageType="create" />} />
<Route path="/" element={<Navigate to={`${FullPageModuleConfig.webUrl}/index`} replace={true} />} />
<Route path="/" element={<Navigate to={`${fullPageModuleConfig.webUrl}/index`} replace={true} />} />
<Route path="*" element={<Navigate to={'/404'} replace={true} />} />
</Routes>
</EnterpriseModuleProvider>
@@ -1,5 +1,5 @@
import { EnterpriseDetailPageProvider, useEnterpriseModuleTranslationContext } from '@repo/ui/foundations';
import { FullPageModuleConfig } from '../../domain/constants';
import { fullPageModuleConfig } from '../../domain/constants';
export default function FullPagePageDetail() {
const { t } = useEnterpriseModuleTranslationContext();
@@ -12,7 +12,7 @@ export default function FullPagePageDetail() {
// showBadges: false,
breadcrumbs: [
{ label: t('nav:example-module'), type: 'text' },
{ label: t('nav:example-full-page'), type: 'link', href: `${FullPageModuleConfig.webUrl}/index` },
{ label: t('nav:example-full-page'), type: 'link', href: `${fullPageModuleConfig.webUrl}/index` },
],
}}
></EnterpriseDetailPageProvider>
@@ -0,0 +1,19 @@
import { create } from 'zustand';
import { EnterpriseModuleState } from '@repo/ui/foundations';
import { FullPageEntity } from '../../domain/entities';
export interface FullPageStoreState extends EnterpriseModuleState<FullPageEntity> {}
export const fullPageStore = create<FullPageStoreState>((set) => ({
metaData: null,
setMetaData: (data) => set({ metaData: data }),
filterData: { page: 1, limit: 10 },
setFilterData: (data) => set({ filterData: data }),
selectedRows: [],
setSelectedRows: (rows) => set({ selectedRows: rows }),
privileges: [],
setPrivileges: (privileges) => set({ privileges }),
}));
@@ -4,7 +4,7 @@ import { ModuleConfigEntity } from '@repo/ui/foundations';
* Core configuration and constants for the Full Page module.
* Used across Domain, Data, and Presentation layers.
*/
export const SinglePageModuleConfig: ModuleConfigEntity = {
export const singlePageModuleConfig: ModuleConfigEntity = {
/** Unique identifier for permissions, caching, and i18n */
moduleKey: 'EXAMPLE_SINGLE_PAGE',
@@ -2,9 +2,10 @@ import { lazy } from 'react';
import { Navigate, Route, Routes } from 'react-router-dom';
import { EnterpriseModuleProvider } from '@repo/ui/foundations';
import { registerModuleNamespace } from '@repo/core-i18n';
import { SinglePageModuleConfig } from '../../domain/constants';
import { singlePageModuleConfig } from '../../domain/constants';
import { singlePageDataService } from '../../domain/factories';
import { SinglePageEntity } from '../../domain/entities';
import { singlePageStore } from '../store';
import singlePageId from '../languages/id/single-page.json';
import singlePageEn from '../languages/en/single-page.json';
@@ -16,7 +17,7 @@ const IndexPage = lazy(() => import('../pages/single-page.page.index'));
// ---------------------------------------------------------------------------
// Called once at import time — safe, idempotent, outside React render cycle.
// The namespace 'single-page' must match config.translationNamespace.
registerModuleNamespace(SinglePageModuleConfig.translationNamespace, {
registerModuleNamespace(singlePageModuleConfig.translationNamespace, {
id: singlePageId,
en: singlePageEn,
});
@@ -26,10 +27,14 @@ registerModuleNamespace(SinglePageModuleConfig.translationNamespace, {
// ---------------------------------------------------------------------------
export default function SinglePageModule() {
return (
<EnterpriseModuleProvider<SinglePageEntity> config={SinglePageModuleConfig} dataServices={singlePageDataService}>
<EnterpriseModuleProvider<SinglePageEntity>
config={singlePageModuleConfig}
dataServices={singlePageDataService}
store={singlePageStore}
>
<Routes>
<Route path="/index" element={<IndexPage />} />
<Route path="/" element={<Navigate to={`${SinglePageModuleConfig.webUrl}/index`} replace={true} />} />
<Route path="/" element={<Navigate to={`${singlePageModuleConfig.webUrl}/index`} replace={true} />} />
<Route path="*" element={<Navigate to={'/404'} replace={true} />} />
</Routes>
</EnterpriseModuleProvider>
@@ -0,0 +1,19 @@
import { create } from 'zustand';
import { EnterpriseModuleState } from '@repo/ui/foundations';
import { SinglePageEntity } from '../../domain/entities';
export interface SinglePageStoreState extends EnterpriseModuleState<SinglePageEntity> {}
export const singlePageStore = create<SinglePageStoreState>((set) => ({
metaData: null,
setMetaData: (data) => set({ metaData: data }),
filterData: { page: 1, limit: 10 },
setFilterData: (data) => set({ filterData: data }),
selectedRows: [],
setSelectedRows: (rows) => set({ selectedRows: rows }),
privileges: [],
setPrivileges: (privileges) => set({ privileges }),
}));