From a366711d129c17f7aae0918939f7b733410e7f54 Mon Sep 17 00:00:00 2001 From: bokhonglo Date: Thu, 16 Apr 2026 12:01:25 +0700 Subject: [PATCH] update limit page --- .../(tables)/user-table/page.tsx | 175 ++++++++++++++++-- 1 file changed, 158 insertions(+), 17 deletions(-) diff --git a/src/app/(admin)/(others-pages)/(tables)/user-table/page.tsx b/src/app/(admin)/(others-pages)/(tables)/user-table/page.tsx index 04a0355..1b198d7 100644 --- a/src/app/(admin)/(others-pages)/(tables)/user-table/page.tsx +++ b/src/app/(admin)/(others-pages)/(tables)/user-table/page.tsx @@ -14,13 +14,26 @@ import { } from "@/service/adminService"; import { useEffect, useState, useCallback } from "react"; import Pagination from "@/components/tables/Pagination"; +import { LIMIT_ITEM_TABLE } from "../../../../../../constant"; export type SortColumn = "created_at" | "updated_at" | "display_name" | "email"; -export default function UserTable() { // UserTable +// Hàm helper format ngày giờ giống với Historian +const formatDateTimeToISO = ( + dateStr: string, + timeStr: string, + isEndOfDay: boolean = false, +): string | undefined => { + if (!dateStr) return undefined; + const time = timeStr || (isEndOfDay ? "23:59" : "00:00"); + + return `${dateStr}T${time}:00.000000+07:00`; +}; + +export default function UserTable() { const [page, setPage] = useState(1); - const [limitInput, setLimitInput] = useState("5"); + const [limitInput, setLimitInput] = useState(LIMIT_ITEM_TABLE.toString()); const [selectedRole, setSelectedRole] = useState(""); const [roles, setRoles] = useState<{ id: string; name: string }[]>([]); @@ -29,15 +42,26 @@ export default function UserTable() { // UserTable const [authProvider, setAuthProvider] = useState(""); const [isDeleted, setIsDeleted] = useState(undefined); + // --- THÊM STATE CHO NGÀY GIỜ --- + const [fromDate, setFromDate] = useState(""); + const [fromTime, setFromTime] = useState(""); + const [toDate, setToDate] = useState(""); + const [toTime, setToTime] = useState(""); + const [selectedUser, setSelectedUser] = useState(null); const [isModalOpen, setIsModalOpen] = useState(false); const [roleUser, setRoleUser] = useState(null); const [isRoleModalOpen, setIsRoleModalOpen] = useState(false); + // Cập nhật params để chứa thêm ngày giờ const [debouncedParams, setDebouncedParams] = useState({ search: "", limit: 5, authProvider: "", + fromDate: "", + fromTime: "", + toDate: "", + toTime: "", }); const [tableData, setTableData] = useState(null); @@ -45,6 +69,32 @@ export default function UserTable() { // UserTable const [sortBy, setSortBy] = useState(undefined); const [sortOrder, setSortOrder] = useState<"asc" | "desc">("asc"); + // Hàm Reset bộ lọc + const handleReset = () => { + setSearchTerm(""); + setAuthProvider(""); + setIsDeleted(undefined); + setSelectedRole(""); + setLimitInput(LIMIT_ITEM_TABLE.toString()); + + setFromDate(""); + setFromTime(""); + setToDate(""); + setToTime(""); + + setPage(1); + + setDebouncedParams({ + search: "", + limit: LIMIT_ITEM_TABLE, + authProvider: "", + fromDate: "", + fromTime: "", + toDate: "", + toTime: "", + }); + }; + useEffect(() => { const fetchRoles = async () => { try { @@ -63,18 +113,31 @@ export default function UserTable() { // UserTable const handler = setTimeout(() => { setDebouncedParams({ search: searchTerm, - limit: parseInt(limitInput) || 5, + limit: parseInt(limitInput) || LIMIT_ITEM_TABLE, authProvider: authProvider, + fromDate, + fromTime, + toDate, + toTime, }); setPage(1); }, 600); return () => clearTimeout(handler); - }, [searchTerm, limitInput, authProvider]); + }, [ + searchTerm, + limitInput, + authProvider, + fromDate, + fromTime, + toDate, + toTime, + ]); const fetchUsers = useCallback(async () => { setLoading(true); try { - const payload: getUserDto = { + // Dùng any để tránh lỗi TS nếu interface getUserDto chưa update + const payload: any = { page: page, limit: debouncedParams.limit, search: debouncedParams.search || undefined, @@ -85,7 +148,22 @@ export default function UserTable() { // UserTable role_ids: selectedRole ? [selectedRole] : undefined, }; - const response = await apiGetListUser(payload); + // Thêm format ngày giờ vào payload + const createdFrom = formatDateTimeToISO( + debouncedParams.fromDate, + debouncedParams.fromTime, + false, + ); + if (createdFrom) payload.created_from = createdFrom; + + const createdTo = formatDateTimeToISO( + debouncedParams.toDate, + debouncedParams.toTime, + true, + ); + if (createdTo) payload.created_to = createdTo; + + const response = await apiGetListUser(payload as getUserDto); if (response?.status) { setTableData(response); } @@ -129,12 +207,12 @@ export default function UserTable() { // UserTable text: `Bạn có chắc muốn khóa người dùng ${user.profile?.display_name || user.email}?`, icon: "warning", showCancelButton: true, - showCloseButton: true, + showCloseButton: true, confirmButtonColor: "#d33", cancelButtonColor: "#3085d6", confirmButtonText: "Đồng ý, khóa!", cancelButtonText: "Hủy", - reverseButtons: true, + reverseButtons: true, }); if (result.isConfirmed) { @@ -179,8 +257,31 @@ export default function UserTable() { // UserTable
- -
+ + + + + + } + > +
setSearchTerm(e.target.value)} - className="w-full px-3 py-2 border rounded-lg dark:bg-gray-800 dark:border-gray-700" + className="w-full px-3 py-2 border rounded-lg dark:bg-gray-800 dark:border-gray-700 outline-none focus:border-brand-500" />
@@ -199,7 +300,7 @@ export default function UserTable() { // UserTable
+ {/* Từ ngày */} +
+ +
+ setFromDate(e.target.value)} + className="w-full px-3 py-2 border rounded-lg dark:bg-gray-800 dark:border-gray-700 outline-none focus:border-brand-500" + /> + setFromTime(e.target.value)} + className="w-full px-3 py-2 border rounded-lg dark:bg-gray-800 dark:border-gray-700 outline-none focus:border-brand-500" + /> +
+
+ + {/* Đến ngày */} +
+ +
+ setToDate(e.target.value)} + className="w-full px-3 py-2 border rounded-lg dark:bg-gray-800 dark:border-gray-700 outline-none focus:border-brand-500" + /> + setToTime(e.target.value)} + className="w-full px-3 py-2 border rounded-lg dark:bg-gray-800 dark:border-gray-700 outline-none focus:border-brand-500" + /> +
+
+ {/* Limit */}
@@ -244,7 +384,7 @@ export default function UserTable() { // UserTable
{loading && ( -
+
)} @@ -264,9 +404,10 @@ export default function UserTable() { // UserTable

Hiển thị trang {pagination?.current_page || 1} /{" "} - {pagination?.total_pages || 1} ({pagination?.total_records || 0} kết quả) + {pagination?.total_pages || 1} ({pagination?.total_records || 0}{" "} + kết quả)

- + {pagination && pagination.total_pages > 1 && (