trithuc-mvc-react 1.0.0
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/api/index.js +57 -0
- package/components/DataManagement/DataTable.jsx +186 -0
- package/components/DataManagement/EditorDialog.jsx +64 -0
- package/components/DataManagement/EditorForm.jsx +147 -0
- package/components/DataManagement/ExportExcelButton.jsx +27 -0
- package/components/DataManagement/FilterElement.jsx +102 -0
- package/components/DataManagement/FilterGod.jsx +83 -0
- package/components/DataManagement/FormField.jsx +240 -0
- package/components/DataManagement/TableHead.jsx +26 -0
- package/components/DataManagement/TableRowRender.jsx +82 -0
- package/components/DataManagement/TableToolbar.jsx +57 -0
- package/components/DataManagement/context.js +4 -0
- package/components/DataManagement/hooks.js +19 -0
- package/components/DataManagement/index.jsx +107 -0
- package/components/date/DateRangePicker.jsx +143 -0
- package/components/date/StaticDateRangePicker.jsx +498 -0
- package/components/date/index.js +1 -0
- package/components/index.js +4 -0
- package/components/table/TablePagination.jsx +34 -0
- package/components/table/TableRowsLoader.jsx +15 -0
- package/components/table/index.js +2 -0
- package/constants/index.js +1 -0
- package/helpers/data-table.js +23 -0
- package/helpers/index.js +1 -0
- package/index.js +3 -0
- package/package.json +15 -0
|
@@ -0,0 +1,498 @@
|
|
|
1
|
+
/* eslint-disable react/prop-types */
|
|
2
|
+
"use client";
|
|
3
|
+
import { useEffect, useState } from "react";
|
|
4
|
+
import * as dateFns from "date-fns";
|
|
5
|
+
import { Box, Paper, Stack } from "@mui/material";
|
|
6
|
+
// import "tailwindcss/tailwind.css";
|
|
7
|
+
|
|
8
|
+
const isBetween = (date, from, to, inclusivity) => {
|
|
9
|
+
if (!["()", "[]", "(]", "[)"].includes(inclusivity)) {
|
|
10
|
+
throw new Error("Inclusivity parameter must be one of (), [], (], [)");
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
const isBeforeEqual = inclusivity[0] === "[",
|
|
14
|
+
isAfterEqual = inclusivity[1] === "]";
|
|
15
|
+
|
|
16
|
+
return (
|
|
17
|
+
(isBeforeEqual ? dateFns.isEqual(from, date) || dateFns.isBefore(from, date) : dateFns.isBefore(from, date)) &&
|
|
18
|
+
(isAfterEqual ? dateFns.isEqual(to, date) || dateFns.isAfter(to, date) : dateFns.isAfter(to, date))
|
|
19
|
+
);
|
|
20
|
+
};
|
|
21
|
+
const days = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];
|
|
22
|
+
|
|
23
|
+
const StaticDateRangePicker = ({ value, onUpdate }) => {
|
|
24
|
+
const [currCalendar, setCurrCalendar] = useState([]);
|
|
25
|
+
const [nextCalendar, setNextCalendar] = useState([]);
|
|
26
|
+
const [currMonth, setCurrMonth] = useState(new Date().getMonth());
|
|
27
|
+
const [currYear, setCurrYear] = useState(new Date().getFullYear());
|
|
28
|
+
|
|
29
|
+
const [dateRange, setDateRange] = useState({
|
|
30
|
+
startDate: value?.startDate,
|
|
31
|
+
endDate: value?.endDate
|
|
32
|
+
});
|
|
33
|
+
// Thanks to https://github.com/date-fns/date-fns/issues/366#issuecomment-270408980
|
|
34
|
+
|
|
35
|
+
const generateCalendar = ({ month, year }) => {
|
|
36
|
+
const startOfMonth = dateFns.startOfMonth(new Date(year, month));
|
|
37
|
+
const endOfMonth = dateFns.endOfMonth(new Date(year, month));
|
|
38
|
+
const startDay = startOfMonth.getDay();
|
|
39
|
+
const daysInMonth = dateFns.getDaysInMonth(startOfMonth);
|
|
40
|
+
const days = [...Array(daysInMonth).keys()].map((v) => v + 1);
|
|
41
|
+
const calendar = [...Array(42).keys()].map((v) => {
|
|
42
|
+
if (v < startDay) {
|
|
43
|
+
return null;
|
|
44
|
+
}
|
|
45
|
+
if (v > daysInMonth + startDay - 1) {
|
|
46
|
+
return null;
|
|
47
|
+
}
|
|
48
|
+
return days[v - startDay];
|
|
49
|
+
});
|
|
50
|
+
return calendar;
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
useEffect(() => {
|
|
54
|
+
const _currCalendar = generateCalendar({
|
|
55
|
+
month: new Date(currYear, currMonth).getMonth(),
|
|
56
|
+
year: new Date(currYear, currMonth).getFullYear()
|
|
57
|
+
});
|
|
58
|
+
setCurrCalendar(_currCalendar);
|
|
59
|
+
|
|
60
|
+
const _nextCalendar = generateCalendar({
|
|
61
|
+
month: dateFns.add(new Date(currYear, currMonth), { months: 1 }).getMonth(),
|
|
62
|
+
year: dateFns.add(new Date(currYear, currMonth), { months: 1 }).getFullYear()
|
|
63
|
+
});
|
|
64
|
+
setNextCalendar(_nextCalendar);
|
|
65
|
+
}, [currMonth, currYear]);
|
|
66
|
+
|
|
67
|
+
useEffect(() => {
|
|
68
|
+
onUpdate?.(dateRange);
|
|
69
|
+
}, [dateRange]);
|
|
70
|
+
|
|
71
|
+
useEffect(() => {
|
|
72
|
+
if (!value) return;
|
|
73
|
+
|
|
74
|
+
if (value.startDate && !dateFns.isSameDay(value.startDate, dateRange.startDate)) {
|
|
75
|
+
if (dateFns.isBefore(value.startDate, dateRange.endDate)) {
|
|
76
|
+
setDateRange((old) => ({ ...old, startDate: value.startDate }));
|
|
77
|
+
} else {
|
|
78
|
+
setDateRange((old) => ({ startDate: value.startDate, endDate: null }));
|
|
79
|
+
}
|
|
80
|
+
let month = value.startDate.getMonth();
|
|
81
|
+
let year = value.startDate.getFullYear();
|
|
82
|
+
if (isNaN(month) || isNaN(year)) return;
|
|
83
|
+
setCurrMonth(month);
|
|
84
|
+
setCurrYear(year);
|
|
85
|
+
} else if (value.endDate && !dateFns.isSameDay(value.endDate, dateRange.endDate)) {
|
|
86
|
+
setDateRange((old) => ({ ...old, endDate: value.endDate }));
|
|
87
|
+
let month = value.endDate.getMonth();
|
|
88
|
+
let year = value.endDate.getFullYear();
|
|
89
|
+
if (isNaN(month) || isNaN(year)) return;
|
|
90
|
+
setCurrMonth(month - 1);
|
|
91
|
+
setCurrYear(year);
|
|
92
|
+
}
|
|
93
|
+
}, [value]);
|
|
94
|
+
|
|
95
|
+
const handleUpdateDateRangeOnLeftCalendar = (day) => {
|
|
96
|
+
let thisDate = new Date(currYear, currMonth, day);
|
|
97
|
+
|
|
98
|
+
if (!dateRange.startDate) {
|
|
99
|
+
setDateRange((d) => ({
|
|
100
|
+
...d,
|
|
101
|
+
startDate: thisDate
|
|
102
|
+
// moment({
|
|
103
|
+
// day: v,
|
|
104
|
+
// month: currMonth,
|
|
105
|
+
// year: currYear,
|
|
106
|
+
// }),
|
|
107
|
+
}));
|
|
108
|
+
} else if (dateRange.startDate && !dateRange.endDate) {
|
|
109
|
+
if (dateFns.isBefore(thisDate, dateRange.startDate)) {
|
|
110
|
+
setDateRange({
|
|
111
|
+
startDate: thisDate,
|
|
112
|
+
// moment({
|
|
113
|
+
// day: v,
|
|
114
|
+
// month: currMonth,
|
|
115
|
+
// year: currYear,
|
|
116
|
+
// }),
|
|
117
|
+
endDate: null
|
|
118
|
+
});
|
|
119
|
+
} else {
|
|
120
|
+
setDateRange((d) => ({
|
|
121
|
+
...d,
|
|
122
|
+
endDate: thisDate
|
|
123
|
+
// moment({
|
|
124
|
+
// day: v,
|
|
125
|
+
// month: currMonth,
|
|
126
|
+
// year: currYear,
|
|
127
|
+
// }),
|
|
128
|
+
}));
|
|
129
|
+
}
|
|
130
|
+
} else if (dateRange.startDate && dateRange.endDate) {
|
|
131
|
+
setDateRange({
|
|
132
|
+
startDate: thisDate,
|
|
133
|
+
// moment({
|
|
134
|
+
// day: v,
|
|
135
|
+
// month: currMonth,
|
|
136
|
+
// year: currYear,
|
|
137
|
+
// }),
|
|
138
|
+
endDate: null
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
};
|
|
142
|
+
const handleUpdateDateRangeOnRightCalendar = (day) => {
|
|
143
|
+
let thisDate = dateFns.add(new Date(currYear, currMonth, day), { months: 1 });
|
|
144
|
+
|
|
145
|
+
if (!dateRange.startDate) {
|
|
146
|
+
setDateRange((d) => ({
|
|
147
|
+
...d,
|
|
148
|
+
startDate: thisDate
|
|
149
|
+
}));
|
|
150
|
+
|
|
151
|
+
// startDate: moment({
|
|
152
|
+
// day: v,
|
|
153
|
+
// month: moment({
|
|
154
|
+
// day: v,
|
|
155
|
+
// month: currMonth,
|
|
156
|
+
// year: currYear,
|
|
157
|
+
// })
|
|
158
|
+
// .add(1, "month")
|
|
159
|
+
// .month(),
|
|
160
|
+
// year: moment({
|
|
161
|
+
// day: v,
|
|
162
|
+
// month: currMonth,
|
|
163
|
+
// year: currYear,
|
|
164
|
+
// })
|
|
165
|
+
// .add(1, "month")
|
|
166
|
+
// .year(),
|
|
167
|
+
// }),
|
|
168
|
+
// }))
|
|
169
|
+
} else if (dateRange.startDate && !dateRange.endDate) {
|
|
170
|
+
if (dateFns.isBefore(thisDate, dateRange.startDate)) {
|
|
171
|
+
setDateRange({
|
|
172
|
+
startDate: thisDate,
|
|
173
|
+
// moment({
|
|
174
|
+
// day: v,
|
|
175
|
+
// month: currMonth,
|
|
176
|
+
// year: currYear,
|
|
177
|
+
// }),
|
|
178
|
+
endDate: null
|
|
179
|
+
});
|
|
180
|
+
} else {
|
|
181
|
+
setDateRange((d) => ({
|
|
182
|
+
...d,
|
|
183
|
+
endDate: thisDate
|
|
184
|
+
// moment({
|
|
185
|
+
// day: v,
|
|
186
|
+
// month: currMonth,
|
|
187
|
+
// year: currYear,
|
|
188
|
+
// }),
|
|
189
|
+
}));
|
|
190
|
+
}
|
|
191
|
+
} else if (dateRange.startDate && dateRange.endDate) {
|
|
192
|
+
setDateRange({
|
|
193
|
+
startDate: thisDate,
|
|
194
|
+
// moment({
|
|
195
|
+
// day: v,
|
|
196
|
+
// month: moment({
|
|
197
|
+
// day: v,
|
|
198
|
+
// month: currMonth,
|
|
199
|
+
// year: currYear,
|
|
200
|
+
// })
|
|
201
|
+
// .add(1, "month")
|
|
202
|
+
// .month(),
|
|
203
|
+
// year: moment({
|
|
204
|
+
// day: v,
|
|
205
|
+
// month: currMonth,
|
|
206
|
+
// year: currYear,
|
|
207
|
+
// })
|
|
208
|
+
// .add(1, "month")
|
|
209
|
+
// .year(),
|
|
210
|
+
// }),
|
|
211
|
+
endDate: null
|
|
212
|
+
});
|
|
213
|
+
}
|
|
214
|
+
};
|
|
215
|
+
|
|
216
|
+
const currTitle = currYear && currMonth ? dateFns.format(new Date(currYear, currMonth), "MMMM") + new Date(currYear, currMonth).getFullYear() : "";
|
|
217
|
+
return (
|
|
218
|
+
<Paper>
|
|
219
|
+
<Box sx={{ display: "flex" }} className="date-range-piker-wrapper">
|
|
220
|
+
<div className="drop-shadow-sm shadow-sm min-w-[10rem] p-3 rounded-lg border border-r-0 flex flex-col">
|
|
221
|
+
<div className="flex justify-between items-center">
|
|
222
|
+
<h3 className="text-lg">
|
|
223
|
+
{" "}
|
|
224
|
+
{dateFns.format(new Date(currYear, currMonth), "MMMM")} {new Date(currYear, currMonth).getFullYear()}
|
|
225
|
+
</h3>
|
|
226
|
+
|
|
227
|
+
<Stack direction="row" spacing={2} alignItems={"center"}>
|
|
228
|
+
<button
|
|
229
|
+
type="button"
|
|
230
|
+
className="p-2 rounded-lg hover:bg-gray-300 border drop-shadow-sm"
|
|
231
|
+
onClick={() => {
|
|
232
|
+
const d = dateFns.sub(new Date(currYear, currMonth), {
|
|
233
|
+
months: 1
|
|
234
|
+
});
|
|
235
|
+
setCurrMonth(d.getMonth());
|
|
236
|
+
setCurrYear(d.getFullYear());
|
|
237
|
+
}}
|
|
238
|
+
>
|
|
239
|
+
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" strokeWidth={1.5} stroke="currentColor" className="w-4 h-4">
|
|
240
|
+
<path strokeLinecap="round" strokeLinejoin="round" d="M15.75 19.5L8.25 12l7.5-7.5" />
|
|
241
|
+
</svg>
|
|
242
|
+
</button>
|
|
243
|
+
<button
|
|
244
|
+
type="button"
|
|
245
|
+
className="p-2 rounded-lg hover:bg-gray-300 border drop-shadow-sm"
|
|
246
|
+
onClick={() => {
|
|
247
|
+
const d = dateFns.add(new Date(currYear, currMonth), {
|
|
248
|
+
months: 1
|
|
249
|
+
});
|
|
250
|
+
setCurrMonth(d.getMonth());
|
|
251
|
+
setCurrYear(d.getFullYear());
|
|
252
|
+
}}
|
|
253
|
+
>
|
|
254
|
+
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" strokeWidth={1.5} stroke="currentColor" className="w-4 h-4">
|
|
255
|
+
<path strokeLinecap="round" strokeLinejoin="round" d="M8.25 4.5l7.5 7.5-7.5 7.5" />
|
|
256
|
+
</svg>
|
|
257
|
+
</button>
|
|
258
|
+
</Stack>
|
|
259
|
+
</div>
|
|
260
|
+
<div className="grid grid-cols-7 p-3 gap-2 mt-3">
|
|
261
|
+
{days.map((v, i) => (
|
|
262
|
+
<div key={i} className="text-center w-12">
|
|
263
|
+
{v}
|
|
264
|
+
</div>
|
|
265
|
+
))}
|
|
266
|
+
</div>
|
|
267
|
+
|
|
268
|
+
<div className="grid grid-cols-7 p-3 gap-2">
|
|
269
|
+
{currCalendar.map((v, i) =>
|
|
270
|
+
v ? (
|
|
271
|
+
<button
|
|
272
|
+
type="button"
|
|
273
|
+
key={i}
|
|
274
|
+
className={`rounded-lg border flex w-12 justify-center p-2 hover:bg-blue-600 hover:text-white ${
|
|
275
|
+
dateFns.isSameDay(new Date(currYear, currMonth, v), dateRange.startDate)
|
|
276
|
+
? // dateRange.startDate?.isSame(
|
|
277
|
+
// moment({ day: v, month: currMonth, year: currYear }),
|
|
278
|
+
// "day"
|
|
279
|
+
// )
|
|
280
|
+
"bg-blue-600 text-white"
|
|
281
|
+
: ""
|
|
282
|
+
} ${
|
|
283
|
+
dateFns.isSameDay(new Date(currYear, currMonth, v), new Date())
|
|
284
|
+
? // moment({ day: v, month: currMonth, year: currYear }).isSame(
|
|
285
|
+
// moment(),
|
|
286
|
+
// "day"
|
|
287
|
+
// )
|
|
288
|
+
"ring-blue-400 ring-2"
|
|
289
|
+
: ""
|
|
290
|
+
} ${
|
|
291
|
+
dateFns.isSameDay(new Date(currYear, currMonth, v), dateRange.endDate)
|
|
292
|
+
? // dateRange.endDate?.isSame(
|
|
293
|
+
// moment({ day: v, month: currMonth, year: currYear }),
|
|
294
|
+
// "day"
|
|
295
|
+
// )
|
|
296
|
+
"bg-blue-600 text-white"
|
|
297
|
+
: ""
|
|
298
|
+
} ${
|
|
299
|
+
isBetween(new Date(currYear, currMonth, v), dateRange.startDate, dateRange.endDate, "[]")
|
|
300
|
+
? // moment({
|
|
301
|
+
// day: v,
|
|
302
|
+
// month: currMonth,
|
|
303
|
+
// year: currYear,
|
|
304
|
+
// }).isBetween(
|
|
305
|
+
// dateRange.startDate,
|
|
306
|
+
// dateRange.endDate,
|
|
307
|
+
// "day",
|
|
308
|
+
// "()"
|
|
309
|
+
// )
|
|
310
|
+
"bg-blue-200"
|
|
311
|
+
: ""
|
|
312
|
+
}`}
|
|
313
|
+
onClick={() => {
|
|
314
|
+
handleUpdateDateRangeOnLeftCalendar(v);
|
|
315
|
+
}}
|
|
316
|
+
>
|
|
317
|
+
{v}
|
|
318
|
+
</button>
|
|
319
|
+
) : (
|
|
320
|
+
<span key={i}></span>
|
|
321
|
+
)
|
|
322
|
+
)}
|
|
323
|
+
</div>
|
|
324
|
+
</div>
|
|
325
|
+
<div className="drop-shadow-sm shadow-sm min-w-[10rem] p-3 rounded-lg border flex flex-col">
|
|
326
|
+
<div className="flex justify-between items-center">
|
|
327
|
+
<h3 className="text-lg">
|
|
328
|
+
{dateFns.format(dateFns.add(new Date(currYear, currMonth), { months: 1 }), "MMMM")}{" "}
|
|
329
|
+
{
|
|
330
|
+
dateFns.add(new Date(currYear, currMonth), { months: 1 }).getFullYear()
|
|
331
|
+
// moment({ month: currMonth }).add(1, "month").year()
|
|
332
|
+
}
|
|
333
|
+
</h3>
|
|
334
|
+
<div className="flex gap-x-2 items-center">
|
|
335
|
+
<button
|
|
336
|
+
type="button"
|
|
337
|
+
className="p-2 rounded-lg hover:bg-gray-300 border drop-shadow-sm"
|
|
338
|
+
onClick={() => {
|
|
339
|
+
const d = dateFns.sub(new Date(currYear, currMonth), {
|
|
340
|
+
months: 1
|
|
341
|
+
});
|
|
342
|
+
// moment({ month: currMonth, year: currYear }).subtract(
|
|
343
|
+
// 1,
|
|
344
|
+
// "month"
|
|
345
|
+
// )
|
|
346
|
+
setCurrMonth(d.getMonth());
|
|
347
|
+
setCurrYear(d.getFullYear());
|
|
348
|
+
}}
|
|
349
|
+
>
|
|
350
|
+
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" strokeWidth={1.5} stroke="currentColor" className="w-4 h-4">
|
|
351
|
+
<path strokeLinecap="round" strokeLinejoin="round" d="M15.75 19.5L8.25 12l7.5-7.5" />
|
|
352
|
+
</svg>
|
|
353
|
+
</button>
|
|
354
|
+
<button
|
|
355
|
+
type="button"
|
|
356
|
+
className="p-2 rounded-lg hover:bg-gray-300 border drop-shadow-sm"
|
|
357
|
+
onClick={() => {
|
|
358
|
+
const d = dateFns.add(new Date(currYear, currMonth), {
|
|
359
|
+
months: 1
|
|
360
|
+
});
|
|
361
|
+
// moment({ month: currMonth }).add(1, "month")
|
|
362
|
+
setCurrMonth(d.getMonth());
|
|
363
|
+
setCurrYear(d.getFullYear());
|
|
364
|
+
}}
|
|
365
|
+
>
|
|
366
|
+
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" strokeWidth={1.5} stroke="currentColor" className="w-4 h-4">
|
|
367
|
+
<path strokeLinecap="round" strokeLinejoin="round" d="M8.25 4.5l7.5 7.5-7.5 7.5" />
|
|
368
|
+
</svg>
|
|
369
|
+
</button>
|
|
370
|
+
</div>
|
|
371
|
+
</div>
|
|
372
|
+
<div className="grid grid-cols-7 p-3 gap-2 mt-3">
|
|
373
|
+
{days.map((v, i) => (
|
|
374
|
+
<div key={i} className="text-center w-12">
|
|
375
|
+
{v}
|
|
376
|
+
</div>
|
|
377
|
+
))}
|
|
378
|
+
</div>
|
|
379
|
+
|
|
380
|
+
<div className="grid grid-cols-7 p-3 gap-2">
|
|
381
|
+
{nextCalendar.map((day, i) =>
|
|
382
|
+
day ? (
|
|
383
|
+
<button
|
|
384
|
+
type="button"
|
|
385
|
+
key={i}
|
|
386
|
+
className={`rounded-lg border flex w-12 justify-center p-2 hover:bg-blue-600 hover:text-white ${
|
|
387
|
+
dateFns.isSameDay(
|
|
388
|
+
dateFns.add(new Date(currYear, currMonth, day), {
|
|
389
|
+
months: 1
|
|
390
|
+
}),
|
|
391
|
+
dateRange.startDate
|
|
392
|
+
)
|
|
393
|
+
? // dateRange.startDate?.isSame(
|
|
394
|
+
// moment({
|
|
395
|
+
// day: v,
|
|
396
|
+
// month: moment({
|
|
397
|
+
// day: v,
|
|
398
|
+
// month: currMonth,
|
|
399
|
+
// year: currYear,
|
|
400
|
+
// })
|
|
401
|
+
// .add(1, "month")
|
|
402
|
+
// .month(),
|
|
403
|
+
// year: moment({ day: v, month: currMonth, year: currYear })
|
|
404
|
+
// .add(1, "month")
|
|
405
|
+
// .year(),
|
|
406
|
+
// }),
|
|
407
|
+
// "day"
|
|
408
|
+
// )
|
|
409
|
+
"bg-blue-600 text-white"
|
|
410
|
+
: ""
|
|
411
|
+
} ${
|
|
412
|
+
dateFns.isSameDay(
|
|
413
|
+
dateFns.add(new Date(currYear, currMonth, day), {
|
|
414
|
+
months: 1
|
|
415
|
+
}),
|
|
416
|
+
new Date()
|
|
417
|
+
)
|
|
418
|
+
? // moment({
|
|
419
|
+
// day: v,
|
|
420
|
+
// month: moment({ day: v, month: currMonth, year: currYear })
|
|
421
|
+
// .add(1, "month")
|
|
422
|
+
// .month(),
|
|
423
|
+
// year: moment({ day: v, month: currMonth, year: currYear })
|
|
424
|
+
// .add(1, "month")
|
|
425
|
+
// .year(),
|
|
426
|
+
// }).isSame(moment(), "day")
|
|
427
|
+
"ring-blue-400 ring-2"
|
|
428
|
+
: ""
|
|
429
|
+
} ${
|
|
430
|
+
dateFns.isSameDay(
|
|
431
|
+
dateFns.add(new Date(currYear, currMonth, day), {
|
|
432
|
+
months: 1
|
|
433
|
+
}),
|
|
434
|
+
dateRange.endDate
|
|
435
|
+
)
|
|
436
|
+
? // dateRange.endDate?.isSame(
|
|
437
|
+
// moment({
|
|
438
|
+
// day: v,
|
|
439
|
+
// month: moment({
|
|
440
|
+
// day: v,
|
|
441
|
+
// month: currMonth,
|
|
442
|
+
// year: currYear,
|
|
443
|
+
// })
|
|
444
|
+
// .add(1, "month")
|
|
445
|
+
// .month(),
|
|
446
|
+
// year: moment({ day: v, month: currMonth, year: currYear })
|
|
447
|
+
// .add(1, "month")
|
|
448
|
+
// .year(),
|
|
449
|
+
// }),
|
|
450
|
+
// "day"
|
|
451
|
+
// )
|
|
452
|
+
"bg-blue-600 text-white"
|
|
453
|
+
: ""
|
|
454
|
+
} ${
|
|
455
|
+
// isBetween(new Date(currYear, currMonth, v), {}))
|
|
456
|
+
isBetween(
|
|
457
|
+
dateFns.add(new Date(currYear, currMonth, day), {
|
|
458
|
+
months: 1
|
|
459
|
+
}),
|
|
460
|
+
dateRange.startDate,
|
|
461
|
+
dateRange.endDate,
|
|
462
|
+
"[]"
|
|
463
|
+
)
|
|
464
|
+
? // moment({
|
|
465
|
+
// day: v,
|
|
466
|
+
// month: moment({ day: v, month: currMonth, year: currYear })
|
|
467
|
+
// .add(1, "month")
|
|
468
|
+
// .month(),
|
|
469
|
+
// year: moment({ day: v, month: currMonth, year: currYear })
|
|
470
|
+
// .add(1, "month")
|
|
471
|
+
// .year(),
|
|
472
|
+
// }).isBetween(
|
|
473
|
+
// dateRange.startDate,
|
|
474
|
+
// dateRange.endDate,
|
|
475
|
+
// "day",
|
|
476
|
+
// "()"
|
|
477
|
+
// )
|
|
478
|
+
"bg-blue-200"
|
|
479
|
+
: ""
|
|
480
|
+
}`}
|
|
481
|
+
onClick={() => {
|
|
482
|
+
handleUpdateDateRangeOnRightCalendar(day);
|
|
483
|
+
}}
|
|
484
|
+
>
|
|
485
|
+
{day}
|
|
486
|
+
</button>
|
|
487
|
+
) : (
|
|
488
|
+
<span key={i}></span>
|
|
489
|
+
)
|
|
490
|
+
)}
|
|
491
|
+
</div>
|
|
492
|
+
</div>
|
|
493
|
+
</Box>
|
|
494
|
+
</Paper>
|
|
495
|
+
);
|
|
496
|
+
};
|
|
497
|
+
|
|
498
|
+
export default StaticDateRangePicker;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default as DateRangePicker } from "./DateRangePicker";
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { TablePagination, useMediaQuery, useTheme } from "@mui/material";
|
|
2
|
+
import PropTypes from "prop-types";
|
|
3
|
+
|
|
4
|
+
TablePaginationCustom.propsType = {
|
|
5
|
+
count: PropTypes.number,
|
|
6
|
+
rowsPerPage: PropTypes.number,
|
|
7
|
+
page: PropTypes.number,
|
|
8
|
+
onPageChange: PropTypes.func,
|
|
9
|
+
onRowsPerPageChange: PropTypes.func
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
function TablePaginationCustom({ count, rowsPerPage, page, onPageChange, onRowsPerPageChange, ...rest }) {
|
|
13
|
+
const theme = useTheme();
|
|
14
|
+
const matchsDownMD = useMediaQuery(theme.breakpoints.down("md"));
|
|
15
|
+
return (
|
|
16
|
+
<TablePagination
|
|
17
|
+
{...rest}
|
|
18
|
+
rowsPerPageOptions={[5, 10, 25, 100]}
|
|
19
|
+
component="div"
|
|
20
|
+
count={count}
|
|
21
|
+
rowsPerPage={rowsPerPage}
|
|
22
|
+
page={page}
|
|
23
|
+
onPageChange={onPageChange}
|
|
24
|
+
onRowsPerPageChange={onRowsPerPageChange}
|
|
25
|
+
showFirstButton={true}
|
|
26
|
+
showLastButton={true}
|
|
27
|
+
labelRowsPerPage={matchsDownMD ? "Số hàng" : "Số bản ghi trên trang:"}
|
|
28
|
+
labelDisplayedRows={function defaultLabelDisplayedRows({ from, to, count }) {
|
|
29
|
+
return `${from}–${to} của ${count !== -1 ? count : `more than ${to}`}`;
|
|
30
|
+
}}
|
|
31
|
+
/>
|
|
32
|
+
);
|
|
33
|
+
}
|
|
34
|
+
export default TablePaginationCustom;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { Skeleton, TableCell, TableRow } from "@mui/material";
|
|
2
|
+
|
|
3
|
+
const TableRowsLoader = ({ rowsNum, colsNum }) => {
|
|
4
|
+
return [...Array(rowsNum)].map((row, x) => (
|
|
5
|
+
<TableRow key={x}>
|
|
6
|
+
{[...Array(colsNum)].map((col, y) => (
|
|
7
|
+
<TableCell key={y} component="th" scope="row">
|
|
8
|
+
<Skeleton animation="wave" variant="text" />
|
|
9
|
+
</TableCell>
|
|
10
|
+
))}
|
|
11
|
+
</TableRow>
|
|
12
|
+
));
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
export default TableRowsLoader;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export const DEFAULT_DATE_FORMAT = "DD/MM/YYYY";
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import moment from "moment";
|
|
2
|
+
import { DEFAULT_DATE_FORMAT } from "../constants";
|
|
3
|
+
|
|
4
|
+
export const currencyFormatter = new Intl.NumberFormat('vi-VN', {
|
|
5
|
+
style: 'currency',
|
|
6
|
+
currency: 'VND',
|
|
7
|
+
});
|
|
8
|
+
export const numberFormatter = new Intl.NumberFormat('vi-VN');
|
|
9
|
+
|
|
10
|
+
export const vndFormat = {
|
|
11
|
+
type: 'number',
|
|
12
|
+
valueFormat: (value) => currencyFormatter.format(value),
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
export const numberFormat = {
|
|
16
|
+
type: 'number',
|
|
17
|
+
valueFormat: (value) => numberFormatter.format(value),
|
|
18
|
+
}
|
|
19
|
+
export const dateFormat = {
|
|
20
|
+
valueFormat: (value) => {
|
|
21
|
+
return value && moment(value).format(DEFAULT_DATE_FORMAT);
|
|
22
|
+
}
|
|
23
|
+
}
|
package/helpers/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './data-table'
|
package/index.js
ADDED
package/package.json
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "trithuc-mvc-react",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"main": "index.js",
|
|
5
|
+
"scripts": {
|
|
6
|
+
"test": "echo \"Error: no test specified\" && exit 1"
|
|
7
|
+
},
|
|
8
|
+
"author": "",
|
|
9
|
+
"license": "ISC",
|
|
10
|
+
"repository": {
|
|
11
|
+
"type": "git",
|
|
12
|
+
"url": "git://git-remote-url"
|
|
13
|
+
},
|
|
14
|
+
"description": ""
|
|
15
|
+
}
|