import Head from 'next/head'; import Link from 'next/link'; import {useRouter} from 'next/router'; import {CalendarIcon, ClockIcon, ExclamationIcon, LocationMarkerIcon} from '@heroicons/react/solid'; import prisma from '../../lib/prisma'; import {collectPageParameters, telemetryEventTypes, useTelemetry} from "../../lib/telemetry"; import {useEffect, useState} from "react"; import dayjs from 'dayjs'; import utc from 'dayjs/plugin/utc'; import timezone from 'dayjs/plugin/timezone'; import 'react-phone-number-input/style.css'; import PhoneInput from 'react-phone-number-input'; import {LocationType} from '../../lib/location'; import Avatar from '../../components/Avatar'; import Button from '../../components/ui/Button'; import {EventTypeCustomInputType} from "../../lib/eventTypeInput"; dayjs.extend(utc); dayjs.extend(timezone); export default function Book(props) { const router = useRouter(); const { date, user, rescheduleUid } = router.query; const [ is24h, setIs24h ] = useState(false); const [ preferredTimeZone, setPreferredTimeZone ] = useState(''); const [ loading, setLoading ] = useState(false); const [ error, setError ] = useState(false); const locations = props.eventType.locations || []; const [ selectedLocation, setSelectedLocation ] = useState(locations.length === 1 ? locations[0].type : ''); const telemetry = useTelemetry(); useEffect(() => { setPreferredTimeZone(localStorage.getItem('timeOption.preferredTimeZone') || dayjs.tz.guess()); setIs24h(!!localStorage.getItem('timeOption.is24hClock')); telemetry.withJitsu(jitsu => jitsu.track(telemetryEventTypes.timeSelected, collectPageParameters())); }); const locationInfo = (type: LocationType) => locations.find( (location) => location.type === type ); // TODO: Move to translations const locationLabels = { [LocationType.InPerson]: 'In-person meeting', [LocationType.Phone]: 'Phone call', }; const bookingHandler = event => { const book = async () => { setLoading(true); setError(false); let notes = ""; if (props.eventType.customInputs) { notes = props.eventType.customInputs.map(input => { const data = event.target["custom_" + input.id]; if (!!data) { if (input.type === EventTypeCustomInputType.Bool) { return input.label + "\n" + (data.value ? "Yes" : "No") } else { return input.label + "\n" + data.value } } }).join("\n\n") } if (!!notes && !!event.target.notes.value) { notes += "\n\nAdditional notes:\n" + event.target.notes.value; } else { notes += event.target.notes.value; } let payload = { start: dayjs(date).format(), end: dayjs(date).add(props.eventType.length, 'minute').format(), name: event.target.name.value, email: event.target.email.value, notes: notes, timeZone: preferredTimeZone, eventTypeId: props.eventType.id, rescheduleUid: rescheduleUid }; if (selectedLocation) { payload['location'] = selectedLocation === LocationType.Phone ? event.target.phone.value : locationInfo(selectedLocation).address; } telemetry.withJitsu(jitsu => jitsu.track(telemetryEventTypes.bookingConfirmed, collectPageParameters())); const res = await fetch( '/api/book/' + user, { body: JSON.stringify(payload), headers: { 'Content-Type': 'application/json' }, method: 'POST' } ); if (res.ok) { let successUrl = `/success?date=${date}&type=${props.eventType.id}&user=${props.user.username}&reschedule=${!!rescheduleUid}&name=${payload.name}`; if (payload['location']) { successUrl += "&location=" + encodeURIComponent(payload['location']); } await router.push(successUrl); } else { setLoading(false); setError(true); } } event.preventDefault(); book(); } return (
{rescheduleUid ? 'Reschedule' : 'Confirm'} your {props.eventType.title} with {props.user.name || props.user.username} | Calendso

{props.user.name}

{props.eventType.title}

{props.eventType.length} minutes

{selectedLocation === LocationType.InPerson &&

{locationInfo(selectedLocation).address}

}

{preferredTimeZone && dayjs(date).tz(preferredTimeZone).format( (is24h ? "H:mm" : "h:mma") + ", dddd DD MMMM YYYY")}

{props.eventType.description}

{locations.length > 1 && (
Location {locations.map( (location) => ( ))}
)} {selectedLocation === LocationType.Phone && (
{}} />
)} {props.eventType.customInputs && props.eventType.customInputs.sort((a,b) => a.id - b.id).map(input => (
{input.type !== EventTypeCustomInputType.Bool && } {input.type === EventTypeCustomInputType.TextLong &&