@appcorp/fusion-storybook 0.3.89 → 0.3.91

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (24) hide show
  1. package/base-modules/expense/context/expense-api-provider.d.ts +16 -0
  2. package/base-modules/expense/context/expense-api-provider.js +229 -0
  3. package/base-modules/expense/context/index.d.ts +3 -0
  4. package/base-modules/expense/context/index.js +3 -0
  5. package/base-modules/expense/{context.d.ts → context/shared.d.ts} +7 -67
  6. package/base-modules/expense/context/shared.js +63 -0
  7. package/base-modules/expense/context/use-expense-module.d.ts +66 -0
  8. package/base-modules/expense/{context.js → context/use-expense-module.js} +23 -236
  9. package/base-modules/expense/page.d.ts +7 -1
  10. package/base-modules/expense/page.js +5 -2
  11. package/base-modules/fee-structure/context/fee-structure-api-provider.d.ts +16 -0
  12. package/base-modules/fee-structure/context/fee-structure-api-provider.js +193 -0
  13. package/base-modules/fee-structure/context/index.d.ts +3 -0
  14. package/base-modules/fee-structure/context/index.js +3 -0
  15. package/base-modules/fee-structure/{context.d.ts → context/shared.d.ts} +7 -54
  16. package/base-modules/fee-structure/context/shared.js +47 -0
  17. package/base-modules/fee-structure/context/use-fee-structure-module.d.ts +54 -0
  18. package/base-modules/fee-structure/{context.js → context/use-fee-structure-module.js} +15 -196
  19. package/base-modules/fee-structure/page.d.ts +7 -1
  20. package/base-modules/fee-structure/page.js +5 -2
  21. package/base-modules/student-fee/page.d.ts +8 -1
  22. package/base-modules/student-fee/page.js +23 -20
  23. package/package.json +1 -1
  24. package/tsconfig.build.tsbuildinfo +1 -1
@@ -1,137 +1,42 @@
1
1
  "use client";
2
- /**
3
- * Expense Module — business logic + API integration
4
- *
5
- * This module wires the generic module state (created by
6
- * `createGenericModule`) to network actions using `useModuleEntityV2`.
7
- * It contains the domain-specific handlers (create/view/edit/delete),
8
- * local validation wiring, and toast notifications.
9
- *
10
- * Key responsibilities:
11
- * - expose `useExpenseModule()` which UI components call for actions
12
- * - keep the module-specific `apiParams` and callbacks in one place
13
- * - ensure cache invalidation and toast notifications on mutation
14
- *
15
- * Exported utilities:
16
- * - `ExpenseProvider` — provider component used by the page
17
- * - `EXPENSE_ACTION_TYPES` — action type constants (from factory)
18
- * - `EXPENSE_DRAWER` — drawer type constants
19
- * - `useExpenseModule()` — hook that returns handlers and state
20
- */
21
- import { useCallback, useEffect, useMemo, useRef } from "react";
2
+ import { useCallback, useMemo } from "react";
22
3
  import { useTheme } from "next-themes";
23
4
  import { useTranslations } from "next-intl";
24
- import { isCreatedOrUpdated } from "@react-pakistan/util-functions/general/is-created-or-updated";
25
5
  import { validateForm } from "@react-pakistan/util-functions/general/validate-form";
26
- import { useModuleEntityV2, } from "@react-pakistan/util-functions/hooks/use-module-entity-v2";
27
- import { useDebounce } from "@react-pakistan/util-functions/hooks/use-debounce";
28
- import { createGenericModule } from "@react-pakistan/util-functions/factory/generic-module-factory";
29
- import { DRAWER_TYPES } from "@react-pakistan/util-functions/factory/generic-component-factory";
30
6
  import { generateThemeToast, TOAST_VARIANT, } from "@appcorp/shadcn/lib/toast-utils";
31
- import { PAYMENT_METHOD, } from "../../type";
32
- import { pageLimit } from "./constants";
33
- import { EXPENSE_API_ROUTES } from "../../constants";
34
- import { getCachedWorkspaceSync } from "../workspace/cache";
35
- import { expenseFormValidation } from "./validate";
7
+ import { getCachedWorkspaceSync } from "../../workspace/cache";
8
+ import { expenseFormValidation } from "../validate";
9
+ import { EXPENSE_ACTION_TYPES, EXPENSE_DRAWER, useExpenseContext, } from "./shared";
10
+ import { useExpenseApiContext } from "./expense-api-provider";
36
11
  // ============================================================================
37
- // 1.1 DRAWER TYPES
38
- // ============================================================================
39
- export const EXPENSE_DRAWER = {
40
- FILTER_DRAWER: DRAWER_TYPES.FILTER_DRAWER,
41
- FORM_DRAWER: DRAWER_TYPES.FORM_DRAWER,
42
- MORE_ACTIONS_DRAWER: DRAWER_TYPES.MORE_ACTIONS_DRAWER,
43
- VIEW_DRAWER: DRAWER_TYPES.VIEW_DRAWER,
44
- };
45
- const normalizeDate = (date) => {
46
- if (!date)
47
- return "";
48
- try {
49
- return new Date(date).toISOString().split("T")[0];
50
- }
51
- catch (_a) {
52
- return "";
53
- }
54
- };
55
- const expenseConfig = {
56
- name: "Expense",
57
- displayName: "Expense",
58
- drawerTypes: DRAWER_TYPES,
59
- initialState: {
60
- // List Data
61
- items: [],
62
- count: 0,
63
- // Search & Pagination
64
- currentPage: 1,
65
- pageLimit,
66
- searchQuery: "",
67
- // UI State
68
- disableSaveButton: false,
69
- drawer: null,
70
- errors: {},
71
- // Form fields
72
- amount: 0,
73
- approvedBy: "",
74
- attachments: [],
75
- category: "",
76
- description: "",
77
- enabled: true,
78
- expenseDate: new Date().toISOString().slice(0, 10),
79
- id: "",
80
- invoiceNumber: "",
81
- paidBy: "",
82
- paymentDate: new Date().toISOString().slice(0, 10),
83
- paymentMethod: PAYMENT_METHOD.CASH,
84
- receiptNumber: "",
85
- remarks: "",
86
- schoolId: "",
87
- status: "",
88
- title: "",
89
- transactionId: "",
90
- vendorContact: "",
91
- vendorName: "",
92
- // Filters
93
- filterCategory: "",
94
- filterEnabled: undefined,
95
- filterStatus: "",
96
- // Relations
97
- school: undefined,
98
- },
99
- };
100
- // ============================================================================
101
- // 1.3 CREATE EXPENSE MODULE
102
- // ============================================================================
103
- export const { actionTypes: EXPENSE_ACTION_TYPES, config: expenseModuleConfig, initialState: initialExpenseState, Provider: ExpenseProvider, reducer: expenseReducer, useContext: useExpenseContext, } = createGenericModule(expenseConfig);
104
- // ============================================================================
105
- // 1.4 ENHANCED EXPENSE HOOK WITH API INTEGRATION
12
+ // ENHANCED EXPENSE HOOK WITH API INTEGRATION
106
13
  // ============================================================================
107
14
  export const useExpenseModule = () => {
108
15
  // ============================================================================
109
- // 1.4.1 STATE & CORE HOOKS
16
+ // 1.4.1 STATE & API HOOKS
110
17
  // ============================================================================
111
18
  var _a;
112
19
  const context = useExpenseContext();
113
20
  const { dispatch } = context;
114
21
  const state = context.state;
22
+ const { listFetchNow, listLoading, updateFetchNow, updateLoading, byIdFetchNow, byIdLoading, deleteFetchNow, deleteLoading, resetFormAndCloseDrawer, } = useExpenseApiContext();
115
23
  const t = useTranslations("expense");
116
24
  const { theme } = useTheme();
117
25
  const workspace = getCachedWorkspaceSync();
118
26
  const schoolId = ((_a = workspace === null || workspace === void 0 ? void 0 : workspace.school) === null || _a === void 0 ? void 0 : _a.id) || "";
119
- const listFetchNowRef = useRef(null);
120
- const debouncedQuery = useDebounce(state.searchQuery, 800);
121
27
  // ============================================================================
122
- // 1.4.2 API PARAMETERS
28
+ // 1.4.2 UTILITIES
29
+ // ============================================================================
30
+ const showToast = useCallback((description, variant) => {
31
+ generateThemeToast({
32
+ description,
33
+ theme: theme,
34
+ variant,
35
+ });
36
+ }, [theme]);
37
+ // ============================================================================
38
+ // 1.4.3 UPDATE PARAMS (used by handleSubmit for validation + fetch body)
123
39
  // ============================================================================
124
- const listParams = useMemo(() => (Object.assign(Object.assign(Object.assign(Object.assign({ currentPage: state.currentPage, pageLimit: state.pageLimit, schoolId }, (debouncedQuery ? { searchQuery: debouncedQuery } : {})), (state.filterCategory ? { filterCategory: state.filterCategory } : {})), (state.filterStatus ? { filterStatus: state.filterStatus } : {})), (state.filterEnabled !== undefined
125
- ? { filterEnabled: state.filterEnabled }
126
- : {}))), [
127
- state.currentPage,
128
- state.filterCategory,
129
- state.filterEnabled,
130
- state.filterStatus,
131
- state.pageLimit,
132
- debouncedQuery,
133
- schoolId,
134
- ]);
135
40
  const updateParams = useMemo(() => ({
136
41
  amount: state.amount,
137
42
  approvedBy: state.approvedBy || null,
@@ -154,114 +59,8 @@ export const useExpenseModule = () => {
154
59
  vendorContact: state.vendorContact || null,
155
60
  vendorName: state.vendorName || null,
156
61
  }), [state, schoolId]);
157
- const byIdParams = useMemo(() => ({ id: state.id }), [state.id]);
158
- const deleteParams = useMemo(() => ({ id: state.id }), [state.id]);
159
62
  // ============================================================================
160
- // 1.4.3 UTILITIES
161
- // ============================================================================
162
- const showToast = useCallback((description, variant) => {
163
- generateThemeToast({
164
- description,
165
- theme: theme,
166
- variant,
167
- });
168
- }, [theme]);
169
- const resetFormAndCloseDrawer = useCallback(() => {
170
- dispatch({ type: EXPENSE_ACTION_TYPES.RESET_FORM });
171
- dispatch({
172
- type: EXPENSE_ACTION_TYPES.SET_ERRORS,
173
- payload: { errors: {} },
174
- });
175
- dispatch({
176
- type: EXPENSE_ACTION_TYPES.SET_DISABLE_SAVE_BUTTON,
177
- payload: { disabled: false },
178
- });
179
- dispatch({
180
- type: EXPENSE_ACTION_TYPES.SET_DRAWER,
181
- payload: { drawer: null },
182
- });
183
- }, [dispatch]);
184
- // ============================================================================
185
- // 1.4.4 API CALLBACKS
186
- // ============================================================================
187
- const listCallback = useCallback(({ data, error }) => {
188
- var _a;
189
- if (error) {
190
- showToast(t("messagesNetworkError"), TOAST_VARIANT.ERROR);
191
- return;
192
- }
193
- if (data) {
194
- const response = data;
195
- const items = (_a = response.items) !== null && _a !== void 0 ? _a : [];
196
- const count = typeof response.count === "number" ? response.count : 0;
197
- dispatch({
198
- type: EXPENSE_ACTION_TYPES.SET_ITEMS,
199
- payload: { items, count },
200
- });
201
- }
202
- }, [dispatch, showToast, t]);
203
- const updateCallback = useCallback(({ data, error }) => {
204
- var _a;
205
- if (error) {
206
- showToast(t("messagesNetworkError"), TOAST_VARIANT.ERROR);
207
- return;
208
- }
209
- if (data) {
210
- const isCreated = isCreatedOrUpdated(data);
211
- showToast(isCreated ? t("messagesExpenseCreated") : t("messagesExpenseUpdated"), TOAST_VARIANT.SUCCESS);
212
- resetFormAndCloseDrawer();
213
- (_a = listFetchNowRef.current) === null || _a === void 0 ? void 0 : _a.call(listFetchNowRef);
214
- }
215
- }, [showToast, t, resetFormAndCloseDrawer]);
216
- const byIdCallback = useCallback(({ data, error }) => {
217
- if (error) {
218
- showToast(t("messagesNetworkError"), TOAST_VARIANT.ERROR);
219
- return;
220
- }
221
- if (data) {
222
- const expense = data;
223
- dispatch({
224
- type: EXPENSE_ACTION_TYPES.SET_FORM_DATA,
225
- payload: {
226
- form: Object.assign(Object.assign({}, expense), { expenseDate: normalizeDate(expense.expenseDate), paymentDate: normalizeDate(expense.paymentDate), paymentMethod: expense.paymentMethod || "", filterEnabled: undefined, filterCategory: "", filterStatus: "" }),
227
- },
228
- });
229
- }
230
- }, [dispatch, showToast, t]);
231
- const deleteCallback = useCallback(({ data, error }) => {
232
- var _a;
233
- if (error) {
234
- showToast(t("messagesNetworkError"), TOAST_VARIANT.ERROR);
235
- return;
236
- }
237
- if (data) {
238
- showToast(t("messagesExpenseDeleted"), TOAST_VARIANT.SUCCESS);
239
- (_a = listFetchNowRef.current) === null || _a === void 0 ? void 0 : _a.call(listFetchNowRef);
240
- }
241
- }, [showToast, t]);
242
- // ============================================================================
243
- // 1.4.5 API HOOKS
244
- // ============================================================================
245
- const { byIdFetchNow, byIdLoading, deleteFetchNow, deleteLoading, listFetchNow, listLoading, updateFetchNow, updateLoading, } = useModuleEntityV2({
246
- byIdCallback,
247
- byIdParams,
248
- deleteCallback,
249
- deleteParams,
250
- headers: {
251
- "Content-Type": "application/json",
252
- // "x-api-token": process.env.NEXT_PUBLIC_API_KEY!,
253
- },
254
- listCallback,
255
- listParams,
256
- listUrl: EXPENSE_API_ROUTES.UNIT,
257
- searchQuery: debouncedQuery,
258
- unitByIdUrl: EXPENSE_API_ROUTES.UNIT,
259
- unitUrl: EXPENSE_API_ROUTES.UNIT,
260
- updateCallback,
261
- updateParams,
262
- });
263
- // ============================================================================
264
- // 1.4.6 HANDLERS
63
+ // 1.4.4 HANDLERS
265
64
  // ============================================================================
266
65
  const handleChange = useCallback((field, value) => {
267
66
  dispatch({
@@ -373,7 +172,7 @@ export const useExpenseModule = () => {
373
172
  });
374
173
  }, [dispatch]);
375
174
  // ============================================================================
376
- // 1.4.7 NETWORK ACTIONS
175
+ // 1.4.5 NETWORK ACTIONS
377
176
  // ============================================================================
378
177
  const handleSubmit = useCallback(() => {
379
178
  dispatch({
@@ -402,7 +201,7 @@ export const useExpenseModule = () => {
402
201
  });
403
202
  }, [dispatch, updateParams, updateFetchNow, t, showToast]);
404
203
  // ============================================================================
405
- // 1.4.8 HEADER & ROW ACTIONS
204
+ // 1.4.6 HEADER & ROW ACTIONS
406
205
  // ============================================================================
407
206
  const headerActions = useMemo(() => [
408
207
  {
@@ -445,19 +244,7 @@ export const useExpenseModule = () => {
445
244
  },
446
245
  ], [handleDelete, handleEdit, handleView, t]);
447
246
  // ============================================================================
448
- // 1.4.9 EFFECTS
449
- // ============================================================================
450
- useEffect(() => {
451
- listFetchNowRef.current = listFetchNow;
452
- }, [listFetchNow]);
453
- useEffect(() => {
454
- var _a;
455
- if (!schoolId)
456
- return;
457
- (_a = listFetchNowRef.current) === null || _a === void 0 ? void 0 : _a.call(listFetchNowRef);
458
- }, [listParams, schoolId]);
459
- // ============================================================================
460
- // 1.4.10 RETURN
247
+ // 1.4.7 RETURN
461
248
  // ============================================================================
462
249
  return Object.assign(Object.assign({}, context), { applyFilters,
463
250
  byIdLoading,
@@ -14,7 +14,11 @@
14
14
  */
15
15
  import { FC } from "react";
16
16
  import { USER_ROLE } from "../../type";
17
- interface Props {
17
+ interface ConfigProps {
18
+ dispatch: React.Dispatch<{
19
+ type: string;
20
+ payload?: unknown;
21
+ }>;
18
22
  drawerButtonCancel: string;
19
23
  drawerButtonSave: string;
20
24
  drawerFilterDescription: string;
@@ -36,6 +40,8 @@ interface Props {
36
40
  tableDescription: string;
37
41
  tableSearchPlaceholder: string;
38
42
  tableTitle: string;
43
+ }
44
+ interface Props extends ConfigProps {
39
45
  userRole: USER_ROLE;
40
46
  }
41
47
  export declare const ExpensePage: FC<Props>;
@@ -18,7 +18,7 @@ import { useMemo } from "react";
18
18
  import { COMPONENT_TYPE } from "@appcorp/shadcn/components/enhanced-table";
19
19
  import { createGenericModulePage, } from "@react-pakistan/util-functions/factory/generic-component-factory";
20
20
  import { DATE_FORMATS, formatDate, } from "@react-pakistan/util-functions/general/format-date";
21
- import { useExpenseModule, ExpenseProvider, EXPENSE_ACTION_TYPES, } from "./context";
21
+ import { useExpenseModule, ExpenseProvider, ExpenseApiProvider, EXPENSE_ACTION_TYPES, } from "./context";
22
22
  import { ExpenseFilter } from "./filter";
23
23
  import { ExpenseForm } from "./form";
24
24
  import { ExpenseMoreActions } from "./more-actions";
@@ -104,6 +104,9 @@ const createExpenseConfig = ({ dispatch, drawerButtonCancel, drawerButtonSave, d
104
104
  // STABLE PAGE COMPONENT (created once, outside render)
105
105
  // ============================================================================
106
106
  const GenericExpensePage = createGenericModulePage();
107
+ // ============================================================================
108
+ // INNER PAGE (requires ExpenseProvider context)
109
+ // ============================================================================
107
110
  const ExpensePageInner = (props) => {
108
111
  const context = useExpenseModule();
109
112
  // Memoize config creation - destructure props to avoid object reference changes
@@ -166,4 +169,4 @@ const ExpensePageInner = (props) => {
166
169
  // ============================================================================
167
170
  // PAGE EXPORTS
168
171
  // ============================================================================
169
- export const ExpensePage = (props) => (_jsx(ExpenseProvider, { children: _jsx(ExpensePageInner, Object.assign({}, props)) }));
172
+ export const ExpensePage = (props) => (_jsx(ExpenseProvider, { children: _jsx(ExpenseApiProvider, { children: _jsx(ExpensePageInner, Object.assign({}, props)) }) }));
@@ -0,0 +1,16 @@
1
+ import type { FetchConfig } from "@react-pakistan/util-functions/hooks/use-fetch";
2
+ export interface FeeStructureApiContextType {
3
+ listFetchNow: (url?: string, config?: FetchConfig) => void;
4
+ listLoading: boolean;
5
+ updateFetchNow: (url?: string, config?: FetchConfig) => void;
6
+ updateLoading: boolean;
7
+ byIdFetchNow: (url?: string, config?: FetchConfig) => void;
8
+ byIdLoading: boolean;
9
+ deleteFetchNow?: (url?: string, config?: FetchConfig) => void;
10
+ deleteLoading: boolean;
11
+ resetFormAndCloseDrawer: () => void;
12
+ }
13
+ export declare const useFeeStructureApiContext: () => FeeStructureApiContextType;
14
+ export declare const FeeStructureApiProvider: ({ children, }: {
15
+ children: React.ReactNode;
16
+ }) => import("react").JSX.Element;
@@ -0,0 +1,193 @@
1
+ "use client";
2
+ import { jsx as _jsx } from "react/jsx-runtime";
3
+ import { createContext, useCallback, useContext, useEffect, useMemo, useRef } from "react";
4
+ import { useTheme } from "next-themes";
5
+ import { useTranslations } from "next-intl";
6
+ import { isCreatedOrUpdated } from "@react-pakistan/util-functions/general/is-created-or-updated";
7
+ import { useModuleEntityV2, } from "@react-pakistan/util-functions/hooks/use-module-entity-v2";
8
+ import { useDebounce } from "@react-pakistan/util-functions/hooks/use-debounce";
9
+ import { generateThemeToast, TOAST_VARIANT, } from "@appcorp/shadcn/lib/toast-utils";
10
+ import { FEE_STRUCTURE_API_ROUTES } from "../../../constants";
11
+ import { getCachedWorkspaceSync } from "../../workspace/cache";
12
+ import { FEE_STRUCTURE_ACTION_TYPES, useFeeStructureContext, } from "./shared";
13
+ // ============================================================================
14
+ // CONTEXT
15
+ // ============================================================================
16
+ const FeeStructureApiContext = createContext(null);
17
+ export const useFeeStructureApiContext = () => {
18
+ const ctx = useContext(FeeStructureApiContext);
19
+ if (!ctx) {
20
+ throw new Error("useFeeStructureApiContext must be used within FeeStructureApiProvider");
21
+ }
22
+ return ctx;
23
+ };
24
+ // ============================================================================
25
+ // PROVIDER
26
+ // ============================================================================
27
+ export const FeeStructureApiProvider = ({ children, }) => {
28
+ var _a;
29
+ const context = useFeeStructureContext();
30
+ const { dispatch } = context;
31
+ const state = context.state;
32
+ const t = useTranslations("feeStructure");
33
+ const { theme } = useTheme();
34
+ const workspace = getCachedWorkspaceSync();
35
+ const debouncedQuery = useDebounce(state.searchQuery, 800);
36
+ const schoolId = ((_a = workspace === null || workspace === void 0 ? void 0 : workspace.school) === null || _a === void 0 ? void 0 : _a.id) || "";
37
+ // ==========================================================================
38
+ // UTILITIES
39
+ // ==========================================================================
40
+ const showToast = useCallback((description, variant) => {
41
+ generateThemeToast({
42
+ description,
43
+ theme: theme,
44
+ variant,
45
+ });
46
+ }, [theme]);
47
+ const resetFormAndCloseDrawer = useCallback(() => {
48
+ dispatch({ type: FEE_STRUCTURE_ACTION_TYPES.RESET_FORM });
49
+ dispatch({
50
+ type: FEE_STRUCTURE_ACTION_TYPES.SET_ERRORS,
51
+ payload: { errors: {} },
52
+ });
53
+ dispatch({
54
+ type: FEE_STRUCTURE_ACTION_TYPES.SET_DISABLE_SAVE_BUTTON,
55
+ payload: { disabled: false },
56
+ });
57
+ dispatch({
58
+ type: FEE_STRUCTURE_ACTION_TYPES.SET_DRAWER,
59
+ payload: { drawer: null },
60
+ });
61
+ }, [dispatch]);
62
+ // ==========================================================================
63
+ // API PARAMETERS
64
+ // ==========================================================================
65
+ const listParams = useMemo(() => (Object.assign(Object.assign({ currentPage: state.currentPage, pageLimit: state.pageLimit, schoolId }, (debouncedQuery ? { searchQuery: debouncedQuery } : {})), (state.filterEnabled !== undefined
66
+ ? { filterEnabled: String(state.filterEnabled) }
67
+ : {}))), [
68
+ state.currentPage,
69
+ state.filterEnabled,
70
+ state.pageLimit,
71
+ debouncedQuery,
72
+ schoolId,
73
+ ]);
74
+ const updateParams = useMemo(() => (Object.assign(Object.assign(Object.assign({}, (state.id ? { id: state.id } : {})), (!state.id ? { schoolId } : {})), { amount: Number(state.amount), classId: state.classId || null, description: state.description || null, enabled: state.enabled, feeType: state.feeType, frequency: state.frequency || null, name: state.name })), [state, schoolId]);
75
+ const byIdParams = useMemo(() => ({ id: state.id }), [state.id]);
76
+ const deleteParams = useMemo(() => ({ id: state.id }), [state.id]);
77
+ // ==========================================================================
78
+ // API CALLBACKS
79
+ // ==========================================================================
80
+ const listCallback = useCallback(({ data, error }) => {
81
+ var _a, _b;
82
+ if (error) {
83
+ showToast(t("messagesNetworkError"), TOAST_VARIANT.ERROR);
84
+ return;
85
+ }
86
+ if (data) {
87
+ const response = data;
88
+ dispatch({
89
+ type: FEE_STRUCTURE_ACTION_TYPES.SET_ITEMS,
90
+ payload: { items: (_a = response.items) !== null && _a !== void 0 ? _a : [], count: (_b = response.count) !== null && _b !== void 0 ? _b : 0 },
91
+ });
92
+ }
93
+ }, [dispatch, showToast, t]);
94
+ const listFetchNowRef = useRef(null);
95
+ const updateCallback = useCallback(({ data, error }) => {
96
+ var _a;
97
+ if (error) {
98
+ showToast(t("messagesNetworkError"), TOAST_VARIANT.ERROR);
99
+ return;
100
+ }
101
+ if (data) {
102
+ const isCreated = isCreatedOrUpdated(data);
103
+ showToast(isCreated
104
+ ? t("messagesFeeStructureCreated")
105
+ : t("messagesFeeStructureUpdated"), TOAST_VARIANT.SUCCESS);
106
+ resetFormAndCloseDrawer();
107
+ (_a = listFetchNowRef.current) === null || _a === void 0 ? void 0 : _a.call(listFetchNowRef);
108
+ }
109
+ }, [resetFormAndCloseDrawer, showToast, t]);
110
+ const byIdCallback = useCallback(({ data, error }) => {
111
+ if (error) {
112
+ showToast(t("messagesNetworkError"), TOAST_VARIANT.ERROR);
113
+ return;
114
+ }
115
+ if (data) {
116
+ dispatch({
117
+ type: FEE_STRUCTURE_ACTION_TYPES.SET_FORM_DATA,
118
+ payload: { form: Object.assign(Object.assign({}, data), { filterEnabled: undefined }) },
119
+ });
120
+ }
121
+ }, [dispatch, showToast, t]);
122
+ const deleteCallback = useCallback(({ data, error }) => {
123
+ var _a;
124
+ if (error) {
125
+ showToast(t("messagesNetworkError"), TOAST_VARIANT.ERROR);
126
+ return;
127
+ }
128
+ if (data) {
129
+ showToast(t("messagesFeeStructureDeleted"), TOAST_VARIANT.SUCCESS);
130
+ (_a = listFetchNowRef.current) === null || _a === void 0 ? void 0 : _a.call(listFetchNowRef);
131
+ }
132
+ }, [showToast, t]);
133
+ // ==========================================================================
134
+ // SINGLE API HOOK INSTANCE
135
+ // ==========================================================================
136
+ const { listFetchNow, listLoading, updateFetchNow, updateLoading, byIdFetchNow, deleteFetchNow, deleteLoading, byIdLoading, } = useModuleEntityV2({
137
+ byIdCallback,
138
+ byIdParams,
139
+ deleteCallback,
140
+ deleteParams,
141
+ listCallback,
142
+ listParams,
143
+ listUrl: FEE_STRUCTURE_API_ROUTES.UNIT,
144
+ searchQuery: debouncedQuery,
145
+ unitByIdUrl: FEE_STRUCTURE_API_ROUTES.UNIT,
146
+ unitUrl: FEE_STRUCTURE_API_ROUTES.UNIT,
147
+ updateCallback,
148
+ updateParams,
149
+ headers: {
150
+ "Content-Type": "application/json",
151
+ },
152
+ });
153
+ // ==========================================================================
154
+ // REF SYNC (for callbacks to always call the latest fetch)
155
+ // ==========================================================================
156
+ useEffect(() => {
157
+ listFetchNowRef.current = listFetchNow;
158
+ }, [listFetchNow]);
159
+ // ==========================================================================
160
+ // AUTO-FETCH EFFECT (runs once, not per child mount)
161
+ // ==========================================================================
162
+ useEffect(() => {
163
+ var _a;
164
+ if (!schoolId)
165
+ return;
166
+ (_a = listFetchNowRef.current) === null || _a === void 0 ? void 0 : _a.call(listFetchNowRef);
167
+ }, [listParams, schoolId]);
168
+ // ==========================================================================
169
+ // CONTEXT VALUE
170
+ // ==========================================================================
171
+ const value = useMemo(() => ({
172
+ listFetchNow,
173
+ listLoading,
174
+ updateFetchNow,
175
+ updateLoading,
176
+ byIdFetchNow,
177
+ byIdLoading,
178
+ deleteFetchNow,
179
+ deleteLoading,
180
+ resetFormAndCloseDrawer,
181
+ }), [
182
+ listFetchNow,
183
+ listLoading,
184
+ updateFetchNow,
185
+ updateLoading,
186
+ byIdFetchNow,
187
+ byIdLoading,
188
+ deleteFetchNow,
189
+ deleteLoading,
190
+ resetFormAndCloseDrawer,
191
+ ]);
192
+ return (_jsx(FeeStructureApiContext.Provider, { value: value, children: children }));
193
+ };
@@ -0,0 +1,3 @@
1
+ export { FEE_STRUCTURE_DRAWER, FEE_STRUCTURE_ACTION_TYPES, feeStructureModuleConfig, initialFeeStructureState, FeeStructureProvider, feeStructureReducer, useFeeStructureContext, } from "./shared";
2
+ export { FeeStructureApiProvider, useFeeStructureApiContext, } from "./fee-structure-api-provider";
3
+ export { useFeeStructureModule } from "./use-fee-structure-module";
@@ -0,0 +1,3 @@
1
+ export { FEE_STRUCTURE_DRAWER, FEE_STRUCTURE_ACTION_TYPES, feeStructureModuleConfig, initialFeeStructureState, FeeStructureProvider, feeStructureReducer, useFeeStructureContext, } from "./shared";
2
+ export { FeeStructureApiProvider, useFeeStructureApiContext, } from "./fee-structure-api-provider";
3
+ export { useFeeStructureModule } from "./use-fee-structure-module";
@@ -1,11 +1,16 @@
1
- import { type RowAction, type TableRow } from "@appcorp/shadcn/components/enhanced-table";
2
- import { FeeStructureBE, FEE_TYPE } from "../../type";
1
+ import { FeeStructureBE, FEE_TYPE } from "../../../type";
3
2
  export declare const FEE_STRUCTURE_DRAWER: {
4
3
  readonly FILTER_DRAWER: string;
5
4
  readonly FORM_DRAWER: string;
6
5
  readonly MORE_ACTIONS_DRAWER: string;
7
6
  readonly VIEW_DRAWER: string;
8
7
  };
8
+ export interface FeeStructuresListResponse {
9
+ items: FeeStructureBE[];
10
+ count: number;
11
+ currentPage: number;
12
+ pageLimit: number;
13
+ }
9
14
  export declare const FEE_STRUCTURE_ACTION_TYPES: {
10
15
  readonly RESET_FORM: "RESET_FORM";
11
16
  readonly SET_CURRENT_PAGE: "SET_CURRENT_PAGE";
@@ -116,55 +121,3 @@ export declare const FEE_STRUCTURE_ACTION_TYPES: {
116
121
  name: string;
117
122
  schoolId: string;
118
123
  }>;
119
- export declare const useFeeStructureModule: () => {
120
- applyFilters: () => void;
121
- byIdLoading: boolean;
122
- clearFilters: () => void;
123
- clearSearch: () => void;
124
- closeDrawer: () => void;
125
- deleteLoading: boolean;
126
- handleChange: (field: string, value: string | number | boolean | FEE_TYPE | null | undefined) => void;
127
- handleCreate: () => void;
128
- handleDelete: (row?: TableRow) => void;
129
- handleEdit: (row?: TableRow) => void;
130
- handleFilters: () => void;
131
- handleMoreActions: () => void;
132
- handlePageChange: (page: number | unknown) => void;
133
- handlePageLimitChange: (k: string, value: object) => void;
134
- handleSearch: (query: string) => void;
135
- handleSubmit: () => void;
136
- handleView: (row?: TableRow) => void;
137
- headerActions: {
138
- enabled: boolean;
139
- handleOnClick: () => void;
140
- label: string;
141
- order: number;
142
- }[];
143
- listFetchNow: (url?: string, config?: import("@react-pakistan/util-functions/hooks/use-fetch").FetchConfig) => void;
144
- listLoading: boolean;
145
- rowActions: RowAction[];
146
- toggleStatus: (row?: TableRow) => void;
147
- updateLoading: boolean;
148
- handleCloseDrawer?: () => void;
149
- state: {
150
- items: FeeStructureBE[];
151
- count: number;
152
- currentPage: number;
153
- pageLimit: number;
154
- searchQuery: string;
155
- disableSaveButton: boolean;
156
- drawer: string | null;
157
- amount: number;
158
- classId: string | null;
159
- description: string | null;
160
- enabled: boolean;
161
- errors: Record<string, string>;
162
- feeType: FEE_TYPE;
163
- filterEnabled: boolean | undefined;
164
- frequency: string | null;
165
- id: string;
166
- name: string;
167
- schoolId: string;
168
- };
169
- dispatch: React.Dispatch<any>;
170
- };