@agent-native/scheduling 0.1.10 → 0.1.12
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/actions/accept-team-invite.d.ts +5 -1
- package/dist/actions/accept-team-invite.d.ts.map +1 -1
- package/dist/actions/add-booking-attendee.d.ts +8 -1
- package/dist/actions/add-booking-attendee.d.ts.map +1 -1
- package/dist/actions/add-booking-note.d.ts +6 -1
- package/dist/actions/add-booking-note.d.ts.map +1 -1
- package/dist/actions/add-date-override.d.ts +10 -1
- package/dist/actions/add-date-override.d.ts.map +1 -1
- package/dist/actions/add-private-link.d.ts +8 -1
- package/dist/actions/add-private-link.d.ts.map +1 -1
- package/dist/actions/assign-round-robin-host.d.ts +6 -1
- package/dist/actions/assign-round-robin-host.d.ts.map +1 -1
- package/dist/actions/cancel-booking.d.ts +8 -1
- package/dist/actions/cancel-booking.d.ts.map +1 -1
- package/dist/actions/check-availability.d.ts +12 -1
- package/dist/actions/check-availability.d.ts.map +1 -1
- package/dist/actions/confirm-booking.d.ts +5 -1
- package/dist/actions/confirm-booking.d.ts.map +1 -1
- package/dist/actions/connect-calendar.d.ts +7 -1
- package/dist/actions/connect-calendar.d.ts.map +1 -1
- package/dist/actions/connect-video.d.ts +7 -1
- package/dist/actions/connect-video.d.ts.map +1 -1
- package/dist/actions/create-booking.d.ts +20 -1
- package/dist/actions/create-booking.d.ts.map +1 -1
- package/dist/actions/create-event-type.d.ts +17 -1
- package/dist/actions/create-event-type.d.ts.map +1 -1
- package/dist/actions/create-host-group.d.ts +7 -1
- package/dist/actions/create-host-group.d.ts.map +1 -1
- package/dist/actions/create-routing-form.d.ts +10 -1
- package/dist/actions/create-routing-form.d.ts.map +1 -1
- package/dist/actions/create-schedule.d.ts +14 -1
- package/dist/actions/create-schedule.d.ts.map +1 -1
- package/dist/actions/create-team.d.ts +11 -1
- package/dist/actions/create-team.d.ts.map +1 -1
- package/dist/actions/create-workflow.d.ts +18 -1
- package/dist/actions/create-workflow.d.ts.map +1 -1
- package/dist/actions/delete-event-type.d.ts +5 -1
- package/dist/actions/delete-event-type.d.ts.map +1 -1
- package/dist/actions/delete-routing-form.d.ts +5 -1
- package/dist/actions/delete-routing-form.d.ts.map +1 -1
- package/dist/actions/delete-schedule.d.ts +5 -1
- package/dist/actions/delete-schedule.d.ts.map +1 -1
- package/dist/actions/delete-workflow.d.ts +5 -1
- package/dist/actions/delete-workflow.d.ts.map +1 -1
- package/dist/actions/disconnect-calendar.d.ts +5 -1
- package/dist/actions/disconnect-calendar.d.ts.map +1 -1
- package/dist/actions/duplicate-event-type.d.ts +7 -1
- package/dist/actions/duplicate-event-type.d.ts.map +1 -1
- package/dist/actions/export-bookings-csv.d.ts +8 -1
- package/dist/actions/export-bookings-csv.d.ts.map +1 -1
- package/dist/actions/find-available-slot.d.ts +9 -1
- package/dist/actions/find-available-slot.d.ts.map +1 -1
- package/dist/actions/get-availability.d.ts +7 -1
- package/dist/actions/get-availability.d.ts.map +1 -1
- package/dist/actions/get-booking.d.ts +5 -1
- package/dist/actions/get-booking.d.ts.map +1 -1
- package/dist/actions/get-event-type.d.ts +8 -1
- package/dist/actions/get-event-type.d.ts.map +1 -1
- package/dist/actions/install-conferencing-app.d.ts +5 -1
- package/dist/actions/install-conferencing-app.d.ts.map +1 -1
- package/dist/actions/invite-team-member.d.ts +8 -1
- package/dist/actions/invite-team-member.d.ts.map +1 -1
- package/dist/actions/list-bookings.d.ts +11 -1
- package/dist/actions/list-bookings.d.ts.map +1 -1
- package/dist/actions/list-calendar-integrations.d.ts +7 -1
- package/dist/actions/list-calendar-integrations.d.ts.map +1 -1
- package/dist/actions/list-event-types.d.ts +6 -1
- package/dist/actions/list-event-types.d.ts.map +1 -1
- package/dist/actions/list-routing-form-responses.d.ts +6 -1
- package/dist/actions/list-routing-form-responses.d.ts.map +1 -1
- package/dist/actions/list-routing-forms.d.ts +5 -1
- package/dist/actions/list-routing-forms.d.ts.map +1 -1
- package/dist/actions/list-schedules.d.ts +3 -1
- package/dist/actions/list-schedules.d.ts.map +1 -1
- package/dist/actions/list-selected-calendars.d.ts +11 -1
- package/dist/actions/list-selected-calendars.d.ts.map +1 -1
- package/dist/actions/list-workflows.d.ts +5 -1
- package/dist/actions/list-workflows.d.ts.map +1 -1
- package/dist/actions/mark-no-show.d.ts +6 -1
- package/dist/actions/mark-no-show.d.ts.map +1 -1
- package/dist/actions/refresh-busy-times.d.ts +6 -1
- package/dist/actions/refresh-busy-times.d.ts.map +1 -1
- package/dist/actions/remove-booking-attendee.d.ts +6 -1
- package/dist/actions/remove-booking-attendee.d.ts.map +1 -1
- package/dist/actions/remove-date-override.d.ts +6 -1
- package/dist/actions/remove-date-override.d.ts.map +1 -1
- package/dist/actions/remove-team-member.d.ts +6 -1
- package/dist/actions/remove-team-member.d.ts.map +1 -1
- package/dist/actions/reorder-event-types.d.ts +5 -1
- package/dist/actions/reorder-event-types.d.ts.map +1 -1
- package/dist/actions/reschedule-booking.d.ts +10 -1
- package/dist/actions/reschedule-booking.d.ts.map +1 -1
- package/dist/actions/revoke-private-link.d.ts +5 -1
- package/dist/actions/revoke-private-link.d.ts.map +1 -1
- package/dist/actions/send-reschedule-link.d.ts +5 -1
- package/dist/actions/send-reschedule-link.d.ts.map +1 -1
- package/dist/actions/set-appearance.d.ts +8 -1
- package/dist/actions/set-appearance.d.ts.map +1 -1
- package/dist/actions/set-default-conferencing-app.d.ts +5 -1
- package/dist/actions/set-default-conferencing-app.d.ts.map +1 -1
- package/dist/actions/set-default-schedule.d.ts +5 -1
- package/dist/actions/set-default-schedule.d.ts.map +1 -1
- package/dist/actions/set-destination-calendar.d.ts +7 -1
- package/dist/actions/set-destination-calendar.d.ts.map +1 -1
- package/dist/actions/set-event-type-hosts.d.ts +12 -1
- package/dist/actions/set-event-type-hosts.d.ts.map +1 -1
- package/dist/actions/set-event-type-location.d.ts +6 -1
- package/dist/actions/set-event-type-location.d.ts.map +1 -1
- package/dist/actions/set-host-availability-override.d.ts +7 -1
- package/dist/actions/set-host-availability-override.d.ts.map +1 -1
- package/dist/actions/set-team-branding.d.ts +11 -1
- package/dist/actions/set-team-branding.d.ts.map +1 -1
- package/dist/actions/submit-routing-form-response.d.ts +10 -1
- package/dist/actions/submit-routing-form-response.d.ts.map +1 -1
- package/dist/actions/toggle-event-type-hidden.d.ts +6 -1
- package/dist/actions/toggle-event-type-hidden.d.ts.map +1 -1
- package/dist/actions/toggle-selected-calendar.d.ts +7 -1
- package/dist/actions/toggle-selected-calendar.d.ts.map +1 -1
- package/dist/actions/toggle-workflow.d.ts +6 -1
- package/dist/actions/toggle-workflow.d.ts.map +1 -1
- package/dist/actions/update-event-type.d.ts +38 -1
- package/dist/actions/update-event-type.d.ts.map +1 -1
- package/dist/actions/update-member-role.d.ts +7 -1
- package/dist/actions/update-member-role.d.ts.map +1 -1
- package/dist/actions/update-profile.d.ts +14 -1
- package/dist/actions/update-profile.d.ts.map +1 -1
- package/dist/actions/update-routing-form.d.ts +11 -1
- package/dist/actions/update-routing-form.d.ts.map +1 -1
- package/dist/actions/update-schedule.d.ts +22 -1
- package/dist/actions/update-schedule.d.ts.map +1 -1
- package/dist/actions/update-workflow.d.ts +19 -1
- package/dist/actions/update-workflow.d.ts.map +1 -1
- package/dist/react/components/SlotPicker.d.ts.map +1 -1
- package/dist/react/components/SlotPicker.js +3 -1
- package/dist/react/components/SlotPicker.js.map +1 -1
- package/dist/react/components/booking-links/AvailabilityEditor.d.ts +2 -1
- package/dist/react/components/booking-links/AvailabilityEditor.d.ts.map +1 -1
- package/dist/react/components/booking-links/AvailabilityEditor.js +28 -22
- package/dist/react/components/booking-links/AvailabilityEditor.js.map +1 -1
- package/dist/react/components/booking-links/BookingLinkCreateDialog.d.ts.map +1 -1
- package/dist/react/components/booking-links/BookingLinkCreateDialog.js +6 -4
- package/dist/react/components/booking-links/BookingLinkCreateDialog.js.map +1 -1
- package/dist/react/components/booking-links/ConferencingSelector.d.ts.map +1 -1
- package/dist/react/components/booking-links/ConferencingSelector.js +25 -19
- package/dist/react/components/booking-links/ConferencingSelector.js.map +1 -1
- package/dist/react/components/booking-links/CustomFieldsEditor.d.ts.map +1 -1
- package/dist/react/components/booking-links/CustomFieldsEditor.js +38 -24
- package/dist/react/components/booking-links/CustomFieldsEditor.js.map +1 -1
- package/dist/react/components/booking-links/DurationPicker.d.ts.map +1 -1
- package/dist/react/components/booking-links/DurationPicker.js +6 -2
- package/dist/react/components/booking-links/DurationPicker.js.map +1 -1
- package/dist/react/components/booking-links/SlugEditor.d.ts.map +1 -1
- package/dist/react/components/booking-links/SlugEditor.js +5 -3
- package/dist/react/components/booking-links/SlugEditor.js.map +1 -1
- package/dist/react/hooks/useEventType.d.ts +2 -2
- package/dist/react/hooks/useReschedule.d.ts +2 -2
- package/dist/react/i18n.d.ts +103 -0
- package/dist/react/i18n.d.ts.map +1 -0
- package/dist/react/i18n.js +970 -0
- package/dist/react/i18n.js.map +1 -0
- package/dist/schema/bookings.d.ts +49 -49
- package/dist/schema/calendar-cache.d.ts +8 -8
- package/dist/schema/credentials.d.ts +35 -35
- package/dist/schema/event-types.d.ts +42 -42
- package/dist/schema/routing-forms.d.ts +20 -20
- package/dist/schema/schedules.d.ts +31 -31
- package/dist/schema/teams.d.ts +19 -19
- package/dist/schema/workflows.d.ts +49 -49
- package/dist/server/availability-engine.d.ts.map +1 -1
- package/dist/server/availability-engine.js.map +1 -1
- package/dist/server/bookings-repo.d.ts.map +1 -1
- package/dist/server/bookings-repo.js.map +1 -1
- package/package.json +10 -11
- package/src/react/components/SlotPicker.tsx +6 -1
- package/src/react/components/booking-links/AvailabilityEditor.tsx +48 -27
- package/src/react/components/booking-links/BookingLinkCreateDialog.tsx +15 -13
- package/src/react/components/booking-links/ConferencingSelector.tsx +35 -30
- package/src/react/components/booking-links/CustomFieldsEditor.tsx +68 -49
- package/src/react/components/booking-links/DurationPicker.tsx +8 -4
- package/src/react/components/booking-links/SlugEditor.tsx +7 -5
- package/src/react/i18n.ts +1044 -0
- package/src/server/availability-engine.ts +3 -1
- package/src/server/bookings-repo.ts +4 -2
|
@@ -11,6 +11,8 @@
|
|
|
11
11
|
*/
|
|
12
12
|
import { Input } from "@/components/ui/input";
|
|
13
13
|
import { Switch } from "@/components/ui/switch";
|
|
14
|
+
import { schedulingMessage, useSchedulingT } from "../../i18n.js";
|
|
15
|
+
import type { LocaleCode } from "@agent-native/core/client";
|
|
14
16
|
|
|
15
17
|
export type DayKey =
|
|
16
18
|
| "monday"
|
|
@@ -33,14 +35,18 @@ export interface DaySchedule {
|
|
|
33
35
|
|
|
34
36
|
export type WeeklySchedule = Record<DayKey, DaySchedule>;
|
|
35
37
|
|
|
36
|
-
const DAYS: {
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
{ key: "
|
|
42
|
-
{ key: "
|
|
43
|
-
{ key: "
|
|
38
|
+
const DAYS: {
|
|
39
|
+
key: DayKey;
|
|
40
|
+
labelKey: Parameters<ReturnType<typeof useSchedulingT>>[0];
|
|
41
|
+
shortKey: Parameters<ReturnType<typeof useSchedulingT>>[0];
|
|
42
|
+
}[] = [
|
|
43
|
+
{ key: "monday", labelKey: "monday", shortKey: "mon" },
|
|
44
|
+
{ key: "tuesday", labelKey: "tuesday", shortKey: "tue" },
|
|
45
|
+
{ key: "wednesday", labelKey: "wednesday", shortKey: "wed" },
|
|
46
|
+
{ key: "thursday", labelKey: "thursday", shortKey: "thu" },
|
|
47
|
+
{ key: "friday", labelKey: "friday", shortKey: "fri" },
|
|
48
|
+
{ key: "saturday", labelKey: "saturday", shortKey: "sat" },
|
|
49
|
+
{ key: "sunday", labelKey: "sunday", shortKey: "sun" },
|
|
44
50
|
];
|
|
45
51
|
|
|
46
52
|
export interface AvailabilityEditorProps {
|
|
@@ -52,6 +58,7 @@ export function AvailabilityEditor({
|
|
|
52
58
|
value,
|
|
53
59
|
onChange,
|
|
54
60
|
}: AvailabilityEditorProps) {
|
|
61
|
+
const t = useSchedulingT();
|
|
55
62
|
const setDay = (day: DayKey, patch: Partial<DaySchedule>) => {
|
|
56
63
|
onChange({
|
|
57
64
|
...value,
|
|
@@ -74,7 +81,9 @@ export function AvailabilityEditor({
|
|
|
74
81
|
|
|
75
82
|
return (
|
|
76
83
|
<div className="space-y-2.5">
|
|
77
|
-
{DAYS.map(({ key,
|
|
84
|
+
{DAYS.map(({ key, labelKey, shortKey }) => {
|
|
85
|
+
const label = t(labelKey);
|
|
86
|
+
const short = t(shortKey);
|
|
78
87
|
const day = value[key] ?? { enabled: false, slots: [] };
|
|
79
88
|
const slot = day.slots[0] ?? { start: "09:00", end: "17:00" };
|
|
80
89
|
return (
|
|
@@ -86,7 +95,7 @@ export function AvailabilityEditor({
|
|
|
86
95
|
<Switch
|
|
87
96
|
checked={day.enabled}
|
|
88
97
|
onCheckedChange={(checked) => setDay(key, { enabled: checked })}
|
|
89
|
-
aria-label={
|
|
98
|
+
aria-label={t("toggleDay", { day: label })}
|
|
90
99
|
/>
|
|
91
100
|
<span className="text-sm font-medium">
|
|
92
101
|
<span className="hidden sm:inline">{label}</span>
|
|
@@ -102,7 +111,7 @@ export function AvailabilityEditor({
|
|
|
102
111
|
onChange={(e) => setSlot(key, "start", e.target.value)}
|
|
103
112
|
className="w-28 sm:w-32"
|
|
104
113
|
/>
|
|
105
|
-
<span className="text-muted-foreground">to</span>
|
|
114
|
+
<span className="text-muted-foreground">{t("to")}</span>
|
|
106
115
|
<Input
|
|
107
116
|
type="time"
|
|
108
117
|
value={slot.end}
|
|
@@ -111,7 +120,9 @@ export function AvailabilityEditor({
|
|
|
111
120
|
/>
|
|
112
121
|
</div>
|
|
113
122
|
) : (
|
|
114
|
-
<span className="text-sm text-muted-foreground">
|
|
123
|
+
<span className="text-sm text-muted-foreground">
|
|
124
|
+
{t("unavailable")}
|
|
125
|
+
</span>
|
|
115
126
|
)}
|
|
116
127
|
</div>
|
|
117
128
|
);
|
|
@@ -124,7 +135,10 @@ export function AvailabilityEditor({
|
|
|
124
135
|
* Summarize a `WeeklySchedule` in a short phrase, e.g. "Weekdays, 9 am - 5 pm".
|
|
125
136
|
* Useful for list-row subtitles.
|
|
126
137
|
*/
|
|
127
|
-
export function summarizeAvailability(
|
|
138
|
+
export function summarizeAvailability(
|
|
139
|
+
ws: WeeklySchedule,
|
|
140
|
+
locale: LocaleCode = "en-US",
|
|
141
|
+
): string {
|
|
128
142
|
const weekdayKeys: DayKey[] = [
|
|
129
143
|
"monday",
|
|
130
144
|
"tuesday",
|
|
@@ -136,7 +150,8 @@ export function summarizeAvailability(ws: WeeklySchedule): string {
|
|
|
136
150
|
const allDays: DayKey[] = [...weekdayKeys, ...weekendKeys];
|
|
137
151
|
|
|
138
152
|
const enabled = allDays.filter((d) => ws[d]?.enabled);
|
|
139
|
-
if (enabled.length === 0)
|
|
153
|
+
if (enabled.length === 0)
|
|
154
|
+
return schedulingMessage(locale, "noAvailabilitySet");
|
|
140
155
|
|
|
141
156
|
const weekdaysOn = weekdayKeys.every((d) => ws[d]?.enabled);
|
|
142
157
|
const weekendsOn = weekendKeys.every((d) => ws[d]?.enabled);
|
|
@@ -144,20 +159,26 @@ export function summarizeAvailability(ws: WeeklySchedule): string {
|
|
|
144
159
|
const weekendsOff = weekendKeys.every((d) => !ws[d]?.enabled);
|
|
145
160
|
|
|
146
161
|
let dayLabel: string;
|
|
147
|
-
if (weekdaysOn && weekendsOn)
|
|
148
|
-
|
|
149
|
-
else if (
|
|
162
|
+
if (weekdaysOn && weekendsOn)
|
|
163
|
+
dayLabel = schedulingMessage(locale, "everyDay");
|
|
164
|
+
else if (weekdaysOn && weekendsOff)
|
|
165
|
+
dayLabel = schedulingMessage(locale, "weekdays");
|
|
166
|
+
else if (weekdaysOff && weekendsOn)
|
|
167
|
+
dayLabel = schedulingMessage(locale, "weekends");
|
|
150
168
|
else {
|
|
151
|
-
const shortNames: Record<DayKey,
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
169
|
+
const shortNames: Record<DayKey, Parameters<typeof schedulingMessage>[1]> =
|
|
170
|
+
{
|
|
171
|
+
monday: "mon",
|
|
172
|
+
tuesday: "tue",
|
|
173
|
+
wednesday: "wed",
|
|
174
|
+
thursday: "thu",
|
|
175
|
+
friday: "fri",
|
|
176
|
+
saturday: "sat",
|
|
177
|
+
sunday: "sun",
|
|
178
|
+
};
|
|
179
|
+
dayLabel = enabled
|
|
180
|
+
.map((d) => schedulingMessage(locale, shortNames[d]))
|
|
181
|
+
.join(", ");
|
|
161
182
|
}
|
|
162
183
|
|
|
163
184
|
const slot = ws[enabled[0]].slots[0];
|
|
@@ -22,6 +22,7 @@ import { Button } from "@/components/ui/button";
|
|
|
22
22
|
import { Input } from "@/components/ui/input";
|
|
23
23
|
import { Label } from "@/components/ui/label";
|
|
24
24
|
import { Textarea } from "@/components/ui/textarea";
|
|
25
|
+
import { useSchedulingT } from "../../i18n.js";
|
|
25
26
|
|
|
26
27
|
export interface BookingLinkCreateDraft {
|
|
27
28
|
title: string;
|
|
@@ -54,13 +55,14 @@ function slugify(value: string) {
|
|
|
54
55
|
}
|
|
55
56
|
|
|
56
57
|
export function BookingLinkCreateDialog(props: BookingLinkCreateDialogProps) {
|
|
58
|
+
const t = useSchedulingT();
|
|
57
59
|
const {
|
|
58
60
|
open,
|
|
59
61
|
onOpenChange,
|
|
60
62
|
slugPrefix,
|
|
61
63
|
defaultLength = 30,
|
|
62
64
|
onSubmit,
|
|
63
|
-
submitLabel = "
|
|
65
|
+
submitLabel = t("continue"),
|
|
64
66
|
} = props;
|
|
65
67
|
|
|
66
68
|
const [form, setForm] = useState<BookingLinkCreateDraft>({
|
|
@@ -100,14 +102,12 @@ export function BookingLinkCreateDialog(props: BookingLinkCreateDialogProps) {
|
|
|
100
102
|
<Dialog open={open} onOpenChange={onOpenChange}>
|
|
101
103
|
<DialogContent>
|
|
102
104
|
<DialogHeader>
|
|
103
|
-
<DialogTitle>
|
|
104
|
-
<DialogDescription>
|
|
105
|
-
Create a new event type for people to book.
|
|
106
|
-
</DialogDescription>
|
|
105
|
+
<DialogTitle>{t("addEventTypeTitle")}</DialogTitle>
|
|
106
|
+
<DialogDescription>{t("addEventTypeDescription")}</DialogDescription>
|
|
107
107
|
</DialogHeader>
|
|
108
108
|
<div className="space-y-4">
|
|
109
109
|
<div className="space-y-1.5">
|
|
110
|
-
<Label htmlFor="blc-title">
|
|
110
|
+
<Label htmlFor="blc-title">{t("title")}</Label>
|
|
111
111
|
<Input
|
|
112
112
|
id="blc-title"
|
|
113
113
|
placeholder="Quick chat"
|
|
@@ -124,7 +124,7 @@ export function BookingLinkCreateDialog(props: BookingLinkCreateDialogProps) {
|
|
|
124
124
|
/>
|
|
125
125
|
</div>
|
|
126
126
|
<div className="space-y-1.5">
|
|
127
|
-
<Label htmlFor="blc-slug">
|
|
127
|
+
<Label htmlFor="blc-slug">{t("url")}</Label>
|
|
128
128
|
<div className="flex rounded-md border border-input focus-within:ring-2 focus-within:ring-ring">
|
|
129
129
|
<span className="flex items-center rounded-l-md bg-muted px-3 text-xs text-muted-foreground">
|
|
130
130
|
{slugPrefix}
|
|
@@ -150,10 +150,10 @@ export function BookingLinkCreateDialog(props: BookingLinkCreateDialogProps) {
|
|
|
150
150
|
</div>
|
|
151
151
|
</div>
|
|
152
152
|
<div className="space-y-1.5">
|
|
153
|
-
<Label htmlFor="blc-desc">
|
|
153
|
+
<Label htmlFor="blc-desc">{t("description")}</Label>
|
|
154
154
|
<Textarea
|
|
155
155
|
id="blc-desc"
|
|
156
|
-
placeholder="
|
|
156
|
+
placeholder={t("shortDescriptionPlaceholder")}
|
|
157
157
|
rows={2}
|
|
158
158
|
value={form.description}
|
|
159
159
|
onChange={(e) =>
|
|
@@ -162,7 +162,7 @@ export function BookingLinkCreateDialog(props: BookingLinkCreateDialogProps) {
|
|
|
162
162
|
/>
|
|
163
163
|
</div>
|
|
164
164
|
<div className="space-y-1.5">
|
|
165
|
-
<Label htmlFor="blc-len">
|
|
165
|
+
<Label htmlFor="blc-len">{t("duration")}</Label>
|
|
166
166
|
<div className="flex items-center gap-2">
|
|
167
167
|
<Input
|
|
168
168
|
id="blc-len"
|
|
@@ -173,19 +173,21 @@ export function BookingLinkCreateDialog(props: BookingLinkCreateDialogProps) {
|
|
|
173
173
|
setForm({ ...form, length: Number(e.currentTarget.value) })
|
|
174
174
|
}
|
|
175
175
|
/>
|
|
176
|
-
<span className="text-sm text-muted-foreground">
|
|
176
|
+
<span className="text-sm text-muted-foreground">
|
|
177
|
+
{t("minutes")}
|
|
178
|
+
</span>
|
|
177
179
|
</div>
|
|
178
180
|
</div>
|
|
179
181
|
</div>
|
|
180
182
|
<DialogFooter>
|
|
181
183
|
<Button variant="outline" onClick={() => onOpenChange(false)}>
|
|
182
|
-
|
|
184
|
+
{t("cancel")}
|
|
183
185
|
</Button>
|
|
184
186
|
<Button
|
|
185
187
|
onClick={submit}
|
|
186
188
|
disabled={!form.title || !form.slug || submitting}
|
|
187
189
|
>
|
|
188
|
-
{submitting ? "
|
|
190
|
+
{submitting ? t("saving") : submitLabel}
|
|
189
191
|
</Button>
|
|
190
192
|
</DialogFooter>
|
|
191
193
|
</DialogContent>
|
|
@@ -41,6 +41,7 @@ import {
|
|
|
41
41
|
SelectItem,
|
|
42
42
|
SelectTrigger,
|
|
43
43
|
} from "@/components/ui/select";
|
|
44
|
+
import { useSchedulingT } from "../../i18n.js";
|
|
44
45
|
|
|
45
46
|
export type ConferencingType = "none" | "google_meet" | "zoom" | "custom";
|
|
46
47
|
|
|
@@ -65,37 +66,38 @@ export interface ConferencingSelectorProps {
|
|
|
65
66
|
|
|
66
67
|
const OPTIONS: {
|
|
67
68
|
type: ConferencingType;
|
|
68
|
-
|
|
69
|
-
|
|
69
|
+
labelKey: Parameters<ReturnType<typeof useSchedulingT>>[0];
|
|
70
|
+
descriptionKey: Parameters<ReturnType<typeof useSchedulingT>>[0];
|
|
70
71
|
Icon: ComponentType<{ className?: string }>;
|
|
71
72
|
}[] = [
|
|
72
73
|
{
|
|
73
74
|
type: "none",
|
|
74
|
-
|
|
75
|
-
|
|
75
|
+
labelKey: "noConferencing",
|
|
76
|
+
descriptionKey: "inPersonOrOther",
|
|
76
77
|
Icon: IconVideoOff,
|
|
77
78
|
},
|
|
78
79
|
{
|
|
79
80
|
type: "google_meet",
|
|
80
|
-
|
|
81
|
-
|
|
81
|
+
labelKey: "googleMeet",
|
|
82
|
+
descriptionKey: "googleMeetDescription",
|
|
82
83
|
Icon: IconBrandGoogle,
|
|
83
84
|
},
|
|
84
85
|
{
|
|
85
86
|
type: "zoom",
|
|
86
|
-
|
|
87
|
-
|
|
87
|
+
labelKey: "zoom",
|
|
88
|
+
descriptionKey: "zoomDescription",
|
|
88
89
|
Icon: IconBrandZoom,
|
|
89
90
|
},
|
|
90
91
|
{
|
|
91
92
|
type: "custom",
|
|
92
|
-
|
|
93
|
-
|
|
93
|
+
labelKey: "customLink",
|
|
94
|
+
descriptionKey: "customLinkDescription",
|
|
94
95
|
Icon: IconLink,
|
|
95
96
|
},
|
|
96
97
|
];
|
|
97
98
|
|
|
98
99
|
export function ConferencingSelector(props: ConferencingSelectorProps) {
|
|
100
|
+
const t = useSchedulingT();
|
|
99
101
|
const id = useId();
|
|
100
102
|
const {
|
|
101
103
|
value,
|
|
@@ -122,7 +124,7 @@ export function ConferencingSelector(props: ConferencingSelectorProps) {
|
|
|
122
124
|
{!hideLabel && (
|
|
123
125
|
<Label className="flex items-center gap-1.5">
|
|
124
126
|
<IconVideo className="h-4 w-4" />
|
|
125
|
-
|
|
127
|
+
{t("conferencing")}
|
|
126
128
|
</Label>
|
|
127
129
|
)}
|
|
128
130
|
|
|
@@ -141,7 +143,7 @@ export function ConferencingSelector(props: ConferencingSelectorProps) {
|
|
|
141
143
|
<div className="min-w-0">
|
|
142
144
|
<div className="flex items-center gap-2">
|
|
143
145
|
<span className="truncate font-medium">
|
|
144
|
-
{selectedOption.
|
|
146
|
+
{t(selectedOption.labelKey)}
|
|
145
147
|
</span>
|
|
146
148
|
{selectedStatus === "connected" &&
|
|
147
149
|
selectedOption.type !== "none" &&
|
|
@@ -151,14 +153,16 @@ export function ConferencingSelector(props: ConferencingSelectorProps) {
|
|
|
151
153
|
className="h-5 gap-1 text-[10px] font-normal"
|
|
152
154
|
>
|
|
153
155
|
<IconCheck className="h-3 w-3" />
|
|
154
|
-
|
|
156
|
+
{t("connected")}
|
|
155
157
|
</Badge>
|
|
156
158
|
)}
|
|
157
159
|
</div>
|
|
158
160
|
<p className="truncate text-xs text-muted-foreground">
|
|
159
161
|
{selectedStatus === "not-configured"
|
|
160
|
-
?
|
|
161
|
-
|
|
162
|
+
? t("providerNotConfigured", {
|
|
163
|
+
provider: t(selectedOption.labelKey),
|
|
164
|
+
})
|
|
165
|
+
: t(selectedOption.descriptionKey)}
|
|
162
166
|
</p>
|
|
163
167
|
</div>
|
|
164
168
|
</div>
|
|
@@ -178,19 +182,21 @@ export function ConferencingSelector(props: ConferencingSelectorProps) {
|
|
|
178
182
|
<opt.Icon className="mt-0.5 h-4 w-4 shrink-0" />
|
|
179
183
|
<div className="min-w-0">
|
|
180
184
|
<div className="flex items-center gap-2">
|
|
181
|
-
<span className="font-medium">{opt.
|
|
185
|
+
<span className="font-medium">{t(opt.labelKey)}</span>
|
|
182
186
|
{status === "connected" &&
|
|
183
187
|
opt.type !== "none" &&
|
|
184
188
|
opt.type !== "custom" && (
|
|
185
189
|
<span className="text-[10px] text-muted-foreground">
|
|
186
|
-
|
|
190
|
+
{t("connected")}
|
|
187
191
|
</span>
|
|
188
192
|
)}
|
|
189
193
|
</div>
|
|
190
194
|
<p className="text-xs text-muted-foreground">
|
|
191
195
|
{isUnavailable
|
|
192
|
-
?
|
|
193
|
-
|
|
196
|
+
? t("providerNeedsCredentials", {
|
|
197
|
+
provider: t(opt.labelKey),
|
|
198
|
+
})
|
|
199
|
+
: t(opt.descriptionKey)}
|
|
194
200
|
</p>
|
|
195
201
|
</div>
|
|
196
202
|
</div>
|
|
@@ -205,10 +211,9 @@ export function ConferencingSelector(props: ConferencingSelectorProps) {
|
|
|
205
211
|
<div className="rounded-md border border-border/60 bg-muted/30 p-3">
|
|
206
212
|
<div className="flex flex-wrap items-center justify-between gap-2">
|
|
207
213
|
<div className="min-w-0 flex-1">
|
|
208
|
-
<p className="text-sm font-medium">
|
|
214
|
+
<p className="text-sm font-medium">{t("connectZoomAccount")}</p>
|
|
209
215
|
<p className="text-xs text-muted-foreground">
|
|
210
|
-
|
|
211
|
-
paste a personal link.
|
|
216
|
+
{t("connectZoomAccountDescription")}
|
|
212
217
|
</p>
|
|
213
218
|
</div>
|
|
214
219
|
<Button
|
|
@@ -218,13 +223,12 @@ export function ConferencingSelector(props: ConferencingSelectorProps) {
|
|
|
218
223
|
disabled={zoomStatus === "not-configured"}
|
|
219
224
|
>
|
|
220
225
|
<IconBrandZoom className="mr-1.5 h-4 w-4" />
|
|
221
|
-
|
|
226
|
+
{t("connectZoom")}
|
|
222
227
|
</Button>
|
|
223
228
|
</div>
|
|
224
229
|
{zoomStatus === "not-configured" && (
|
|
225
230
|
<p className="mt-2 text-[11px] text-muted-foreground">
|
|
226
|
-
|
|
227
|
-
<code>ZOOM_CLIENT_SECRET</code> to enable Zoom OAuth.
|
|
231
|
+
{t("zoomNotConfigured")}
|
|
228
232
|
</p>
|
|
229
233
|
)}
|
|
230
234
|
</div>
|
|
@@ -237,10 +241,11 @@ export function ConferencingSelector(props: ConferencingSelectorProps) {
|
|
|
237
241
|
<div className="rounded-md border border-border/60 bg-muted/30 p-3">
|
|
238
242
|
<div className="flex flex-wrap items-center justify-between gap-2">
|
|
239
243
|
<div className="min-w-0 flex-1">
|
|
240
|
-
<p className="text-sm font-medium">
|
|
244
|
+
<p className="text-sm font-medium">
|
|
245
|
+
{t("connectGoogleCalendar")}
|
|
246
|
+
</p>
|
|
241
247
|
<p className="text-xs text-muted-foreground">
|
|
242
|
-
|
|
243
|
-
created.
|
|
248
|
+
{t("connectGoogleCalendarDescription")}
|
|
244
249
|
</p>
|
|
245
250
|
</div>
|
|
246
251
|
<Button
|
|
@@ -251,7 +256,7 @@ export function ConferencingSelector(props: ConferencingSelectorProps) {
|
|
|
251
256
|
disabled={googleStatus === "not-configured"}
|
|
252
257
|
>
|
|
253
258
|
<IconBrandGoogle className="mr-1.5 h-4 w-4" />
|
|
254
|
-
|
|
259
|
+
{t("connectGoogle")}
|
|
255
260
|
</Button>
|
|
256
261
|
</div>
|
|
257
262
|
</div>
|
|
@@ -261,7 +266,7 @@ export function ConferencingSelector(props: ConferencingSelectorProps) {
|
|
|
261
266
|
{value.type === "custom" && (
|
|
262
267
|
<div className="space-y-1.5">
|
|
263
268
|
<Label htmlFor={`${id}-url`} className="text-xs">
|
|
264
|
-
|
|
269
|
+
{t("meetingUrl")}
|
|
265
270
|
</Label>
|
|
266
271
|
<Input
|
|
267
272
|
id={`${id}-url`}
|