您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符
 
 

234 行
6.8 KiB

  1. "use client";
  2. import React, { useCallback, useState } from "react";
  3. import { useTranslation } from "react-i18next";
  4. import Button from "@mui/material/Button";
  5. import Stack from "@mui/material/Stack";
  6. import {
  7. CalendarMonth,
  8. EditCalendar,
  9. Luggage,
  10. MoreTime,
  11. } from "@mui/icons-material";
  12. import { Menu, MenuItem, SxProps, Typography } from "@mui/material";
  13. import AssignedProjects from "./AssignedProjects";
  14. import { AssignedProject, ProjectWithTasks } from "@/app/api/projects";
  15. import {
  16. RecordLeaveInput,
  17. RecordTimesheetInput,
  18. revalidateCacheAfterAmendment,
  19. } from "@/app/api/timesheets/actions";
  20. import { LeaveType, TeamLeaves, TeamTimeSheets } from "@/app/api/timesheets";
  21. import { CalendarIcon } from "@mui/x-date-pickers";
  22. import PastEntryCalendarModal from "../PastEntryCalendar/PastEntryCalendarModal";
  23. import { HolidaysResult } from "@/app/api/holidays";
  24. import { TimesheetAmendmentModal } from "../TimesheetAmendment/TimesheetAmendmentModal";
  25. import TimeLeaveModal from "../TimeLeaveModal/TimeLeaveModal";
  26. import LeaveModal from "../LeaveModal";
  27. export interface Props {
  28. leaveTypes: LeaveType[];
  29. allProjects: ProjectWithTasks[];
  30. assignedProjects: AssignedProject[];
  31. defaultLeaveRecords: RecordLeaveInput;
  32. defaultTimesheets: RecordTimesheetInput;
  33. holidays: HolidaysResult[];
  34. teamTimesheets: TeamTimeSheets;
  35. teamLeaves: TeamLeaves;
  36. fastEntryEnabled: boolean;
  37. maintainNormalStaffWorkspaceAbility: boolean;
  38. maintainManagementStaffWorkspaceAbility: boolean;
  39. isFullTime: boolean;
  40. }
  41. const menuItemSx: SxProps = {
  42. gap: 1,
  43. color: "neutral.700",
  44. };
  45. const UserWorkspacePage: React.FC<Props> = ({
  46. leaveTypes,
  47. allProjects,
  48. assignedProjects,
  49. defaultLeaveRecords,
  50. defaultTimesheets,
  51. holidays,
  52. teamTimesheets,
  53. teamLeaves,
  54. fastEntryEnabled,
  55. maintainNormalStaffWorkspaceAbility,
  56. maintainManagementStaffWorkspaceAbility,
  57. isFullTime,
  58. }) => {
  59. const [anchorEl, setAnchorEl] = useState<null | HTMLElement>(null);
  60. const [isTimeLeaveModalVisible, setTimeLeaveModalVisible] = useState(false);
  61. const [isLeaveCalendarVisible, setLeaveCalendarVisible] = useState(false);
  62. const [isPastEventModalVisible, setPastEventModalVisible] = useState(false);
  63. const [isTimesheetAmendmentVisible, setisTimesheetAmendmentVisible] =
  64. useState(false);
  65. const { t } = useTranslation("home");
  66. const showTimesheetAmendment = Object.keys(teamTimesheets).length > 0;
  67. const handleOpenActionMenu = useCallback<
  68. React.MouseEventHandler<HTMLButtonElement>
  69. >((event) => {
  70. setAnchorEl(event.currentTarget);
  71. }, []);
  72. const handleCloseActionMenu = useCallback(() => {
  73. setAnchorEl(null);
  74. }, []);
  75. const handleAddTimeLeaveButton = useCallback(() => {
  76. setAnchorEl(null);
  77. setTimeLeaveModalVisible(true);
  78. }, []);
  79. const handleCloseTimeLeaveModal = useCallback(() => {
  80. setTimeLeaveModalVisible(false);
  81. }, []);
  82. const handleOpenLeaveCalendarButton = useCallback(() => {
  83. setAnchorEl(null);
  84. setLeaveCalendarVisible(true);
  85. }, []);
  86. const handleCloseLeaveCalendarButton = useCallback(() => {
  87. setLeaveCalendarVisible(false);
  88. }, []);
  89. const handlePastEventClick = useCallback(() => {
  90. setAnchorEl(null);
  91. setPastEventModalVisible(true);
  92. }, []);
  93. const handlePastEventClose = useCallback(() => {
  94. setPastEventModalVisible(false);
  95. }, []);
  96. const handleAmendmentClick = useCallback(() => {
  97. setAnchorEl(null);
  98. setisTimesheetAmendmentVisible(true);
  99. }, []);
  100. const handleAmendmentClose = useCallback(() => {
  101. setisTimesheetAmendmentVisible(false);
  102. revalidateCacheAfterAmendment();
  103. }, []);
  104. return (
  105. <>
  106. <Stack
  107. direction="row"
  108. justifyContent="space-between"
  109. flexWrap="wrap"
  110. rowGap={2}
  111. >
  112. <Typography variant="h4" marginInlineEnd={2}>
  113. {t("User Workspace")}
  114. </Typography>
  115. <Button
  116. startIcon={<CalendarIcon />}
  117. variant="contained"
  118. onClick={handleOpenActionMenu}
  119. >
  120. {t("Timesheet Actions")}
  121. </Button>
  122. </Stack>
  123. <Menu
  124. anchorEl={anchorEl}
  125. open={Boolean(anchorEl)}
  126. onClose={handleCloseActionMenu}
  127. anchorOrigin={{
  128. vertical: "bottom",
  129. horizontal: "right",
  130. }}
  131. transformOrigin={{
  132. vertical: "top",
  133. horizontal: "right",
  134. }}
  135. >
  136. <MenuItem onClick={handleAddTimeLeaveButton} sx={menuItemSx}>
  137. <MoreTime />
  138. {t("Enter Timesheet")}
  139. </MenuItem>
  140. <MenuItem onClick={handleOpenLeaveCalendarButton} sx={menuItemSx}>
  141. <Luggage />
  142. {t("Record Leave")}
  143. </MenuItem>
  144. <MenuItem onClick={handlePastEventClick} sx={menuItemSx}>
  145. <CalendarMonth />
  146. {t("View Past Entries")}
  147. </MenuItem>
  148. {showTimesheetAmendment && (
  149. <MenuItem onClick={handleAmendmentClick} sx={menuItemSx}>
  150. <EditCalendar />
  151. {t("Timesheet Amendment")}
  152. </MenuItem>
  153. )}
  154. </Menu>
  155. <PastEntryCalendarModal
  156. open={isPastEventModalVisible}
  157. handleClose={handlePastEventClose}
  158. timesheet={defaultTimesheets}
  159. leaves={defaultLeaveRecords}
  160. allProjects={allProjects}
  161. leaveTypes={leaveTypes}
  162. companyHolidays={holidays}
  163. />
  164. <TimeLeaveModal
  165. fastEntryEnabled={fastEntryEnabled}
  166. companyHolidays={holidays}
  167. isOpen={isTimeLeaveModalVisible}
  168. onClose={handleCloseTimeLeaveModal}
  169. leaveTypes={leaveTypes}
  170. allProjects={allProjects}
  171. assignedProjects={assignedProjects}
  172. timesheetRecords={defaultTimesheets}
  173. leaveRecords={defaultLeaveRecords}
  174. isFullTime={isFullTime}
  175. />
  176. <LeaveModal
  177. open={isLeaveCalendarVisible}
  178. onClose={handleCloseLeaveCalendarButton}
  179. leaveTypes={leaveTypes}
  180. companyHolidays={holidays}
  181. allProjects={allProjects}
  182. leaveRecords={defaultLeaveRecords}
  183. timesheetRecords={defaultTimesheets}
  184. isFullTime={isFullTime}
  185. />
  186. {assignedProjects.length > 0 ? (
  187. <AssignedProjects
  188. assignedProjects={assignedProjects}
  189. maintainNormalStaffWorkspaceAbility={
  190. maintainNormalStaffWorkspaceAbility
  191. }
  192. maintainManagementStaffWorkspaceAbility={
  193. maintainManagementStaffWorkspaceAbility
  194. }
  195. />
  196. ) : (
  197. <Typography variant="subtitle1">
  198. {t("You have no assigned projects!")}
  199. </Typography>
  200. )}
  201. {showTimesheetAmendment && (
  202. <TimesheetAmendmentModal
  203. allProjects={allProjects}
  204. leaveTypes={leaveTypes}
  205. companyHolidays={holidays}
  206. teamLeaves={teamLeaves}
  207. teamTimesheets={teamTimesheets}
  208. open={isTimesheetAmendmentVisible}
  209. onClose={handleAmendmentClose}
  210. />
  211. )}
  212. </>
  213. );
  214. };
  215. export default UserWorkspacePage;