Merge pull request #437 from emrysal/bugfix/fixes-saving-event-type
Resolved errors on the pages/event-types/[type].tsx pagepull/441/head
commit
b5cd38b77a
|
@ -0,0 +1,42 @@
|
|||
import { DialogClose, DialogContent } from "@components/Dialog";
|
||||
import * as DialogPrimitive from "@radix-ui/react-dialog";
|
||||
import { ExclamationIcon } from "@heroicons/react/outline";
|
||||
import React from "react";
|
||||
|
||||
export default function ConfirmationDialogContent({
|
||||
title,
|
||||
alert,
|
||||
confirmBtnText,
|
||||
cancelBtnText,
|
||||
onConfirm,
|
||||
children,
|
||||
}) {
|
||||
confirmBtnText = confirmBtnText || "Confirm";
|
||||
cancelBtnText = cancelBtnText || "Cancel";
|
||||
|
||||
return (
|
||||
<DialogContent>
|
||||
<div className="flex">
|
||||
{alert && (
|
||||
<div className="mr-3 mt-0.5">
|
||||
{alert === "danger" && (
|
||||
<div className="text-center p-2 rounded-full mx-auto bg-red-100">
|
||||
<ExclamationIcon className="w-5 h-5 text-red-600" />
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
<div>
|
||||
<DialogPrimitive.Title className="text-xl font-bold text-gray-900">{title}</DialogPrimitive.Title>
|
||||
<DialogPrimitive.Description className="text-neutral-500">{children}</DialogPrimitive.Description>
|
||||
</div>
|
||||
</div>
|
||||
<div className="mt-5 sm:mt-4 sm:flex sm:flex-row-reverse">
|
||||
<DialogClose onClick={onConfirm} className="btn btn-primary">
|
||||
{confirmBtnText}
|
||||
</DialogClose>
|
||||
<DialogClose className="btn btn-white mx-2">{cancelBtnText}</DialogClose>
|
||||
</div>
|
||||
</DialogContent>
|
||||
);
|
||||
}
|
|
@ -2,7 +2,7 @@ import { GetServerSideProps } from "next";
|
|||
import Head from "next/head";
|
||||
import Link from "next/link";
|
||||
import { useRouter } from "next/router";
|
||||
import { useEffect, useRef, useState } from "react";
|
||||
import React, { useEffect, useRef, useState } from "react";
|
||||
import Select, { OptionBase } from "react-select";
|
||||
import prisma from "@lib/prisma";
|
||||
import { LocationType } from "@lib/location";
|
||||
|
@ -10,18 +10,17 @@ import Shell from "@components/Shell";
|
|||
import { getSession } from "next-auth/client";
|
||||
import { Scheduler } from "@components/ui/Scheduler";
|
||||
import { Disclosure, RadioGroup } from "@headlessui/react";
|
||||
|
||||
import { PhoneIcon, XIcon } from "@heroicons/react/outline";
|
||||
import { EventTypeCustomInput, EventTypeCustomInputType } from "@lib/eventTypeInput";
|
||||
import {
|
||||
LocationMarkerIcon,
|
||||
LinkIcon,
|
||||
PlusIcon,
|
||||
DocumentIcon,
|
||||
ChevronRightIcon,
|
||||
ClockIcon,
|
||||
DocumentIcon,
|
||||
ExternalLinkIcon,
|
||||
LinkIcon,
|
||||
LocationMarkerIcon,
|
||||
PlusIcon,
|
||||
TrashIcon,
|
||||
ExternalLinkIcon,
|
||||
} from "@heroicons/react/solid";
|
||||
|
||||
import dayjs from "dayjs";
|
||||
|
@ -34,6 +33,9 @@ import throttle from "lodash.throttle";
|
|||
import "react-dates/initialize";
|
||||
import "react-dates/lib/css/_datepicker.css";
|
||||
import { DateRangePicker, OrientationShape, toMomentObject } from "react-dates";
|
||||
import Switch from "@components/ui/Switch";
|
||||
import { Dialog, DialogTrigger } from "@components/Dialog";
|
||||
import ConfirmationDialogContent from "@components/dialog/ConfirmationDialogContent";
|
||||
|
||||
dayjs.extend(utc);
|
||||
dayjs.extend(timezone);
|
||||
|
@ -57,7 +59,17 @@ type DateOverride = {
|
|||
endTime: number;
|
||||
};
|
||||
|
||||
type EventTypeInput = {
|
||||
type AdvancedOptions = {
|
||||
eventName?: string;
|
||||
periodType?: string;
|
||||
periodDays?: number;
|
||||
periodStartDate?: Date | string;
|
||||
periodEndDate?: Date | string;
|
||||
periodCountCalendarDays?: boolean;
|
||||
requiresConfirmation?: boolean;
|
||||
};
|
||||
|
||||
type EventTypeInput = AdvancedOptions & {
|
||||
id: number;
|
||||
title: string;
|
||||
slug: string;
|
||||
|
@ -65,16 +77,9 @@ type EventTypeInput = {
|
|||
length: number;
|
||||
hidden: boolean;
|
||||
locations: unknown;
|
||||
eventName: string;
|
||||
customInputs: EventTypeCustomInput[];
|
||||
timeZone: string;
|
||||
availability?: { openingHours: OpeningHours[]; dateOverrides: DateOverride[] };
|
||||
periodType?: string;
|
||||
periodDays?: number;
|
||||
periodStartDate?: Date | string;
|
||||
periodEndDate?: Date | string;
|
||||
periodCountCalendarDays?: boolean;
|
||||
enteredRequiresConfirmation: boolean;
|
||||
};
|
||||
|
||||
const PERIOD_TYPES = [
|
||||
|
@ -100,7 +105,6 @@ export default function EventTypePage({
|
|||
}: Props): JSX.Element {
|
||||
const router = useRouter();
|
||||
|
||||
console.log(eventType);
|
||||
const inputOptions: OptionBase[] = [
|
||||
{ value: EventTypeCustomInputType.Text, label: "Text" },
|
||||
{ value: EventTypeCustomInputType.TextLong, label: "Multiline Text" },
|
||||
|
@ -176,11 +180,11 @@ export default function EventTypePage({
|
|||
);
|
||||
});
|
||||
|
||||
const [hidden, setHidden] = useState<boolean>(eventType.hidden);
|
||||
const titleRef = useRef<HTMLInputElement>();
|
||||
const slugRef = useRef<HTMLInputElement>();
|
||||
const descriptionRef = useRef<HTMLTextAreaElement>();
|
||||
const lengthRef = useRef<HTMLInputElement>();
|
||||
const isHiddenRef = useRef<HTMLInputElement>();
|
||||
const requiresConfirmationRef = useRef<HTMLInputElement>();
|
||||
const eventNameRef = useRef<HTMLInputElement>();
|
||||
const periodDaysRef = useRef<HTMLInputElement>();
|
||||
|
@ -197,26 +201,17 @@ export default function EventTypePage({
|
|||
const enteredSlug: string = slugRef.current.value;
|
||||
const enteredDescription: string = descriptionRef.current.value;
|
||||
const enteredLength: number = parseInt(lengthRef.current.value);
|
||||
const enteredIsHidden: boolean = isHiddenRef.current.checked;
|
||||
const enteredRequiresConfirmation: boolean = requiresConfirmationRef.current.checked;
|
||||
const enteredEventName: string = eventNameRef.current.value;
|
||||
|
||||
const type = periodType.type;
|
||||
const enteredPeriodDays = parseInt(periodDaysRef?.current?.value);
|
||||
const enteredPeriodDaysType = Boolean(parseInt(periodDaysTypeRef?.current.value));
|
||||
|
||||
const enteredPeriodStartDate = periodStartDate ? periodStartDate.toDate() : null;
|
||||
const enteredPeriodEndDate = periodEndDate ? periodEndDate.toDate() : null;
|
||||
|
||||
console.log("values", {
|
||||
type,
|
||||
periodDaysTypeRef,
|
||||
enteredPeriodDays,
|
||||
enteredPeriodDaysType,
|
||||
enteredPeriodStartDate,
|
||||
enteredPeriodEndDate,
|
||||
});
|
||||
// TODO: Add validation
|
||||
const advancedOptionsPayload: AdvancedOptions = {};
|
||||
if (requiresConfirmationRef.current) {
|
||||
advancedOptionsPayload.requiresConfirmation = requiresConfirmationRef.current.checked;
|
||||
advancedOptionsPayload.eventName = eventNameRef.current.value;
|
||||
advancedOptionsPayload.periodType = periodType.type;
|
||||
advancedOptionsPayload.periodDays = parseInt(periodDaysRef?.current?.value);
|
||||
advancedOptionsPayload.periodCountCalendarDays = Boolean(parseInt(periodDaysTypeRef?.current.value));
|
||||
advancedOptionsPayload.periodStartDate = periodStartDate ? periodStartDate.toDate() : null;
|
||||
advancedOptionsPayload.periodEndDate = periodEndDate ? periodEndDate.toDate() : null;
|
||||
}
|
||||
|
||||
const payload: EventTypeInput = {
|
||||
id: eventType.id,
|
||||
|
@ -224,23 +219,14 @@ export default function EventTypePage({
|
|||
slug: enteredSlug,
|
||||
description: enteredDescription,
|
||||
length: enteredLength,
|
||||
hidden: enteredIsHidden,
|
||||
hidden,
|
||||
locations,
|
||||
eventName: enteredEventName,
|
||||
customInputs,
|
||||
timeZone: selectedTimeZone,
|
||||
periodType: type,
|
||||
periodDays: enteredPeriodDays,
|
||||
periodStartDate: enteredPeriodStartDate,
|
||||
periodEndDate: enteredPeriodEndDate,
|
||||
periodCountCalendarDays: enteredPeriodDaysType,
|
||||
requiresConfirmation: enteredRequiresConfirmation,
|
||||
availability: enteredAvailability || null,
|
||||
...advancedOptionsPayload,
|
||||
};
|
||||
|
||||
if (enteredAvailability) {
|
||||
payload.availability = enteredAvailability;
|
||||
}
|
||||
|
||||
await fetch("/api/availability/eventtype", {
|
||||
method: "PATCH",
|
||||
body: JSON.stringify(payload),
|
||||
|
@ -249,7 +235,7 @@ export default function EventTypePage({
|
|||
},
|
||||
});
|
||||
|
||||
router.push("/availability");
|
||||
router.push("/event-types");
|
||||
}
|
||||
|
||||
async function deleteEventTypeHandler(event) {
|
||||
|
@ -696,33 +682,6 @@ export default function EventTypePage({
|
|||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div className="block sm:flex items-center">
|
||||
<div className="min-w-44 mb-4 sm:mb-0">
|
||||
<label htmlFor="hidden" className="text-sm flex font-medium text-neutral-700">
|
||||
Hide event type
|
||||
</label>
|
||||
</div>
|
||||
<div className="w-full">
|
||||
<div className="relative flex items-start">
|
||||
<div className="flex items-center h-5">
|
||||
<input
|
||||
ref={isHiddenRef}
|
||||
id="ishidden"
|
||||
name="ishidden"
|
||||
type="checkbox"
|
||||
className="focus:ring-primary-500 h-4 w-4 text-primary-600 border-gray-300 rounded"
|
||||
defaultChecked={eventType.hidden}
|
||||
/>
|
||||
</div>
|
||||
<div className="ml-3 text-sm">
|
||||
<p className="text-neutral-900">
|
||||
Hide the event type from your page, so it can only be booked through its
|
||||
URL.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="block sm:flex items-center">
|
||||
<div className="min-w-44 mb-4 sm:mb-0">
|
||||
<label
|
||||
|
@ -895,6 +854,12 @@ export default function EventTypePage({
|
|||
</div>
|
||||
<div className="w-full sm:w-2/12 ml-2 px-4 mt-8 sm:mt-0 min-w-32">
|
||||
<div className="space-y-4">
|
||||
<Switch
|
||||
name="isHidden"
|
||||
defaultChecked={hidden}
|
||||
onCheckedChange={setHidden}
|
||||
label="Hide event type"
|
||||
/>
|
||||
<a
|
||||
href={"/" + user.username + "/" + eventType.slug}
|
||||
target="_blank"
|
||||
|
@ -914,13 +879,20 @@ export default function EventTypePage({
|
|||
<LinkIcon className="w-4 h-4 mt-1 mr-2 text-neutral-500" />
|
||||
Copy link
|
||||
</button>
|
||||
<button
|
||||
onClick={deleteEventTypeHandler}
|
||||
type="button"
|
||||
className="flex text-md font-medium text-neutral-700">
|
||||
<Dialog>
|
||||
<DialogTrigger className="flex text-md font-medium text-neutral-700">
|
||||
<TrashIcon className="w-4 h-4 mt-1 mr-2 text-neutral-500" />
|
||||
Delete
|
||||
</button>
|
||||
</DialogTrigger>
|
||||
<ConfirmationDialogContent
|
||||
alert="danger"
|
||||
title="Delete Event Type"
|
||||
confirmBtnText="Yes, delete event type"
|
||||
onConfirm={deleteEventTypeHandler}>
|
||||
Are you sure you want to delete this event type? Anyone who you've shared this link
|
||||
with will no longer be able to book using it.
|
||||
</ConfirmationDialogContent>
|
||||
</Dialog>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
Loading…
Reference in New Issue