-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathsee-more-times.tsx
134 lines (126 loc) · 3.97 KB
/
see-more-times.tsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
import { BRAND_COLOR, NYLAS_SCHEDULER_API_URL } from "@/lib/constants";
import { Contractor, UserData } from "@/lib/types";
import { NylasScheduler } from "@nylas/react";
import { Dispatch, useCallback, useEffect, useRef, useState } from "react";
import { Button } from "./ui/button";
import { Dialog, DialogContent } from "./ui/dialog";
type SeeMoreTimesProps = {
contractor: Contractor | undefined;
selectedDurationInMinutes: number;
user: UserData | undefined;
bookingInfo: any;
selectedTimeslot: { start_time: Date; end_time: Date } | null;
setBookingInfo: Dispatch<any>;
timeslotConfirmedHandler: (
timeslot: { start_time: Date; end_time: Date } | undefined
) => Promise<boolean>;
};
export default function SeeMoreTimes({
contractor,
selectedDurationInMinutes,
user,
bookingInfo,
selectedTimeslot,
setBookingInfo,
timeslotConfirmedHandler,
}: SeeMoreTimesProps) {
const [loading, setLoading] = useState<boolean>(false);
const [showScheduler, setShowScheduler] = useState<boolean>(false);
const [sessionId, setSessionId] = useState<string | null>(null);
const schedulerRef = useRef<HTMLNylasSchedulerElement>(null);
/**
* This function creates a session for the contractor's
* scheduler instance based on the selected duration.
*
* This dynamically creates a session that is passed to the
* NylasScheduler component which fetches availability and allows
* the user to book a timeslot based on the contractor's pre-configured
* availability.
*/
const createSession = useCallback(async () => {
if (!contractor) {
return;
}
const createSession: any = await fetch("/api/session", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
contractor_id: contractor.uid,
duration: selectedDurationInMinutes,
}),
});
const schedulerSession = await createSession.json();
return schedulerSession?.data?.session_id;
}, [contractor, selectedDurationInMinutes]);
/**
* Create a session to pass prop sessionId to NylasScheduler
*/
useEffect(() => {
// If already initialized, return
if (loading) {
return;
}
// Create a session to pass prop sessionId to NylasScheduler
if (!sessionId && contractor) {
setLoading(true);
createSession().then((sessionId) => {
setSessionId(sessionId);
setLoading(false);
});
}
}, [contractor, createSession, sessionId, loading]);
/**
* Update bookingInfo when user changes
*/
useEffect(() => {
setBookingInfo({
primaryParticipant: {
name: user?.name,
email: user?.email,
},
});
}, [user, setBookingInfo]);
return (
<Dialog open={showScheduler} onOpenChange={() => setShowScheduler(false)}>
<Button
variant={"link"}
onClick={() => setShowScheduler(true)}
className="p-0 text-blue-600 dark:text-blue-500"
>
See more times
</Button>
<DialogContent className="h-[575px] p-0 overflow-hidden">
{sessionId && (
<NylasScheduler
key={sessionId}
ref={schedulerRef}
mode="app"
sessionId={sessionId}
schedulerApiUrl={NYLAS_SCHEDULER_API_URL}
themeConfig={{
"--nylas-primary": BRAND_COLOR,
}}
bookingInfo={bookingInfo}
eventOverrides={{
timeslotConfirmed: async (event) => {
event.preventDefault();
timeslotConfirmedHandler(event.detail);
},
}}
>
<span slot="timeslot-picker-cta-label">Confirm</span>
</NylasScheduler>
)}
{!sessionId && (
<div className="flex flex-col items-center justify-center h-full">
<p className="text-lg font-semibold text-gray-600 dark:text-gray-400">
Loading...
</p>
</div>
)}
</DialogContent>
</Dialog>
);
}