Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions clients/shared/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -178,3 +178,4 @@ export {
useMarkAllNotificationsRead,
usePostDeviceToken,
} from "./api/notifications";
export { usePutUsersIdOnboard } from "./api/generated/endpoints/users/users";
23 changes: 14 additions & 9 deletions clients/web/src/components/onboarding/InviteTeamStep.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,17 @@ import type { OnboardingFormData } from "./types";
type InviteTeamStepProps = {
formData: OnboardingFormData;
updateForm: (updates: Partial<OnboardingFormData>) => void;
onNext: () => void;
isSubmitting?: boolean;
};

export function InviteTeamStep({ formData, updateForm }: InviteTeamStepProps) {
export function InviteTeamStep({
formData,
updateForm,
onNext,
isSubmitting,
}: InviteTeamStepProps) {
const [invited, setInvited] = useState(false);

return (
<div className="flex w-screen h-screen">
<LeftPanel />
Expand All @@ -18,7 +24,6 @@ export function InviteTeamStep({ formData, updateForm }: InviteTeamStepProps) {
<div className="w-[90%] max-w-[35.4375rem] flex flex-col items-center gap-6">
{/* Logo */}
<div className="w-20 h-20 border border-text-default rounded-lg bg-bg-primary shrink-0" />

{/* Header */}
<div className="flex flex-col items-center gap-2 text-center">
<h1 className="font-normal text-[clamp(1.25rem,2.5vw,1.5rem)] leading-8 text-text-heading m-0">
Expand All @@ -28,7 +33,6 @@ export function InviteTeamStep({ formData, updateForm }: InviteTeamStepProps) {
SelfServe is better when the whole staff is connected.
</p>
</div>

{/* Email input */}
<div className="flex flex-col gap-2 w-full">
<div className="w-full flex items-center gap-2 bg-bg-input rounded-lg px-3 py-2 box-border">
Expand Down Expand Up @@ -56,17 +60,18 @@ export function InviteTeamStep({ formData, updateForm }: InviteTeamStepProps) {
You can also do this later from your settings.
</p>
</div>

{/* Actions */}
<div className="flex flex-col gap-3 items-center w-full">
<button
onClick={() => console.log("Go to dashboard")}
className="w-full h-14 rounded-[0.875rem] bg-primary text-bg-primary border-none text-base"
onClick={onNext}
disabled={isSubmitting}
className="w-full h-14 rounded-[0.875rem] bg-primary text-bg-primary border-none text-base disabled:opacity-50"
>
Go to Dashboard
{isSubmitting ? "Setting up..." : "Go to Dashboard"}
</button>
<button
onClick={() => console.log("Skip for now")}
onClick={onNext}
disabled={isSubmitting}
className="text-sm text-text-muted bg-transparent border-none"
>
Skip for now
Expand Down
38 changes: 37 additions & 1 deletion clients/web/src/components/onboarding/OnboardingPage.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import { useState } from "react";
import { useAuth } from "@clerk/clerk-react";
import { useNavigate } from "@tanstack/react-router";
import { WelcomeStep } from "./WelcomeStep";
import { RoleSelectionStep } from "./RoleSelectionStep";
import { EmployeeRoleStep } from "./EmployeeRoleStep";
Expand Down Expand Up @@ -26,6 +28,10 @@ export function OnboardingPage() {
const [currentStep, setCurrentStep] = useState<Step>("welcome");
const [formData, setFormData] =
useState<OnboardingFormData>(INITIAL_FORM_DATA);
const [isPending, setIsPending] = useState(false);

const { userId, getToken } = useAuth();
const navigate = useNavigate();

const updateForm = (updates: Partial<OnboardingFormData>) => {
setFormData((prev) => ({ ...prev, ...updates }));
Expand All @@ -40,6 +46,29 @@ export function OnboardingPage() {
}
};

const handleSubmit = async () => {
if (!userId) return;
setIsPending(true);
try {
const token = await getToken();
await fetch(`${process.env.API_BASE_URL}/users/${userId}/onboard`, {
method: "PUT",
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${token}`,
},
body: JSON.stringify({
role: formData.role ?? undefined,
hotel_name: formData.hotelName || undefined,
department: formData.employeeRole ?? undefined,
}),
});
navigate({ to: "/" });
} finally {
setIsPending(false);
}
};

const renderStep = () => {
switch (currentStep) {
case "welcome":
Expand Down Expand Up @@ -75,7 +104,14 @@ export function OnboardingPage() {
/>
);
case "inviteTeam":
return <InviteTeamStep formData={formData} updateForm={updateForm} />;
return (
<InviteTeamStep
formData={formData}
updateForm={updateForm}
onNext={handleSubmit}
isSubmitting={isPending}
/>
);
}
};

Expand Down
Loading