aq-fe-framework 0.1.155 → 0.1.156
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/dist/api/apiFactory.ts +46 -0
- package/dist/api/baseAxios.ts +22 -0
- package/dist/app/admin/(core)/core12196/page.tsx +13 -0
- package/dist/app/admin/(core)/core16209/page.tsx +13 -0
- package/dist/app/admin/(core)/core18256/page.tsx +12 -0
- package/dist/app/admin/(core)/core26965/page.tsx +13 -0
- package/dist/app/admin/(core)/core27311/page.tsx +13 -0
- package/dist/app/admin/(core)/core38677/page.tsx +13 -0
- package/dist/app/admin/(core)/core40207/page.tsx +13 -0
- package/dist/app/admin/(core)/core60524/page.tsx +11 -0
- package/dist/app/admin/(core)/core64229/page.tsx +12 -0
- package/dist/app/admin/(core)/core71678/page.tsx +11 -0
- package/dist/app/admin/(core)/core76318/page.tsx +13 -0
- package/dist/app/admin/(core)/core83092/page.tsx +13 -0
- package/dist/app/admin/[...slug]/page.tsx +7 -0
- package/dist/app/admin/error.tsx +42 -0
- package/dist/app/admin/layout.tsx +21 -0
- package/dist/app/admin/test/page.tsx +44 -0
- package/dist/app/auth/login/page.tsx +14 -0
- package/dist/app/globals.css +59 -0
- package/dist/app/layout.tsx +39 -0
- package/dist/app/page.tsx +18 -0
- package/dist/{chunk-PAHZ57DT.mjs → chunk-JLT4BL7I.mjs} +1 -1
- package/dist/components/Aceternity/BoxesBackground/MyBoxes.tsx +66 -0
- package/dist/components/Aceternity/BoxesBackground/MyBoxesBackground.tsx +31 -0
- package/dist/components/ActionIcons/ActionIcon/MyActionIcon.tsx +47 -0
- package/dist/components/ActionIcons/ActionIconCRUD/MyActionIconDelete.tsx +81 -0
- package/dist/components/ActionIcons/ActionIconCRUD/MyActionIconUpdate.tsx +68 -0
- package/dist/components/ActionIcons/ActionIconCheck/MyActionIconCheck.tsx +50 -0
- package/dist/components/ActionIcons/ActionIconDownloadPDF/MyActionIconDownloadPDF.tsx +13 -0
- package/dist/components/ActionIcons/ActionIconModal/MyActionIconModal.tsx +113 -0
- package/dist/components/ActionIcons/ActionIconUpload/MyActionIconUpload.tsx +19 -0
- package/dist/components/ActionIcons/ActionIconViewPdf/MyActionIconViewPDF.tsx +63 -0
- package/dist/components/ActionIcons/SwitchTheme/MySwitchTheme.tsx +36 -0
- package/dist/components/AppSpotlight/MyAppSpotlight.tsx +112 -0
- package/dist/components/Buttons/Anchor/MyAnchorViewPDF.tsx +46 -0
- package/dist/components/Buttons/Button/MyButton.tsx +90 -0
- package/dist/components/Buttons/ButtonCRUD/AQButtonCreateByImportFile.tsx +81 -0
- package/dist/components/Buttons/ButtonCRUD/AQButtonExportData.tsx +75 -0
- package/dist/components/Buttons/ButtonCRUD/MyButtonCreate.tsx +68 -0
- package/dist/components/Buttons/ButtonImport/MyButtonImport.tsx +29 -0
- package/dist/components/Buttons/ButtonImport/SelectFieldModal.tsx +100 -0
- package/dist/components/Buttons/ButtonImport/SelectFileModal.tsx +81 -0
- package/dist/components/Buttons/ButtonImport/useS_ButtonImport.ts +196 -0
- package/dist/components/Buttons/ButtonModal/AQSelectTableByOpenModal.tsx +71 -0
- package/dist/components/Buttons/ButtonModal/MyButtonModal.tsx +117 -0
- package/dist/components/Buttons/ButtonPrintPDF/MyButtonPrintPDF.tsx +37 -0
- package/dist/components/Buttons/ButtonPrintPDFTable/MyButtonPrintTablePDF.tsx +174 -0
- package/dist/components/Buttons/ButtonRouterBack/MyButtonRouterBack.tsx +29 -0
- package/dist/components/Buttons/ButtonViewPDF/MyButtonViewPDF.tsx +121 -0
- package/dist/components/Calendar/MyCalendar.tsx +118 -0
- package/dist/components/CenterFull/MyCenterFull.tsx +10 -0
- package/dist/components/Checkbox/MyCheckbox.tsx +9 -0
- package/dist/components/Combobox/Select/MySelect.tsx +12 -0
- package/dist/components/DataDisplay/Card/AQCard.tsx +49 -0
- package/dist/components/DataDisplay/CardInformation/MyCardInformation.tsx +77 -0
- package/dist/components/DataDisplay/DataTable/MyDataTable.tsx +184 -0
- package/dist/components/DataDisplay/IconText/MyIconText.tsx +17 -0
- package/dist/components/DataDisplay/KeyLabel/MyKeyLabel.tsx +15 -0
- package/dist/components/DataDisplay/NumberFormatter/MyNumberFormatter.tsx +9 -0
- package/dist/components/DataDisplay/StatCard/AQStatCard1.tsx +68 -0
- package/dist/components/FaviconSetter/FaviconSetter.tsx +33 -0
- package/dist/components/Inputs/DateInput/MyDateInput.tsx +11 -0
- package/dist/components/Inputs/Fieldset/MyFieldset.tsx +32 -0
- package/dist/components/Inputs/FileInput/MyFileInput.tsx +12 -0
- package/dist/components/Inputs/NumberInput/MyNumberInput.tsx +12 -0
- package/dist/components/Inputs/TextArea/MyTextArea.tsx +11 -0
- package/dist/components/Inputs/TextEditor/MyTextEditor.tsx +191 -0
- package/dist/components/Inputs/TextInput/MyTextInput.tsx +30 -0
- package/dist/components/Layouts/BasicAppShell/BasicAppShell.tsx +357 -0
- package/dist/components/Layouts/BasicAppShell/css.module.css +62 -0
- package/dist/components/Layouts/BasicAppShell/useS_BasicAppShell.ts +64 -0
- package/dist/components/Layouts/Container/MyContainer.tsx +16 -0
- package/dist/components/Layouts/FlexColumn/MyFlexColumn.tsx +14 -0
- package/dist/components/Layouts/FlexEnd/MyFlexEnd.tsx +14 -0
- package/dist/components/Layouts/FlexRow/MyFlexRow.tsx +14 -0
- package/dist/components/Layouts/HeaderMegaMenu/HeaderMegaMenu.tsx +147 -0
- package/dist/components/Layouts/HeaderMegaMenu/HeaderMegaMenuStore.ts +19 -0
- package/dist/components/Layouts/HeaderMegaMenu/css.module.css +50 -0
- package/dist/components/Layouts/HtmlWrapper/MyHtmlWrapper.tsx +29 -0
- package/dist/components/Layouts/PageContent/MyPageContent.tsx +67 -0
- package/dist/components/Layouts/Tab/MyTab.tsx +33 -0
- package/dist/components/Loaders/MyCardioLoader.tsx +12 -0
- package/dist/components/RESTAPIComponents/DataTableSelect/MyDataTableSelect.tsx +61 -0
- package/dist/components/RESTAPIComponents/SelectAPIGet/MySelectAPIGet.tsx +37 -0
- package/dist/components/ScheduleX/MyScheduleX.tsx +58 -0
- package/dist/components/Skeletons/SkeletonTable/MySkeletonTable.tsx +9 -0
- package/dist/components/index.mjs +1 -1
- package/dist/components/index.ts +62 -0
- package/dist/constants/array/daysOfWeek.ts +9 -0
- package/dist/constants/enum/ENUM_EMAILCONFIG.ts +6 -0
- package/dist/constants/enum/global.ts +26 -0
- package/dist/constants/object/color.ts +5 -0
- package/dist/constants/object/documentTypes.ts +8 -0
- package/dist/{components/index.css → css.module-4ICLUKPO.module.css} +29 -16
- package/dist/css.module-P45UW6UZ.module.css +4 -0
- package/dist/data/menuData.ts +31 -0
- package/dist/hooks/custom-hooks/useC_MutationAction.tsx +36 -0
- package/dist/hooks/index.ts +2 -0
- package/dist/hooks/query/AQ/useQ_AQ_GetAQModule.ts +14 -0
- package/dist/interfaces/EmailConfig.ts +10 -0
- package/dist/interfaces/IAQModule.ts +21 -0
- package/dist/interfaces/base.ts +9 -0
- package/dist/interfaces/global-interface/IAQSSO.ts +15 -0
- package/dist/interfaces/global-interface/IAQSyncData.ts +9 -0
- package/dist/interfaces/global-interface/IAcademicYear.ts +12 -0
- package/dist/interfaces/global-interface/IChangePassWord.ts +8 -0
- package/dist/interfaces/global-interface/IComplaintProccess.ts +9 -0
- package/dist/interfaces/global-interface/ICreateAccount.ts +24 -0
- package/dist/interfaces/global-interface/IDocument.ts +25 -0
- package/dist/interfaces/global-interface/IDocumentAttribute.ts +12 -0
- package/dist/interfaces/global-interface/IEvent.ts +30 -0
- package/dist/interfaces/global-interface/IEventComplaint.ts +20 -0
- package/dist/interfaces/global-interface/IEventFillter.ts +14 -0
- package/dist/interfaces/global-interface/IFile.ts +8 -0
- package/dist/interfaces/global-interface/IImportStudentPaticipation.ts +8 -0
- package/dist/interfaces/global-interface/IPagePermission.ts +12 -0
- package/dist/interfaces/global-interface/IRolePermission.ts +7 -0
- package/dist/interfaces/global-interface/ISRMUserinfo.ts +35 -0
- package/dist/interfaces/global-interface/IScientificProfileProjectUser.ts +15 -0
- package/dist/interfaces/global-interface/IScientificProfileResearchGroup.ts +15 -0
- package/dist/interfaces/global-interface/IScientificProfileResearchGroupUser.ts +14 -0
- package/dist/interfaces/global-interface/IScientificProfileResearchProject.ts +21 -0
- package/dist/interfaces/global-interface/ISignIn.ts +7 -0
- package/dist/interfaces/global-interface/ISystemCatalogAcademicYear.ts +15 -0
- package/dist/interfaces/global-interface/ISystemCatalogDomainCategory.ts +11 -0
- package/dist/interfaces/global-interface/ISystemCatalogProjectLevelCategory.ts +11 -0
- package/dist/interfaces/global-interface/ISystemCatalogProjectTypeCategory.ts +11 -0
- package/dist/interfaces/global-interface/ISystemCatalogRoleActivity.ts +11 -0
- package/dist/interfaces/global-interface/ISystemCatalogTaskCategory.ts +11 -0
- package/dist/interfaces/global-interface/ISystemManagementAcademicHistory.ts +31 -0
- package/dist/interfaces/global-interface/ISystemManagementProfessionalWorkHistory.ts +14 -0
- package/dist/interfaces/global-interface/ISystemManagementPublishedScientificWork.ts +14 -0
- package/dist/interfaces/global-interface/ISystemManagementRoleGroup.ts +12 -0
- package/dist/interfaces/global-interface/ISystemManagementRoleGroupMenuPermission.ts +18 -0
- package/dist/interfaces/global-interface/ISystemManagementScientificResearchProject.ts +16 -0
- package/dist/interfaces/global-interface/ISystemManagementUserMenuPermission.ts +18 -0
- package/dist/interfaces/global-interface/IUpdateAccount.ts +15 -0
- package/dist/interfaces/global-interface/IUser.ts +21 -0
- package/dist/interfaces/global-interface/IUserPermission.ts +7 -0
- package/dist/lib/utils.ts +6 -0
- package/dist/modules-features/admin/core/MainDashboard/BarChart_CourseStatus.tsx +87 -0
- package/dist/modules-features/admin/core/MainDashboard/BarChart_ExamStatus.tsx +65 -0
- package/dist/modules-features/admin/core/MainDashboard/BarChart_RevenueByAcademicYear.tsx +82 -0
- package/dist/modules-features/admin/core/MainDashboard/BarChart_StudentStatusIn30Days.tsx +67 -0
- package/dist/modules-features/admin/core/MainDashboard/HBarChart_CourseDropOutPercentage.tsx +77 -0
- package/dist/modules-features/admin/core/MainDashboard/HBarChart_CourseProgressPercentage.tsx +77 -0
- package/dist/modules-features/admin/core/MainDashboard/LineChart_RevenueIn12Months.tsx +78 -0
- package/dist/modules-features/admin/core/MainDashboard/LineChart_TotalRevenueByDiscountIn3Months.tsx +69 -0
- package/dist/modules-features/admin/core/MainDashboard/LineChart_TotalRevenueByVoucherIn3Months.tsx +69 -0
- package/dist/modules-features/admin/core/MainDashboard/LineChart_TotalStudentIn12Months.tsx +64 -0
- package/dist/modules-features/admin/core/MainDashboard/ViewDiscountStat.tsx +311 -0
- package/dist/modules-features/admin/core/MainDashboard/ViewVoucherStat.tsx +311 -0
- package/dist/modules-features/admin/core/core12196/F_core12196.tsx +20 -0
- package/dist/modules-features/admin/core/core12196/F_core12196_Create.tsx +101 -0
- package/dist/modules-features/admin/core/core12196/F_core12196_Delete.tsx +19 -0
- package/dist/modules-features/admin/core/core12196/F_core12196_Read.tsx +165 -0
- package/dist/modules-features/admin/core/core12196/F_core12196_Update.tsx +112 -0
- package/dist/modules-features/admin/core/core16209/F_core16209.tsx +108 -0
- package/dist/modules-features/admin/core/core16209/F_core16209_Create.tsx +112 -0
- package/dist/modules-features/admin/core/core16209/F_core16209_Delete.tsx +17 -0
- package/dist/modules-features/admin/core/core16209/F_core16209_Update.tsx +114 -0
- package/dist/modules-features/admin/core/core18256/F_core18256.tsx +29 -0
- package/dist/modules-features/admin/core/core18256/F_core18256_Create.tsx +34 -0
- package/dist/modules-features/admin/core/core18256/F_core18256_Delete.tsx +14 -0
- package/dist/modules-features/admin/core/core18256/F_core18256_Read.tsx +59 -0
- package/dist/modules-features/admin/core/core18256/F_core18256_Select.tsx +40 -0
- package/dist/modules-features/admin/core/core18256/F_core18256_Update.tsx +22 -0
- package/dist/modules-features/admin/core/core26965/F_core26965.tsx +17 -0
- package/dist/modules-features/admin/core/core26965/F_core26965_Create.tsx +106 -0
- package/dist/modules-features/admin/core/core26965/F_core26965_Delete.tsx +19 -0
- package/dist/modules-features/admin/core/core26965/F_core26965_Read.tsx +165 -0
- package/dist/modules-features/admin/core/core26965/F_core26965_Update.tsx +112 -0
- package/dist/modules-features/admin/core/core27311/F_core27311.tsx +21 -0
- package/dist/modules-features/admin/core/core27311/F_core27311_Create.tsx +109 -0
- package/dist/modules-features/admin/core/core27311/F_core27311_Delete.tsx +19 -0
- package/dist/modules-features/admin/core/core27311/F_core27311_Read.tsx +165 -0
- package/dist/modules-features/admin/core/core27311/F_core27311_Update.tsx +113 -0
- package/dist/modules-features/admin/core/core35923/F_core35923.tsx +46 -0
- package/dist/modules-features/admin/core/core38677/F_core38677.tsx +28 -0
- package/dist/modules-features/admin/core/core38677/F_core38677_ReadUser.tsx +79 -0
- package/dist/modules-features/admin/core/core38677/F_core38677_Save.tsx +52 -0
- package/dist/modules-features/admin/core/core38677/F_core38677_ViewMenuPermissions.tsx +264 -0
- package/dist/modules-features/admin/core/core40207/F_core40207.tsx +9 -0
- package/dist/modules-features/admin/core/core40207/F_core40207_Create.tsx +81 -0
- package/dist/modules-features/admin/core/core40207/F_core40207_Delete.tsx +17 -0
- package/dist/modules-features/admin/core/core40207/F_core40207_Read.tsx +98 -0
- package/dist/modules-features/admin/core/core40207/F_core40207_Update.tsx +83 -0
- package/dist/modules-features/admin/core/core47643/F_core47643.tsx +10 -0
- package/dist/modules-features/admin/core/core47643/F_core47643_Delete.tsx +13 -0
- package/dist/modules-features/admin/core/core47643/F_core47643_Form.tsx +34 -0
- package/dist/modules-features/admin/core/core47643/F_core47643_Read.tsx +57 -0
- package/dist/modules-features/admin/core/core60524/F_core60524.tsx +13 -0
- package/dist/modules-features/admin/core/core60524/F_core60524_Form.tsx +111 -0
- package/dist/modules-features/admin/core/core60524/F_core60524_Save.tsx +56 -0
- package/dist/modules-features/admin/core/core60524/useS_core60524.ts +16 -0
- package/dist/modules-features/admin/core/core64229/F_core64229.tsx +7 -0
- package/dist/modules-features/admin/core/core64229/F_core64229_Delete.tsx +21 -0
- package/dist/modules-features/admin/core/core64229/F_core64229_Form.tsx +95 -0
- package/dist/modules-features/admin/core/core64229/F_core64229_Read.tsx +67 -0
- package/dist/modules-features/admin/core/core71678/F_core71678.tsx +8 -0
- package/dist/modules-features/admin/core/core71678/F_core71678_ChangePermission.tsx +117 -0
- package/dist/modules-features/admin/core/core71678/F_core71678_Create.tsx +61 -0
- package/dist/modules-features/admin/core/core71678/F_core71678_Delete.tsx +16 -0
- package/dist/modules-features/admin/core/core71678/F_core71678_Read.tsx +92 -0
- package/dist/modules-features/admin/core/core71678/F_core71678_Update.tsx +49 -0
- package/dist/modules-features/admin/core/core76318/F_core76318.tsx +9 -0
- package/dist/modules-features/admin/core/core76318/F_core76318_Create.tsx +89 -0
- package/dist/modules-features/admin/core/core76318/F_core76318_Delete.tsx +17 -0
- package/dist/modules-features/admin/core/core76318/F_core76318_Read.tsx +104 -0
- package/dist/modules-features/admin/core/core76318/F_core76318_Update.tsx +89 -0
- package/dist/modules-features/admin/core/core83092/F_core83092.tsx +27 -0
- package/dist/modules-features/admin/core/core83092/F_core83092_ReadUser.tsx +85 -0
- package/dist/modules-features/admin/core/core83092/F_core83092_Save.tsx +52 -0
- package/dist/modules-features/admin/core/core83092/F_core83092_ViewMenuPermissions.tsx +263 -0
- package/dist/modules-features/admin/core/core83092/useS_core83092.tsx +70 -0
- package/dist/modules-features/authenticate/F_authenticate_Login/F_authenticate_Login.tsx +154 -0
- package/dist/modules-features/authenticate/F_authenticate_Login/css.module.css +4 -0
- package/dist/modules-features/authenticate/F_authenticate_Logout.tsx +22 -0
- package/dist/modules-features/authenticate/F_authenticate_SplashPage.tsx +21 -0
- package/dist/modules-features/authenticate/useS_authenticate.ts +23 -0
- package/dist/modules-features/index.mjs +2 -2
- package/dist/modules-features/index.ts +79 -0
- package/dist/providers/MyMantineProvider.tsx +140 -0
- package/dist/providers/MyReactQueryProvider.tsx +24 -0
- package/dist/providers/Provider.tsx +13 -0
- package/dist/providers/mantine.module.css +21 -0
- package/dist/stores/CreateGenericStore.ts +23 -0
- package/dist/stores/index.ts +1 -0
- package/dist/types/types.ts +16 -0
- package/dist/utils/index.ts +9 -0
- package/dist/utils/utils_converter.ts +39 -0
- package/dist/utils/utils_currency.ts +5 -0
- package/dist/utils/utils_date.ts +34 -0
- package/dist/utils/utils_excel.ts +128 -0
- package/dist/utils/utils_file.ts +61 -0
- package/dist/utils/utils_notification.ts +46 -0
- package/dist/utils/utils_pdf.ts +21 -0
- package/dist/utils/utils_time.ts +15 -0
- package/dist/utils/utils_validateForm.ts +9 -0
- package/package.json +1 -1
- package/dist/modules-features/index.css +0 -100
@@ -0,0 +1,140 @@
|
|
1
|
+
'use client'
|
2
|
+
import { ActionIcon, Blockquote, Divider, FileInput, Indicator, MantineProvider, Modal, Paper, Select, SimpleGrid, Space, Switch, Table, TextInput, Textarea, Title, Tooltip, createTheme } from '@mantine/core';
|
3
|
+
import { DateInput, TimeInput } from '@mantine/dates';
|
4
|
+
import { ModalsProvider } from '@mantine/modals';
|
5
|
+
import { Notifications } from '@mantine/notifications';
|
6
|
+
import { IconFile, IconInfoCircle } from '@tabler/icons-react';
|
7
|
+
import dayjs from 'dayjs';
|
8
|
+
import 'dayjs/locale/vi';
|
9
|
+
import { ReactNode } from 'react';
|
10
|
+
import classes from './mantine.module.css';
|
11
|
+
dayjs.locale('vi');
|
12
|
+
export default function MyMantineProvider({ children }: { children?: ReactNode }) {
|
13
|
+
return (
|
14
|
+
<MantineProvider defaultColorScheme="light" theme={theme}>
|
15
|
+
<ModalsProvider labels={{
|
16
|
+
confirm: 'Thêm', cancel: 'Huỷ'
|
17
|
+
}}>
|
18
|
+
<Notifications />
|
19
|
+
{children}
|
20
|
+
</ModalsProvider>
|
21
|
+
</MantineProvider >
|
22
|
+
)
|
23
|
+
}
|
24
|
+
|
25
|
+
const theme = createTheme({
|
26
|
+
cursorType: 'pointer',
|
27
|
+
components: {
|
28
|
+
Switch: Switch.extend({
|
29
|
+
defaultProps: {
|
30
|
+
maw: "fit-content"
|
31
|
+
}
|
32
|
+
}),
|
33
|
+
Paper: Paper.extend({
|
34
|
+
defaultProps: {
|
35
|
+
withBorder: true,
|
36
|
+
shadow: "sm",
|
37
|
+
radius: "md",
|
38
|
+
}
|
39
|
+
}),
|
40
|
+
TextInput: TextInput.extend({
|
41
|
+
defaultProps: {
|
42
|
+
classNames: classes
|
43
|
+
}
|
44
|
+
}),
|
45
|
+
Textarea: Textarea.extend({
|
46
|
+
defaultProps: {
|
47
|
+
autosize: true,
|
48
|
+
minRows: 4,
|
49
|
+
w: '100%'
|
50
|
+
}
|
51
|
+
}),
|
52
|
+
Title: Title.extend({
|
53
|
+
defaultProps: {
|
54
|
+
order: 2
|
55
|
+
}
|
56
|
+
}),
|
57
|
+
Modal: Modal.extend({
|
58
|
+
defaultProps: {
|
59
|
+
centered: true,
|
60
|
+
overlayProps: {
|
61
|
+
backgroundOpacity: 0.55,
|
62
|
+
blur: 3,
|
63
|
+
},
|
64
|
+
}
|
65
|
+
}),
|
66
|
+
DateInput: DateInput.extend({
|
67
|
+
defaultProps: {
|
68
|
+
dateParser: (value) => {
|
69
|
+
const [day, month, year] = value.split("/");
|
70
|
+
return new Date(`${year}-${month}-${day}`);
|
71
|
+
},
|
72
|
+
valueFormat: "DD/MM/YYYY",
|
73
|
+
locale: "vi",
|
74
|
+
clearable: true,
|
75
|
+
highlightToday: true,
|
76
|
+
},
|
77
|
+
}),
|
78
|
+
TimeInput: TimeInput.extend({
|
79
|
+
defaultProps: {
|
80
|
+
}
|
81
|
+
}),
|
82
|
+
Divider: Divider.extend({
|
83
|
+
defaultProps: {
|
84
|
+
my: "md"
|
85
|
+
}
|
86
|
+
}),
|
87
|
+
|
88
|
+
Tooltip: Tooltip.extend({
|
89
|
+
defaultProps: {
|
90
|
+
withArrow: true,
|
91
|
+
transitionProps: { transition: 'skew-up', duration: 150 }
|
92
|
+
}
|
93
|
+
}),
|
94
|
+
SimpleGrid: SimpleGrid.extend({
|
95
|
+
defaultProps: {
|
96
|
+
cols: { base: 1, sm: 2, lg: 4 }
|
97
|
+
}
|
98
|
+
}),
|
99
|
+
Blockquote: Blockquote.extend({
|
100
|
+
defaultProps: {
|
101
|
+
iconSize: 30,
|
102
|
+
icon: <IconInfoCircle />
|
103
|
+
}
|
104
|
+
}),
|
105
|
+
ActionIcon: ActionIcon.extend({
|
106
|
+
defaultProps: {
|
107
|
+
variant: "light"
|
108
|
+
}
|
109
|
+
}),
|
110
|
+
Indicator: Indicator.extend({
|
111
|
+
defaultProps: {
|
112
|
+
size: 16,
|
113
|
+
inline: true,
|
114
|
+
}
|
115
|
+
}),
|
116
|
+
Table: Table.extend({
|
117
|
+
defaultProps: {
|
118
|
+
withTableBorder: true,
|
119
|
+
withColumnBorders: true,
|
120
|
+
highlightOnHover: true,
|
121
|
+
},
|
122
|
+
}),
|
123
|
+
Space: Space.extend({
|
124
|
+
defaultProps: {
|
125
|
+
my: "md",
|
126
|
+
mx: "md"
|
127
|
+
}
|
128
|
+
}),
|
129
|
+
FileInput: FileInput.extend({
|
130
|
+
defaultProps: {
|
131
|
+
leftSection: <IconFile></IconFile>
|
132
|
+
}
|
133
|
+
}),
|
134
|
+
Select: Select.extend({
|
135
|
+
defaultProps: {
|
136
|
+
allowDeselect: false
|
137
|
+
}
|
138
|
+
})
|
139
|
+
}
|
140
|
+
});
|
@@ -0,0 +1,24 @@
|
|
1
|
+
"use client"
|
2
|
+
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
|
3
|
+
import { ReactQueryDevtools } from '@tanstack/react-query-devtools';
|
4
|
+
import { ReactNode } from "react";
|
5
|
+
const queryClient = new QueryClient({
|
6
|
+
defaultOptions: {
|
7
|
+
queries: {
|
8
|
+
refetchOnWindowFocus: false,
|
9
|
+
},
|
10
|
+
mutations: {
|
11
|
+
onSuccess: () => {
|
12
|
+
queryClient.invalidateQueries();
|
13
|
+
},
|
14
|
+
},
|
15
|
+
},
|
16
|
+
});
|
17
|
+
export default function MyReactQueryProvider({ children }: { children?: ReactNode }) {
|
18
|
+
return (
|
19
|
+
<QueryClientProvider client={queryClient}>
|
20
|
+
{children}
|
21
|
+
<ReactQueryDevtools buttonPosition={"bottom-left"} initialIsOpen={false} />
|
22
|
+
</QueryClientProvider>
|
23
|
+
)
|
24
|
+
}
|
@@ -0,0 +1,13 @@
|
|
1
|
+
import { ReactNode } from 'react';
|
2
|
+
import MyMantineProvider from './MyMantineProvider';
|
3
|
+
import MyReactQueryProvider from './MyReactQueryProvider';
|
4
|
+
|
5
|
+
export default function Provider({ children }: { children?: ReactNode }) {
|
6
|
+
return (
|
7
|
+
<MyReactQueryProvider>
|
8
|
+
<MyMantineProvider>
|
9
|
+
{children}
|
10
|
+
</MyMantineProvider>
|
11
|
+
</MyReactQueryProvider>
|
12
|
+
)
|
13
|
+
}
|
@@ -0,0 +1,21 @@
|
|
1
|
+
.input {
|
2
|
+
&[data-variant="underline"] {
|
3
|
+
border: 2px solid transparent;
|
4
|
+
border-radius: 5px;
|
5
|
+
padding-left: 8px;
|
6
|
+
padding-right: 8px;
|
7
|
+
background-color: white;
|
8
|
+
|
9
|
+
&:focus,
|
10
|
+
&:focus-visible {
|
11
|
+
border-color: var(--mantine-color-gray-5);
|
12
|
+
outline: none;
|
13
|
+
}
|
14
|
+
|
15
|
+
&:active {
|
16
|
+
border-color: var(--mantine-color-gray-5);
|
17
|
+
}
|
18
|
+
|
19
|
+
transition: border-color 0.2s ease-in-out;
|
20
|
+
}
|
21
|
+
}
|
@@ -0,0 +1,23 @@
|
|
1
|
+
import { create } from "zustand";
|
2
|
+
import { persist } from "zustand/middleware";
|
3
|
+
|
4
|
+
interface GenericStore<T> {
|
5
|
+
state: T;
|
6
|
+
setState: (newState: T) => void;
|
7
|
+
setProperty: <K extends keyof T>(key: K, value: T[K]) => void;
|
8
|
+
resetState: () => void;
|
9
|
+
}
|
10
|
+
|
11
|
+
export function createGenericStore<T>({ initialState, storageKey }: { initialState: T, storageKey?: string }) {
|
12
|
+
const storeCreator = (set: any) => ({
|
13
|
+
state: initialState,
|
14
|
+
setState: (newState: T) => set({ state: newState }),
|
15
|
+
setProperty: <K extends keyof T>(key: K, value: T[K]) =>
|
16
|
+
set((store: GenericStore<T>) => ({ state: { ...store.state, [key]: value } })),
|
17
|
+
resetState: () => set({ state: initialState }),
|
18
|
+
});
|
19
|
+
|
20
|
+
return storageKey
|
21
|
+
? create(persist<GenericStore<T>>(storeCreator, { name: storageKey }))
|
22
|
+
: create<GenericStore<T>>(storeCreator);
|
23
|
+
}
|
@@ -0,0 +1 @@
|
|
1
|
+
export * from './CreateGenericStore';
|
@@ -0,0 +1,16 @@
|
|
1
|
+
import { MantineSize } from "@mantine/core";
|
2
|
+
|
3
|
+
export type TYPES_MANTINE_SIZE = number | MantineSize | (string & {}) | undefined;
|
4
|
+
export type TYPES_CRUD =
|
5
|
+
"default"
|
6
|
+
| "create"
|
7
|
+
| "update"
|
8
|
+
| "delete"
|
9
|
+
| "save"
|
10
|
+
| "createMultiple"
|
11
|
+
| "check"
|
12
|
+
| "import"
|
13
|
+
| "print"
|
14
|
+
| "cancel"
|
15
|
+
| "export"
|
16
|
+
| "select";
|
@@ -0,0 +1,9 @@
|
|
1
|
+
export * from './utils_converter';
|
2
|
+
export * from './utils_currency';
|
3
|
+
export * from './utils_date';
|
4
|
+
export * from './utils_excel';
|
5
|
+
export * from './utils_file';
|
6
|
+
export * from './utils_notification';
|
7
|
+
export * from './utils_pdf';
|
8
|
+
export * from './utils_time';
|
9
|
+
export * from './utils_validateForm';
|
@@ -0,0 +1,39 @@
|
|
1
|
+
// export const utils_converter_enumToOptions = (enumObj: object) => {
|
2
|
+
// return Object.entries(enumObj)
|
3
|
+
// .filter(([key]) => isNaN(Number(key))) // Loại bỏ các key là số
|
4
|
+
// .map(([label, value]) => ({ value: String(value), label }));
|
5
|
+
// };
|
6
|
+
|
7
|
+
export const utils_converter_getLabelByValue = (data: Record<number, string>, value?: number | string): string => {
|
8
|
+
const numericValue = Number(value); // Chuyển về number
|
9
|
+
return data[numericValue] || "Không xác định";
|
10
|
+
};
|
11
|
+
|
12
|
+
export const utils_converter_getKeyByValue = <K extends string | number, V>(obj: Record<K, V>, value: V): K | undefined => {
|
13
|
+
return (Object.entries(obj) as [K, V][]).find(([_, v]) => v === value)?.[0];
|
14
|
+
};
|
15
|
+
|
16
|
+
/**
|
17
|
+
* Chuyển đổi enum thành mảng các đối tượng {value, label}
|
18
|
+
* @param enumObject - Đối tượng enum cần chuyển đổi
|
19
|
+
* @returns Mảng các đối tượng có dạng {value: string, label: string}
|
20
|
+
*/
|
21
|
+
export function utils_converter_enumToSelectOptions<T extends Record<string, string | number>>(enumObject: T): Array<{ value: string, label: string }> {
|
22
|
+
const result: Array<{ value: string, label: string }> = [];
|
23
|
+
|
24
|
+
// Lọc các key là string và value là number (các key enum thông thường)
|
25
|
+
const numericEnumKeys = Object.keys(enumObject).filter(key => isNaN(Number(key)));
|
26
|
+
|
27
|
+
for (const key of numericEnumKeys) {
|
28
|
+
const enumValue = enumObject[key];
|
29
|
+
if (typeof enumValue === 'number') {
|
30
|
+
// Thêm cặp value-label vào mảng kết quả
|
31
|
+
result.push({
|
32
|
+
value: String(enumValue),
|
33
|
+
label: key
|
34
|
+
});
|
35
|
+
}
|
36
|
+
}
|
37
|
+
|
38
|
+
return result;
|
39
|
+
}
|
@@ -0,0 +1,34 @@
|
|
1
|
+
export function U0DateToDDMMYYYString(date: Date) {
|
2
|
+
if (!(date instanceof Date) || isNaN(date.getTime())) return "";
|
3
|
+
const day = String(date.getDate()).padStart(2, "0");
|
4
|
+
const month = String(date.getMonth() + 1).padStart(2, "0"); // Tháng bắt đầu từ 0 nên phải cộng thêm 1
|
5
|
+
const year = date.getFullYear();
|
6
|
+
return `${day}/${month}/${year}`;
|
7
|
+
}
|
8
|
+
|
9
|
+
export function utils_date_dateToDDMMYYYString(date: Date) {
|
10
|
+
const day = String(date.getDate()).padStart(2, "0");
|
11
|
+
const month = String(date.getMonth() + 1).padStart(2, "0"); // Tháng bắt đầu từ 0 nên phải cộng thêm 1
|
12
|
+
const year = date.getFullYear();
|
13
|
+
return `${day}/${month}/${year}`;
|
14
|
+
}
|
15
|
+
|
16
|
+
export function utils_date_formatToDateTimeStartEnd(startDate: Date, endDate: Date) {
|
17
|
+
const startday = String(startDate.getDate()).padStart(2, "0");
|
18
|
+
const startmonth = String(startDate.getMonth() + 1).padStart(2, "0"); // Tháng bắt đầu từ 0 nên phải cộng thêm 1
|
19
|
+
const startyear = startDate.getFullYear();
|
20
|
+
const starthour = String(startDate.getHours()).padStart(2, "0");
|
21
|
+
const startminute = String(startDate.getMinutes()).padStart(2, "0");
|
22
|
+
|
23
|
+
const endhour = String(endDate.getHours()).padStart(2, "0");
|
24
|
+
const endminuate = String(endDate.getMinutes()).padStart(2, "0");
|
25
|
+
|
26
|
+
return `${startday}/${startmonth}/${startyear} [${starthour}:${startminute} - ${endhour}:${endminuate}]`;
|
27
|
+
}
|
28
|
+
|
29
|
+
export function utils_date_getHHmm(date: Date) {
|
30
|
+
if (!(date instanceof Date) || isNaN(date.getTime())) return "";
|
31
|
+
const hour = String(date.getHours()).padStart(2, "0");
|
32
|
+
const minute = String(date.getMinutes()).padStart(2, "0");
|
33
|
+
return `${hour}:${minute}`;
|
34
|
+
}
|
@@ -0,0 +1,128 @@
|
|
1
|
+
import ExcelJS from "exceljs";
|
2
|
+
import saveAs from "file-saver";
|
3
|
+
|
4
|
+
export interface IUtils_Excel_ColumnConfig<T> {
|
5
|
+
fieldKey: keyof T | string; // string để hỗ trợ nested key như "user.code"
|
6
|
+
fieldName: string;
|
7
|
+
isRequired?: boolean;
|
8
|
+
}
|
9
|
+
|
10
|
+
function isObjectPath(path: string): boolean {
|
11
|
+
// true nếu không chứa số hoặc ký tự đặc biệt (ngoài chấm ngăn cách field)
|
12
|
+
return /^[a-zA-Z_$][a-zA-Z0-9_$]*(\.[a-zA-Z_$][a-zA-Z0-9_$]*)+$/.test(path);
|
13
|
+
}
|
14
|
+
|
15
|
+
function getValueByPath(obj: any, path: string): any {
|
16
|
+
if (isObjectPath(path)) {
|
17
|
+
return path.split(".").reduce((acc, key) => acc?.[key], obj);
|
18
|
+
}
|
19
|
+
return obj?.[path];
|
20
|
+
}
|
21
|
+
|
22
|
+
export async function utils_excel_exportExcel<T extends Record<string, any>>({
|
23
|
+
workbook,
|
24
|
+
sheetName,
|
25
|
+
data,
|
26
|
+
config,
|
27
|
+
}: {
|
28
|
+
workbook: ExcelJS.Workbook;
|
29
|
+
sheetName: string;
|
30
|
+
data: T[];
|
31
|
+
config: IUtils_Excel_ColumnConfig<T>[];
|
32
|
+
}) {
|
33
|
+
const sheet = workbook.addWorksheet(sheetName);
|
34
|
+
|
35
|
+
const fieldKeys: string[] = config.map((item) => String(item.fieldKey));
|
36
|
+
const headerMappings: Record<string, string> = {};
|
37
|
+
const markedColumns: string[] = [];
|
38
|
+
|
39
|
+
config.forEach((item) => {
|
40
|
+
const fieldKeyStr = String(item.fieldKey);
|
41
|
+
headerMappings[fieldKeyStr] = item.fieldName;
|
42
|
+
if (item.isRequired) markedColumns.push(fieldKeyStr);
|
43
|
+
});
|
44
|
+
|
45
|
+
sheet.columns = fieldKeys.map((fieldKey) => ({
|
46
|
+
key: fieldKey,
|
47
|
+
width: 20,
|
48
|
+
}));
|
49
|
+
|
50
|
+
const displayRow = sheet.addRow(
|
51
|
+
fieldKeys.map((fieldKey) =>
|
52
|
+
markedColumns.includes(fieldKey)
|
53
|
+
? `${headerMappings[fieldKey]} *`
|
54
|
+
: headerMappings[fieldKey] || fieldKey
|
55
|
+
)
|
56
|
+
);
|
57
|
+
|
58
|
+
const keyRow = sheet.addRow(fieldKeys);
|
59
|
+
|
60
|
+
data.forEach((item) => {
|
61
|
+
const rowData: Record<string, any> = {};
|
62
|
+
fieldKeys.forEach((fieldKey) => {
|
63
|
+
rowData[fieldKey] = getValueByPath(item, fieldKey);
|
64
|
+
});
|
65
|
+
sheet.addRow(rowData);
|
66
|
+
});
|
67
|
+
|
68
|
+
// Style the first row (display names)
|
69
|
+
for (let i = 1; i <= fieldKeys.length; i++) {
|
70
|
+
const cell = displayRow.getCell(i);
|
71
|
+
cell.font = { bold: true };
|
72
|
+
cell.fill = {
|
73
|
+
type: "pattern",
|
74
|
+
pattern: "solid",
|
75
|
+
fgColor: { argb: "FFE0E0E0" },
|
76
|
+
};
|
77
|
+
}
|
78
|
+
|
79
|
+
// Style the second row (field keys)
|
80
|
+
for (let i = 1; i <= fieldKeys.length; i++) {
|
81
|
+
const cell = keyRow.getCell(i);
|
82
|
+
cell.font = { italic: true };
|
83
|
+
cell.fill = {
|
84
|
+
type: "pattern",
|
85
|
+
pattern: "solid",
|
86
|
+
fgColor: { argb: "FFF0F0F0" },
|
87
|
+
};
|
88
|
+
}
|
89
|
+
|
90
|
+
// Apply red color to asterisks in headers
|
91
|
+
if (markedColumns.length > 0) {
|
92
|
+
for (let i = 1; i <= fieldKeys.length; i++) {
|
93
|
+
const cell = displayRow.getCell(i);
|
94
|
+
const text = cell.value;
|
95
|
+
|
96
|
+
if (typeof text === "string" && text.endsWith(" *")) {
|
97
|
+
cell.value = {
|
98
|
+
richText: [
|
99
|
+
{
|
100
|
+
text: text.slice(0, -2),
|
101
|
+
font: { bold: true },
|
102
|
+
},
|
103
|
+
{
|
104
|
+
text: " *",
|
105
|
+
font: { bold: true, color: { argb: "FFFF0000" } },
|
106
|
+
},
|
107
|
+
],
|
108
|
+
};
|
109
|
+
}
|
110
|
+
}
|
111
|
+
}
|
112
|
+
|
113
|
+
return workbook;
|
114
|
+
}
|
115
|
+
|
116
|
+
export async function utils_excel_download({
|
117
|
+
workbook,
|
118
|
+
name,
|
119
|
+
}: {
|
120
|
+
workbook: ExcelJS.Workbook;
|
121
|
+
name: string;
|
122
|
+
}) {
|
123
|
+
const buffer = await workbook.xlsx.writeBuffer();
|
124
|
+
const blob = new Blob([buffer], {
|
125
|
+
type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
|
126
|
+
});
|
127
|
+
saveAs(blob, name);
|
128
|
+
}
|
@@ -0,0 +1,61 @@
|
|
1
|
+
import Docxtemplater from 'docxtemplater';
|
2
|
+
import { saveAs } from 'file-saver';
|
3
|
+
import PizZip from 'pizzip';
|
4
|
+
|
5
|
+
export interface IAQFileDetail {
|
6
|
+
fileName?: string,
|
7
|
+
fileExtension?: string,
|
8
|
+
fileBase64String?: string
|
9
|
+
}
|
10
|
+
|
11
|
+
export function utils_file_fileToAQDocumentType(file: File): Promise<IAQFileDetail> {
|
12
|
+
return new Promise((resolve, reject) => {
|
13
|
+
const fileReader = new FileReader();
|
14
|
+
|
15
|
+
// Đọc tệp dưới dạng Base64
|
16
|
+
fileReader.onloadend = () => {
|
17
|
+
const fileName = file.name; // Tên tệp
|
18
|
+
const fileExtension = file.name.split(".").pop(); // Phần mở rộng tệp
|
19
|
+
const fileBase64String = fileReader.result as string; // Base64 string của tệp
|
20
|
+
|
21
|
+
resolve({
|
22
|
+
fileName,
|
23
|
+
fileExtension,
|
24
|
+
fileBase64String: fileBase64String.split(",")[1], // Chỉ lấy phần base64 sau dấu phẩy
|
25
|
+
});
|
26
|
+
};
|
27
|
+
|
28
|
+
fileReader.onerror = reject;
|
29
|
+
|
30
|
+
// Đọc tệp dưới dạng Data URL (Base64)
|
31
|
+
fileReader.readAsDataURL(file);
|
32
|
+
});
|
33
|
+
}
|
34
|
+
|
35
|
+
export async function utils_file_docxtemplaterDownload({
|
36
|
+
data,
|
37
|
+
filePath,
|
38
|
+
fileName
|
39
|
+
}: {
|
40
|
+
data: any,
|
41
|
+
filePath: string,
|
42
|
+
fileName?: string
|
43
|
+
}) {
|
44
|
+
const response = await fetch(filePath);
|
45
|
+
const arrayBuffer = await response.arrayBuffer();
|
46
|
+
|
47
|
+
// Tạo PizZip từ nội dung mẫu
|
48
|
+
const zip = new PizZip(arrayBuffer);
|
49
|
+
|
50
|
+
// Tạo Docxtemplater từ PizZip
|
51
|
+
const doc = new Docxtemplater(zip);
|
52
|
+
|
53
|
+
// Dữ liệu để thay thế
|
54
|
+
|
55
|
+
doc.render(data);
|
56
|
+
// Xuất kết quả thành DOCX
|
57
|
+
const buffer = doc.getZip().generate({ type: 'blob' });
|
58
|
+
|
59
|
+
// Tải xuống tệp DOCX
|
60
|
+
saveAs(buffer, fileName || 'output.docx');
|
61
|
+
}
|
@@ -0,0 +1,46 @@
|
|
1
|
+
import { DefaultMantineColor } from "@mantine/core";
|
2
|
+
import { notifications } from "@mantine/notifications";
|
3
|
+
|
4
|
+
interface I {
|
5
|
+
crudType?: "delete" | "update" | "create" | "error" | "importSucess";
|
6
|
+
message?: string;
|
7
|
+
color?: DefaultMantineColor | undefined;
|
8
|
+
}
|
9
|
+
|
10
|
+
export function utils_notification_show({ crudType = "create", message, color }: I) {
|
11
|
+
if (crudType == "create") {
|
12
|
+
notifications.show({
|
13
|
+
message: message ? message : "Thêm thành công!",
|
14
|
+
color: color ? color : "green",
|
15
|
+
});
|
16
|
+
return;
|
17
|
+
}
|
18
|
+
if (crudType == "update") {
|
19
|
+
notifications.show({
|
20
|
+
message: message ? message : "Cập nhật thành công!",
|
21
|
+
color: color ? color : "green",
|
22
|
+
});
|
23
|
+
return;
|
24
|
+
}
|
25
|
+
if (crudType == "delete") {
|
26
|
+
notifications.show({
|
27
|
+
message: message ? message : "Xóa thành công!",
|
28
|
+
color: color ? color : "green",
|
29
|
+
});
|
30
|
+
return;
|
31
|
+
}
|
32
|
+
if (crudType == "error") {
|
33
|
+
notifications.show({
|
34
|
+
message: message ? message : "Lỗi!",
|
35
|
+
color: color ? color : "red",
|
36
|
+
});
|
37
|
+
return;
|
38
|
+
}
|
39
|
+
|
40
|
+
if (crudType == "importSucess") {
|
41
|
+
notifications.show({
|
42
|
+
message: message ? message : "Import thành công!",
|
43
|
+
});
|
44
|
+
return;
|
45
|
+
}
|
46
|
+
}
|
@@ -0,0 +1,21 @@
|
|
1
|
+
import axios from "axios";
|
2
|
+
|
3
|
+
export async function utils_pdf_download(url: string) {
|
4
|
+
try {
|
5
|
+
const response = await axios.get(url, {
|
6
|
+
responseType: "blob", // Đảm bảo nhận dữ liệu dạng blob để tải file
|
7
|
+
});
|
8
|
+
|
9
|
+
// Tạo một URL tạm từ dữ liệu blob nhận được
|
10
|
+
const blob = new Blob([response.data], { type: "application/pdf" });
|
11
|
+
const link = document.createElement("a");
|
12
|
+
link.href = window.URL.createObjectURL(blob);
|
13
|
+
link.download = "file.pdf";
|
14
|
+
link.click();
|
15
|
+
|
16
|
+
// Giải phóng URL tạm khi đã hoàn thành
|
17
|
+
window.URL.revokeObjectURL(link.href);
|
18
|
+
} catch (error) {
|
19
|
+
console.error("Error downloading PDF:", error);
|
20
|
+
}
|
21
|
+
}
|
@@ -0,0 +1,15 @@
|
|
1
|
+
export const utils_time_convertTimeStringToSeconds = (time: string): number => {
|
2
|
+
const [hours, minutes, seconds] = time.split(":").map(Number);
|
3
|
+
return hours * 3600 + minutes * 60 + seconds;
|
4
|
+
};
|
5
|
+
|
6
|
+
export const utils_time_getCurrentTimeString = (): string => {
|
7
|
+
const formatTime = (number: number) => {
|
8
|
+
return number < 10 ? "0" + number : number;
|
9
|
+
};
|
10
|
+
const now = new Date();
|
11
|
+
const hours = formatTime(now.getHours());
|
12
|
+
const minutes = formatTime(now.getMinutes());
|
13
|
+
const seconds = formatTime(now.getSeconds());
|
14
|
+
return `${hours}:${minutes}:${seconds}`;
|
15
|
+
};
|
@@ -0,0 +1,9 @@
|
|
1
|
+
import { isNotEmpty } from "@mantine/form";
|
2
|
+
|
3
|
+
export function U0MyValidateEmpty(message?: string) {
|
4
|
+
return isNotEmpty(message ? message : "Không được để trống")
|
5
|
+
}
|
6
|
+
|
7
|
+
export function U0MyValidateEmail(value?: string) {
|
8
|
+
return /^\S+@\S+$/.test(value!) ? null : "Email không đúng định dạng";
|
9
|
+
}
|