quit_smoking_website/src/components/onboarding-dialog.tsx
Avery Felts e78dc3f940 Add smoking cessation tracker application
Features:
- User authentication via WorkOS (Apple, Google, Phone)
- Daily check-in dialog for usage tracking
- Calendar view with usage heatmap
- Personalized reduction plan generator after 7 days of tracking
- Custom OKLCH color theme with DM Sans and Space Mono fonts

Tech stack:
- Next.js 15 with App Router
- Shadcn/UI components
- Prisma with SQLite database
- Tailwind CSS v4

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-23 15:41:41 -07:00

118 lines
3.5 KiB
TypeScript

"use client";
import { useState } from "react";
import {
Dialog,
DialogContent,
DialogDescription,
DialogHeader,
DialogTitle,
} from "@/components/ui/dialog";
import { Button } from "@/components/ui/button";
import { Label } from "@/components/ui/label";
interface OnboardingDialogProps {
open: boolean;
onComplete: (preferences: {
substanceType: string;
stayLoggedIn: boolean;
}) => Promise<void>;
}
export function OnboardingDialog({ open, onComplete }: OnboardingDialogProps) {
const [step, setStep] = useState<"substance" | "login">("substance");
const [substanceType, setSubstanceType] = useState<string>("");
const [stayLoggedIn, setStayLoggedIn] = useState<boolean | null>(null);
const [isSubmitting, setIsSubmitting] = useState(false);
const handleSubstanceSelect = (type: string) => {
setSubstanceType(type);
setStep("login");
};
const handleLoginPreference = async (stay: boolean) => {
setStayLoggedIn(stay);
setIsSubmitting(true);
await onComplete({
substanceType,
stayLoggedIn: stay,
});
setIsSubmitting(false);
};
return (
<Dialog open={open}>
<DialogContent className="sm:max-w-md" onInteractOutside={(e) => e.preventDefault()}>
<DialogHeader>
<DialogTitle>
{step === "substance" ? "What are you tracking?" : "Stay Logged In?"}
</DialogTitle>
<DialogDescription>
{step === "substance"
? "Select the substance you want to track and reduce."
: "Would you like to stay logged in on this device?"}
</DialogDescription>
</DialogHeader>
{step === "substance" ? (
<div className="space-y-4 py-4">
<div className="grid grid-cols-2 gap-4">
<Button
variant="outline"
size="lg"
className="h-24 flex flex-col gap-2"
onClick={() => handleSubstanceSelect("nicotine")}
>
<span className="text-2xl">🚬</span>
<span>Nicotine</span>
</Button>
<Button
variant="outline"
size="lg"
className="h-24 flex flex-col gap-2"
onClick={() => handleSubstanceSelect("weed")}
>
<span className="text-2xl">🌿</span>
<span>Cannabis</span>
</Button>
</div>
</div>
) : (
<div className="space-y-4 py-4">
<p className="text-sm text-muted-foreground text-center">
If you choose to stay logged in, you won&apos;t need to sign in again
for 30 days on this device.
</p>
<div className="flex gap-4 justify-center">
<Button
variant="outline"
size="lg"
onClick={() => handleLoginPreference(false)}
disabled={isSubmitting}
>
No, log me out
</Button>
<Button
size="lg"
onClick={() => handleLoginPreference(true)}
disabled={isSubmitting}
>
Yes, stay logged in
</Button>
</div>
<Button
variant="ghost"
size="sm"
className="w-full"
onClick={() => setStep("substance")}
disabled={isSubmitting}
>
Back
</Button>
</div>
)}
</DialogContent>
</Dialog>
);
}