"use client"; import SearchBox, { Criterion } from "../SearchBox"; import { useCallback, useMemo, useState } from "react"; import { useTranslation } from "react-i18next"; import SearchResults, { Column } from "../SearchResults/index"; import EditNote from "@mui/icons-material/EditNote"; import DeleteIcon from "@mui/icons-material/Delete"; import { useRouter } from "next/navigation"; import { deleteDialog, successDialog } from "../Swal/CustomAlerts"; import useUploadContext from "../UploadProvider/useUploadContext"; import { downloadFile } from "@/app/utils/commonUtil"; import { UserResult } from "@/app/api/user"; import { deleteUser } from "@/app/api/user/actions"; import QrCodeIcon from "@mui/icons-material/QrCode"; import UserSearchLoading from "./UserSearchLoading"; import { searchUsersByUsernameOrName } from "@/app/api/user/client"; interface Props { users: UserResult[]; } type SearchQuery = Partial>; type SearchParamNames = keyof SearchQuery; const UserSearch: React.FC = ({ users }) => { const { t } = useTranslation("user"); const [filteredUser, setFilteredUser] = useState(users); const [pagingController, setPagingController] = useState({ pageNum: 1, pageSize: 10, }); const router = useRouter(); const { setIsUploading } = useUploadContext(); const [isSearching, setIsSearching] = useState(false); const searchCriteria: Criterion[] = useMemo( () => [ { label: "用戶/姓名", paramName: "username", type: "text", }, { label: t("staffNo"), paramName: "staffNo", type: "text", }, ], [t], ); const onUserClick = useCallback( (users: UserResult) => { console.log(users); router.push(`/settings/user/edit?id=${users.id}`); }, [router, t], ); const onDeleteClick = useCallback((users: UserResult) => { deleteDialog(async () => { await deleteUser(users.id); successDialog(t("Delete Success"), t); }, t); }, [t]); const columns = useMemo[]>( () => [ { name: "action", label: t("Edit"), onClick: onUserClick, buttonIcon: , sx: { width: "10%", minWidth: "80px" }, }, { name: "username", label: t("Username"), align: "left", headerAlign: "left", sx: { width: "22.5%", minWidth: "120px" }, }, { name: "name", label: t("name"), align: "left", headerAlign: "left", sx: { width: "22.5%", minWidth: "120px" }, }, { name: "staffNo", label: t("staffNo"), align: "left", headerAlign: "left", sx: { width: "22.5%", minWidth: "120px" }, }, { name: "action", label: t("Delete"), onClick: onDeleteClick, buttonIcon: , color: "error", sx: { width: "10%", minWidth: "80px" }, }, ], [t, onUserClick, onDeleteClick], ); return ( <> { setIsSearching(true); try { let results: UserResult[] = []; if (query.username && query.username.trim()) { results = await searchUsersByUsernameOrName(query.username); } else { results = users; } if (query.staffNo && query.staffNo.trim()) { results = results.filter((user) => user.staffNo?.toString().includes(query.staffNo?.toString() || "") ); } setFilteredUser(results); setPagingController({ pageNum: 1, pageSize: pagingController.pageSize }); } catch (error) { console.error("Error searching users:", error); setFilteredUser( users.filter((user) => { const userMatch = !query.username || user.username?.toLowerCase().includes(query.username?.toLowerCase() || "") || user.name?.toLowerCase().includes(query.username?.toLowerCase() || ""); const staffNoMatch = !query.staffNo || user.staffNo?.toString().includes(query.staffNo?.toString() || ""); return userMatch && staffNoMatch; }) ); } finally { setIsSearching(false); } }} /> items={filteredUser} columns={columns} pagingController={pagingController} setPagingController={setPagingController} /> ); }; export default UserSearch;