@appcorp/fusion-storybook 0.3.85 → 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.
- package/base-modules/student-fee/context/index.d.ts +3 -0
- package/base-modules/student-fee/context/index.js +3 -0
- package/base-modules/student-fee/context/student-fee-api-provider.d.ts +16 -0
- package/base-modules/student-fee/context/student-fee-api-provider.js +233 -0
- package/base-modules/student-fee/context/use-student-fee-module.js +54 -179
- package/base-modules/student-fee/filter.js +5 -16
- package/base-modules/student-fee/page.js +2 -1
- package/package.json +1 -1
- package/tsconfig.build.tsbuildinfo +1 -1
|
@@ -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,
|
|
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,59 +27,19 @@ const calculateAmounts = (originalFee, discountAmount, amountPaid) => {
|
|
|
29
27
|
// ============================================================================
|
|
30
28
|
export const useStudentFeeModule = () => {
|
|
31
29
|
// ============================================================================
|
|
32
|
-
// 1.4.1 STATE &
|
|
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
|
|
46
|
-
// ============================================================================
|
|
47
|
-
const listParams = useMemo(() => (Object.assign({ currentPage: state.currentPage, pageLimit: state.pageLimit, schoolId }, (debouncedQuery ? { searchQuery: debouncedQuery } : {}))), [state.currentPage, state.pageLimit, debouncedQuery, schoolId]);
|
|
48
|
-
const updateParams = useMemo(() => ({
|
|
49
|
-
amount: Number(state.amount),
|
|
50
|
-
amountDue: Number(state.amountDue),
|
|
51
|
-
amountPaid: Number(state.amountPaid),
|
|
52
|
-
discountAmount: Number(state.discountAmount),
|
|
53
|
-
discountCodeId: state.discountCodeId,
|
|
54
|
-
dueDate: state.dueDate,
|
|
55
|
-
enabled: state.enabled,
|
|
56
|
-
familyId: state.familyId,
|
|
57
|
-
feeStructureId: state.feeStructureId,
|
|
58
|
-
id: state.id,
|
|
59
|
-
paidAt: state.paidAt || null,
|
|
60
|
-
remarks: state.remarks || null,
|
|
61
|
-
schoolId,
|
|
62
|
-
status: state.status,
|
|
63
|
-
studentProfileId: state.studentProfileId,
|
|
64
|
-
}), [
|
|
65
|
-
state.amount,
|
|
66
|
-
state.amountDue,
|
|
67
|
-
state.amountPaid,
|
|
68
|
-
state.discountAmount,
|
|
69
|
-
state.discountCodeId,
|
|
70
|
-
state.dueDate,
|
|
71
|
-
state.enabled,
|
|
72
|
-
state.familyId,
|
|
73
|
-
state.feeStructureId,
|
|
74
|
-
state.id,
|
|
75
|
-
state.paidAt,
|
|
76
|
-
state.remarks,
|
|
77
|
-
state.status,
|
|
78
|
-
state.studentProfileId,
|
|
79
|
-
schoolId,
|
|
80
|
-
]);
|
|
81
|
-
const byIdParams = useMemo(() => ({ id: state.id }), [state.id]);
|
|
82
|
-
const deleteParams = useMemo(() => ({ id: state.id }), [state.id]);
|
|
83
|
-
// ============================================================================
|
|
84
|
-
// 1.4.3 UTILITIES
|
|
42
|
+
// 1.4.2 UTILITIES
|
|
85
43
|
// ============================================================================
|
|
86
44
|
const showToast = useCallback((description, variant) => {
|
|
87
45
|
generateThemeToast({
|
|
@@ -90,21 +48,6 @@ export const useStudentFeeModule = () => {
|
|
|
90
48
|
variant,
|
|
91
49
|
});
|
|
92
50
|
}, [theme]);
|
|
93
|
-
const resetFormAndCloseDrawer = useCallback(() => {
|
|
94
|
-
dispatch({ type: STUDENT_FEE_ACTION_TYPES.RESET_FORM });
|
|
95
|
-
dispatch({
|
|
96
|
-
type: STUDENT_FEE_ACTION_TYPES.SET_ERRORS,
|
|
97
|
-
payload: { errors: {} },
|
|
98
|
-
});
|
|
99
|
-
dispatch({
|
|
100
|
-
type: STUDENT_FEE_ACTION_TYPES.SET_DISABLE_SAVE_BUTTON,
|
|
101
|
-
payload: { disabled: false },
|
|
102
|
-
});
|
|
103
|
-
dispatch({
|
|
104
|
-
type: STUDENT_FEE_ACTION_TYPES.SET_DRAWER,
|
|
105
|
-
payload: { drawer: null },
|
|
106
|
-
});
|
|
107
|
-
}, [dispatch]);
|
|
108
51
|
const resetRecordFormState = useCallback(() => {
|
|
109
52
|
var _a, _b;
|
|
110
53
|
const dueDay = (_a = workspace === null || workspace === void 0 ? void 0 : workspace.dueDateLength) !== null && _a !== void 0 ? _a : 1;
|
|
@@ -148,101 +91,43 @@ export const useStudentFeeModule = () => {
|
|
|
148
91
|
});
|
|
149
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]);
|
|
150
93
|
// ============================================================================
|
|
151
|
-
// 1.4.
|
|
152
|
-
// ============================================================================
|
|
153
|
-
const listCallback = useCallback(({ data, error }) => {
|
|
154
|
-
var _a, _b;
|
|
155
|
-
if (error) {
|
|
156
|
-
showToast(t("messagesNetworkError"), TOAST_VARIANT.ERROR);
|
|
157
|
-
return;
|
|
158
|
-
}
|
|
159
|
-
if (data) {
|
|
160
|
-
const response = data;
|
|
161
|
-
dispatch({
|
|
162
|
-
type: STUDENT_FEE_ACTION_TYPES.SET_ITEMS,
|
|
163
|
-
payload: { items: (_a = response.items) !== null && _a !== void 0 ? _a : [], count: (_b = response.count) !== null && _b !== void 0 ? _b : 0 },
|
|
164
|
-
});
|
|
165
|
-
}
|
|
166
|
-
}, [dispatch, showToast, t]);
|
|
167
|
-
const updateCallback = useCallback(({ data, error }) => {
|
|
168
|
-
var _a;
|
|
169
|
-
if (error) {
|
|
170
|
-
showToast(t("messagesNetworkError"), TOAST_VARIANT.ERROR);
|
|
171
|
-
return;
|
|
172
|
-
}
|
|
173
|
-
if (data) {
|
|
174
|
-
const isCreated = isCreatedOrUpdated(data);
|
|
175
|
-
showToast(isCreated
|
|
176
|
-
? t("messagesStudentFeeCreated")
|
|
177
|
-
: t("messagesStudentFeeUpdated"), TOAST_VARIANT.SUCCESS);
|
|
178
|
-
resetFormAndCloseDrawer();
|
|
179
|
-
(_a = listFetchNowRef.current) === null || _a === void 0 ? void 0 : _a.call(listFetchNowRef);
|
|
180
|
-
}
|
|
181
|
-
}, [showToast, t, resetFormAndCloseDrawer]);
|
|
182
|
-
const byIdCallback = useCallback(({ data, error }) => {
|
|
183
|
-
if (error) {
|
|
184
|
-
showToast(t("messagesNetworkError"), TOAST_VARIANT.ERROR);
|
|
185
|
-
return;
|
|
186
|
-
}
|
|
187
|
-
if (data) {
|
|
188
|
-
const fee = data;
|
|
189
|
-
const rawDueDate = fee.dueDate;
|
|
190
|
-
const dueDate = rawDueDate instanceof Date
|
|
191
|
-
? `${rawDueDate.getFullYear()}-${String(rawDueDate.getMonth() + 1).padStart(2, "0")}-${String(rawDueDate.getDate()).padStart(2, "0")}`
|
|
192
|
-
: String(rawDueDate).slice(0, 10);
|
|
193
|
-
const rawPaidAt = fee.paidAt;
|
|
194
|
-
const today = new Date();
|
|
195
|
-
const todayStr = `${today.getFullYear()}-${String(today.getMonth() + 1).padStart(2, "0")}-${String(today.getDate()).padStart(2, "0")}`;
|
|
196
|
-
const paidAt = rawPaidAt instanceof Date
|
|
197
|
-
? `${rawPaidAt.getFullYear()}-${String(rawPaidAt.getMonth() + 1).padStart(2, "0")}-${String(rawPaidAt.getDate()).padStart(2, "0")}`
|
|
198
|
-
: rawPaidAt
|
|
199
|
-
? String(rawPaidAt).slice(0, 10)
|
|
200
|
-
: todayStr;
|
|
201
|
-
const originalFee = Number(fee.amount) + Number(fee.discountAmount || 0);
|
|
202
|
-
dispatch({
|
|
203
|
-
type: STUDENT_FEE_ACTION_TYPES.SET_FORM_DATA,
|
|
204
|
-
payload: {
|
|
205
|
-
form: Object.assign(Object.assign({}, fee), { dueDate,
|
|
206
|
-
paidAt,
|
|
207
|
-
originalFee }),
|
|
208
|
-
},
|
|
209
|
-
});
|
|
210
|
-
}
|
|
211
|
-
}, [dispatch, showToast, t]);
|
|
212
|
-
const deleteCallback = useCallback(({ data, error }) => {
|
|
213
|
-
var _a;
|
|
214
|
-
if (error) {
|
|
215
|
-
showToast(t("messagesNetworkError"), TOAST_VARIANT.ERROR);
|
|
216
|
-
return;
|
|
217
|
-
}
|
|
218
|
-
if (data) {
|
|
219
|
-
showToast(t("messagesStudentFeeDeleted"), TOAST_VARIANT.SUCCESS);
|
|
220
|
-
(_a = listFetchNowRef.current) === null || _a === void 0 ? void 0 : _a.call(listFetchNowRef);
|
|
221
|
-
}
|
|
222
|
-
}, [showToast, t]);
|
|
223
|
-
// ============================================================================
|
|
224
|
-
// 1.4.5 API HOOKS
|
|
94
|
+
// 1.4.3 UPDATE PARAMS (used by handleSubmit for validation + fetch body)
|
|
225
95
|
// ============================================================================
|
|
226
|
-
const
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
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
|
+
]);
|
|
244
129
|
// ============================================================================
|
|
245
|
-
// 1.4.
|
|
130
|
+
// 1.4.4 HANDLERS
|
|
246
131
|
// ============================================================================
|
|
247
132
|
const handleChange = useCallback(async (field, value) => {
|
|
248
133
|
var _a, _b, _c;
|
|
@@ -515,15 +400,16 @@ export const useStudentFeeModule = () => {
|
|
|
515
400
|
payload: { currentPage: 1 },
|
|
516
401
|
});
|
|
517
402
|
listFetchNow === null || listFetchNow === void 0 ? void 0 : listFetchNow(undefined, {
|
|
518
|
-
params: Object.assign(Object.assign(
|
|
403
|
+
params: Object.assign(Object.assign({ currentPage: 1, pageLimit: state.pageLimit, schoolId }, (state.filterEnabled && { filterEnabled: state.filterEnabled })), (state.filterStatus && { filterStatus: state.filterStatus })),
|
|
519
404
|
});
|
|
520
405
|
}, [
|
|
521
406
|
closeDrawer,
|
|
522
407
|
dispatch,
|
|
523
408
|
listFetchNow,
|
|
524
|
-
|
|
409
|
+
schoolId,
|
|
525
410
|
state.filterEnabled,
|
|
526
411
|
state.filterStatus,
|
|
412
|
+
state.pageLimit,
|
|
527
413
|
]);
|
|
528
414
|
const clearFilters = useCallback(() => {
|
|
529
415
|
dispatch({
|
|
@@ -548,10 +434,10 @@ export const useStudentFeeModule = () => {
|
|
|
548
434
|
});
|
|
549
435
|
}, [dispatch]);
|
|
550
436
|
// ============================================================================
|
|
551
|
-
// 1.4.
|
|
437
|
+
// 1.4.5 NETWORK ACTIONS
|
|
552
438
|
// ============================================================================
|
|
553
439
|
const handleProceedMonthlyCreation = useCallback(async () => {
|
|
554
|
-
var _a
|
|
440
|
+
var _a;
|
|
555
441
|
const schoolId = (_a = workspace === null || workspace === void 0 ? void 0 : workspace.school) === null || _a === void 0 ? void 0 : _a.id;
|
|
556
442
|
if (!schoolId) {
|
|
557
443
|
showToast(t("messagesNetworkError"), TOAST_VARIANT.ERROR);
|
|
@@ -574,9 +460,9 @@ export const useStudentFeeModule = () => {
|
|
|
574
460
|
}
|
|
575
461
|
showToast(t("messagesMonthlyJobQueued"), TOAST_VARIANT.SUCCESS);
|
|
576
462
|
resetFormAndCloseDrawer();
|
|
577
|
-
|
|
463
|
+
listFetchNow === null || listFetchNow === void 0 ? void 0 : listFetchNow();
|
|
578
464
|
}
|
|
579
|
-
catch (
|
|
465
|
+
catch (_b) {
|
|
580
466
|
showToast(t("messagesNetworkError"), TOAST_VARIANT.ERROR);
|
|
581
467
|
}
|
|
582
468
|
finally {
|
|
@@ -585,7 +471,7 @@ export const useStudentFeeModule = () => {
|
|
|
585
471
|
payload: { disabled: false },
|
|
586
472
|
});
|
|
587
473
|
}
|
|
588
|
-
}, [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]);
|
|
589
475
|
const handleSubmit = useCallback(() => {
|
|
590
476
|
dispatch({
|
|
591
477
|
type: STUDENT_FEE_ACTION_TYPES.SET_DISABLE_SAVE_BUTTON,
|
|
@@ -613,13 +499,12 @@ export const useStudentFeeModule = () => {
|
|
|
613
499
|
});
|
|
614
500
|
}, [dispatch, updateParams, t, showToast, updateFetchNow]);
|
|
615
501
|
const handleSubmitSingleEntry = useCallback(async (fees, amountPaid, remarks, paidAt) => {
|
|
616
|
-
var _a
|
|
502
|
+
var _a;
|
|
617
503
|
dispatch({
|
|
618
504
|
type: STUDENT_FEE_ACTION_TYPES.SET_DISABLE_SAVE_BUTTON,
|
|
619
505
|
payload: { disabled: true },
|
|
620
506
|
});
|
|
621
507
|
try {
|
|
622
|
-
// const feeIds = fees.map((f) => f.id);
|
|
623
508
|
const res = await fetch(STUDENT_FEE_API_ROUTES.SINGLE_ENTRY, {
|
|
624
509
|
method: API_METHODS.POST,
|
|
625
510
|
headers: { "Content-Type": "application/json" },
|
|
@@ -638,9 +523,9 @@ export const useStudentFeeModule = () => {
|
|
|
638
523
|
}
|
|
639
524
|
showToast(t("messagesStudentFeeUpdated"), TOAST_VARIANT.SUCCESS);
|
|
640
525
|
resetFormAndCloseDrawer();
|
|
641
|
-
|
|
526
|
+
listFetchNow === null || listFetchNow === void 0 ? void 0 : listFetchNow();
|
|
642
527
|
}
|
|
643
|
-
catch (
|
|
528
|
+
catch (_b) {
|
|
644
529
|
showToast(t("messagesNetworkError"), TOAST_VARIANT.ERROR);
|
|
645
530
|
}
|
|
646
531
|
finally {
|
|
@@ -649,9 +534,9 @@ export const useStudentFeeModule = () => {
|
|
|
649
534
|
payload: { disabled: false },
|
|
650
535
|
});
|
|
651
536
|
}
|
|
652
|
-
}, [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]);
|
|
653
538
|
// ============================================================================
|
|
654
|
-
// 1.4.
|
|
539
|
+
// 1.4.6 HEADER & ROW ACTIONS
|
|
655
540
|
// ============================================================================
|
|
656
541
|
const headerActions = useMemo(() => [
|
|
657
542
|
{
|
|
@@ -695,17 +580,7 @@ export const useStudentFeeModule = () => {
|
|
|
695
580
|
},
|
|
696
581
|
], [handleDelete, handleEdit, handleView, t]);
|
|
697
582
|
// ============================================================================
|
|
698
|
-
// 1.4.
|
|
699
|
-
// ============================================================================
|
|
700
|
-
useEffect(() => {
|
|
701
|
-
listFetchNowRef.current = listFetchNow;
|
|
702
|
-
}, [listFetchNow]);
|
|
703
|
-
useEffect(() => {
|
|
704
|
-
var _a;
|
|
705
|
-
(_a = listFetchNowRef.current) === null || _a === void 0 ? void 0 : _a.call(listFetchNowRef);
|
|
706
|
-
}, [listParams]);
|
|
707
|
-
// ============================================================================
|
|
708
|
-
// 1.4.10 RETURN
|
|
583
|
+
// 1.4.7 RETURN
|
|
709
584
|
// ============================================================================
|
|
710
585
|
return Object.assign(Object.assign({}, context), { applyFilters,
|
|
711
586
|
byIdLoading,
|
|
@@ -6,30 +6,19 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
6
6
|
* Filter UI for the student-fee list. Supports filterEnabled (radio) and
|
|
7
7
|
* filterStatus (payment status combobox).
|
|
8
8
|
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
* (each time the filter drawer opens). We only need state + a simple
|
|
13
|
-
* handleChange, which context provides directly.
|
|
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.
|
|
14
12
|
*/
|
|
15
|
-
import { useCallback } from "react";
|
|
16
13
|
import { EnhancedRadio } from "@appcorp/shadcn/components/enhanced-radio";
|
|
17
14
|
import { useEnhancedCombobox } from "@appcorp/shadcn/hooks/use-enhanced-combobox";
|
|
18
|
-
import {
|
|
15
|
+
import { useStudentFeeModule } from "./context";
|
|
19
16
|
import { PAYMENT_STATUS_OPTIONS } from "./constants";
|
|
20
17
|
import { STUDENT_FEE_API_ROUTES } from "../../constants";
|
|
21
18
|
import { useTranslations } from "next-intl";
|
|
22
19
|
export const StudentFeeFilter = () => {
|
|
23
|
-
const { state,
|
|
20
|
+
const { state, handleChange } = useStudentFeeModule();
|
|
24
21
|
const { filterEnabled, filterStatus } = state;
|
|
25
|
-
const handleChange = useCallback((field, value) => {
|
|
26
|
-
if (field === "filterEnabled" || field === "filterStatus") {
|
|
27
|
-
dispatch({
|
|
28
|
-
type: STUDENT_FEE_ACTION_TYPES.SET_INPUT_FIELD,
|
|
29
|
-
payload: { key: field, value },
|
|
30
|
-
});
|
|
31
|
-
}
|
|
32
|
-
}, [dispatch]);
|
|
33
22
|
const t = useTranslations("studentFee");
|
|
34
23
|
const paymentStatusLabelMap = {
|
|
35
24
|
PENDING: t("formOptionPending"),
|
|
@@ -19,6 +19,7 @@ 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";
|
|
@@ -199,4 +200,4 @@ const StudentFeePageInner = (props) => {
|
|
|
199
200
|
// ============================================================================
|
|
200
201
|
// PAGE EXPORTS
|
|
201
202
|
// ============================================================================
|
|
202
|
-
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)) }) }));
|