@hanzo/booker 8.3.0 → 8.3.2
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/README.md +6 -6
- package/dist/cjs/Booker.js +23 -0
- package/dist/cjs/Booker.js.map +1 -0
- package/dist/cjs/BookingForm.js +32 -0
- package/dist/cjs/BookingForm.js.map +1 -0
- package/dist/cjs/CalendarEmbed.js +20 -0
- package/dist/cjs/CalendarEmbed.js.map +1 -0
- package/dist/cjs/Confirmation.js +34 -0
- package/dist/cjs/Confirmation.js.map +1 -0
- package/dist/cjs/EventHeader.js +31 -0
- package/dist/cjs/EventHeader.js.map +1 -0
- package/dist/cjs/MonthCalendar.js +24 -0
- package/dist/cjs/MonthCalendar.js.map +1 -0
- package/dist/cjs/TimeSlots.js +21 -0
- package/dist/cjs/TimeSlots.js.map +1 -0
- package/dist/cjs/client.js +113 -0
- package/dist/cjs/client.js.map +1 -0
- package/dist/cjs/hooks.js +121 -0
- package/dist/cjs/hooks.js.map +1 -0
- package/dist/cjs/index.js +55 -0
- package/dist/cjs/index.js.map +1 -0
- package/dist/cjs/package.json +1 -0
- package/dist/cjs/time.js +129 -0
- package/dist/cjs/time.js.map +1 -0
- package/dist/cjs/useBooker.js +135 -0
- package/dist/cjs/useBooker.js.map +1 -0
- package/dist/esm/Booker.js +20 -0
- package/dist/esm/Booker.js.map +1 -0
- package/dist/esm/BookingForm.js +29 -0
- package/dist/esm/BookingForm.js.map +1 -0
- package/dist/esm/CalendarEmbed.js +17 -0
- package/dist/esm/CalendarEmbed.js.map +1 -0
- package/dist/esm/Confirmation.js +31 -0
- package/dist/esm/Confirmation.js.map +1 -0
- package/dist/esm/EventHeader.js +28 -0
- package/dist/esm/EventHeader.js.map +1 -0
- package/dist/esm/MonthCalendar.js +21 -0
- package/dist/esm/MonthCalendar.js.map +1 -0
- package/dist/esm/TimeSlots.js +18 -0
- package/dist/esm/TimeSlots.js.map +1 -0
- package/dist/esm/client.js +104 -0
- package/dist/esm/client.js.map +1 -0
- package/dist/esm/hooks.js +115 -0
- package/dist/esm/hooks.js.map +1 -0
- package/dist/esm/index.js +18 -13
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/time.js +113 -0
- package/dist/esm/time.js.map +1 -0
- package/dist/esm/useBooker.js +132 -0
- package/dist/esm/useBooker.js.map +1 -0
- package/package.json +28 -28
- package/src/Booker.tsx +7 -7
- package/src/BookingForm.tsx +2 -2
- package/src/CalendarEmbed.tsx +7 -7
- package/src/Confirmation.tsx +4 -4
- package/src/EventHeader.tsx +1 -1
- package/src/MonthCalendar.tsx +1 -1
- package/src/TimeSlots.tsx +2 -2
- package/src/hooks.ts +1 -1
- package/src/index.ts +11 -11
- package/src/useBooker.ts +9 -4
- package/types/Booker.d.ts +2 -2
- package/types/Booker.d.ts.map +1 -1
- package/types/BookingForm.d.ts +2 -2
- package/types/BookingForm.d.ts.map +1 -1
- package/types/CalendarEmbed.d.ts +2 -2
- package/types/CalendarEmbed.d.ts.map +1 -1
- package/types/Confirmation.d.ts +2 -2
- package/types/Confirmation.d.ts.map +1 -1
- package/types/EventHeader.d.ts +2 -2
- package/types/EventHeader.d.ts.map +1 -1
- package/types/MonthCalendar.d.ts +1 -1
- package/types/MonthCalendar.d.ts.map +1 -1
- package/types/TimeSlots.d.ts +2 -2
- package/types/TimeSlots.d.ts.map +1 -1
- package/types/client.d.ts.map +1 -1
- package/types/hooks.d.ts +1 -1
- package/types/hooks.d.ts.map +1 -1
- package/types/index.d.ts +11 -11
- package/types/index.d.ts.map +1 -1
- package/types/useBooker.d.ts +3 -3
- package/types/useBooker.d.ts.map +1 -1
- package/dist/cjs/Booker.cjs +0 -153
- package/dist/cjs/Booker.native.js +0 -158
- package/dist/cjs/Booker.native.js.map +0 -1
- package/dist/cjs/BookingForm.cjs +0 -197
- package/dist/cjs/BookingForm.native.js +0 -203
- package/dist/cjs/BookingForm.native.js.map +0 -1
- package/dist/cjs/CalendarEmbed.cjs +0 -121
- package/dist/cjs/CalendarEmbed.native.js +0 -125
- package/dist/cjs/CalendarEmbed.native.js.map +0 -1
- package/dist/cjs/Confirmation.cjs +0 -177
- package/dist/cjs/Confirmation.native.js +0 -185
- package/dist/cjs/Confirmation.native.js.map +0 -1
- package/dist/cjs/EventHeader.cjs +0 -112
- package/dist/cjs/EventHeader.native.js +0 -118
- package/dist/cjs/EventHeader.native.js.map +0 -1
- package/dist/cjs/MonthCalendar.cjs +0 -177
- package/dist/cjs/MonthCalendar.native.js +0 -191
- package/dist/cjs/MonthCalendar.native.js.map +0 -1
- package/dist/cjs/TimeSlots.cjs +0 -119
- package/dist/cjs/TimeSlots.native.js +0 -126
- package/dist/cjs/TimeSlots.native.js.map +0 -1
- package/dist/cjs/client.cjs +0 -136
- package/dist/cjs/client.native.js +0 -267
- package/dist/cjs/client.native.js.map +0 -1
- package/dist/cjs/hooks.cjs +0 -193
- package/dist/cjs/hooks.native.js +0 -221
- package/dist/cjs/hooks.native.js.map +0 -1
- package/dist/cjs/index.cjs +0 -71
- package/dist/cjs/index.native.js +0 -74
- package/dist/cjs/index.native.js.map +0 -1
- package/dist/cjs/time.cjs +0 -145
- package/dist/cjs/time.native.js +0 -150
- package/dist/cjs/time.native.js.map +0 -1
- package/dist/cjs/useBooker.cjs +0 -151
- package/dist/cjs/useBooker.native.js +0 -173
- package/dist/cjs/useBooker.native.js.map +0 -1
- package/dist/esm/Booker.mjs +0 -128
- package/dist/esm/Booker.mjs.map +0 -1
- package/dist/esm/Booker.native.js +0 -130
- package/dist/esm/Booker.native.js.map +0 -1
- package/dist/esm/BookingForm.mjs +0 -172
- package/dist/esm/BookingForm.mjs.map +0 -1
- package/dist/esm/BookingForm.native.js +0 -175
- package/dist/esm/BookingForm.native.js.map +0 -1
- package/dist/esm/CalendarEmbed.mjs +0 -96
- package/dist/esm/CalendarEmbed.mjs.map +0 -1
- package/dist/esm/CalendarEmbed.native.js +0 -97
- package/dist/esm/CalendarEmbed.native.js.map +0 -1
- package/dist/esm/Confirmation.mjs +0 -152
- package/dist/esm/Confirmation.mjs.map +0 -1
- package/dist/esm/Confirmation.native.js +0 -157
- package/dist/esm/Confirmation.native.js.map +0 -1
- package/dist/esm/EventHeader.mjs +0 -87
- package/dist/esm/EventHeader.mjs.map +0 -1
- package/dist/esm/EventHeader.native.js +0 -90
- package/dist/esm/EventHeader.native.js.map +0 -1
- package/dist/esm/MonthCalendar.mjs +0 -152
- package/dist/esm/MonthCalendar.mjs.map +0 -1
- package/dist/esm/MonthCalendar.native.js +0 -163
- package/dist/esm/MonthCalendar.native.js.map +0 -1
- package/dist/esm/TimeSlots.mjs +0 -94
- package/dist/esm/TimeSlots.mjs.map +0 -1
- package/dist/esm/TimeSlots.native.js +0 -98
- package/dist/esm/TimeSlots.native.js.map +0 -1
- package/dist/esm/client.mjs +0 -104
- package/dist/esm/client.mjs.map +0 -1
- package/dist/esm/client.native.js +0 -232
- package/dist/esm/client.native.js.map +0 -1
- package/dist/esm/hooks.mjs +0 -165
- package/dist/esm/hooks.mjs.map +0 -1
- package/dist/esm/hooks.native.js +0 -190
- package/dist/esm/hooks.native.js.map +0 -1
- package/dist/esm/index.mjs +0 -13
- package/dist/esm/index.mjs.map +0 -1
- package/dist/esm/index.native.js +0 -13
- package/dist/esm/index.native.js.map +0 -1
- package/dist/esm/time.mjs +0 -107
- package/dist/esm/time.mjs.map +0 -1
- package/dist/esm/time.native.js +0 -109
- package/dist/esm/time.native.js.map +0 -1
- package/dist/esm/useBooker.mjs +0 -126
- package/dist/esm/useBooker.mjs.map +0 -1
- package/dist/esm/useBooker.native.js +0 -145
- package/dist/esm/useBooker.native.js.map +0 -1
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// @hanzo/calendar — universal (web + native) booking UI on the Hanzo Calendar
|
|
3
|
+
// backend, built with hanzogui primitives.
|
|
4
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
5
|
+
exports.isBeforeToday = exports.sameMonth = exports.addMonths = exports.startOfMonth = exports.dateFromKey = exports.formatBookingWhen = exports.formatSlotTime = exports.formatDayLong = exports.formatMonthLabel = exports.weekdayLabels = exports.monthRange = exports.monthMatrix = exports.ymd = exports.visitorTimeZone = exports.cancelBooking = exports.fetchBooking = exports.createBooking = exports.fetchSlots = exports.fetchEventType = exports.CalendarError = exports.CAL_API_VERSION = exports.DEFAULT_API_URL = exports.useBooking = exports.useCreateBooking = exports.useAvailableSlots = exports.useEventType = exports.useBooker = exports.BookingForm = exports.TimeSlots = exports.MonthCalendar = exports.EventHeader = exports.Confirmation = exports.CalendarEmbed = exports.Booker = void 0;
|
|
6
|
+
var Booker_tsx_1 = require("./Booker.js");
|
|
7
|
+
Object.defineProperty(exports, "Booker", { enumerable: true, get: function () { return Booker_tsx_1.Booker; } });
|
|
8
|
+
var CalendarEmbed_tsx_1 = require("./CalendarEmbed.js");
|
|
9
|
+
Object.defineProperty(exports, "CalendarEmbed", { enumerable: true, get: function () { return CalendarEmbed_tsx_1.CalendarEmbed; } });
|
|
10
|
+
var Confirmation_tsx_1 = require("./Confirmation.js");
|
|
11
|
+
Object.defineProperty(exports, "Confirmation", { enumerable: true, get: function () { return Confirmation_tsx_1.Confirmation; } });
|
|
12
|
+
// Composable sub-views (use these to build a custom flow).
|
|
13
|
+
var EventHeader_tsx_1 = require("./EventHeader.js");
|
|
14
|
+
Object.defineProperty(exports, "EventHeader", { enumerable: true, get: function () { return EventHeader_tsx_1.EventHeader; } });
|
|
15
|
+
var MonthCalendar_tsx_1 = require("./MonthCalendar.js");
|
|
16
|
+
Object.defineProperty(exports, "MonthCalendar", { enumerable: true, get: function () { return MonthCalendar_tsx_1.MonthCalendar; } });
|
|
17
|
+
var TimeSlots_tsx_1 = require("./TimeSlots.js");
|
|
18
|
+
Object.defineProperty(exports, "TimeSlots", { enumerable: true, get: function () { return TimeSlots_tsx_1.TimeSlots; } });
|
|
19
|
+
var BookingForm_tsx_1 = require("./BookingForm.js");
|
|
20
|
+
Object.defineProperty(exports, "BookingForm", { enumerable: true, get: function () { return BookingForm_tsx_1.BookingForm; } });
|
|
21
|
+
// Orchestration hook + data hooks.
|
|
22
|
+
var useBooker_ts_1 = require("./useBooker.js");
|
|
23
|
+
Object.defineProperty(exports, "useBooker", { enumerable: true, get: function () { return useBooker_ts_1.useBooker; } });
|
|
24
|
+
var hooks_ts_1 = require("./hooks.js");
|
|
25
|
+
Object.defineProperty(exports, "useEventType", { enumerable: true, get: function () { return hooks_ts_1.useEventType; } });
|
|
26
|
+
Object.defineProperty(exports, "useAvailableSlots", { enumerable: true, get: function () { return hooks_ts_1.useAvailableSlots; } });
|
|
27
|
+
Object.defineProperty(exports, "useCreateBooking", { enumerable: true, get: function () { return hooks_ts_1.useCreateBooking; } });
|
|
28
|
+
Object.defineProperty(exports, "useBooking", { enumerable: true, get: function () { return hooks_ts_1.useBooking; } });
|
|
29
|
+
// Data plane.
|
|
30
|
+
var client_ts_1 = require("./client.js");
|
|
31
|
+
Object.defineProperty(exports, "DEFAULT_API_URL", { enumerable: true, get: function () { return client_ts_1.DEFAULT_API_URL; } });
|
|
32
|
+
Object.defineProperty(exports, "CAL_API_VERSION", { enumerable: true, get: function () { return client_ts_1.CAL_API_VERSION; } });
|
|
33
|
+
Object.defineProperty(exports, "CalendarError", { enumerable: true, get: function () { return client_ts_1.CalendarError; } });
|
|
34
|
+
Object.defineProperty(exports, "fetchEventType", { enumerable: true, get: function () { return client_ts_1.fetchEventType; } });
|
|
35
|
+
Object.defineProperty(exports, "fetchSlots", { enumerable: true, get: function () { return client_ts_1.fetchSlots; } });
|
|
36
|
+
Object.defineProperty(exports, "createBooking", { enumerable: true, get: function () { return client_ts_1.createBooking; } });
|
|
37
|
+
Object.defineProperty(exports, "fetchBooking", { enumerable: true, get: function () { return client_ts_1.fetchBooking; } });
|
|
38
|
+
Object.defineProperty(exports, "cancelBooking", { enumerable: true, get: function () { return client_ts_1.cancelBooking; } });
|
|
39
|
+
// Time plane (Intl/Date helpers).
|
|
40
|
+
var time_ts_1 = require("./time.js");
|
|
41
|
+
Object.defineProperty(exports, "visitorTimeZone", { enumerable: true, get: function () { return time_ts_1.visitorTimeZone; } });
|
|
42
|
+
Object.defineProperty(exports, "ymd", { enumerable: true, get: function () { return time_ts_1.ymd; } });
|
|
43
|
+
Object.defineProperty(exports, "monthMatrix", { enumerable: true, get: function () { return time_ts_1.monthMatrix; } });
|
|
44
|
+
Object.defineProperty(exports, "monthRange", { enumerable: true, get: function () { return time_ts_1.monthRange; } });
|
|
45
|
+
Object.defineProperty(exports, "weekdayLabels", { enumerable: true, get: function () { return time_ts_1.weekdayLabels; } });
|
|
46
|
+
Object.defineProperty(exports, "formatMonthLabel", { enumerable: true, get: function () { return time_ts_1.formatMonthLabel; } });
|
|
47
|
+
Object.defineProperty(exports, "formatDayLong", { enumerable: true, get: function () { return time_ts_1.formatDayLong; } });
|
|
48
|
+
Object.defineProperty(exports, "formatSlotTime", { enumerable: true, get: function () { return time_ts_1.formatSlotTime; } });
|
|
49
|
+
Object.defineProperty(exports, "formatBookingWhen", { enumerable: true, get: function () { return time_ts_1.formatBookingWhen; } });
|
|
50
|
+
Object.defineProperty(exports, "dateFromKey", { enumerable: true, get: function () { return time_ts_1.dateFromKey; } });
|
|
51
|
+
Object.defineProperty(exports, "startOfMonth", { enumerable: true, get: function () { return time_ts_1.startOfMonth; } });
|
|
52
|
+
Object.defineProperty(exports, "addMonths", { enumerable: true, get: function () { return time_ts_1.addMonths; } });
|
|
53
|
+
Object.defineProperty(exports, "sameMonth", { enumerable: true, get: function () { return time_ts_1.sameMonth; } });
|
|
54
|
+
Object.defineProperty(exports, "isBeforeToday", { enumerable: true, get: function () { return time_ts_1.isBeforeToday; } });
|
|
55
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":";AAAA,8EAA8E;AAC9E,2CAA2C;;;AAE3C,0CAAuD;AAA9C,oGAAA,MAAM,OAAA;AACf,wDAA4E;AAAnE,kHAAA,aAAa,OAAA;AACtB,sDAAyE;AAAhE,gHAAA,YAAY,OAAA;AAErB,2DAA2D;AAC3D,oDAAsE;AAA7D,8GAAA,WAAW,OAAA;AACpB,wDAA4E;AAAnE,kHAAA,aAAa,OAAA;AACtB,gDAAgE;AAAvD,0GAAA,SAAS,OAAA;AAClB,oDAAsE;AAA7D,8GAAA,WAAW,OAAA;AAEpB,mCAAmC;AACnC,+CAKuB;AAJrB,yGAAA,SAAS,OAAA;AAKX,uCAUmB;AATjB,wGAAA,YAAY,OAAA;AACZ,6GAAA,iBAAiB,OAAA;AACjB,4GAAA,gBAAgB,OAAA;AAChB,sGAAA,UAAU,OAAA;AAQZ,cAAc;AACd,yCAmBoB;AAlBlB,4GAAA,eAAe,OAAA;AACf,4GAAA,eAAe,OAAA;AACf,0GAAA,aAAa,OAAA;AACb,2GAAA,cAAc,OAAA;AACd,uGAAA,UAAU,OAAA;AACV,0GAAA,aAAa,OAAA;AACb,yGAAA,YAAY,OAAA;AACZ,0GAAA,aAAa,OAAA;AAaf,kCAAkC;AAClC,qCAgBkB;AAfhB,0GAAA,eAAe,OAAA;AACf,8FAAA,GAAG,OAAA;AACH,sGAAA,WAAW,OAAA;AACX,qGAAA,UAAU,OAAA;AACV,wGAAA,aAAa,OAAA;AACb,2GAAA,gBAAgB,OAAA;AAChB,wGAAA,aAAa,OAAA;AACb,yGAAA,cAAc,OAAA;AACd,4GAAA,iBAAiB,OAAA;AACjB,sGAAA,WAAW,OAAA;AACX,uGAAA,YAAY,OAAA;AACZ,oGAAA,SAAS,OAAA;AACT,oGAAA,SAAS,OAAA;AACT,wGAAA,aAAa,OAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{ "type": "commonjs" }
|
package/dist/cjs/time.js
ADDED
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// Time plane — pure date/timezone helpers via Intl + Date only.
|
|
3
|
+
// No external date library. Web and React Native safe.
|
|
4
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
5
|
+
exports.visitorTimeZone = visitorTimeZone;
|
|
6
|
+
exports.ymd = ymd;
|
|
7
|
+
exports.startOfMonth = startOfMonth;
|
|
8
|
+
exports.addMonths = addMonths;
|
|
9
|
+
exports.sameMonth = sameMonth;
|
|
10
|
+
exports.isBeforeToday = isBeforeToday;
|
|
11
|
+
exports.monthMatrix = monthMatrix;
|
|
12
|
+
exports.monthRange = monthRange;
|
|
13
|
+
exports.weekdayLabels = weekdayLabels;
|
|
14
|
+
exports.formatMonthLabel = formatMonthLabel;
|
|
15
|
+
exports.formatDayLong = formatDayLong;
|
|
16
|
+
exports.formatSlotTime = formatSlotTime;
|
|
17
|
+
exports.formatBookingWhen = formatBookingWhen;
|
|
18
|
+
exports.dateFromKey = dateFromKey;
|
|
19
|
+
/** The visitor's IANA time zone, e.g. "America/New_York". */
|
|
20
|
+
function visitorTimeZone() {
|
|
21
|
+
try {
|
|
22
|
+
return Intl.DateTimeFormat().resolvedOptions().timeZone || 'UTC';
|
|
23
|
+
}
|
|
24
|
+
catch {
|
|
25
|
+
return 'UTC';
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
/** Calendar date "YYYY-MM-DD" from a Date's local components. */
|
|
29
|
+
function ymd(d) {
|
|
30
|
+
const y = d.getFullYear();
|
|
31
|
+
const m = String(d.getMonth() + 1).padStart(2, '0');
|
|
32
|
+
const day = String(d.getDate()).padStart(2, '0');
|
|
33
|
+
return `${y}-${m}-${day}`;
|
|
34
|
+
}
|
|
35
|
+
function startOfMonth(d) {
|
|
36
|
+
return new Date(d.getFullYear(), d.getMonth(), 1);
|
|
37
|
+
}
|
|
38
|
+
function addMonths(d, n) {
|
|
39
|
+
return new Date(d.getFullYear(), d.getMonth() + n, 1);
|
|
40
|
+
}
|
|
41
|
+
function sameMonth(a, b) {
|
|
42
|
+
return a.getFullYear() === b.getFullYear() && a.getMonth() === b.getMonth();
|
|
43
|
+
}
|
|
44
|
+
/** True if the day key is strictly before today (lexicographic works on YYYY-MM-DD). */
|
|
45
|
+
function isBeforeToday(key) {
|
|
46
|
+
return key < ymd(new Date());
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* A 6×7 grid of days covering the month of `viewDate`, including the leading
|
|
50
|
+
* and trailing days needed to fill whole weeks.
|
|
51
|
+
*/
|
|
52
|
+
function monthMatrix(viewDate, weekStartsOn = 0) {
|
|
53
|
+
const year = viewDate.getFullYear();
|
|
54
|
+
const month = viewDate.getMonth();
|
|
55
|
+
const firstWeekday = new Date(year, month, 1).getDay();
|
|
56
|
+
const startOffset = (firstWeekday - weekStartsOn + 7) % 7;
|
|
57
|
+
const cells = [];
|
|
58
|
+
for (let i = 0; i < 42; i++) {
|
|
59
|
+
const date = new Date(year, month, 1 - startOffset + i);
|
|
60
|
+
cells.push({ date, key: ymd(date), inMonth: date.getMonth() === month });
|
|
61
|
+
}
|
|
62
|
+
return cells;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* ISO start/end covering the visible month, clamped so the start is never in
|
|
66
|
+
* the past (the backend rejects past ranges anyway).
|
|
67
|
+
*/
|
|
68
|
+
function monthRange(viewDate) {
|
|
69
|
+
const year = viewDate.getFullYear();
|
|
70
|
+
const month = viewDate.getMonth();
|
|
71
|
+
const startOfView = new Date(year, month, 1, 0, 0, 0, 0);
|
|
72
|
+
const now = new Date();
|
|
73
|
+
const start = startOfView.getTime() > now.getTime() ? startOfView : now;
|
|
74
|
+
const endOfView = new Date(year, month + 1, 0, 23, 59, 59, 999);
|
|
75
|
+
return { startTime: start.toISOString(), endTime: endOfView.toISOString() };
|
|
76
|
+
}
|
|
77
|
+
/** Short weekday headers ordered from `weekStartsOn` (0 = Sunday). */
|
|
78
|
+
function weekdayLabels(weekStartsOn = 0) {
|
|
79
|
+
const fmt = new Intl.DateTimeFormat(undefined, { weekday: 'short' });
|
|
80
|
+
const out = [];
|
|
81
|
+
for (let i = 0; i < 7; i++) {
|
|
82
|
+
// 2023-01-01 is a Sunday; offset from there.
|
|
83
|
+
const d = new Date(2023, 0, 1 + ((i + weekStartsOn) % 7));
|
|
84
|
+
out.push(fmt.format(d));
|
|
85
|
+
}
|
|
86
|
+
return out;
|
|
87
|
+
}
|
|
88
|
+
function formatMonthLabel(d) {
|
|
89
|
+
return new Intl.DateTimeFormat(undefined, { month: 'long', year: 'numeric' }).format(d);
|
|
90
|
+
}
|
|
91
|
+
function formatDayLong(d) {
|
|
92
|
+
return new Intl.DateTimeFormat(undefined, {
|
|
93
|
+
weekday: 'long',
|
|
94
|
+
month: 'long',
|
|
95
|
+
day: 'numeric',
|
|
96
|
+
}).format(d);
|
|
97
|
+
}
|
|
98
|
+
/** Slot time in the visitor's zone, e.g. "9:00 AM". */
|
|
99
|
+
function formatSlotTime(iso, timeZone) {
|
|
100
|
+
return new Intl.DateTimeFormat(undefined, {
|
|
101
|
+
hour: 'numeric',
|
|
102
|
+
minute: '2-digit',
|
|
103
|
+
timeZone,
|
|
104
|
+
}).format(new Date(iso));
|
|
105
|
+
}
|
|
106
|
+
/** Full human "when" for a confirmation, e.g. "Monday, July 27, 2026 at 9:00 AM PDT". */
|
|
107
|
+
function formatBookingWhen(iso, timeZone) {
|
|
108
|
+
const at = new Date(iso);
|
|
109
|
+
const date = new Intl.DateTimeFormat(undefined, {
|
|
110
|
+
weekday: 'long',
|
|
111
|
+
month: 'long',
|
|
112
|
+
day: 'numeric',
|
|
113
|
+
year: 'numeric',
|
|
114
|
+
timeZone,
|
|
115
|
+
}).format(at);
|
|
116
|
+
const time = new Intl.DateTimeFormat(undefined, {
|
|
117
|
+
hour: 'numeric',
|
|
118
|
+
minute: '2-digit',
|
|
119
|
+
timeZoneName: 'short',
|
|
120
|
+
timeZone,
|
|
121
|
+
}).format(at);
|
|
122
|
+
return `${date} at ${time}`;
|
|
123
|
+
}
|
|
124
|
+
/** A parsed local Date from a "YYYY-MM-DD" key (noon avoids DST edge slips). */
|
|
125
|
+
function dateFromKey(key) {
|
|
126
|
+
const [y, m, d] = key.split('-').map(Number);
|
|
127
|
+
return new Date(y, (m ?? 1) - 1, d ?? 1, 12, 0, 0, 0);
|
|
128
|
+
}
|
|
129
|
+
//# sourceMappingURL=time.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"time.js","sourceRoot":"","sources":["../../src/time.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// Orchestration hook — the one booking state machine both shells consume.
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
exports.useBooker = useBooker;
|
|
5
|
+
const react_1 = require("react");
|
|
6
|
+
const client_ts_1 = require("./client.js");
|
|
7
|
+
const hooks_ts_1 = require("./hooks.js");
|
|
8
|
+
const time_ts_1 = require("./time.js");
|
|
9
|
+
function useBooker(opts) {
|
|
10
|
+
const api = opts.apiUrl ?? client_ts_1.DEFAULT_API_URL;
|
|
11
|
+
const timeZone = opts.timeZone ?? (0, time_ts_1.visitorTimeZone)();
|
|
12
|
+
const weekStartsOn = opts.weekStartsOn ?? 0;
|
|
13
|
+
const event = (0, hooks_ts_1.useEventType)(api, opts.eventSlug, opts.host);
|
|
14
|
+
const [viewDate, setViewDate] = (0, react_1.useState)(() => (0, time_ts_1.startOfMonth)(new Date()));
|
|
15
|
+
const { startTime, endTime } = (0, react_1.useMemo)(() => (0, time_ts_1.monthRange)(viewDate), [viewDate]);
|
|
16
|
+
const slots = (0, hooks_ts_1.useAvailableSlots)(api, {
|
|
17
|
+
eventTypeSlug: opts.eventSlug,
|
|
18
|
+
username: opts.host,
|
|
19
|
+
startTime,
|
|
20
|
+
endTime,
|
|
21
|
+
timeZone,
|
|
22
|
+
enabled: !!event.data,
|
|
23
|
+
});
|
|
24
|
+
const [selectedDay, setSelectedDay] = (0, react_1.useState)(null);
|
|
25
|
+
const [selectedSlot, setSelectedSlot] = (0, react_1.useState)(null);
|
|
26
|
+
const [phase, setPhase] = (0, react_1.useState)('pick');
|
|
27
|
+
const [booking, setBooking] = (0, react_1.useState)(null);
|
|
28
|
+
const create = (0, hooks_ts_1.useCreateBooking)(api);
|
|
29
|
+
const availableKeys = (0, react_1.useMemo)(() => {
|
|
30
|
+
const map = slots.data ?? {};
|
|
31
|
+
return new Set(Object.keys(map).filter((k) => (map[k]?.length ?? 0) > 0));
|
|
32
|
+
}, [slots.data]);
|
|
33
|
+
const daySlots = (0, react_1.useMemo)(() => {
|
|
34
|
+
if (!selectedDay)
|
|
35
|
+
return [];
|
|
36
|
+
return slots.data?.[selectedDay] ?? [];
|
|
37
|
+
}, [slots.data, selectedDay]);
|
|
38
|
+
// Optionally auto-select the soonest available day once slots arrive.
|
|
39
|
+
(0, react_1.useEffect)(() => {
|
|
40
|
+
if (!opts.autoSelectFirst)
|
|
41
|
+
return;
|
|
42
|
+
if (selectedDay && availableKeys.has(selectedDay))
|
|
43
|
+
return;
|
|
44
|
+
const first = [...availableKeys].sort()[0];
|
|
45
|
+
if (first) {
|
|
46
|
+
setSelectedDay(first);
|
|
47
|
+
setSelectedSlot(null);
|
|
48
|
+
}
|
|
49
|
+
}, [opts.autoSelectFirst, availableKeys, selectedDay]);
|
|
50
|
+
const now = (0, time_ts_1.startOfMonth)(new Date());
|
|
51
|
+
const atFirstMonth = viewDate.getFullYear() === now.getFullYear() && viewDate.getMonth() === now.getMonth();
|
|
52
|
+
const goPrevMonth = () => {
|
|
53
|
+
if (atFirstMonth)
|
|
54
|
+
return;
|
|
55
|
+
setViewDate((d) => (0, time_ts_1.addMonths)(d, -1));
|
|
56
|
+
setSelectedDay(null);
|
|
57
|
+
setSelectedSlot(null);
|
|
58
|
+
};
|
|
59
|
+
const goNextMonth = () => {
|
|
60
|
+
setViewDate((d) => (0, time_ts_1.addMonths)(d, 1));
|
|
61
|
+
setSelectedDay(null);
|
|
62
|
+
setSelectedSlot(null);
|
|
63
|
+
};
|
|
64
|
+
const selectDay = (key) => {
|
|
65
|
+
setSelectedDay(key);
|
|
66
|
+
setSelectedSlot(null);
|
|
67
|
+
};
|
|
68
|
+
const selectSlot = (iso) => {
|
|
69
|
+
setSelectedSlot(iso);
|
|
70
|
+
setPhase('form');
|
|
71
|
+
create.reset();
|
|
72
|
+
};
|
|
73
|
+
const back = () => {
|
|
74
|
+
setPhase('pick');
|
|
75
|
+
setSelectedSlot(null);
|
|
76
|
+
create.reset();
|
|
77
|
+
};
|
|
78
|
+
const reset = () => {
|
|
79
|
+
setBooking(null);
|
|
80
|
+
setSelectedSlot(null);
|
|
81
|
+
setSelectedDay(null);
|
|
82
|
+
setPhase('pick');
|
|
83
|
+
create.reset();
|
|
84
|
+
slots.refetch();
|
|
85
|
+
};
|
|
86
|
+
const submit = async (responses) => {
|
|
87
|
+
if (!selectedSlot)
|
|
88
|
+
return;
|
|
89
|
+
const result = await create.submit({
|
|
90
|
+
eventTypeSlug: opts.eventSlug,
|
|
91
|
+
username: opts.host,
|
|
92
|
+
start: selectedSlot,
|
|
93
|
+
timeZone,
|
|
94
|
+
responses,
|
|
95
|
+
});
|
|
96
|
+
if (result.ok) {
|
|
97
|
+
setBooking(result.booking);
|
|
98
|
+
setPhase('done');
|
|
99
|
+
opts.onBooked?.(result.booking);
|
|
100
|
+
}
|
|
101
|
+
else if (result.conflict) {
|
|
102
|
+
// Slot was just taken — refresh availability and return to picking.
|
|
103
|
+
slots.refetch();
|
|
104
|
+
setSelectedSlot(null);
|
|
105
|
+
setPhase('pick');
|
|
106
|
+
}
|
|
107
|
+
// non-conflict errors stay visible in the form via `error`.
|
|
108
|
+
};
|
|
109
|
+
return {
|
|
110
|
+
api,
|
|
111
|
+
timeZone,
|
|
112
|
+
weekStartsOn,
|
|
113
|
+
event,
|
|
114
|
+
slots,
|
|
115
|
+
viewDate,
|
|
116
|
+
availableKeys,
|
|
117
|
+
selectedDay,
|
|
118
|
+
daySlots,
|
|
119
|
+
selectedSlot,
|
|
120
|
+
phase,
|
|
121
|
+
booking,
|
|
122
|
+
submitting: create.submitting,
|
|
123
|
+
error: create.error,
|
|
124
|
+
conflict: create.conflict,
|
|
125
|
+
goPrevMonth,
|
|
126
|
+
goNextMonth,
|
|
127
|
+
atFirstMonth,
|
|
128
|
+
selectDay,
|
|
129
|
+
selectSlot,
|
|
130
|
+
submit,
|
|
131
|
+
back,
|
|
132
|
+
reset,
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
//# sourceMappingURL=useBooker.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useBooker.js","sourceRoot":"","sources":["../../src/useBooker.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { SizableText, Spinner, XStack, YStack } from '@hanzo/gui';
|
|
3
|
+
import { BookingForm } from './BookingForm.js';
|
|
4
|
+
import { Confirmation } from './Confirmation.js';
|
|
5
|
+
import { EventHeader } from './EventHeader.js';
|
|
6
|
+
import { MonthCalendar } from './MonthCalendar.js';
|
|
7
|
+
import { TimeSlots } from './TimeSlots.js';
|
|
8
|
+
import { useBooker } from './useBooker.js';
|
|
9
|
+
/** Universal scheduling flow: event → month → times → details → confirmation. */
|
|
10
|
+
export function Booker(props) {
|
|
11
|
+
const m = useBooker(props);
|
|
12
|
+
return (_jsx(YStack, { backgroundColor: "$background", borderColor: "$borderColor", borderWidth: 1, borderRadius: "$6", padding: "$4", gap: "$4", width: "100%", maxWidth: 860, alignSelf: "center", children: m.event.loading ? (_jsxs(StatePanel, { children: [_jsx(Spinner, { size: "large", color: "$color9" }), _jsx(SizableText, { size: "$3", color: "$color10", children: "Loading\u2026" })] })) : m.event.error || !m.event.data ? (_jsxs(StatePanel, { children: [_jsx(SizableText, { size: "$5", fontWeight: "600", color: "$color12", children: "Couldn't load this event" }), _jsx(SizableText, { size: "$3", color: "$color10", textAlign: "center", children: m.event.error ?? 'The event type was not found.' })] })) : m.phase === 'done' && m.booking ? (_jsx(Confirmation, { booking: m.booking, timeZone: m.timeZone, onDone: m.reset })) : (_jsxs(YStack, { gap: "$4", children: [_jsx(EventHeader, { event: m.event.data, host: props.host, timeZone: m.timeZone, compact: m.phase === 'form' }), m.phase === 'form' && m.selectedSlot ? (_jsx(BookingForm, { slotIso: m.selectedSlot, timeZone: m.timeZone, eventLength: m.event.data.length, submitting: m.submitting, error: m.error, onSubmit: m.submit, onBack: m.back })) : (_jsxs(_Fragment, { children: [m.conflict ? _jsx(JustTakenBanner, {}) : null, m.slots.error ? (_jsxs(SizableText, { size: "$2", color: "$red10", children: ["Couldn't load availability: ", m.slots.error] })) : null, _jsxs(XStack, { gap: "$5", flexDirection: "column", $sm: { flexDirection: 'row' }, alignItems: "flex-start", children: [_jsx(MonthCalendar, { viewDate: m.viewDate, availableKeys: m.availableKeys, selectedDay: m.selectedDay, onSelectDay: m.selectDay, onPrev: m.goPrevMonth, onNext: m.goNextMonth, atFirstMonth: m.atFirstMonth, weekStartsOn: m.weekStartsOn, loading: m.slots.loading }), _jsx(TimeSlots, { dayKey: m.selectedDay, slots: m.daySlots, timeZone: m.timeZone, onPick: m.selectSlot, selectedIso: m.selectedSlot, loading: m.slots.loading && !m.selectedDay })] }), m.availableKeys.size === 0 && !m.slots.loading && !m.slots.error ? (_jsx(SizableText, { size: "$3", color: "$color10", textAlign: "center", children: "No availability this month \u2014 try the next month." })) : null] }))] })) }));
|
|
13
|
+
}
|
|
14
|
+
function StatePanel({ children }) {
|
|
15
|
+
return (_jsx(YStack, { alignItems: "center", justifyContent: "center", gap: "$3", padding: "$8", minHeight: 220, children: children }));
|
|
16
|
+
}
|
|
17
|
+
function JustTakenBanner() {
|
|
18
|
+
return (_jsx(YStack, { backgroundColor: "$yellow3", borderColor: "$yellow6", borderWidth: 1, borderRadius: "$4", padding: "$2.5", children: _jsx(SizableText, { size: "$2", color: "$yellow11", children: "That time was just taken. We refreshed the calendar \u2014 please pick another." }) }));
|
|
19
|
+
}
|
|
20
|
+
//# sourceMappingURL=Booker.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Booker.js","sourceRoot":"","sources":["../../src/Booker.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useState } from 'react';
|
|
3
|
+
import { Button, Input, SizableText, TextArea, XStack, YStack } from '@hanzo/gui';
|
|
4
|
+
import { formatBookingWhen } from './time.js';
|
|
5
|
+
const EMAIL_RE = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
|
6
|
+
/** Attendee details form for the chosen slot. */
|
|
7
|
+
export function BookingForm({ slotIso, timeZone, eventLength, submitting, error, onSubmit, onBack, }) {
|
|
8
|
+
const [name, setName] = useState('');
|
|
9
|
+
const [email, setEmail] = useState('');
|
|
10
|
+
const [notes, setNotes] = useState('');
|
|
11
|
+
const [touched, setTouched] = useState(false);
|
|
12
|
+
const nameValid = name.trim().length > 0;
|
|
13
|
+
const emailValid = EMAIL_RE.test(email.trim());
|
|
14
|
+
const valid = nameValid && emailValid;
|
|
15
|
+
const submit = () => {
|
|
16
|
+
setTouched(true);
|
|
17
|
+
if (!valid || submitting)
|
|
18
|
+
return;
|
|
19
|
+
onSubmit({ name: name.trim(), email: email.trim(), notes: notes.trim() || undefined });
|
|
20
|
+
};
|
|
21
|
+
return (_jsxs(YStack, { gap: "$3", flex: 1, minWidth: 240, children: [_jsxs(YStack, { gap: "$1", children: [_jsxs(XStack, { alignItems: "center", gap: "$2", children: [_jsx(BackLink, { onPress: onBack }), _jsx(SizableText, { size: "$5", fontWeight: "700", color: "$color12", children: "Enter details" })] }), _jsxs(SizableText, { size: "$3", color: "$color11", children: [formatBookingWhen(slotIso, timeZone), " \u00B7 ", eventLength, " min"] })] }), _jsx(Field, { label: "Name", required: true, invalid: touched && !nameValid, hint: "Please enter your name", children: _jsx(Input, { value: name, onChangeText: setName, placeholder: "Ada Lovelace", autoComplete: "name", size: "$4" }) }), _jsx(Field, { label: "Email", required: true, invalid: touched && !emailValid, hint: "Please enter a valid email", children: _jsx(Input, { value: email, onChangeText: setEmail, placeholder: "ada@example.com", keyboardType: "email-address", autoCapitalize: "none", autoComplete: "email", size: "$4" }) }), _jsx(Field, { label: "Notes", hint: "Optional", children: _jsx(TextArea, { value: notes, onChangeText: setNotes, placeholder: "Anything that would help prepare?", numberOfLines: 3, size: "$4" }) }), error ? (_jsx(YStack, { backgroundColor: "$red3", borderColor: "$red6", borderWidth: 1, borderRadius: "$4", padding: "$2.5", children: _jsx(SizableText, { size: "$2", color: "$red11", children: error }) })) : null, _jsxs(XStack, { gap: "$2", justifyContent: "flex-end", marginTop: "$1", children: [_jsx(Button, { size: "$4", chromeless: true, onPress: onBack, disabled: submitting, children: "Back" }), _jsx(Button, { size: "$4", theme: "blue", onPress: submit, disabled: submitting || (touched && !valid), opacity: submitting ? 0.7 : 1, children: submitting ? 'Booking…' : 'Confirm booking' })] })] }));
|
|
22
|
+
}
|
|
23
|
+
function Field({ label, required, invalid, hint, children, }) {
|
|
24
|
+
return (_jsxs(YStack, { gap: "$1.5", children: [_jsxs(SizableText, { size: "$2", color: "$color11", fontWeight: "600", children: [label, required ? _jsx(SizableText, { color: "$red10", children: " *" }) : null] }), children, invalid && hint ? (_jsx(SizableText, { size: "$1", color: "$red10", children: hint })) : null] }));
|
|
25
|
+
}
|
|
26
|
+
function BackLink({ onPress }) {
|
|
27
|
+
return (_jsx(YStack, { width: 30, height: 30, alignItems: "center", justifyContent: "center", borderRadius: "$4", cursor: "pointer", hoverStyle: { backgroundColor: '$color4' }, pressStyle: { backgroundColor: '$color6' }, onPress: onPress, "aria-label": "Back", role: "button", children: _jsx(SizableText, { size: "$6", color: "$color11", children: '‹' }) }));
|
|
28
|
+
}
|
|
29
|
+
//# sourceMappingURL=BookingForm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"BookingForm.js","sourceRoot":"","sources":["../../src/BookingForm.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { SizableText, Spinner, YStack } from '@hanzo/gui';
|
|
3
|
+
import { BookingForm } from './BookingForm.js';
|
|
4
|
+
import { Confirmation } from './Confirmation.js';
|
|
5
|
+
import { EventHeader } from './EventHeader.js';
|
|
6
|
+
import { TimeSlots } from './TimeSlots.js';
|
|
7
|
+
import { formatMonthLabel } from './time.js';
|
|
8
|
+
import { useBooker } from './useBooker.js';
|
|
9
|
+
/**
|
|
10
|
+
* Compact booking card for a marketing hero — soonest availability inline,
|
|
11
|
+
* no month grid. Same state machine as <Booker>.
|
|
12
|
+
*/
|
|
13
|
+
export function CalendarEmbed(props) {
|
|
14
|
+
const m = useBooker({ ...props, autoSelectFirst: true });
|
|
15
|
+
return (_jsx(YStack, { backgroundColor: "$background", borderColor: "$borderColor", borderWidth: 1, borderRadius: "$6", padding: "$4", gap: "$3", width: "100%", maxWidth: 420, children: m.event.loading ? (_jsx(YStack, { alignItems: "center", justifyContent: "center", gap: "$2", padding: "$6", minHeight: 160, children: _jsx(Spinner, { size: "large", color: "$color9" }) })) : m.event.error || !m.event.data ? (_jsxs(YStack, { alignItems: "center", justifyContent: "center", padding: "$5", minHeight: 140, gap: "$1", children: [_jsx(SizableText, { size: "$4", fontWeight: "600", color: "$color12", children: "Unavailable" }), _jsx(SizableText, { size: "$2", color: "$color10", textAlign: "center", children: m.event.error ?? 'Event not found.' })] })) : m.phase === 'done' && m.booking ? (_jsx(Confirmation, { booking: m.booking, timeZone: m.timeZone, onDone: m.reset })) : m.phase === 'form' && m.selectedSlot ? (_jsx(BookingForm, { slotIso: m.selectedSlot, timeZone: m.timeZone, eventLength: m.event.data.length, submitting: m.submitting, error: m.error, onSubmit: m.submit, onBack: m.back })) : (_jsxs(_Fragment, { children: [_jsx(EventHeader, { event: m.event.data, host: props.host, timeZone: m.timeZone, compact: true }), m.conflict ? (_jsx(SizableText, { size: "$1", color: "$yellow11", children: "That time was just taken \u2014 pick another." })) : null, m.slots.loading && m.availableKeys.size === 0 ? (_jsx(YStack, { alignItems: "center", padding: "$4", children: _jsx(Spinner, { color: "$color9" }) })) : m.availableKeys.size === 0 ? (_jsxs(SizableText, { size: "$2", color: "$color10", children: ["No availability in ", formatMonthLabel(m.viewDate), "."] })) : (_jsx(TimeSlots, { dayKey: m.selectedDay, slots: m.daySlots, timeZone: m.timeZone, onPick: m.selectSlot, selectedIso: m.selectedSlot, loading: m.slots.loading, compact: true, maxHeight: 220 }))] })) }));
|
|
16
|
+
}
|
|
17
|
+
//# sourceMappingURL=CalendarEmbed.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CalendarEmbed.js","sourceRoot":"","sources":["../../src/CalendarEmbed.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,WAAW,EAAE,OAAO,EAAU,MAAM,EAAE,MAAM,YAAY,CAAA;AAEjE,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAmB,CAAA;AAC/C,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAoB,CAAA;AACjD,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAmB,CAAA;AAC/C,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAiB,CAAA;AAC3C,OAAO,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAA;AAC5C,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAA;AAW1C;;;GAGG;AACH,MAAM,UAAU,aAAa,CAAC,KAAyB;IACrD,MAAM,CAAC,GAAG,SAAS,CAAC,EAAE,GAAG,KAAK,EAAE,eAAe,EAAE,IAAI,EAAE,CAAC,CAAA;IAExD,OAAO,CACL,KAAC,MAAM,IACL,eAAe,EAAC,aAAa,EAC7B,WAAW,EAAC,cAAc,EAC1B,WAAW,EAAE,CAAC,EACd,YAAY,EAAC,IAAI,EACjB,OAAO,EAAC,IAAI,EACZ,GAAG,EAAC,IAAI,EACR,KAAK,EAAC,MAAM,EACZ,QAAQ,EAAE,GAAG,YAEZ,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CACjB,KAAC,MAAM,IACL,UAAU,EAAC,QAAQ,EACnB,cAAc,EAAC,QAAQ,EACvB,GAAG,EAAC,IAAI,EACR,OAAO,EAAC,IAAI,EACZ,SAAS,EAAE,GAAG,YAEd,KAAC,OAAO,IAAC,IAAI,EAAC,OAAO,EAAC,KAAK,EAAC,SAAS,GAAG,GACjC,CACV,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CACnC,MAAC,MAAM,IACL,UAAU,EAAC,QAAQ,EACnB,cAAc,EAAC,QAAQ,EACvB,OAAO,EAAC,IAAI,EACZ,SAAS,EAAE,GAAG,EACd,GAAG,EAAC,IAAI,aAER,KAAC,WAAW,IAAC,IAAI,EAAC,IAAI,EAAC,UAAU,EAAC,KAAK,EAAC,KAAK,EAAC,UAAU,4BAE1C,EACd,KAAC,WAAW,IAAC,IAAI,EAAC,IAAI,EAAC,KAAK,EAAC,UAAU,EAAC,SAAS,EAAC,QAAQ,YACvD,CAAC,CAAC,KAAK,CAAC,KAAK,IAAI,kBAAkB,GACxB,IACP,CACV,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,KAAK,MAAM,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CACpC,KAAC,YAAY,IAAC,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE,QAAQ,EAAE,CAAC,CAAC,QAAQ,EAAE,MAAM,EAAE,CAAC,CAAC,KAAK,GAAI,CAC5E,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,KAAK,MAAM,IAAI,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CACzC,KAAC,WAAW,IACV,OAAO,EAAE,CAAC,CAAC,YAAY,EACvB,QAAQ,EAAE,CAAC,CAAC,QAAQ,EACpB,WAAW,EAAE,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAChC,UAAU,EAAE,CAAC,CAAC,UAAU,EACxB,KAAK,EAAE,CAAC,CAAC,KAAK,EACd,QAAQ,EAAE,CAAC,CAAC,MAAM,EAClB,MAAM,EAAE,CAAC,CAAC,IAAI,GACd,CACH,CAAC,CAAC,CAAC,CACF,8BACE,KAAC,WAAW,IACV,KAAK,EAAE,CAAC,CAAC,KAAK,CAAC,IAAI,EACnB,IAAI,EAAE,KAAK,CAAC,IAAI,EAChB,QAAQ,EAAE,CAAC,CAAC,QAAQ,EACpB,OAAO,SACP,EACD,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CACZ,KAAC,WAAW,IAAC,IAAI,EAAC,IAAI,EAAC,KAAK,EAAC,WAAW,8DAE1B,CACf,CAAC,CAAC,CAAC,IAAI,EACP,CAAC,CAAC,KAAK,CAAC,OAAO,IAAI,CAAC,CAAC,aAAa,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,CAC/C,KAAC,MAAM,IAAC,UAAU,EAAC,QAAQ,EAAC,OAAO,EAAC,IAAI,YACtC,KAAC,OAAO,IAAC,KAAK,EAAC,SAAS,GAAG,GACpB,CACV,CAAC,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,CAC/B,MAAC,WAAW,IAAC,IAAI,EAAC,IAAI,EAAC,KAAK,EAAC,UAAU,oCACjB,gBAAgB,CAAC,CAAC,CAAC,QAAQ,CAAC,SACpC,CACf,CAAC,CAAC,CAAC,CACF,KAAC,SAAS,IACR,MAAM,EAAE,CAAC,CAAC,WAAW,EACrB,KAAK,EAAE,CAAC,CAAC,QAAQ,EACjB,QAAQ,EAAE,CAAC,CAAC,QAAQ,EACpB,MAAM,EAAE,CAAC,CAAC,UAAU,EACpB,WAAW,EAAE,CAAC,CAAC,YAAY,EAC3B,OAAO,EAAE,CAAC,CAAC,KAAK,CAAC,OAAO,EACxB,OAAO,QACP,SAAS,EAAE,GAAG,GACd,CACH,IACA,CACJ,GACM,CACV,CAAA;AACH,CAAC"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Button, Paragraph, Separator, SizableText, Spinner, XStack, YStack, } from '@hanzo/gui';
|
|
3
|
+
import { DEFAULT_API_URL } from './client.js';
|
|
4
|
+
import { useBooking } from './hooks.js';
|
|
5
|
+
import { visitorTimeZone } from './time.js';
|
|
6
|
+
import { formatBookingWhen } from './time.js';
|
|
7
|
+
/** Booking confirmation card. Accepts a booking object or fetches by uid. */
|
|
8
|
+
export function Confirmation({ booking, uid, apiUrl, timeZone, onDone, }) {
|
|
9
|
+
const api = apiUrl ?? DEFAULT_API_URL;
|
|
10
|
+
const tz = timeZone ?? visitorTimeZone();
|
|
11
|
+
const fetched = useBooking(api, booking ? undefined : uid);
|
|
12
|
+
const data = booking ?? fetched.data;
|
|
13
|
+
if (!data && fetched.loading) {
|
|
14
|
+
return (_jsxs(YStack, { alignItems: "center", justifyContent: "center", padding: "$6", gap: "$3", minHeight: 200, children: [_jsx(Spinner, { size: "large", color: "$color9" }), _jsx(SizableText, { size: "$3", color: "$color10", children: "Loading your booking\u2026" })] }));
|
|
15
|
+
}
|
|
16
|
+
if (!data) {
|
|
17
|
+
return (_jsxs(YStack, { alignItems: "center", justifyContent: "center", padding: "$6", gap: "$2", minHeight: 200, children: [_jsx(SizableText, { size: "$4", fontWeight: "600", color: "$color12", children: "Booking not found" }), _jsx(SizableText, { size: "$3", color: "$color10", textAlign: "center", children: fetched.error ?? 'We could not load this booking.' })] }));
|
|
18
|
+
}
|
|
19
|
+
const attendee = data.attendees?.[0];
|
|
20
|
+
const location = data.location;
|
|
21
|
+
return (_jsxs(YStack, { gap: "$3", padding: "$1", alignItems: "center", children: [_jsx(YStack, { width: 52, height: 52, borderRadius: 9999, backgroundColor: "$green4", alignItems: "center", justifyContent: "center", children: _jsx(SizableText, { size: "$8", color: "$green11", children: '✓' }) }), _jsxs(YStack, { gap: "$1", alignItems: "center", children: [_jsx(SizableText, { size: "$7", fontWeight: "700", color: "$color12", textAlign: "center", children: "You're booked" }), _jsx(SizableText, { size: "$4", color: "$color11", textAlign: "center", children: data.title })] }), _jsx(Separator, { width: "100%" }), _jsxs(YStack, { gap: "$2.5", width: "100%", maxWidth: 420, children: [_jsx(Row, { label: "When", value: formatBookingWhen(data.start, tz) }), location ? _jsx(Row, { label: "Where", value: location }) : null, attendee?.email ? _jsx(Row, { label: "Guest", value: attendee.email }) : null, _jsx(Row, { label: "Status", value: titleCase(data.status) }), _jsx(Row, { label: "Reference", value: data.uid })] }), _jsxs(Paragraph, { size: "$2", color: "$color10", textAlign: "center", marginTop: "$1", children: ["A calendar invite is on its way to ", attendee?.email ?? 'your inbox', "."] }), onDone ? (_jsx(Button, { size: "$3", chromeless: true, onPress: onDone, marginTop: "$1", children: "Book another time" })) : null] }));
|
|
22
|
+
}
|
|
23
|
+
function Row({ label, value }) {
|
|
24
|
+
return (_jsxs(XStack, { justifyContent: "space-between", gap: "$3", alignItems: "flex-start", children: [_jsx(SizableText, { size: "$3", color: "$color10", children: label }), _jsx(SizableText, { size: "$3", color: "$color12", fontWeight: "500", textAlign: "right", flexShrink: 1, children: value })] }));
|
|
25
|
+
}
|
|
26
|
+
function titleCase(s) {
|
|
27
|
+
if (!s)
|
|
28
|
+
return '';
|
|
29
|
+
return s.charAt(0).toUpperCase() + s.slice(1).toLowerCase();
|
|
30
|
+
}
|
|
31
|
+
//# sourceMappingURL=Confirmation.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Confirmation.js","sourceRoot":"","sources":["../../src/Confirmation.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Paragraph, SizableText, XStack, YStack } from '@hanzo/gui';
|
|
3
|
+
/** Event identity: host, title, duration, timezone, description. */
|
|
4
|
+
export function EventHeader({ event, host, timeZone, compact }) {
|
|
5
|
+
const name = event.profile?.name || host;
|
|
6
|
+
const initial = (name?.[0] || 'H').toUpperCase();
|
|
7
|
+
return (_jsxs(YStack, { gap: "$2", children: [_jsxs(XStack, { alignItems: "center", gap: "$2.5", children: [_jsx(YStack, { width: 28, height: 28, borderRadius: 9999, backgroundColor: "$color5", alignItems: "center", justifyContent: "center", children: _jsx(SizableText, { size: "$2", color: "$color11", fontWeight: "600", children: initial }) }), _jsx(SizableText, { size: "$3", color: "$color10", children: name })] }), _jsx(SizableText, { size: compact ? '$6' : '$8', fontWeight: "700", color: "$color12", children: event.title }), _jsxs(XStack, { gap: "$2", alignItems: "center", flexWrap: "wrap", children: [_jsxs(Pill, { children: [event.length, " min"] }), _jsx(Pill, { children: shortZone(timeZone) }), event.locations?.[0]?.type ? (_jsx(Pill, { children: prettyLocation(event.locations[0].type) })) : null] }), !compact && event.description ? (_jsx(Paragraph, { size: "$3", color: "$color11", marginTop: "$1", children: event.description })) : null] }));
|
|
8
|
+
}
|
|
9
|
+
function Pill({ children }) {
|
|
10
|
+
return (_jsx(XStack, { backgroundColor: "$color3", paddingHorizontal: "$2.5", paddingVertical: "$1", borderRadius: "$10", alignItems: "center", children: _jsx(SizableText, { size: "$1", color: "$color11", children: children }) }));
|
|
11
|
+
}
|
|
12
|
+
function shortZone(tz) {
|
|
13
|
+
const city = tz.split('/').pop() || tz;
|
|
14
|
+
return city.replace(/_/g, ' ');
|
|
15
|
+
}
|
|
16
|
+
function prettyLocation(type) {
|
|
17
|
+
const t = type.toLowerCase();
|
|
18
|
+
if (t.includes('google'))
|
|
19
|
+
return 'Google Meet';
|
|
20
|
+
if (t.includes('zoom'))
|
|
21
|
+
return 'Zoom';
|
|
22
|
+
if (t.includes('phone'))
|
|
23
|
+
return 'Phone';
|
|
24
|
+
if (t.includes('person'))
|
|
25
|
+
return 'In person';
|
|
26
|
+
return 'Video call';
|
|
27
|
+
}
|
|
28
|
+
//# sourceMappingURL=EventHeader.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"EventHeader.js","sourceRoot":"","sources":["../../src/EventHeader.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { SizableText, Spinner, XStack, YStack } from '@hanzo/gui';
|
|
3
|
+
import { formatMonthLabel, isBeforeToday, monthMatrix, weekdayLabels, } from './time.js';
|
|
4
|
+
/** Navigable month grid; days with availability are selectable. */
|
|
5
|
+
export function MonthCalendar({ viewDate, availableKeys, selectedDay, onSelectDay, onPrev, onNext, atFirstMonth, weekStartsOn = 0, loading, }) {
|
|
6
|
+
const cells = monthMatrix(viewDate, weekStartsOn);
|
|
7
|
+
const rows = [];
|
|
8
|
+
for (let i = 0; i < cells.length; i += 7)
|
|
9
|
+
rows.push(cells.slice(i, i + 7));
|
|
10
|
+
const labels = weekdayLabels(weekStartsOn);
|
|
11
|
+
return (_jsxs(YStack, { gap: "$2", flex: 1, minWidth: 260, children: [_jsxs(XStack, { alignItems: "center", justifyContent: "space-between", paddingVertical: "$1", children: [_jsx(NavArrow, { label: "Previous month", disabled: atFirstMonth, onPress: onPrev, children: '‹' }), _jsxs(XStack, { alignItems: "center", gap: "$2", children: [_jsx(SizableText, { size: "$5", fontWeight: "700", color: "$color12", children: formatMonthLabel(viewDate) }), loading ? _jsx(Spinner, { size: "small", color: "$color9" }) : null] }), _jsx(NavArrow, { label: "Next month", onPress: onNext, children: '›' })] }), _jsx(XStack, { children: labels.map((l) => (_jsx(YStack, { flexBasis: 0, flexGrow: 1, alignItems: "center", paddingVertical: "$1", children: _jsx(SizableText, { size: "$1", color: "$color10", children: l }) }, l))) }), _jsx(YStack, { gap: "$1.5", children: rows.map((row, r) => (_jsx(XStack, { gap: "$1.5", children: row.map((cell) => (_jsx(DayCell, { cell: cell, available: availableKeys.has(cell.key), past: isBeforeToday(cell.key), selected: selectedDay === cell.key, onSelectDay: onSelectDay }, cell.key))) }, r))) })] }));
|
|
12
|
+
}
|
|
13
|
+
function DayCell({ cell, available, past, selected, onSelectDay, }) {
|
|
14
|
+
const selectable = cell.inMonth && available && !past;
|
|
15
|
+
const dayNum = cell.date.getDate();
|
|
16
|
+
return (_jsxs(YStack, { flexBasis: 0, flexGrow: 1, aspectRatio: 1, alignItems: "center", justifyContent: "center", borderRadius: "$4", borderWidth: 1, borderColor: selected ? '$color12' : selectable ? '$color5' : 'transparent', backgroundColor: selected ? '$color12' : selectable ? '$color2' : 'transparent', opacity: cell.inMonth ? 1 : 0, cursor: selectable ? 'pointer' : 'default', hoverStyle: selectable && !selected ? { backgroundColor: '$color4' } : undefined, pressStyle: selectable ? { backgroundColor: '$color6' } : undefined, onPress: selectable ? () => onSelectDay(cell.key) : undefined, "aria-label": selectable ? `Select ${cell.key}` : undefined, role: selectable ? 'button' : undefined, children: [_jsx(SizableText, { size: "$3", fontWeight: selectable ? '600' : '400', color: selected ? '$color1' : selectable ? '$color12' : '$color8', children: dayNum }), selectable && !selected ? (_jsx(YStack, { position: "absolute", bottom: 4, width: 4, height: 4, borderRadius: 9999, backgroundColor: "$color10" })) : null] }));
|
|
17
|
+
}
|
|
18
|
+
function NavArrow({ children, onPress, disabled, label, }) {
|
|
19
|
+
return (_jsx(YStack, { width: 34, height: 34, alignItems: "center", justifyContent: "center", borderRadius: "$4", opacity: disabled ? 0.35 : 1, cursor: disabled ? 'default' : 'pointer', hoverStyle: disabled ? undefined : { backgroundColor: '$color4' }, pressStyle: disabled ? undefined : { backgroundColor: '$color6' }, onPress: disabled ? undefined : onPress, "aria-label": label, role: "button", children: _jsx(SizableText, { size: "$6", color: "$color11", children: children }) }));
|
|
20
|
+
}
|
|
21
|
+
//# sourceMappingURL=MonthCalendar.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MonthCalendar.js","sourceRoot":"","sources":["../../src/MonthCalendar.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Button, ScrollView, SizableText, XStack, YStack } from '@hanzo/gui';
|
|
3
|
+
import { dateFromKey, formatDayLong, formatSlotTime } from './time.js';
|
|
4
|
+
/** Time-slot pills for the selected day, shown in the visitor's time zone. */
|
|
5
|
+
export function TimeSlots({ dayKey, slots, timeZone, onPick, selectedIso, loading, compact, maxHeight = 360, }) {
|
|
6
|
+
if (!dayKey) {
|
|
7
|
+
return (_jsx(Centered, { children: _jsx(SizableText, { size: "$3", color: "$color10", textAlign: "center", children: "Select a day to see available times." }) }));
|
|
8
|
+
}
|
|
9
|
+
const heading = formatDayLong(dateFromKey(dayKey));
|
|
10
|
+
return (_jsxs(YStack, { gap: "$2", flex: 1, minWidth: 200, children: [_jsx(SizableText, { size: "$4", fontWeight: "600", color: "$color12", children: heading }), loading ? (_jsx(Centered, { children: _jsx(SizableText, { size: "$2", color: "$color10", children: "Loading times\u2026" }) })) : slots.length === 0 ? (_jsx(Centered, { children: _jsx(SizableText, { size: "$3", color: "$color10", textAlign: "center", children: "No times left on this day. Try another." }) })) : (_jsx(ScrollView, { maxHeight: maxHeight, showsVerticalScrollIndicator: false, children: _jsx(XStack, { flexWrap: "wrap", gap: "$2", flexDirection: compact ? 'row' : 'column', children: slots.map((slot) => {
|
|
11
|
+
const active = selectedIso === slot.time;
|
|
12
|
+
return (_jsx(Button, { size: "$3", theme: active ? 'blue' : undefined, chromeless: !active, borderWidth: 1, borderColor: active ? '$color8' : '$color6', backgroundColor: active ? undefined : '$color1', hoverStyle: { borderColor: '$color10' }, pressStyle: { backgroundColor: '$color4' }, onPress: () => onPick(slot.time), "aria-label": `Book ${formatSlotTime(slot.time, timeZone)}`, ...(compact ? {} : { alignSelf: 'stretch' }), children: formatSlotTime(slot.time, timeZone) }, slot.time));
|
|
13
|
+
}) }) }))] }));
|
|
14
|
+
}
|
|
15
|
+
function Centered({ children }) {
|
|
16
|
+
return (_jsx(YStack, { flex: 1, minHeight: 120, alignItems: "center", justifyContent: "center", padding: "$4", children: children }));
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=TimeSlots.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TimeSlots.js","sourceRoot":"","sources":["../../src/TimeSlots.tsx"],"names":[],"mappings":"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"}
|