diff --git a/project.inlang/messages/de.json b/project.inlang/messages/de.json index dde7118..caf9776 100644 --- a/project.inlang/messages/de.json +++ b/project.inlang/messages/de.json @@ -946,6 +946,34 @@ "action": "Termin bestätigen", "success": "Termin erfolgreich bestätigt", "error": "Fehler beim Bestätigen des Termins" + }, + "addAppointment": { + "preview": "Neuer Termin {time} Uhr {channel}", + "steps": { + "selectClient": { + "hasNoEmail": "Klient hat keine E-Mail Adresse", + "action": "Klient suchen" + }, + "agents": { + "title": "Akteur auswählen" + }, + "clientData": { + "shareEmail": "Klient wünscht Benachrichtigungen per E-Mail", + "phoneHint": "Format: +1234567890 (optional)", + "action": "Daten hinzufügen" + }, + "summary": { + "action": "Termin hinzufügen" + }, + "error": { + "title": "Fehler beim Hinzufügen des Termins", + "description": "Das Hinzufügen des Termins ist fehlgeschlagen. Bitte versuchen Sie es erneut." + }, + "success": { + "title": "Termin hinzugefügt", + "description": "Der Termin wurde erfolgreich hinzugefügt" + } + } } }, "emails": { diff --git a/project.inlang/messages/en.json b/project.inlang/messages/en.json index 75a87dc..a96a89b 100644 --- a/project.inlang/messages/en.json +++ b/project.inlang/messages/en.json @@ -955,6 +955,34 @@ "action": "Confirm Appointment", "success": "Appointment confirmed successfully", "error": "Failed to confirm appointment" + }, + "addAppointment": { + "preview": "Add {time} {channel}", + "steps": { + "selectClient": { + "hasNoEmail": "Client has no e-mail", + "action": "Search Client" + }, + "agents": { + "title": "Select an Agent" + }, + "clientData": { + "shareEmail": "Client wishes updates via E-Mail", + "phoneHint": "Format: +1234567890 (optional)", + "action": "Add Client Details" + }, + "summary": { + "action": "Add Appointment" + }, + "error": { + "title": "Error adding Appointment", + "description": "Adding an appointment failed. Please try again." + }, + "success": { + "title": "Appointment added", + "description": "This appointment was added successfully" + } + } } }, "emails": { diff --git a/src/lib/components/ui/passkey/state.svelte b/src/lib/components/ui/passkey/state.svelte index fbc162d..b11332c 100644 --- a/src/lib/components/ui/passkey/state.svelte +++ b/src/lib/components/ui/passkey/state.svelte @@ -25,16 +25,25 @@ onclick?.(); } }; + + const onKeyDown = (event: KeyboardEvent) => { + if (event.key === "Enter") { + if (!disabledStates.includes(state)) { + onclick?.(); + } + } + }; diff --git a/src/routes/(pages)/dashboard/calendar/(components)/add-appointment/AddAppointment.svelte b/src/routes/(pages)/dashboard/calendar/(components)/add-appointment/AddAppointment.svelte new file mode 100644 index 0000000..246bec9 --- /dev/null +++ b/src/routes/(pages)/dashboard/calendar/(components)/add-appointment/AddAppointment.svelte @@ -0,0 +1,85 @@ + + + +{#if step === "email"} + +{:else if step === "agent" && item.availableAgents} + +{:else if step === "summary"} + +{:else if step === "client"} + +{:else if step === "success"} + +{:else} + +{/if} diff --git a/src/routes/(pages)/dashboard/calendar/(components)/add-appointment/SelectAgent.svelte b/src/routes/(pages)/dashboard/calendar/(components)/add-appointment/SelectAgent.svelte new file mode 100644 index 0000000..9dbc0af --- /dev/null +++ b/src/routes/(pages)/dashboard/calendar/(components)/add-appointment/SelectAgent.svelte @@ -0,0 +1,53 @@ + + +
+ + {m["calendar.addAppointment.steps.agents.title"]()} + +
    + {#each availableAgents as agent (agent.id)} +
  • + +
  • + {/each} +
+
diff --git a/src/routes/(pages)/dashboard/calendar/(components)/add-appointment/Summary.svelte b/src/routes/(pages)/dashboard/calendar/(components)/add-appointment/Summary.svelte new file mode 100644 index 0000000..013027b --- /dev/null +++ b/src/routes/(pages)/dashboard/calendar/(components)/add-appointment/Summary.svelte @@ -0,0 +1,76 @@ + + +
+
+ + + {toDisplayDateTime(newAppointment.dateTime, { + year: "numeric", + month: "long", + day: "numeric", + weekday: "short", + hour: "2-digit", + minute: "2-digit", + })} + +
+ {#if newAppointment.name} +
+ + + {newAppointment.name} + +
+ {/if} + {#if newAppointment.email} + + {/if} + {#if newAppointment.phone} + + {/if} + {#if agent} +
+ + + {agent.name} + +
+ {/if} +
+
+ {#if step !== "summary"} + + {/if} +
diff --git a/src/routes/(pages)/dashboard/calendar/(components)/add-appointment/client-data-form/client-data-form.svelte b/src/routes/(pages)/dashboard/calendar/(components)/add-appointment/client-data-form/client-data-form.svelte new file mode 100644 index 0000000..58df4f6 --- /dev/null +++ b/src/routes/(pages)/dashboard/calendar/(components)/add-appointment/client-data-form/client-data-form.svelte @@ -0,0 +1,90 @@ + + + + + + {#snippet children({ props })} + {m["form.name"]()} + + {/snippet} + + + + + + {#snippet children({ props })} + {m["form.phone"]()} + + {/snippet} + + + + {m["calendar.addAppointment.steps.clientData.phoneHint"]()} + + + {#if newAppointment.email} + + + {#snippet children({ props })} + { + $formData.shareEmail = v; + }} + /> + {/snippet} + + + + {/if} +
+ + {m["calendar.addAppointment.steps.clientData.action"]()} + +
+
diff --git a/src/routes/(pages)/dashboard/calendar/(components)/add-appointment/client-data-form/index.ts b/src/routes/(pages)/dashboard/calendar/(components)/add-appointment/client-data-form/index.ts new file mode 100644 index 0000000..fea0200 --- /dev/null +++ b/src/routes/(pages)/dashboard/calendar/(components)/add-appointment/client-data-form/index.ts @@ -0,0 +1,5 @@ +import ClientDataForm from "./client-data-form.svelte"; + +export { ClientDataForm }; +export { formSchema } from "./schema"; +export type { FormSchema } from "./schema"; diff --git a/src/routes/(pages)/dashboard/calendar/(components)/add-appointment/client-data-form/schema.ts b/src/routes/(pages)/dashboard/calendar/(components)/add-appointment/client-data-form/schema.ts new file mode 100644 index 0000000..725322a --- /dev/null +++ b/src/routes/(pages)/dashboard/calendar/(components)/add-appointment/client-data-form/schema.ts @@ -0,0 +1,10 @@ +import { m } from "$i18n/messages"; +import { z } from "zod"; + +export const formSchema = z.object({ + shareEmail: z.boolean(), + name: z.string().min(2, m["form.errors.name"]()).max(50, m["form.errors.name"]()), + phone: z.e164(m["form.errors.phoneNoInvalid"]()).optional(), +}); + +export type FormSchema = typeof formSchema; diff --git a/src/routes/(pages)/dashboard/calendar/(components)/add-appointment/search-client-form/index.ts b/src/routes/(pages)/dashboard/calendar/(components)/add-appointment/search-client-form/index.ts new file mode 100644 index 0000000..1bd7c4b --- /dev/null +++ b/src/routes/(pages)/dashboard/calendar/(components)/add-appointment/search-client-form/index.ts @@ -0,0 +1,5 @@ +import SearchClientForm from "./search-client-form.svelte"; + +export { SearchClientForm }; +export { formSchema } from "./schema"; +export type { FormSchema } from "./schema"; diff --git a/src/routes/(pages)/dashboard/calendar/(components)/add-appointment/search-client-form/schema.ts b/src/routes/(pages)/dashboard/calendar/(components)/add-appointment/search-client-form/schema.ts new file mode 100644 index 0000000..eedcbb9 --- /dev/null +++ b/src/routes/(pages)/dashboard/calendar/(components)/add-appointment/search-client-form/schema.ts @@ -0,0 +1,8 @@ +import { m } from "$i18n/messages"; +import { z } from "zod"; + +export const formSchema = z.object({ + email: z.email(m["form.errors.email"]()), +}); + +export type FormSchema = typeof formSchema; diff --git a/src/routes/(pages)/dashboard/calendar/(components)/add-appointment/search-client-form/search-client-form.svelte b/src/routes/(pages)/dashboard/calendar/(components)/add-appointment/search-client-form/search-client-form.svelte new file mode 100644 index 0000000..80b86dc --- /dev/null +++ b/src/routes/(pages)/dashboard/calendar/(components)/add-appointment/search-client-form/search-client-form.svelte @@ -0,0 +1,95 @@ + + + + + + {#snippet children({ props })} + {m["form.email"]()} + + {/snippet} + + + + + + +
+ + {m["calendar.addAppointment.steps.selectClient.action"]()} + +
+
diff --git a/src/routes/(pages)/dashboard/calendar/(components)/add-appointment/types.ts b/src/routes/(pages)/dashboard/calendar/(components)/add-appointment/types.ts new file mode 100644 index 0000000..043eb77 --- /dev/null +++ b/src/routes/(pages)/dashboard/calendar/(components)/add-appointment/types.ts @@ -0,0 +1,11 @@ +export type TAddAppointment = { + dateTime: Date; + agentId?: string; + email?: string; + hasNoEmail?: boolean; + shareEmail?: boolean; + name?: string; + phone?: string; +}; + +export type TAddAppointmentStep = "email" | "agent" | "client" | "summary" | "success" | "error"; diff --git a/src/routes/(pages)/dashboard/calendar/+page.svelte b/src/routes/(pages)/dashboard/calendar/+page.svelte index 4375416..cd48c62 100644 --- a/src/routes/(pages)/dashboard/calendar/+page.svelte +++ b/src/routes/(pages)/dashboard/calendar/+page.svelte @@ -1,5 +1,6 @@