Feat disable guests for events (#719)
* Abstracts CheckboxField * Allows disabling the guests field while booking Co-authored-by: Bailey Pumfleet <pumfleet@hey.com>pull/722/head
parent
1c2998fc13
commit
e1f1386332
|
@ -329,42 +329,48 @@ const BookingPage = (props: any): JSX.Element => {
|
|||
)}
|
||||
</div>
|
||||
))}
|
||||
<div className="mb-4">
|
||||
{!guestToggle && (
|
||||
<label
|
||||
onClick={toggleGuestEmailInput}
|
||||
htmlFor="guests"
|
||||
className="block text-sm font-medium dark:text-white text-blue-500 mb-1 hover:cursor-pointer">
|
||||
+ Additional Guests
|
||||
</label>
|
||||
)}
|
||||
{guestToggle && (
|
||||
<div>
|
||||
{!props.eventType.disableGuests && (
|
||||
<div className="mb-4">
|
||||
{!guestToggle && (
|
||||
<label
|
||||
onClick={toggleGuestEmailInput}
|
||||
htmlFor="guests"
|
||||
className="block text-sm font-medium dark:text-white text-gray-700 mb-1">
|
||||
Guests
|
||||
className="block text-sm font-medium dark:text-white text-blue-500 mb-1 hover:cursor-pointer">
|
||||
+ Additional Guests
|
||||
</label>
|
||||
<ReactMultiEmail
|
||||
placeholder="guest@example.com"
|
||||
emails={guestEmails}
|
||||
onChange={(_emails: string[]) => {
|
||||
setGuestEmails(_emails);
|
||||
}}
|
||||
getLabel={(email: string, index: number, removeEmail: (index: number) => void) => {
|
||||
return (
|
||||
<div data-tag key={index}>
|
||||
{email}
|
||||
<span data-tag-handle onClick={() => removeEmail(index)}>
|
||||
×
|
||||
</span>
|
||||
</div>
|
||||
);
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
{guestToggle && (
|
||||
<div>
|
||||
<label
|
||||
htmlFor="guests"
|
||||
className="block text-sm font-medium dark:text-white text-gray-700 mb-1">
|
||||
Guests
|
||||
</label>
|
||||
<ReactMultiEmail
|
||||
placeholder="guest@example.com"
|
||||
emails={guestEmails}
|
||||
onChange={(_emails: string[]) => {
|
||||
setGuestEmails(_emails);
|
||||
}}
|
||||
getLabel={(
|
||||
email: string,
|
||||
index: number,
|
||||
removeEmail: (index: number) => void
|
||||
) => {
|
||||
return (
|
||||
<div data-tag key={index}>
|
||||
{email}
|
||||
<span data-tag-handle onClick={() => removeEmail(index)}>
|
||||
×
|
||||
</span>
|
||||
</div>
|
||||
);
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
<div className="mb-4">
|
||||
<label
|
||||
htmlFor="notes"
|
||||
|
|
|
@ -0,0 +1,37 @@
|
|||
import React, { forwardRef, InputHTMLAttributes } from "react";
|
||||
|
||||
type Props = InputHTMLAttributes<HTMLInputElement> & {
|
||||
label: string;
|
||||
description: string;
|
||||
};
|
||||
|
||||
const CheckboxField = forwardRef<HTMLInputElement, Props>(({ label, description, ...rest }, ref) => {
|
||||
return (
|
||||
<div className="items-center block sm:flex">
|
||||
<div className="mb-4 min-w-44 sm:mb-0">
|
||||
<label htmlFor={rest.id} className="flex text-sm font-medium text-neutral-700">
|
||||
{label}
|
||||
</label>
|
||||
</div>
|
||||
<div className="w-full">
|
||||
<div className="relative flex items-start">
|
||||
<div className="flex items-center h-5">
|
||||
<input
|
||||
{...rest}
|
||||
ref={ref}
|
||||
type="checkbox"
|
||||
className="w-4 h-4 border-gray-300 rounded focus:ring-primary-500 text-primary-600"
|
||||
/>
|
||||
</div>
|
||||
<div className="ml-3 text-sm">
|
||||
<p className="text-neutral-900">{description}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
});
|
||||
|
||||
CheckboxField.displayName = "CheckboxField";
|
||||
|
||||
export default CheckboxField;
|
|
@ -43,6 +43,7 @@ export async function getServerSideProps(context) {
|
|||
periodStartDate: true,
|
||||
periodEndDate: true,
|
||||
periodCountCalendarDays: true,
|
||||
disableGuests: true,
|
||||
users: {
|
||||
select: {
|
||||
username: true,
|
||||
|
|
|
@ -47,6 +47,7 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
|
|||
length: parseInt(req.body.length),
|
||||
hidden: req.body.hidden,
|
||||
requiresConfirmation: req.body.requiresConfirmation,
|
||||
disableGuests: req.body.disableGuests,
|
||||
locations: req.body.locations,
|
||||
eventName: req.body.eventName,
|
||||
customInputs: !req.body.customInputs
|
||||
|
|
|
@ -49,6 +49,7 @@ import classNames from "@lib/classNames";
|
|||
import { inferSSRProps } from "@lib/types/inferSSRProps";
|
||||
import { asStringOrThrow } from "@lib/asStringOrNull";
|
||||
import Button from "@components/ui/Button";
|
||||
import CheckboxField from "@components/ui/form/CheckboxField";
|
||||
|
||||
dayjs.extend(utc);
|
||||
dayjs.extend(timezone);
|
||||
|
@ -194,7 +195,6 @@ const EventTypePage = (props: inferSSRProps<typeof getServerSideProps>) => {
|
|||
|
||||
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);
|
||||
|
@ -208,7 +208,9 @@ const EventTypePage = (props: inferSSRProps<typeof getServerSideProps>) => {
|
|||
title: enteredTitle,
|
||||
slug: enteredSlug,
|
||||
description: formData.description as string,
|
||||
length: formData.length as number,
|
||||
length: formData.length as unknown as number,
|
||||
requiresConfirmation: formData.requiresConfirmation === "on",
|
||||
disableGuests: formData.disableGuests === "on",
|
||||
hidden,
|
||||
locations,
|
||||
customInputs,
|
||||
|
@ -720,35 +722,23 @@ const EventTypePage = (props: inferSSRProps<typeof getServerSideProps>) => {
|
|||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div className="items-center block sm:flex">
|
||||
<div className="mb-4 min-w-44 sm:mb-0">
|
||||
<label
|
||||
htmlFor="requiresConfirmation"
|
||||
className="flex text-sm font-medium text-neutral-700">
|
||||
Opt-in booking
|
||||
</label>
|
||||
</div>
|
||||
<div className="w-full">
|
||||
<div className="relative flex items-start">
|
||||
<div className="flex items-center h-5">
|
||||
<input
|
||||
ref={requiresConfirmationRef}
|
||||
id="requiresConfirmation"
|
||||
name="requiresConfirmation"
|
||||
type="checkbox"
|
||||
className="w-4 h-4 border-gray-300 rounded focus:ring-primary-500 text-primary-600"
|
||||
defaultChecked={eventType.requiresConfirmation}
|
||||
/>
|
||||
</div>
|
||||
<div className="ml-3 text-sm">
|
||||
<p className="text-neutral-900">
|
||||
The booking needs to be manually confirmed before it is pushed to the
|
||||
integrations and a confirmation mail is sent.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<CheckboxField
|
||||
ref={requiresConfirmationRef}
|
||||
id="requiresConfirmation"
|
||||
name="requiresConfirmation"
|
||||
label="Opt-in booking"
|
||||
description="The booking needs to be manually confirmed before it is pushed to the integrations and a confirmation mail is sent."
|
||||
defaultChecked={eventType.requiresConfirmation}
|
||||
/>
|
||||
|
||||
<CheckboxField
|
||||
id="disableGuests"
|
||||
name="disableGuests"
|
||||
label="Disable guests"
|
||||
description="Disable adding aditional guests while booking."
|
||||
defaultChecked={eventType.disableGuests}
|
||||
/>
|
||||
|
||||
<hr className="border-neutral-200" />
|
||||
|
||||
|
@ -1153,6 +1143,7 @@ export const getServerSideProps = async (context: GetServerSidePropsContext) =>
|
|||
periodEndDate: true,
|
||||
periodCountCalendarDays: true,
|
||||
requiresConfirmation: true,
|
||||
disableGuests: true,
|
||||
team: {
|
||||
select: {
|
||||
slug: true,
|
||||
|
|
|
@ -33,6 +33,7 @@ export async function getServerSideProps(context) {
|
|||
periodStartDate: true,
|
||||
periodEndDate: true,
|
||||
periodCountCalendarDays: true,
|
||||
disableGuests: true,
|
||||
team: {
|
||||
select: {
|
||||
slug: true,
|
||||
|
|
|
@ -0,0 +1,2 @@
|
|||
-- AlterTable
|
||||
ALTER TABLE "EventType" ADD COLUMN "disableGuests" BOOLEAN NOT NULL DEFAULT false;
|
|
@ -38,6 +38,7 @@ model EventType {
|
|||
periodDays Int?
|
||||
periodCountCalendarDays Boolean?
|
||||
requiresConfirmation Boolean @default(false)
|
||||
disableGuests Boolean @default(false)
|
||||
minimumBookingNotice Int @default(120)
|
||||
schedulingType SchedulingType?
|
||||
Schedule Schedule[]
|
||||
|
|
Loading…
Reference in New Issue