From 67c318e5279b867d64d4afd8b1e703f02affb803 Mon Sep 17 00:00:00 2001 From: Carina Wollendorfer <30310907+CarinaWolli@users.noreply.github.com> Date: Sun, 14 Jan 2024 08:58:10 -0500 Subject: [PATCH] fix: use DateRangePicker component in my-account/out-of-office (#13207) --- .../DateRangePicker/DateSelect.css | 110 ----------- .../out-of-office/DateRangePicker/index.tsx | 47 ----- .../my-account/out-of-office/index.tsx | 173 ++++++++++-------- apps/web/public/static/locales/en/common.json | 1 + .../loggedInViewer/outOfOffice.handler.ts | 11 +- .../loggedInViewer/outOfOffice.schema.ts | 6 +- 6 files changed, 106 insertions(+), 242 deletions(-) delete mode 100644 apps/web/components/out-of-office/DateRangePicker/DateSelect.css delete mode 100644 apps/web/components/out-of-office/DateRangePicker/index.tsx diff --git a/apps/web/components/out-of-office/DateRangePicker/DateSelect.css b/apps/web/components/out-of-office/DateRangePicker/DateSelect.css deleted file mode 100644 index 6ea26081a2..0000000000 --- a/apps/web/components/out-of-office/DateRangePicker/DateSelect.css +++ /dev/null @@ -1,110 +0,0 @@ -.custom-date > .tremor-DateRangePicker-root > .tremor-DateRangePicker-button { - box-shadow: none; - width: 100%; - background-color: transparent; - } - - /* Media query for screens larger than 768px */ - @media (max-width: 639) { - .custom-date > .tremor-DateRangePicker-root > .tremor-DateRangePicker-button { - max-width: 400px; - } - } - - .recharts-cartesian-grid-horizontal line{ - @apply stroke-emphasis - } - - .tremor-DateRangePicker-button button{ - @apply !h-9 !max-h-9 border-default hover:border-emphasis - } - - .tremor-DateRangePicker-calendarButton, - .tremor-DateRangePicker-dropdownButton { - @apply border-subtle bg-default focus-within:ring-emphasis hover:border-subtle dark:focus-within:ring-emphasis hover:bg-subtle text-sm leading-4 placeholder:text-sm placeholder:font-normal focus-within:ring-0; - } - - .tremor-DateRangePicker-dropdownModal{ - @apply divide-none - } - - .tremor-DropdownItem-root{ - @apply !h-9 !max-h-9 bg-default hover:bg-subtle text-default hover:text-emphasis - } - - .tremor-DateRangePicker-calendarButtonText, - .tremor-DateRangePicker-dropdownButtonText { - @apply text-default; - } - - .tremor-DateRangePicker-calendarHeaderText{ - @apply !text-default - } - - .tremor-DateRangePicker-calendarHeader svg{ - @apply text-default - } - - .tremor-DateRangePicker-calendarHeader button{ - @apply hover:bg-emphasis shadow-none focus:ring-0 - } - - - .tremor-DateRangePicker-calendarHeader button:hover svg{ - @apply text-emphasis - } - - .tremor-DateRangePicker-calendarButtonIcon{ - @apply text-default - } - - .tremor-DateRangePicker-calendarModal, - .tremor-DateRangePicker-dropdownModal { - @apply bg-default border-subtle shadow-dropdown - } - - .tremor-DateRangePicker-calendarBodyDate button{ - @apply text-default hover:bg-emphasis - } - - .tremor-DateRangePicker-calendarBodyDate button:disabled, - .tremor-DateRangePicker-calendarBodyDate button[disabled]{ - @apply opacity-25 - } - - .tremor-DateRangePicker-calendarHeader button{ - @apply border-default text-default - } - - .tremor-DateRangePicker-calendarBodyDate .bg-gray-100{ - @apply bg-subtle - } - - .tremor-DateRangePicker-calendarBodyDate .bg-gray-500{ - @apply !bg-brand-default text-inverted - } - - - .tremor-Card-root { - @apply p-5 bg-default; - } - - .tremor-TableCell-root { - @apply pl-0; - } - - .recharts-responsive-container { - @apply -mx-4; - } - .tremor-Card-root > p { - @apply mb-2 text-base font-semibold; - } - - .tremor-Legend-legendItem { - @apply ml-2; - } - - .tremor-TableBody-root { - @apply divide-subtle; - } - \ No newline at end of file diff --git a/apps/web/components/out-of-office/DateRangePicker/index.tsx b/apps/web/components/out-of-office/DateRangePicker/index.tsx deleted file mode 100644 index 5a20178822..0000000000 --- a/apps/web/components/out-of-office/DateRangePicker/index.tsx +++ /dev/null @@ -1,47 +0,0 @@ -import type { BookingRedirectForm } from "@pages/settings/my-account/out-of-office"; -import { DateRangePicker } from "@tremor/react"; -import type { UseFormSetValue } from "react-hook-form"; - -import dayjs from "@calcom/dayjs"; -import { useLocale } from "@calcom/lib/hooks/useLocale"; - -import "./DateSelect.css"; - -interface IOutOfOfficeDateRangeSelectProps { - dateRange: [Date | null, Date | null, null]; - setDateRange: React.Dispatch>; - setValue: UseFormSetValue; -} - -const OutOfOfficeDateRangePicker = (props: IOutOfOfficeDateRangeSelectProps) => { - const { t } = useLocale(); - const { dateRange, setDateRange, setValue } = props; - return ( -
- { - const [start, end] = datesArray; - - if (start) { - setDateRange([start, end as Date | null, null]); - } - if (start && end) { - setValue("startDate", start.toISOString()); - setValue("endDate", end.toISOString()); - } - }} - color="gray" - options={undefined} - enableDropdown={false} - placeholder={t("select_date_range")} - enableYearPagination={true} - minDate={dayjs().startOf("d").toDate()} - maxDate={dayjs().add(2, "y").endOf("d").toDate()} - /> -
- ); -}; - -export { OutOfOfficeDateRangePicker }; diff --git a/apps/web/pages/settings/my-account/out-of-office/index.tsx b/apps/web/pages/settings/my-account/out-of-office/index.tsx index 1524422af4..be7a32f828 100644 --- a/apps/web/pages/settings/my-account/out-of-office/index.tsx +++ b/apps/web/pages/settings/my-account/out-of-office/index.tsx @@ -1,23 +1,31 @@ import { Trash2 } from "lucide-react"; import React, { useState } from "react"; -import { useForm, useFormState } from "react-hook-form"; +import { Controller, useForm, useFormState } from "react-hook-form"; import dayjs from "@calcom/dayjs"; +import SectionBottomActions from "@calcom/features/settings/SectionBottomActions"; import { getLayout } from "@calcom/features/settings/layouts/SettingsLayout"; import { ShellMain } from "@calcom/features/shell/Shell"; import { useHasTeamPlan } from "@calcom/lib/hooks/useHasPaidPlan"; import { useLocale } from "@calcom/lib/hooks/useLocale"; import { trpc } from "@calcom/trpc/react"; import useMeQuery from "@calcom/trpc/react/hooks/useMeQuery"; -import { Button, Meta, showToast, Select, SkeletonText, UpgradeTeamsBadge, Switch } from "@calcom/ui"; +import { + Button, + Meta, + showToast, + Select, + SkeletonText, + UpgradeTeamsBadge, + Switch, + DateRangePicker, +} from "@calcom/ui"; import { TableNew, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@calcom/ui"; import PageWrapper from "@components/PageWrapper"; -import { OutOfOfficeDateRangePicker } from "@components/out-of-office/DateRangePicker"; export type BookingRedirectForm = { - startDate: string; - endDate: string; + dateRange: { startDate: Date; endDate: Date }; toTeamUserId: number | null; }; @@ -25,18 +33,20 @@ const OutOfOfficeSection = () => { const { t } = useLocale(); const utils = trpc.useContext(); - const [dateRange, setDateRange] = useState<[Date | null, Date | null, null | null]>([ - dayjs().startOf("d").toDate(), - dayjs().add(1, "d").endOf("d").toDate(), - null, - ]); const [profileRedirect, setProfileRedirect] = useState(false); const [selectedMember, setSelectedMember] = useState<{ label: string; value: number | null } | null>(null); - const { handleSubmit, setValue } = useForm({ + const [dateRange] = useState<{ startDate: Date; endDate: Date }>({ + startDate: dayjs().startOf("d").toDate(), + endDate: dayjs().add(1, "d").endOf("d").toDate(), + }); + + const { handleSubmit, setValue, getValues, control } = useForm({ defaultValues: { - startDate: dateRange[0]?.toISOString(), - endDate: dateRange[1]?.toISOString(), + dateRange: { + startDate: dateRange.startDate, + endDate: dateRange.endDate, + }, toTeamUserId: null, }, }); @@ -74,75 +84,81 @@ const OutOfOfficeSection = () => { setValue("toTeamUserId", null); setSelectedMember(null); })}> -
+
{/* Add startDate and end date inputs */} -
- {/* Add toggle to enable/disable redirect */} -
- { - setProfileRedirect(state); - }} - label={hasTeamPlan ? t("redirect_team_enabled") : t("redirect_team_disabled")} - /> - {!hasTeamPlan && ( -
- -
- )} -
-
- {profileRedirect && ( -
-

{t("team_member")}

- { + if (selectedOption?.value) { + setSelectedMember(selectedOption); + setValue("toTeamUserId", selectedOption?.value); + } + }} />
-
- -
- + )} +
+

{t("time_range")}

+ ( + { + setValue("dateRange", { + startDate, + endDate, + }); + }} + /> + )} + />
- -
+ + + ); @@ -166,10 +182,10 @@ const OutOfOfficeEntriesList = () => { return (
- + {t("time_range")} - {t("username")} + {t("redirect_to")} {t("action")} @@ -230,6 +246,7 @@ const OutOfOfficePage = () => { + ); diff --git a/apps/web/public/static/locales/en/common.json b/apps/web/public/static/locales/en/common.json index 510957ec8e..d303b2d8c8 100644 --- a/apps/web/public/static/locales/en/common.json +++ b/apps/web/public/static/locales/en/common.json @@ -2222,5 +2222,6 @@ "add_a_redirect": "Add a redirect", "create_entry": "Create entry", "time_range": "Time range", + "redirect_to": "Redirect to", "ADD_NEW_STRINGS_ABOVE_THIS_LINE_TO_PREVENT_MERGE_CONFLICTS": "↑↑↑↑↑↑↑↑↑↑↑↑↑ Add your new strings above here ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑" } diff --git a/packages/trpc/server/routers/loggedInViewer/outOfOffice.handler.ts b/packages/trpc/server/routers/loggedInViewer/outOfOffice.handler.ts index 3e0b83d205..9163aa2392 100644 --- a/packages/trpc/server/routers/loggedInViewer/outOfOffice.handler.ts +++ b/packages/trpc/server/routers/loggedInViewer/outOfOffice.handler.ts @@ -18,12 +18,13 @@ type TBookingRedirect = { }; export const outOfOfficeCreate = async ({ ctx, input }: TBookingRedirect) => { - if (!input.startDate || !input.endDate) { + const { startDate, endDate } = input.dateRange; + if (!startDate || !endDate) { throw new TRPCError({ code: "BAD_REQUEST", message: "start_date_and_end_date_required" }); } - const inputStartTime = dayjs(input.startDate).startOf("day"); - const inputEndTime = dayjs(input.endDate).endOf("day"); + const inputStartTime = dayjs(startDate).startOf("day"); + const inputEndTime = dayjs(endDate).endOf("day"); const offset = dayjs(inputStartTime).utcOffset(); // If start date is after end date throw error @@ -137,8 +138,8 @@ export const outOfOfficeCreate = async ({ ctx, input }: TBookingRedirect) => { const createdRedirect = await prisma.outOfOfficeEntry.create({ data: { uuid: uuidv4(), - start: dayjs(input.startDate).startOf("day").toISOString(), - end: dayjs(input.endDate).endOf("day").toISOString(), + start: dayjs(startDate).startOf("day").toISOString(), + end: dayjs(endDate).endOf("day").toISOString(), userId: ctx.user.id, toUserId: toUserId, createdAt: new Date(), diff --git a/packages/trpc/server/routers/loggedInViewer/outOfOffice.schema.ts b/packages/trpc/server/routers/loggedInViewer/outOfOffice.schema.ts index 793a10cad0..4740fb2268 100644 --- a/packages/trpc/server/routers/loggedInViewer/outOfOffice.schema.ts +++ b/packages/trpc/server/routers/loggedInViewer/outOfOffice.schema.ts @@ -1,8 +1,10 @@ import { z } from "zod"; export const ZOutOfOfficeInputSchema = z.object({ - startDate: z.string(), - endDate: z.string(), + dateRange: z.object({ + startDate: z.date(), + endDate: z.date(), + }), toTeamUserId: z.number().nullable(), });