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.
 
 

183 line
5.1 KiB

  1. "use client";
  2. import { HolidaysList } from "@/app/api/holidays";
  3. import React, { useCallback, useMemo, useState } from "react";
  4. import { Button, Stack } from "@mui/material/";
  5. import { useTranslation } from "react-i18next";
  6. import FullCalendar from "@fullcalendar/react";
  7. import dayGridPlugin from "@fullcalendar/daygrid"; // a plugin!
  8. import interactionPlugin from "@fullcalendar/interaction"; // needed for dayClick
  9. import listPlugin from "@fullcalendar/list";
  10. import CompanyHolidayDialog from "./CompanyHolidayDialog";
  11. import {
  12. FormProvider,
  13. SubmitErrorHandler,
  14. SubmitHandler,
  15. useForm,
  16. useFormContext,
  17. } from "react-hook-form";
  18. import {
  19. deleteCompanyHoliday,
  20. saveCompanyHoliday,
  21. } from "@/app/api/holidays/actions";
  22. import { useRouter } from "next/navigation";
  23. import { deleteDialog, submitDialog } from "../Swal/CustomAlerts";
  24. import { getPublicHolidaysForNYears } from "@/app/utils/holidayUtils";
  25. import { MAINTAIN_HOLIDAY } from "@/middleware";
  26. interface Props {
  27. holidays: HolidaysList[];
  28. abilities: String[];
  29. }
  30. const CompanyHoliday: React.FC<Props> = ({ holidays, abilities }) => {
  31. const { t } = useTranslation("holidays");
  32. const router = useRouter();
  33. const formValues = useFormContext();
  34. const [serverError, setServerError] = useState("");
  35. const maintainHoliday = abilities.includes(MAINTAIN_HOLIDAY)
  36. const companyHolidays = useMemo(
  37. () => [...getPublicHolidaysForNYears(2), ...holidays],
  38. [holidays],
  39. );
  40. const [dateContent, setDateContent] = useState<{ date: string }>({
  41. date: "",
  42. });
  43. const [open, setOpen] = useState(false);
  44. const [isEdit, setIsEdit] = useState(false);
  45. const [editable, setEditable] = useState(true);
  46. const handleClose = () => {
  47. setOpen(false);
  48. setEditable(true);
  49. setIsEdit(false);
  50. formProps.setValue("name", "");
  51. formProps.setValue("id", null);
  52. };
  53. const handleDateClick = (event: any) => {
  54. // console.log(event.dateStr)
  55. setDateContent({ date: event.dateStr });
  56. setOpen(true);
  57. };
  58. const handleEventClick = (event: any) => {
  59. // event.event.id: if id !== "", holiday is created by company
  60. console.log(event.event.id);
  61. if (event.event.id === null || event.event.id === "") {
  62. setEditable(false);
  63. }
  64. formProps.setValue("name", event.event.title);
  65. formProps.setValue("id", event.event.id);
  66. setDateContent({ date: event.event.startStr });
  67. setOpen(true);
  68. setIsEdit(true);
  69. };
  70. const onSubmit = useCallback<SubmitHandler<any>>(
  71. async (data) => {
  72. try {
  73. // console.log(data);
  74. setServerError("");
  75. submitDialog(async () => {
  76. await saveCompanyHoliday(data);
  77. window.location.reload();
  78. setOpen(false);
  79. setIsEdit(false);
  80. }, t);
  81. } catch (e) {
  82. console.log(e);
  83. setServerError(t("An error has occurred. Please try again later."));
  84. }
  85. },
  86. [t, router],
  87. );
  88. const handleDelete = async (event: any) => {
  89. try {
  90. setServerError("");
  91. deleteDialog(async () => {
  92. await deleteCompanyHoliday(parseInt(formProps.getValues("id")));
  93. window.location.reload();
  94. setOpen(false);
  95. setIsEdit(false);
  96. }, t);
  97. } catch (e) {
  98. console.log(e);
  99. setServerError(t("An error has occurred. Please try again later."));
  100. }
  101. };
  102. const onSubmitError = useCallback<SubmitErrorHandler<any>>((errors) => {
  103. console.log(errors);
  104. }, []);
  105. const formProps = useForm<any>({
  106. defaultValues: {
  107. id: null,
  108. name: "",
  109. },
  110. });
  111. return (
  112. <>
  113. <FormProvider {...formProps}>
  114. <FullCalendar
  115. plugins={[dayGridPlugin, interactionPlugin, listPlugin]}
  116. initialView="dayGridMonth"
  117. events={companyHolidays}
  118. eventColor="#ff0000"
  119. dateClick={handleDateClick}
  120. eventClick={handleEventClick}
  121. headerToolbar={{
  122. start: "today prev next",
  123. center: "title",
  124. end: "dayGridMonth listMonth",
  125. }}
  126. buttonText={{
  127. month: t("Calender View"),
  128. list: t("List View"),
  129. today: t("Today"),
  130. }}
  131. />
  132. <CompanyHolidayDialog
  133. open={maintainHoliday && open}
  134. onClose={handleClose}
  135. title={
  136. !editable
  137. ? "Bank Holiday"
  138. : isEdit
  139. ? "Edit Holiday"
  140. : "Create Holiday"
  141. }
  142. content={dateContent}
  143. actions={
  144. <Stack
  145. direction="row"
  146. justifyContent="flex-end"
  147. gap={1}
  148. component="form"
  149. onSubmit={formProps.handleSubmit(onSubmit, onSubmitError)}
  150. >
  151. <Button onClick={handleClose}>Close</Button>
  152. {isEdit && (
  153. <Button disabled={!editable} onClick={handleDelete}>
  154. Delete
  155. </Button>
  156. )}
  157. <Button disabled={!editable} type="submit">
  158. Submit
  159. </Button>
  160. </Stack>
  161. }
  162. editable={editable}
  163. />
  164. </FormProvider>
  165. </>
  166. );
  167. };
  168. export default CompanyHoliday;