@appcorp/fusion-storybook 0.3.84 → 0.3.86

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.
@@ -0,0 +1,3 @@
1
+ export { STUDENT_FEE_DRAWER, STUDENT_FEE_ACTION_TYPES, studentFeeModuleConfig, initialStudentFeeState, StudentFeeProvider, studentFeeReducer, useStudentFeeContext, } from "./shared";
2
+ export { StudentFeeApiProvider, useStudentFeeApiContext } from "./student-fee-api-provider";
3
+ export { useStudentFeeModule } from "./use-student-fee-module";
@@ -0,0 +1,3 @@
1
+ export { STUDENT_FEE_DRAWER, STUDENT_FEE_ACTION_TYPES, studentFeeModuleConfig, initialStudentFeeState, StudentFeeProvider, studentFeeReducer, useStudentFeeContext, } from "./shared";
2
+ export { StudentFeeApiProvider, useStudentFeeApiContext } from "./student-fee-api-provider";
3
+ export { useStudentFeeModule } from "./use-student-fee-module";
@@ -0,0 +1,16 @@
1
+ import type { FetchConfig } from "@react-pakistan/util-functions/hooks/use-fetch";
2
+ export interface StudentFeeApiContextType {
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 useStudentFeeApiContext: () => StudentFeeApiContextType;
14
+ export declare const StudentFeeApiProvider: ({ children, }: {
15
+ children: React.ReactNode;
16
+ }) => import("react").JSX.Element;
@@ -0,0 +1,233 @@
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 { STUDENT_FEE_API_ROUTES } from "../../../constants";
11
+ import { getCachedWorkspaceSync } from "../../workspace/cache";
12
+ import { STUDENT_FEE_ACTION_TYPES, useStudentFeeContext, } from "./shared";
13
+ // ============================================================================
14
+ // CONTEXT
15
+ // ============================================================================
16
+ const StudentFeeApiContext = createContext(null);
17
+ export const useStudentFeeApiContext = () => {
18
+ const ctx = useContext(StudentFeeApiContext);
19
+ if (!ctx) {
20
+ throw new Error("useStudentFeeApiContext must be used within StudentFeeApiProvider");
21
+ }
22
+ return ctx;
23
+ };
24
+ // ============================================================================
25
+ // PROVIDER
26
+ // ============================================================================
27
+ export const StudentFeeApiProvider = ({ children, }) => {
28
+ var _a;
29
+ const context = useStudentFeeContext();
30
+ const { dispatch } = context;
31
+ const state = context.state;
32
+ const t = useTranslations("studentFee");
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: STUDENT_FEE_ACTION_TYPES.RESET_FORM });
49
+ dispatch({
50
+ type: STUDENT_FEE_ACTION_TYPES.SET_ERRORS,
51
+ payload: { errors: {} },
52
+ });
53
+ dispatch({
54
+ type: STUDENT_FEE_ACTION_TYPES.SET_DISABLE_SAVE_BUTTON,
55
+ payload: { disabled: false },
56
+ });
57
+ dispatch({
58
+ type: STUDENT_FEE_ACTION_TYPES.SET_DRAWER,
59
+ payload: { drawer: null },
60
+ });
61
+ }, [dispatch]);
62
+ // ==========================================================================
63
+ // API PARAMETERS
64
+ // ==========================================================================
65
+ const listParams = useMemo(() => (Object.assign({ currentPage: state.currentPage, pageLimit: state.pageLimit, schoolId }, (debouncedQuery ? { searchQuery: debouncedQuery } : {}))), [state.currentPage, state.pageLimit, debouncedQuery, schoolId]);
66
+ const updateParams = useMemo(() => ({
67
+ amount: Number(state.amount),
68
+ amountDue: Number(state.amountDue),
69
+ amountPaid: Number(state.amountPaid),
70
+ discountAmount: Number(state.discountAmount),
71
+ discountCodeId: state.discountCodeId,
72
+ dueDate: state.dueDate,
73
+ enabled: state.enabled,
74
+ familyId: state.familyId,
75
+ feeStructureId: state.feeStructureId,
76
+ id: state.id,
77
+ paidAt: state.paidAt || null,
78
+ remarks: state.remarks || null,
79
+ schoolId,
80
+ status: state.status,
81
+ studentProfileId: state.studentProfileId,
82
+ }), [
83
+ state.amount,
84
+ state.amountDue,
85
+ state.amountPaid,
86
+ state.discountAmount,
87
+ state.discountCodeId,
88
+ state.dueDate,
89
+ state.enabled,
90
+ state.familyId,
91
+ state.feeStructureId,
92
+ state.id,
93
+ state.paidAt,
94
+ state.remarks,
95
+ state.status,
96
+ state.studentProfileId,
97
+ schoolId,
98
+ ]);
99
+ const byIdParams = useMemo(() => ({ id: state.id }), [state.id]);
100
+ const deleteParams = useMemo(() => ({ id: state.id }), [state.id]);
101
+ // ==========================================================================
102
+ // API CALLBACKS
103
+ // ==========================================================================
104
+ const listCallback = useCallback(({ data, error }) => {
105
+ var _a, _b;
106
+ if (error) {
107
+ showToast(t("messagesNetworkError"), TOAST_VARIANT.ERROR);
108
+ return;
109
+ }
110
+ if (data) {
111
+ const response = data;
112
+ dispatch({
113
+ type: STUDENT_FEE_ACTION_TYPES.SET_ITEMS,
114
+ payload: { items: (_a = response.items) !== null && _a !== void 0 ? _a : [], count: (_b = response.count) !== null && _b !== void 0 ? _b : 0 },
115
+ });
116
+ }
117
+ }, [dispatch, showToast, t]);
118
+ const listFetchNowRef = useRef(null);
119
+ const updateCallback = useCallback(({ data, error }) => {
120
+ var _a;
121
+ if (error) {
122
+ showToast(t("messagesNetworkError"), TOAST_VARIANT.ERROR);
123
+ return;
124
+ }
125
+ if (data) {
126
+ const isCreated = isCreatedOrUpdated(data);
127
+ showToast(isCreated
128
+ ? t("messagesStudentFeeCreated")
129
+ : t("messagesStudentFeeUpdated"), TOAST_VARIANT.SUCCESS);
130
+ resetFormAndCloseDrawer();
131
+ (_a = listFetchNowRef.current) === null || _a === void 0 ? void 0 : _a.call(listFetchNowRef);
132
+ }
133
+ }, [showToast, t, resetFormAndCloseDrawer]);
134
+ const byIdCallback = useCallback(({ data, error }) => {
135
+ if (error) {
136
+ showToast(t("messagesNetworkError"), TOAST_VARIANT.ERROR);
137
+ return;
138
+ }
139
+ if (data) {
140
+ const fee = data;
141
+ const rawDueDate = fee.dueDate;
142
+ const dueDate = rawDueDate instanceof Date
143
+ ? `${rawDueDate.getFullYear()}-${String(rawDueDate.getMonth() + 1).padStart(2, "0")}-${String(rawDueDate.getDate()).padStart(2, "0")}`
144
+ : String(rawDueDate).slice(0, 10);
145
+ const rawPaidAt = fee.paidAt;
146
+ const today = new Date();
147
+ const todayStr = `${today.getFullYear()}-${String(today.getMonth() + 1).padStart(2, "0")}-${String(today.getDate()).padStart(2, "0")}`;
148
+ const paidAt = rawPaidAt instanceof Date
149
+ ? `${rawPaidAt.getFullYear()}-${String(rawPaidAt.getMonth() + 1).padStart(2, "0")}-${String(rawPaidAt.getDate()).padStart(2, "0")}`
150
+ : rawPaidAt
151
+ ? String(rawPaidAt).slice(0, 10)
152
+ : todayStr;
153
+ const originalFee = Number(fee.amount) + Number(fee.discountAmount || 0);
154
+ dispatch({
155
+ type: STUDENT_FEE_ACTION_TYPES.SET_FORM_DATA,
156
+ payload: {
157
+ form: Object.assign(Object.assign({}, fee), { dueDate,
158
+ paidAt,
159
+ originalFee }),
160
+ },
161
+ });
162
+ }
163
+ }, [dispatch, showToast, t]);
164
+ const deleteCallback = useCallback(({ data, error }) => {
165
+ var _a;
166
+ if (error) {
167
+ showToast(t("messagesNetworkError"), TOAST_VARIANT.ERROR);
168
+ return;
169
+ }
170
+ if (data) {
171
+ showToast(t("messagesStudentFeeDeleted"), TOAST_VARIANT.SUCCESS);
172
+ (_a = listFetchNowRef.current) === null || _a === void 0 ? void 0 : _a.call(listFetchNowRef);
173
+ }
174
+ }, [showToast, t]);
175
+ // ==========================================================================
176
+ // SINGLE API HOOK INSTANCE
177
+ // ==========================================================================
178
+ const { listFetchNow, listLoading, updateFetchNow, updateLoading, byIdFetchNow, deleteFetchNow, deleteLoading, byIdLoading, } = useModuleEntityV2({
179
+ byIdCallback,
180
+ byIdParams,
181
+ deleteCallback,
182
+ deleteParams,
183
+ listCallback,
184
+ listParams,
185
+ listUrl: STUDENT_FEE_API_ROUTES.UNIT,
186
+ searchQuery: debouncedQuery,
187
+ unitByIdUrl: STUDENT_FEE_API_ROUTES.UNIT,
188
+ unitUrl: STUDENT_FEE_API_ROUTES.UNIT,
189
+ updateCallback,
190
+ updateParams,
191
+ headers: {
192
+ "Content-Type": "application/json",
193
+ },
194
+ });
195
+ // ==========================================================================
196
+ // REF SYNC (for callbacks to always call the latest fetch)
197
+ // ==========================================================================
198
+ useEffect(() => {
199
+ listFetchNowRef.current = listFetchNow;
200
+ }, [listFetchNow]);
201
+ // ==========================================================================
202
+ // AUTO-FETCH EFFECT (runs once, not per child mount)
203
+ // ==========================================================================
204
+ useEffect(() => {
205
+ var _a;
206
+ (_a = listFetchNowRef.current) === null || _a === void 0 ? void 0 : _a.call(listFetchNowRef);
207
+ }, [listParams]);
208
+ // ==========================================================================
209
+ // CONTEXT VALUE
210
+ // ==========================================================================
211
+ const value = useMemo(() => ({
212
+ listFetchNow,
213
+ listLoading,
214
+ updateFetchNow,
215
+ updateLoading,
216
+ byIdFetchNow,
217
+ byIdLoading,
218
+ deleteFetchNow,
219
+ deleteLoading,
220
+ resetFormAndCloseDrawer,
221
+ }), [
222
+ listFetchNow,
223
+ listLoading,
224
+ updateFetchNow,
225
+ updateLoading,
226
+ byIdFetchNow,
227
+ byIdLoading,
228
+ deleteFetchNow,
229
+ deleteLoading,
230
+ resetFormAndCloseDrawer,
231
+ ]);
232
+ return (_jsx(StudentFeeApiContext.Provider, { value: value, children: children }));
233
+ };
@@ -1,13 +1,10 @@
1
1
  "use client";
2
- import { useCallback, useEffect, useMemo, useRef } from "react";
2
+ import { useCallback, useMemo } from "react";
3
3
  import { useTheme } from "next-themes";
4
4
  import { useTranslations } from "next-intl";
5
5
  import { validateForm } from "@react-pakistan/util-functions/general/validate-form";
6
- import { isCreatedOrUpdated } from "@react-pakistan/util-functions/general/is-created-or-updated";
7
6
  import { getStorageValue } from "@react-pakistan/util-functions/local-storage/get-storage-value";
8
7
  import { API_METHODS } from "@react-pakistan/util-functions/constants/api-methods";
9
- import { useModuleEntityV2, } from "@react-pakistan/util-functions/hooks/use-module-entity-v2";
10
- import { useDebounce } from "@react-pakistan/util-functions/hooks/use-debounce";
11
8
  import { generateThemeToast, TOAST_VARIANT, } from "@appcorp/shadcn/lib/toast-utils";
12
9
  import { PAYMENT_STATUS, DISCOUNT_TYPE, } from "../../../type";
13
10
  import { STUDENT_FEE_API_ROUTES } from "../../../constants";
@@ -16,6 +13,7 @@ import { getCachedWorkspaceSync } from "../../workspace/cache";
16
13
  import { getCachedFeeStructureById } from "../../fee-structure/cache";
17
14
  import { getCachedDiscountCodesSync } from "../../discount-code/cache";
18
15
  import { STUDENT_FEE_ACTION_TYPES, STUDENT_FEE_DRAWER, useStudentFeeContext, } from "./shared";
16
+ import { useStudentFeeApiContext } from "./student-fee-api-provider";
19
17
  // ============================================================================
20
18
  // AMOUNT CALCULATION HELPER
21
19
  // ============================================================================
@@ -29,66 +27,19 @@ const calculateAmounts = (originalFee, discountAmount, amountPaid) => {
29
27
  // ============================================================================
30
28
  export const useStudentFeeModule = () => {
31
29
  // ============================================================================
32
- // 1.4.1 STATE & CORE HOOKS
30
+ // 1.4.1 STATE, CONTEXT & API HOOKS
33
31
  // ============================================================================
34
32
  var _a, _b, _c, _d;
35
33
  const context = useStudentFeeContext();
36
34
  const { dispatch } = context;
37
35
  const state = context.state;
36
+ const { listFetchNow, listLoading, updateFetchNow, updateLoading, byIdFetchNow, byIdLoading, deleteFetchNow, deleteLoading, resetFormAndCloseDrawer, } = useStudentFeeApiContext();
38
37
  const t = useTranslations("studentFee");
39
38
  const { theme } = useTheme();
40
39
  const workspace = getCachedWorkspaceSync();
41
- const listFetchNowRef = useRef(null);
42
- const debouncedQuery = useDebounce(state.searchQuery, 800);
43
40
  const schoolId = ((_a = workspace === null || workspace === void 0 ? void 0 : workspace.school) === null || _a === void 0 ? void 0 : _a.id) || "";
44
41
  // ============================================================================
45
- // 1.4.2 API PARAMETERS
46
- // ============================================================================
47
- const listParams = useMemo(() => (Object.assign({ currentPage: state.currentPage, pageLimit: state.pageLimit, schoolId }, (debouncedQuery ? { searchQuery: debouncedQuery } : {}))), [
48
- state.currentPage,
49
- // state.filterEnabled,
50
- // state.filterStatus,
51
- state.pageLimit,
52
- debouncedQuery,
53
- schoolId,
54
- ]);
55
- const updateParams = useMemo(() => ({
56
- amount: Number(state.amount),
57
- amountDue: Number(state.amountDue),
58
- amountPaid: Number(state.amountPaid),
59
- discountAmount: Number(state.discountAmount),
60
- discountCodeId: state.discountCodeId,
61
- dueDate: state.dueDate,
62
- enabled: state.enabled,
63
- familyId: state.familyId,
64
- feeStructureId: state.feeStructureId,
65
- id: state.id,
66
- paidAt: state.paidAt || null,
67
- remarks: state.remarks || null,
68
- schoolId,
69
- status: state.status,
70
- studentProfileId: state.studentProfileId,
71
- }), [
72
- state.amount,
73
- state.amountDue,
74
- state.amountPaid,
75
- state.discountAmount,
76
- state.discountCodeId,
77
- state.dueDate,
78
- state.enabled,
79
- state.familyId,
80
- state.feeStructureId,
81
- state.id,
82
- state.paidAt,
83
- state.remarks,
84
- state.status,
85
- state.studentProfileId,
86
- schoolId,
87
- ]);
88
- const byIdParams = useMemo(() => ({ id: state.id }), [state.id]);
89
- const deleteParams = useMemo(() => ({ id: state.id }), [state.id]);
90
- // ============================================================================
91
- // 1.4.3 UTILITIES
42
+ // 1.4.2 UTILITIES
92
43
  // ============================================================================
93
44
  const showToast = useCallback((description, variant) => {
94
45
  generateThemeToast({
@@ -97,21 +48,6 @@ export const useStudentFeeModule = () => {
97
48
  variant,
98
49
  });
99
50
  }, [theme]);
100
- const resetFormAndCloseDrawer = useCallback(() => {
101
- dispatch({ type: STUDENT_FEE_ACTION_TYPES.RESET_FORM });
102
- dispatch({
103
- type: STUDENT_FEE_ACTION_TYPES.SET_ERRORS,
104
- payload: { errors: {} },
105
- });
106
- dispatch({
107
- type: STUDENT_FEE_ACTION_TYPES.SET_DISABLE_SAVE_BUTTON,
108
- payload: { disabled: false },
109
- });
110
- dispatch({
111
- type: STUDENT_FEE_ACTION_TYPES.SET_DRAWER,
112
- payload: { drawer: null },
113
- });
114
- }, [dispatch]);
115
51
  const resetRecordFormState = useCallback(() => {
116
52
  var _a, _b;
117
53
  const dueDay = (_a = workspace === null || workspace === void 0 ? void 0 : workspace.dueDateLength) !== null && _a !== void 0 ? _a : 1;
@@ -155,101 +91,43 @@ export const useStudentFeeModule = () => {
155
91
  });
156
92
  }, [dispatch, workspace === null || workspace === void 0 ? void 0 : workspace.dueDateLength, (_b = workspace === null || workspace === void 0 ? void 0 : workspace.school) === null || _b === void 0 ? void 0 : _b.id]);
157
93
  // ============================================================================
158
- // 1.4.4 API CALLBACKS
94
+ // 1.4.3 UPDATE PARAMS (used by handleSubmit for validation + fetch body)
159
95
  // ============================================================================
160
- const listCallback = useCallback(({ data, error }) => {
161
- var _a, _b;
162
- if (error) {
163
- showToast(t("messagesNetworkError"), TOAST_VARIANT.ERROR);
164
- return;
165
- }
166
- if (data) {
167
- const response = data;
168
- dispatch({
169
- type: STUDENT_FEE_ACTION_TYPES.SET_ITEMS,
170
- payload: { items: (_a = response.items) !== null && _a !== void 0 ? _a : [], count: (_b = response.count) !== null && _b !== void 0 ? _b : 0 },
171
- });
172
- }
173
- }, [dispatch, showToast, t]);
174
- const updateCallback = useCallback(({ data, error }) => {
175
- var _a;
176
- if (error) {
177
- showToast(t("messagesNetworkError"), TOAST_VARIANT.ERROR);
178
- return;
179
- }
180
- if (data) {
181
- const isCreated = isCreatedOrUpdated(data);
182
- showToast(isCreated
183
- ? t("messagesStudentFeeCreated")
184
- : t("messagesStudentFeeUpdated"), TOAST_VARIANT.SUCCESS);
185
- resetFormAndCloseDrawer();
186
- (_a = listFetchNowRef.current) === null || _a === void 0 ? void 0 : _a.call(listFetchNowRef);
187
- }
188
- }, [showToast, t, resetFormAndCloseDrawer]);
189
- const byIdCallback = useCallback(({ data, error }) => {
190
- if (error) {
191
- showToast(t("messagesNetworkError"), TOAST_VARIANT.ERROR);
192
- return;
193
- }
194
- if (data) {
195
- const fee = data;
196
- const rawDueDate = fee.dueDate;
197
- const dueDate = rawDueDate instanceof Date
198
- ? `${rawDueDate.getFullYear()}-${String(rawDueDate.getMonth() + 1).padStart(2, "0")}-${String(rawDueDate.getDate()).padStart(2, "0")}`
199
- : String(rawDueDate).slice(0, 10);
200
- const rawPaidAt = fee.paidAt;
201
- const today = new Date();
202
- const todayStr = `${today.getFullYear()}-${String(today.getMonth() + 1).padStart(2, "0")}-${String(today.getDate()).padStart(2, "0")}`;
203
- const paidAt = rawPaidAt instanceof Date
204
- ? `${rawPaidAt.getFullYear()}-${String(rawPaidAt.getMonth() + 1).padStart(2, "0")}-${String(rawPaidAt.getDate()).padStart(2, "0")}`
205
- : rawPaidAt
206
- ? String(rawPaidAt).slice(0, 10)
207
- : todayStr;
208
- const originalFee = Number(fee.amount) + Number(fee.discountAmount || 0);
209
- dispatch({
210
- type: STUDENT_FEE_ACTION_TYPES.SET_FORM_DATA,
211
- payload: {
212
- form: Object.assign(Object.assign({}, fee), { dueDate,
213
- paidAt,
214
- originalFee }),
215
- },
216
- });
217
- }
218
- }, [dispatch, showToast, t]);
219
- const deleteCallback = useCallback(({ data, error }) => {
220
- var _a;
221
- if (error) {
222
- showToast(t("messagesNetworkError"), TOAST_VARIANT.ERROR);
223
- return;
224
- }
225
- if (data) {
226
- showToast(t("messagesStudentFeeDeleted"), TOAST_VARIANT.SUCCESS);
227
- (_a = listFetchNowRef.current) === null || _a === void 0 ? void 0 : _a.call(listFetchNowRef);
228
- }
229
- }, [showToast, t]);
230
- // ============================================================================
231
- // 1.4.5 API HOOKS
232
- // ============================================================================
233
- const { listFetchNow, listLoading, updateFetchNow, updateLoading, byIdFetchNow, deleteFetchNow, deleteLoading, byIdLoading, } = useModuleEntityV2({
234
- byIdCallback,
235
- byIdParams,
236
- deleteCallback,
237
- deleteParams,
238
- listCallback,
239
- listParams,
240
- listUrl: STUDENT_FEE_API_ROUTES.UNIT,
241
- searchQuery: debouncedQuery,
242
- unitByIdUrl: STUDENT_FEE_API_ROUTES.UNIT,
243
- unitUrl: STUDENT_FEE_API_ROUTES.UNIT,
244
- updateCallback,
245
- updateParams,
246
- headers: {
247
- "Content-Type": "application/json",
248
- // "x-api-token": process.env.NEXT_PUBLIC_API_KEY!,
249
- },
250
- });
96
+ const updateParams = useMemo(() => ({
97
+ amount: Number(state.amount),
98
+ amountDue: Number(state.amountDue),
99
+ amountPaid: Number(state.amountPaid),
100
+ discountAmount: Number(state.discountAmount),
101
+ discountCodeId: state.discountCodeId,
102
+ dueDate: state.dueDate,
103
+ enabled: state.enabled,
104
+ familyId: state.familyId,
105
+ feeStructureId: state.feeStructureId,
106
+ id: state.id,
107
+ paidAt: state.paidAt || null,
108
+ remarks: state.remarks || null,
109
+ schoolId,
110
+ status: state.status,
111
+ studentProfileId: state.studentProfileId,
112
+ }), [
113
+ state.amount,
114
+ state.amountDue,
115
+ state.amountPaid,
116
+ state.discountAmount,
117
+ state.discountCodeId,
118
+ state.dueDate,
119
+ state.enabled,
120
+ state.familyId,
121
+ state.feeStructureId,
122
+ state.id,
123
+ state.paidAt,
124
+ state.remarks,
125
+ state.status,
126
+ state.studentProfileId,
127
+ schoolId,
128
+ ]);
251
129
  // ============================================================================
252
- // 1.4.6 HANDLERS
130
+ // 1.4.4 HANDLERS
253
131
  // ============================================================================
254
132
  const handleChange = useCallback(async (field, value) => {
255
133
  var _a, _b, _c;
@@ -522,15 +400,16 @@ export const useStudentFeeModule = () => {
522
400
  payload: { currentPage: 1 },
523
401
  });
524
402
  listFetchNow === null || listFetchNow === void 0 ? void 0 : listFetchNow(undefined, {
525
- params: Object.assign(Object.assign({}, listParams), { filterEnabled: state.filterEnabled, filterStatus: state.filterStatus }),
403
+ params: Object.assign(Object.assign({ currentPage: 1, pageLimit: state.pageLimit, schoolId }, (state.filterEnabled && { filterEnabled: state.filterEnabled })), (state.filterStatus && { filterStatus: state.filterStatus })),
526
404
  });
527
405
  }, [
528
406
  closeDrawer,
529
407
  dispatch,
530
408
  listFetchNow,
531
- listParams,
409
+ schoolId,
532
410
  state.filterEnabled,
533
411
  state.filterStatus,
412
+ state.pageLimit,
534
413
  ]);
535
414
  const clearFilters = useCallback(() => {
536
415
  dispatch({
@@ -546,7 +425,8 @@ export const useStudentFeeModule = () => {
546
425
  type: STUDENT_FEE_ACTION_TYPES.SET_CURRENT_PAGE,
547
426
  payload: { currentPage: 1 },
548
427
  });
549
- }, [dispatch]);
428
+ listFetchNow();
429
+ }, [dispatch, listFetchNow]);
550
430
  const handleSearch = useCallback((query) => {
551
431
  dispatch({
552
432
  type: STUDENT_FEE_ACTION_TYPES.SET_SEARCH_QUERY,
@@ -554,10 +434,10 @@ export const useStudentFeeModule = () => {
554
434
  });
555
435
  }, [dispatch]);
556
436
  // ============================================================================
557
- // 1.4.7 NETWORK ACTIONS
437
+ // 1.4.5 NETWORK ACTIONS
558
438
  // ============================================================================
559
439
  const handleProceedMonthlyCreation = useCallback(async () => {
560
- var _a, _b;
440
+ var _a;
561
441
  const schoolId = (_a = workspace === null || workspace === void 0 ? void 0 : workspace.school) === null || _a === void 0 ? void 0 : _a.id;
562
442
  if (!schoolId) {
563
443
  showToast(t("messagesNetworkError"), TOAST_VARIANT.ERROR);
@@ -580,9 +460,9 @@ export const useStudentFeeModule = () => {
580
460
  }
581
461
  showToast(t("messagesMonthlyJobQueued"), TOAST_VARIANT.SUCCESS);
582
462
  resetFormAndCloseDrawer();
583
- (_b = listFetchNowRef.current) === null || _b === void 0 ? void 0 : _b.call(listFetchNowRef);
463
+ listFetchNow === null || listFetchNow === void 0 ? void 0 : listFetchNow();
584
464
  }
585
- catch (_c) {
465
+ catch (_b) {
586
466
  showToast(t("messagesNetworkError"), TOAST_VARIANT.ERROR);
587
467
  }
588
468
  finally {
@@ -591,7 +471,7 @@ export const useStudentFeeModule = () => {
591
471
  payload: { disabled: false },
592
472
  });
593
473
  }
594
- }, [dispatch, showToast, t, (_c = workspace === null || workspace === void 0 ? void 0 : workspace.school) === null || _c === void 0 ? void 0 : _c.id, resetFormAndCloseDrawer]);
474
+ }, [dispatch, showToast, t, (_c = workspace === null || workspace === void 0 ? void 0 : workspace.school) === null || _c === void 0 ? void 0 : _c.id, resetFormAndCloseDrawer, listFetchNow]);
595
475
  const handleSubmit = useCallback(() => {
596
476
  dispatch({
597
477
  type: STUDENT_FEE_ACTION_TYPES.SET_DISABLE_SAVE_BUTTON,
@@ -619,14 +499,12 @@ export const useStudentFeeModule = () => {
619
499
  });
620
500
  }, [dispatch, updateParams, t, showToast, updateFetchNow]);
621
501
  const handleSubmitSingleEntry = useCallback(async (fees, amountPaid, remarks, paidAt) => {
622
- var _a, _b;
623
- console.log("Submitting single entry fees:", fees);
502
+ var _a;
624
503
  dispatch({
625
504
  type: STUDENT_FEE_ACTION_TYPES.SET_DISABLE_SAVE_BUTTON,
626
505
  payload: { disabled: true },
627
506
  });
628
507
  try {
629
- // const feeIds = fees.map((f) => f.id);
630
508
  const res = await fetch(STUDENT_FEE_API_ROUTES.SINGLE_ENTRY, {
631
509
  method: API_METHODS.POST,
632
510
  headers: { "Content-Type": "application/json" },
@@ -645,9 +523,9 @@ export const useStudentFeeModule = () => {
645
523
  }
646
524
  showToast(t("messagesStudentFeeUpdated"), TOAST_VARIANT.SUCCESS);
647
525
  resetFormAndCloseDrawer();
648
- (_b = listFetchNowRef.current) === null || _b === void 0 ? void 0 : _b.call(listFetchNowRef);
526
+ listFetchNow === null || listFetchNow === void 0 ? void 0 : listFetchNow();
649
527
  }
650
- catch (_c) {
528
+ catch (_b) {
651
529
  showToast(t("messagesNetworkError"), TOAST_VARIANT.ERROR);
652
530
  }
653
531
  finally {
@@ -656,9 +534,9 @@ export const useStudentFeeModule = () => {
656
534
  payload: { disabled: false },
657
535
  });
658
536
  }
659
- }, [dispatch, showToast, t, (_d = workspace === null || workspace === void 0 ? void 0 : workspace.school) === null || _d === void 0 ? void 0 : _d.id, resetFormAndCloseDrawer]);
537
+ }, [dispatch, showToast, t, (_d = workspace === null || workspace === void 0 ? void 0 : workspace.school) === null || _d === void 0 ? void 0 : _d.id, resetFormAndCloseDrawer, listFetchNow]);
660
538
  // ============================================================================
661
- // 1.4.8 HEADER & ROW ACTIONS
539
+ // 1.4.6 HEADER & ROW ACTIONS
662
540
  // ============================================================================
663
541
  const headerActions = useMemo(() => [
664
542
  {
@@ -702,17 +580,7 @@ export const useStudentFeeModule = () => {
702
580
  },
703
581
  ], [handleDelete, handleEdit, handleView, t]);
704
582
  // ============================================================================
705
- // 1.4.9 EFFECTS
706
- // ============================================================================
707
- useEffect(() => {
708
- listFetchNowRef.current = listFetchNow;
709
- }, [listFetchNow]);
710
- useEffect(() => {
711
- var _a;
712
- (_a = listFetchNowRef.current) === null || _a === void 0 ? void 0 : _a.call(listFetchNowRef);
713
- }, [listParams]);
714
- // ============================================================================
715
- // 1.4.10 RETURN
583
+ // 1.4.7 RETURN
716
584
  // ============================================================================
717
585
  return Object.assign(Object.assign({}, context), { applyFilters,
718
586
  byIdLoading,
@@ -5,6 +5,10 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
5
5
  *
6
6
  * Filter UI for the student-fee list. Supports filterEnabled (radio) and
7
7
  * filterStatus (payment status combobox).
8
+ *
9
+ * The API provider (StudentFeeApiProvider) manages a single useModuleEntityV2
10
+ * instance shared across all consumers, so calling useStudentFeeModule from
11
+ * child components no longer creates redundant API hooks or auto-fetch effects.
8
12
  */
9
13
  import { EnhancedRadio } from "@appcorp/shadcn/components/enhanced-radio";
10
14
  import { useEnhancedCombobox } from "@appcorp/shadcn/hooks/use-enhanced-combobox";
@@ -19,12 +19,11 @@ 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
21
  import { useStudentFeeModule, StudentFeeProvider, STUDENT_FEE_ACTION_TYPES, } from "./context";
22
+ import { StudentFeeApiProvider } from "./context/student-fee-api-provider";
22
23
  import { StudentFeeFilter } from "./filter";
23
24
  import { StudentFeeForm } from "./form";
24
25
  import { StudentFeeMoreActions } from "./more-actions";
25
26
  import { StudentFeeView } from "./view";
26
- // import { StudentFeeSingleEntry } from "./single-entry";
27
- // import { StudentFeeCreateMonthly } from "./monthly-create";
28
27
  import { resolveRbacPermissions } from "../../utils/resolve-rbac-permissions";
29
28
  import { RbacNoAccess } from "../../components/rbac-no-access";
30
29
  import { formatStudentName, formatAmount, formatAmountPaid, formatAmountDue, } from "./constants";
@@ -201,4 +200,4 @@ const StudentFeePageInner = (props) => {
201
200
  // ============================================================================
202
201
  // PAGE EXPORTS
203
202
  // ============================================================================
204
- export const StudentFeePage = (props) => (_jsx(StudentFeeProvider, { children: _jsx(StudentFeePageInner, Object.assign({}, props)) }));
203
+ export const StudentFeePage = (props) => (_jsx(StudentFeeProvider, { children: _jsx(StudentFeeApiProvider, { children: _jsx(StudentFeePageInner, Object.assign({}, props)) }) }));