You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

138 line
3.7 KiB

  1. "use client";
  2. import { StaffResult } from "@/app/api/staff";
  3. import React, { useCallback, useEffect, useMemo, useState } from "react";
  4. import SearchBox, { Criterion } from "../SearchBox/index";
  5. import { useTranslation } from "react-i18next";
  6. import SearchResults, { Column } from "../SearchResults/index";
  7. import EditNote from "@mui/icons-material/EditNote";
  8. import DeleteIcon from "@mui/icons-material/Delete";
  9. import { deleteStaff } from "@/app/api/staff/actions";
  10. import { useRouter } from "next/navigation";
  11. import { deleteDialog, successDialog } from "../Swal/CustomAlerts";
  12. import Person from '@mui/icons-material/Person';
  13. interface Props {
  14. staff: StaffResult[];
  15. }
  16. type SearchQuery = Partial<Omit<StaffResult, "id">>;
  17. type SearchParamNames = keyof SearchQuery;
  18. const StaffSearch: React.FC<Props> = ({ staff }) => {
  19. const { t } = useTranslation();
  20. const [filteredStaff, setFilteredStaff] = useState(staff);
  21. const router = useRouter();
  22. const searchCriteria: Criterion<SearchParamNames>[] = useMemo(
  23. () => [
  24. {
  25. label: t("Team"),
  26. paramName: "team",
  27. type: "select",
  28. options: ["1", "2"],
  29. },
  30. {
  31. label: t("Staff Name"),
  32. paramName: "name",
  33. type: "text",
  34. },
  35. {
  36. label: t("Staff ID"),
  37. paramName: "staffId",
  38. type: "text",
  39. },
  40. {
  41. label: t("Grade"),
  42. paramName: "grade",
  43. type: "select",
  44. options: ["pos1", "CEO"],
  45. },
  46. {
  47. label: t("Current Position"),
  48. paramName: "currentPosition",
  49. type: "select",
  50. options: ["pos1", "CEO"],
  51. },
  52. ],
  53. [t]
  54. );
  55. const onStaffClick = useCallback(
  56. (staff: StaffResult) => {
  57. console.log(staff);
  58. const id = staff.id;
  59. router.push(`/settings/staff/edit?id=${id}`);
  60. },
  61. [router, t]
  62. );
  63. const onUserClick = useCallback(
  64. (staff: StaffResult) => {
  65. console.log(staff);
  66. router.push(`/settings/staff/user?id=${staff.id}`);
  67. },
  68. [router, t]
  69. );
  70. const deleteClick = useCallback((staff: StaffResult) => {
  71. deleteDialog(async () => {
  72. await deleteStaff(staff.id);
  73. successDialog(t("Delete Success"), t);
  74. setFilteredStaff((prev) => prev.filter((obj) => obj.id !== staff.id));
  75. }, t);
  76. }, []);
  77. const columns = useMemo<Column<StaffResult>[]>(
  78. () => [
  79. {
  80. name: "action",
  81. label: t("Actions"),
  82. onClick: onStaffClick,
  83. buttonIcon: <EditNote />,
  84. },
  85. {
  86. name: "id",
  87. label: t("Actions"),
  88. onClick: onUserClick,
  89. buttonIcon: <Person />,
  90. },
  91. { name: "team", label: t("Team") },
  92. { name: "name", label: t("Staff Name") },
  93. { name: "staffId", label: t("Staff ID") },
  94. { name: "grade", label: t("Grade") },
  95. { name: "currentPosition", label: t("Current Position") },
  96. {
  97. name: "action",
  98. label: t("Actions"),
  99. onClick: deleteClick,
  100. buttonIcon: <DeleteIcon />,
  101. color: "error",
  102. },
  103. ],
  104. [t, onStaffClick, deleteClick]
  105. );
  106. return (
  107. <>
  108. <SearchBox
  109. criteria={searchCriteria}
  110. onSearch={(query) => {
  111. setFilteredStaff(
  112. staff.filter(
  113. (s) =>
  114. s.staffId.toLowerCase().includes(query.staffId.toLowerCase()) &&
  115. s.name.toLowerCase().includes(query.name.toLowerCase())
  116. // (query.team === "All" || s.team === query.team) &&
  117. // (query.category === "All" || s.category === query.category) &&
  118. // (query.team === "All" || s.team === query.team),
  119. )
  120. );
  121. }}
  122. />
  123. <SearchResults<StaffResult> items={filteredStaff} columns={columns} />
  124. </>
  125. );
  126. };
  127. export default StaffSearch;