meeting-scheduler-npm-package 1.0.5 → 1.0.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/MeetingScheduler.d.ts +6 -15
- package/dist/index.cjs.js +161 -79
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.esm.js +161 -79
- package/dist/index.esm.js.map +1 -1
- package/package.json +1 -1
|
@@ -1,11 +1,4 @@
|
|
|
1
1
|
import React from "react";
|
|
2
|
-
export interface Slot {
|
|
3
|
-
start_local: string;
|
|
4
|
-
end_local: string;
|
|
5
|
-
start_utc: string;
|
|
6
|
-
end_utc: string;
|
|
7
|
-
is_booked: boolean;
|
|
8
|
-
}
|
|
9
2
|
export interface FormData {
|
|
10
3
|
name: string;
|
|
11
4
|
email: string;
|
|
@@ -13,14 +6,12 @@ export interface FormData {
|
|
|
13
6
|
message: string;
|
|
14
7
|
}
|
|
15
8
|
export interface MeetingSchedulerProps {
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
onSuccess?: () => void;
|
|
23
|
-
onError?: (err: string) => void;
|
|
9
|
+
apiBaseUrl?: string;
|
|
10
|
+
defaultAvailabilityId?: number;
|
|
11
|
+
defaultUserId?: number;
|
|
12
|
+
initialMonth?: Date;
|
|
13
|
+
onBookingSuccess?: (data: any) => void;
|
|
14
|
+
onBookingError?: (error: any) => void;
|
|
24
15
|
}
|
|
25
16
|
declare const MeetingScheduler: React.FC<MeetingSchedulerProps>;
|
|
26
17
|
export default MeetingScheduler;
|
package/dist/index.cjs.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
var React = require('react');
|
|
4
|
+
var lucideReact = require('lucide-react');
|
|
4
5
|
|
|
5
6
|
var jsxRuntime = {exports: {}};
|
|
6
7
|
|
|
@@ -488,156 +489,237 @@ function IoIosArrowBack (props) {
|
|
|
488
489
|
return GenIcon({"attr":{"viewBox":"0 0 512 512"},"child":[{"tag":"path","attr":{"d":"M294.1 256L167 129c-9.4-9.4-9.4-24.6 0-33.9s24.6-9.3 34 0L345 239c9.1 9.1 9.3 23.7.7 33.1L201.1 417c-4.7 4.7-10.9 7-17 7s-12.3-2.3-17-7c-9.4-9.4-9.4-24.6 0-33.9l127-127.1z"},"child":[]}]})(props);
|
|
489
490
|
}
|
|
490
491
|
|
|
491
|
-
const
|
|
492
|
-
const
|
|
493
|
-
|
|
492
|
+
const MeetingScheduler = ({ apiBaseUrl: propApiBase, defaultAvailabilityId = 5, defaultUserId = 1, initialMonth, onBookingSuccess, onBookingError, }) => {
|
|
493
|
+
const API_BASE = propApiBase;
|
|
494
|
+
// ────────────────────────────────────────────────
|
|
495
|
+
// State
|
|
496
|
+
// ────────────────────────────────────────────────
|
|
497
|
+
const [currentMonth, setCurrentMonth] = React.useState(initialMonth || new Date(2026, 0, 1));
|
|
494
498
|
const [selectedDate, setSelectedDate] = React.useState(null);
|
|
495
499
|
const [availableSlots, setAvailableSlots] = React.useState([]);
|
|
496
500
|
const [selectedSlot, setSelectedSlot] = React.useState(null);
|
|
497
501
|
const [loading, setLoading] = React.useState(false);
|
|
498
|
-
const [timezone, setTimezone] = React.useState("UTC");
|
|
499
502
|
const [formData, setFormData] = React.useState({
|
|
500
503
|
name: "",
|
|
501
504
|
email: "",
|
|
502
505
|
phone: "",
|
|
503
506
|
message: "",
|
|
504
507
|
});
|
|
505
|
-
|
|
508
|
+
const [timezone, setTimezone] = React.useState("UTC");
|
|
509
|
+
// Detect user timezone
|
|
506
510
|
React.useEffect(() => {
|
|
507
|
-
|
|
511
|
+
const detected = Intl.DateTimeFormat().resolvedOptions().timeZone;
|
|
512
|
+
setTimezone(detected);
|
|
508
513
|
}, []);
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
514
|
+
// ────────────────────────────────────────────────
|
|
515
|
+
// Helpers
|
|
516
|
+
// ────────────────────────────────────────────────
|
|
517
|
+
const formatTimeTo12Hour = (dateTimeStr) => {
|
|
518
|
+
if (!dateTimeStr)
|
|
519
|
+
return "";
|
|
520
|
+
const timePart = dateTimeStr.split(" ")[1];
|
|
521
|
+
let [hours, minutes] = timePart.split(":").map(Number);
|
|
522
|
+
const ampm = hours >= 12 ? "PM" : "AM";
|
|
523
|
+
hours = hours % 12;
|
|
524
|
+
hours = hours || 12;
|
|
525
|
+
return `${hours}:${minutes.toString().padStart(2, "0")} ${ampm}`;
|
|
519
526
|
};
|
|
520
527
|
const today = new Date();
|
|
521
528
|
today.setHours(0, 0, 0, 0);
|
|
522
529
|
const isPastDate = (date) => date <= today;
|
|
523
|
-
|
|
530
|
+
const isSlotTooSoon = (slotStartUtc) => {
|
|
531
|
+
const slotTime = new Date(slotStartUtc);
|
|
532
|
+
const oneHourFromNow = new Date();
|
|
533
|
+
oneHourFromNow.setHours(oneHourFromNow.getHours() + 1);
|
|
534
|
+
return slotTime < oneHourFromNow;
|
|
535
|
+
};
|
|
536
|
+
const daysOfWeek = ["SUN", "MON", "TUE", "WED", "THU", "FRI", "SAT"];
|
|
537
|
+
const getDaysInMonth = (date) => {
|
|
538
|
+
const year = date.getFullYear();
|
|
539
|
+
const month = date.getMonth();
|
|
540
|
+
const firstDay = new Date(year, month, 1).getDay();
|
|
541
|
+
const daysInMonth = new Date(year, month + 1, 0).getDate();
|
|
542
|
+
const days = [];
|
|
543
|
+
for (let i = 0; i < firstDay; i++)
|
|
544
|
+
days.push(null);
|
|
545
|
+
for (let i = 1; i <= daysInMonth; i++)
|
|
546
|
+
days.push(new Date(year, month, i));
|
|
547
|
+
return days;
|
|
548
|
+
};
|
|
549
|
+
const formatDateHeader = (date) => date.toLocaleDateString("en-US", {
|
|
550
|
+
weekday: "long",
|
|
551
|
+
month: "long",
|
|
552
|
+
day: "numeric",
|
|
553
|
+
});
|
|
554
|
+
const isCurrentMonth = currentMonth.getMonth() === new Date().getMonth() &&
|
|
555
|
+
currentMonth.getFullYear() === new Date().getFullYear();
|
|
556
|
+
// ────────────────────────────────────────────────
|
|
557
|
+
// API Calls
|
|
558
|
+
// ────────────────────────────────────────────────
|
|
524
559
|
const getAuthToken = async () => {
|
|
525
560
|
var _a;
|
|
526
|
-
if (propAuthToken)
|
|
527
|
-
return propAuthToken;
|
|
528
561
|
const existing = localStorage.getItem("auth_token");
|
|
529
562
|
if (existing)
|
|
530
563
|
return existing;
|
|
531
564
|
try {
|
|
532
|
-
const res = await fetch(`${
|
|
565
|
+
const res = await fetch(`${API_BASE}/v1/user/login`, {
|
|
533
566
|
method: "POST",
|
|
534
567
|
headers: { "Content-Type": "application/json" },
|
|
535
|
-
body: JSON.stringify({
|
|
568
|
+
body: JSON.stringify({
|
|
569
|
+
email: "superadmin1@example.com",
|
|
570
|
+
password: "password",
|
|
571
|
+
}),
|
|
536
572
|
});
|
|
537
573
|
const data = await res.json();
|
|
538
574
|
const token = data.token || data.access_token || ((_a = data.data) === null || _a === void 0 ? void 0 : _a.token);
|
|
539
|
-
if (token)
|
|
575
|
+
if (token) {
|
|
540
576
|
localStorage.setItem("auth_token", token);
|
|
541
|
-
|
|
577
|
+
return token;
|
|
578
|
+
}
|
|
579
|
+
return null;
|
|
542
580
|
}
|
|
543
|
-
catch (
|
|
581
|
+
catch (err) {
|
|
582
|
+
console.error("Auth login failed", err);
|
|
544
583
|
return null;
|
|
545
584
|
}
|
|
546
585
|
};
|
|
547
|
-
/* ============ API ============ */
|
|
548
586
|
const fetchSlots = async (date) => {
|
|
587
|
+
if (!API_BASE) {
|
|
588
|
+
console.warn("API_BASE not provided");
|
|
589
|
+
return;
|
|
590
|
+
}
|
|
549
591
|
setLoading(true);
|
|
550
592
|
const token = await getAuthToken();
|
|
551
593
|
if (!token) {
|
|
552
|
-
|
|
594
|
+
// Swal.fire("Error", "Authentication failed.", "error");
|
|
553
595
|
setLoading(false);
|
|
554
596
|
return;
|
|
555
597
|
}
|
|
556
598
|
const yyyy = date.getFullYear();
|
|
557
599
|
const mm = String(date.getMonth() + 1).padStart(2, "0");
|
|
558
600
|
const dd = String(date.getDate()).padStart(2, "0");
|
|
601
|
+
const dateStr = `${yyyy}-${mm}-${dd}`;
|
|
559
602
|
try {
|
|
560
|
-
const res = await fetch(`${
|
|
603
|
+
const res = await fetch(`${API_BASE}/v1/meeting-schedule/check-schedule/${dateStr}?timezone=${timezone}`, {
|
|
604
|
+
headers: {
|
|
605
|
+
Authorization: `Bearer ${token}`,
|
|
606
|
+
"Content-Type": "application/json",
|
|
607
|
+
},
|
|
608
|
+
});
|
|
561
609
|
const data = await res.json();
|
|
562
610
|
setAvailableSlots(data.slots || []);
|
|
563
611
|
}
|
|
564
|
-
catch (
|
|
565
|
-
|
|
612
|
+
catch (err) {
|
|
613
|
+
console.error("fetchSlots error:", err);
|
|
566
614
|
}
|
|
567
615
|
finally {
|
|
568
616
|
setLoading(false);
|
|
569
617
|
}
|
|
570
618
|
};
|
|
571
|
-
const
|
|
572
|
-
if (!selectedSlot)
|
|
619
|
+
const handleScheduleClick = async () => {
|
|
620
|
+
if (!selectedSlot || !API_BASE)
|
|
573
621
|
return;
|
|
574
622
|
setLoading(true);
|
|
575
623
|
const token = await getAuthToken();
|
|
576
624
|
if (!token) {
|
|
577
|
-
|
|
625
|
+
// Swal.fire("Error", "Authentication failed.", "error");
|
|
578
626
|
setLoading(false);
|
|
579
627
|
return;
|
|
580
628
|
}
|
|
629
|
+
const payload = {
|
|
630
|
+
user_id: defaultUserId,
|
|
631
|
+
availability_id: defaultAvailabilityId,
|
|
632
|
+
visitor: {
|
|
633
|
+
name: formData.name,
|
|
634
|
+
email: formData.email,
|
|
635
|
+
phone: formData.phone,
|
|
636
|
+
timezone,
|
|
637
|
+
},
|
|
638
|
+
start: selectedSlot.start_local,
|
|
639
|
+
end: selectedSlot.end_local,
|
|
640
|
+
message: formData.message,
|
|
641
|
+
};
|
|
581
642
|
try {
|
|
582
|
-
const res = await fetch(`${
|
|
643
|
+
const res = await fetch(`${API_BASE}/v1/meeting-schedule/book-schedule`, {
|
|
583
644
|
method: "POST",
|
|
584
645
|
headers: {
|
|
585
|
-
"Content-Type": "application/json",
|
|
586
646
|
Authorization: `Bearer ${token}`,
|
|
647
|
+
"Content-Type": "application/json",
|
|
587
648
|
},
|
|
588
|
-
body: JSON.stringify(
|
|
589
|
-
user_id: userId,
|
|
590
|
-
availability_id: availabilityId,
|
|
591
|
-
visitor: Object.assign(Object.assign({}, formData), { timezone }),
|
|
592
|
-
start: selectedSlot.start_local,
|
|
593
|
-
end: selectedSlot.end_local,
|
|
594
|
-
}),
|
|
649
|
+
body: JSON.stringify(payload),
|
|
595
650
|
});
|
|
596
|
-
if (
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
651
|
+
if (res.ok) {
|
|
652
|
+
// Swal.fire({
|
|
653
|
+
// icon: "success",
|
|
654
|
+
// title: "Meeting Scheduled!",
|
|
655
|
+
// text: `A confirmation email has been sent to ${formData.email}`,
|
|
656
|
+
// confirmButtonColor: "#F66117",
|
|
657
|
+
// });
|
|
658
|
+
// Reset
|
|
659
|
+
setFormData({ name: "", email: "", phone: "", message: "" });
|
|
660
|
+
setSelectedDate(null);
|
|
661
|
+
setSelectedSlot(null);
|
|
662
|
+
setAvailableSlots([]);
|
|
663
|
+
onBookingSuccess === null || onBookingSuccess === void 0 ? void 0 : onBookingSuccess(payload);
|
|
664
|
+
}
|
|
665
|
+
else {
|
|
666
|
+
throw new Error("Booking failed");
|
|
667
|
+
}
|
|
604
668
|
}
|
|
605
|
-
catch (
|
|
606
|
-
|
|
607
|
-
|
|
669
|
+
catch (err) {
|
|
670
|
+
// Swal.fire("Error", "Failed to book meeting.", "error");
|
|
671
|
+
onBookingError === null || onBookingError === void 0 ? void 0 : onBookingError(err);
|
|
608
672
|
}
|
|
609
673
|
finally {
|
|
610
674
|
setLoading(false);
|
|
611
675
|
}
|
|
612
676
|
};
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
677
|
+
// ────────────────────────────────────────────────
|
|
678
|
+
// Handlers
|
|
679
|
+
// ────────────────────────────────────────────────
|
|
680
|
+
const handleDateClick = (d) => {
|
|
681
|
+
if (isPastDate(d))
|
|
682
|
+
return;
|
|
683
|
+
setSelectedDate(d);
|
|
684
|
+
setSelectedSlot(null);
|
|
685
|
+
fetchSlots(d);
|
|
686
|
+
};
|
|
687
|
+
const handleInputChange = (e) => {
|
|
688
|
+
setFormData((prev) => (Object.assign(Object.assign({}, prev), { [e.target.name]: e.target.value })));
|
|
625
689
|
};
|
|
626
|
-
const
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
690
|
+
const days = getDaysInMonth(currentMonth);
|
|
691
|
+
const isFormValid = formData.name &&
|
|
692
|
+
formData.email &&
|
|
693
|
+
formData.phone &&
|
|
694
|
+
!!selectedSlot &&
|
|
695
|
+
!loading;
|
|
696
|
+
return (jsxRuntimeExports.jsxs("div", { className: "md:px-8 pb-10 bg-gradient-to-r from-[#EFF6FF] via-[#EEF2FF] to-[#FAF5FF] px-2 min-h-screen", children: [jsxRuntimeExports.jsx("div", { className: "h-28 mb-4" }), jsxRuntimeExports.jsxs("div", { className: "max-w-[1280px] mx-auto", children: [jsxRuntimeExports.jsxs("div", { className: "bg-gradient-to-r from-[#F56218] via-[#F54900] to-[#FBAA02] rounded-2xl p-6 mb-5 shadow-lg text-white", children: [jsxRuntimeExports.jsx("div", { className: "text-sm mb-1 bg-[#FFFFFF33] rounded-[34px] w-[170px] px-2 py-1 text-center", children: "Betopia Meeting" }), jsxRuntimeExports.jsx("h1", { className: "text-2xl md:text-3xl xl:text-[36px] font-semibold mb-2", children: "30 Minute Meeting" }), jsxRuntimeExports.jsxs("div", { className: "flex flex-wrap gap-4 text-sm", children: [jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2 text-lg md:text-xl", children: [jsxRuntimeExports.jsx(lucideReact.Clock, { size: 16 }), " ", jsxRuntimeExports.jsx("span", { children: "30 min" })] }), jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2 text-lg md:text-xl", children: [jsxRuntimeExports.jsx(lucideReact.FileText, { size: 16 }), " ", jsxRuntimeExports.jsx("span", { children: "Web conferencing details provided upon confirmation" })] }), jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2 text-lg md:text-xl", children: [jsxRuntimeExports.jsx(lucideReact.Globe, { size: 16 }), " ", jsxRuntimeExports.jsx("span", { children: timezone.replace("_", " ") })] })] })] }), jsxRuntimeExports.jsxs("div", { className: "grid gap-6 xl:grid-cols-[845px_410px]", children: [jsxRuntimeExports.jsxs("div", { className: "grid md:grid-cols-2 gap-6 bg-white rounded-2xl p-6 shadow-md", children: [jsxRuntimeExports.jsxs("div", { children: [jsxRuntimeExports.jsx("h2", { className: "text-2xl md:text-3xl xl:text-[36px] font-semibold mb-2 text-[#1E2939]", children: "Select a Date & Time" }), jsxRuntimeExports.jsx("p", { className: "text-[#6A7282] text-sm md:text-base mb-5", children: "Choose your preferred date and time slot" }), jsxRuntimeExports.jsxs("div", { className: "mb-6", children: [jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between mb-4", children: [jsxRuntimeExports.jsx("button", { onClick: () => {
|
|
697
|
+
if (!isCurrentMonth) {
|
|
698
|
+
setCurrentMonth(new Date(currentMonth.getFullYear(), currentMonth.getMonth() - 1));
|
|
699
|
+
}
|
|
700
|
+
}, disabled: isCurrentMonth, className: `p-2 rounded-lg transition-colors ${isCurrentMonth
|
|
701
|
+
? "text-gray-300 cursor-not-allowed"
|
|
702
|
+
: "hover:bg-gray-100 text-gray-700"}`, children: jsxRuntimeExports.jsx(IoIosArrowBack, {}) }), jsxRuntimeExports.jsx("span", { className: "font-semibold text-[#1E2939]", children: currentMonth.toLocaleDateString("en-US", {
|
|
703
|
+
month: "long",
|
|
704
|
+
year: "numeric",
|
|
705
|
+
}) }), jsxRuntimeExports.jsx("button", { onClick: () => setCurrentMonth(new Date(currentMonth.getFullYear(), currentMonth.getMonth() + 1)), className: "p-2 hover:bg-gray-100 rounded-lg", children: jsxRuntimeExports.jsx(IoIosArrowForward, {}) })] }), jsxRuntimeExports.jsx("div", { className: "grid grid-cols-7 gap-2 mb-2", children: daysOfWeek.map((day) => (jsxRuntimeExports.jsx("div", { className: "text-center text-xs font-semibold text-[#4F39F6] p-2", children: day }, day))) }), jsxRuntimeExports.jsx("div", { className: "grid grid-cols-7 gap-2", children: days.map((day, idx) => {
|
|
706
|
+
const isPast = day ? isPastDate(day) : false;
|
|
707
|
+
return (jsxRuntimeExports.jsx("button", { disabled: !day || isPast, onClick: () => day && handleDateClick(day), className: `p-3 text-center rounded-lg transition-all ${!day ? "invisible" : ""} ${(selectedDate === null || selectedDate === void 0 ? void 0 : selectedDate.toDateString()) === (day === null || day === void 0 ? void 0 : day.toDateString())
|
|
708
|
+
? "bg-gradient-to-b from-[#F66117] to-[#FBAA02] text-white font-bold"
|
|
709
|
+
: isPast
|
|
710
|
+
? "text-gray-300 cursor-not-allowed"
|
|
711
|
+
: "hover:bg-gray-100"}`, children: day === null || day === void 0 ? void 0 : day.getDate() }, idx));
|
|
712
|
+
}) })] })] }), jsxRuntimeExports.jsxs("div", { className: "md:pl-6", children: [jsxRuntimeExports.jsx("h3", { className: "font-semibold mb-3 md:mt-[22%]", children: selectedDate ? formatDateHeader(selectedDate) : "Select a date first" }), loading ? (jsxRuntimeExports.jsx("div", { className: "animate-pulse space-y-2", children: [1, 2, 3, 4, 5].map((i) => (jsxRuntimeExports.jsx("div", { className: "h-12 bg-gray-100 rounded-lg w-full" }, i))) })) : selectedDate ? (jsxRuntimeExports.jsxs("div", { className: "space-y-2 max-h-[400px] overflow-y-auto pr-2", children: [availableSlots.map((slot, i) => {
|
|
713
|
+
const isTooSoon = isSlotTooSoon(slot.start_utc);
|
|
714
|
+
const isDisabled = slot.is_booked || isTooSoon;
|
|
715
|
+
return (jsxRuntimeExports.jsxs("button", { disabled: isDisabled, onClick: () => setSelectedSlot(slot), className: `w-full p-3 rounded-lg text-left transition-all ${selectedSlot === slot
|
|
716
|
+
? "bg-[#F66117] text-white font-semibold"
|
|
717
|
+
: isDisabled
|
|
718
|
+
? "bg-gray-50 text-gray-300 cursor-not-allowed"
|
|
719
|
+
: "bg-gray-50 hover:bg-gray-100"}`, children: [formatTimeTo12Hour(slot.start_local), " -", " ", formatTimeTo12Hour(slot.end_local), isTooSoon && " (Too early)"] }, i));
|
|
720
|
+
}), availableSlots.length === 0 && (jsxRuntimeExports.jsx("p", { className: "text-gray-400 text-center py-10", children: "No slots available for this date." }))] })) : (jsxRuntimeExports.jsxs("div", { className: "text-center py-20 text-gray-400", children: [jsxRuntimeExports.jsx("div", { className: "w-[48px] mx-auto mb-3 opacity-50", children: jsxRuntimeExports.jsx(lucideReact.Calendar, { size: 48 }) }), jsxRuntimeExports.jsx("p", { children: "Please select a date to view available times" })] }))] })] }), jsxRuntimeExports.jsxs("div", { className: "bg-white rounded-2xl p-6 shadow-md h-fit", children: [jsxRuntimeExports.jsx("h2", { className: "text-xl font-semibold mb-6", children: "Enter Details" }), selectedDate && selectedSlot && (jsxRuntimeExports.jsxs("div", { className: "bg-gradient-to-r from-[#EEF2FF] to-[#FAF5FF] border border-blue-200 rounded-lg p-4 mb-[22px]", children: [jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2 text-[#432DD7] mb-1", children: [jsxRuntimeExports.jsx(lucideReact.Calendar, { size: 16 }), " ", jsxRuntimeExports.jsx("span", { className: "font-semibold", children: formatDateHeader(selectedDate) })] }), jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2 text-[#8200DB]", children: [jsxRuntimeExports.jsx(lucideReact.Clock, { size: 16 }), " ", jsxRuntimeExports.jsxs("span", { className: "font-semibold", children: [formatTimeTo12Hour(selectedSlot.start_local), " -", " ", formatTimeTo12Hour(selectedSlot.end_local)] })] })] })), jsxRuntimeExports.jsxs("div", { className: "space-y-2", children: [jsxRuntimeExports.jsxs("div", { children: [jsxRuntimeExports.jsxs("label", { className: "flex items-center gap-2 text-sm font-medium mb-2", children: [jsxRuntimeExports.jsxs("svg", { width: "16", height: "16", viewBox: "0 0 16 16", fill: "none", xmlns: "http://www.w3.org/2000/svg", children: [jsxRuntimeExports.jsx("path", { d: "M12.6693 14V12.6667C12.6693 11.9594 12.3883 11.2811 11.8882 10.781C11.3881 10.281 10.7098 10 10.0026 10H6.0026C5.29536 10 4.61708 10.281 4.11699 10.781C3.61689 11.2811 3.33594 11.9594 3.33594 12.6667V14", stroke: "#4F39F6", strokeWidth: "1.33333", strokeLinecap: "round", strokeLinejoin: "round" }), jsxRuntimeExports.jsx("path", { d: "M8.0026 7.33333C9.47536 7.33333 10.6693 6.13943 10.6693 4.66667C10.6693 3.19391 9.47536 2 8.0026 2C6.52984 2 5.33594 3.19391 5.33594 4.66667C5.33594 6.13943 6.52984 7.33333 8.0026 7.33333Z", stroke: "#4F39F6", strokeWidth: "1.33333", strokeLinecap: "round", strokeLinejoin: "round" })] }), "Name *"] }), jsxRuntimeExports.jsx("input", { type: "text", name: "name", value: formData.name, onChange: handleInputChange, placeholder: "John Doe", className: "w-full p-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-1 focus:ring-[#F66117]" })] }), jsxRuntimeExports.jsxs("div", { children: [jsxRuntimeExports.jsxs("label", { className: "flex items-center gap-2 text-sm font-medium mb-2", children: [jsxRuntimeExports.jsxs("svg", { width: "16", height: "16", viewBox: "0 0 16 16", fill: "none", xmlns: "http://www.w3.org/2000/svg", children: [jsxRuntimeExports.jsx("path", { d: "M13.3359 2.66797H2.66927C1.93289 2.66797 1.33594 3.26492 1.33594 4.0013V12.0013C1.33594 12.7377 1.93289 13.3346 2.66927 13.3346H13.3359C14.0723 13.3346 14.6693 12.7377 14.6693 12.0013V4.0013C14.6693 3.26492 14.0723 2.66797 13.3359 2.66797Z", stroke: "#4F39F6", strokeWidth: "1.33333", strokeLinecap: "round", strokeLinejoin: "round" }), jsxRuntimeExports.jsx("path", { d: "M14.6693 4.66797L8.68927 8.46797C8.48345 8.59692 8.24548 8.66531 8.0026 8.66531C7.75973 8.66531 7.52176 8.59692 7.31594 8.46797L1.33594 4.66797", stroke: "#4F39F6", strokeWidth: "1.33333", strokeLinecap: "round", strokeLinejoin: "round" })] }), "Email *"] }), jsxRuntimeExports.jsx("input", { type: "email", name: "email", value: formData.email, onChange: handleInputChange, placeholder: "john@example.com", className: "w-full p-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-1 focus:ring-[#F66117]" })] }), jsxRuntimeExports.jsxs("div", { children: [jsxRuntimeExports.jsxs("label", { className: "flex items-center gap-2 text-sm font-medium mb-2", children: [jsxRuntimeExports.jsx("svg", { width: "15", height: "15", viewBox: "0 0 15 15", fill: "none", xmlns: "http://www.w3.org/2000/svg", children: jsxRuntimeExports.jsx("path", { d: "M13.9228 10.6147V12.6147C13.9236 12.8004 13.8855 12.9841 13.8111 13.1543C13.7368 13.3244 13.6277 13.4771 13.4909 13.6026C13.354 13.7281 13.1925 13.8237 13.0166 13.8832C12.8408 13.9427 12.6544 13.9647 12.4695 13.948C10.418 13.7251 8.44747 13.0241 6.71614 11.9014C5.10536 10.8778 3.7397 9.51215 2.71614 7.90137C1.58946 6.16217 0.888302 4.18203 0.669474 2.12137C0.652814 1.93701 0.674724 1.75121 0.733807 1.57578C0.792891 1.40036 0.887854 1.23916 1.01265 1.10245C1.13745 0.965735 1.28934 0.856506 1.45867 0.781715C1.62799 0.706923 1.81103 0.668208 1.99614 0.668033H3.99614C4.31968 0.664849 4.63334 0.779419 4.87865 0.990389C5.12396 1.20136 5.28419 1.49433 5.32947 1.8147C5.41389 2.45474 5.57044 3.08318 5.79614 3.68803C5.88584 3.92665 5.90525 4.18598 5.85208 4.43529C5.79891 4.6846 5.67538 4.91344 5.49614 5.0947L4.64947 5.94137C5.59851 7.6104 6.98044 8.99233 8.64947 9.94137L9.49614 9.0947C9.6774 8.91546 9.90624 8.79193 10.1556 8.73876C10.4049 8.68559 10.6642 8.705 10.9028 8.7947C11.5077 9.0204 12.1361 9.17695 12.7761 9.26137C13.1 9.30705 13.3957 9.47017 13.6072 9.7197C13.8186 9.96922 13.9309 10.2878 13.9228 10.6147Z", stroke: "#4F39F6", strokeWidth: "1.33333", strokeLinecap: "round", strokeLinejoin: "round" }) }), "Phone *"] }), jsxRuntimeExports.jsx("input", { type: "tel", name: "phone", value: formData.phone, onChange: handleInputChange, placeholder: "+1 (555) 000-0000", className: "w-full p-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-1 focus:ring-[#F66117]" })] }), jsxRuntimeExports.jsxs("div", { children: [jsxRuntimeExports.jsxs("label", { className: "flex items-center gap-2 text-sm font-medium mb-2", children: [jsxRuntimeExports.jsx("svg", { width: "16", height: "16", viewBox: "0 0 16 16", fill: "none", xmlns: "http://www.w3.org/2000/svg", children: jsxRuntimeExports.jsx("path", { d: "M14 10C14 10.3536 13.8595 10.6928 13.6095 10.9428C13.3594 11.1929 13.0203 11.3333 12.6667 11.3333H4.66667L2 14V3.33333C2 2.97971 2.14048 2.64057 2.39052 2.39052C2.64057 2.14048 2.97971 2 3.33333 2H12.6667C13.0203 2 13.3594 2.14048 13.6095 2.39052C13.8595 2.64057 14 2.97971 14 3.33333V10Z", stroke: "#4F39F6", strokeWidth: "1.33333", strokeLinecap: "round", strokeLinejoin: "round" }) }), "Additional Notes"] }), jsxRuntimeExports.jsx("textarea", { name: "message", value: formData.message, onChange: handleInputChange, rows: 2, placeholder: "Please share anything that will help prepare for our meeting...", className: "w-full p-3 border border-gray-300 rounded-lg focus:outline-none focus:ring-1 focus:ring-[#F66117]" })] }), jsxRuntimeExports.jsx("button", { type: "button", onClick: handleScheduleClick, disabled: !isFormValid, className: `w-full p-4 rounded-lg font-semibold transition-all ${isFormValid
|
|
721
|
+
? "bg-gradient-to-r from-[#F56116] to-[#FBA702] text-white hover:opacity-90"
|
|
722
|
+
: "bg-[#E5E7EB] text-[#99A1AF] cursor-not-allowed"}`, children: loading ? "Processing..." : "Schedule Event" }), jsxRuntimeExports.jsx("p", { className: "text-xs text-gray-600 text-center", children: "By proceeding, you confirm that you have read and agree to" }), jsxRuntimeExports.jsxs("p", { className: "text-xs text-gray-600 text-center", children: [jsxRuntimeExports.jsx("a", { href: "/terms-conditions", className: "text-[14px] text-[#4F39F6]", children: "Terms of Use" }), " ", "and", " ", jsxRuntimeExports.jsx("a", { href: "/cookie-policy", className: "text-[14px] text-[#4F39F6]", children: "Cookie policy" })] })] })] })] })] })] }));
|
|
641
723
|
};
|
|
642
724
|
|
|
643
725
|
exports.MeetingScheduler = MeetingScheduler;
|