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

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