import { useState, type ComponentType, type ReactNode } from 'react';
import {
Check,
ChevronLeft,
ChevronRight,
KeyRound,
LockKeyhole,
Settings2,
ShieldCheck,
UserPlus,
X,
} from 'lucide-react';
import { toast } from 'sonner';
import { api } from '@/api';
import { errMessage } from '@/lib/utils';
import { Button } from '@/components/ui/button';
import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label';
import { Card, CardHeader, CardTitle, CardContent } from '@/components/ui/card';
import { BRAND } from '@/lib/brand';
import { BrandGlyph, BrandMark } from '@/components/brand/Brand';
function PromiseItem({
icon: Icon,
title,
children,
}: {
icon: ComponentType<{ className?: string }>;
title: string;
children: ReactNode;
}) {
return (
{title}
{children}
);
}
export default function OnboardingWizard({ onComplete }: { onComplete: () => void }) {
const [step, setStep] = useState(0);
const [username, setUsername] = useState('');
const [password, setPassword] = useState('');
const [confirm, setConfirm] = useState('');
const [loading, setLoading] = useState(false);
const [error, setError] = useState('');
const handleCreate = async (e: React.FormEvent) => {
e.preventDefault();
setError('');
let validationError = '';
if (password !== confirm) {
validationError = 'Passwords do not match.';
} else if (password.length < 8) {
validationError = 'Password must be at least 8 characters.';
}
if (validationError) {
setError(validationError);
toast.error(validationError);
return;
}
setLoading(true);
try {
await api.createUser({ username, password });
toast.success('User created successfully.');
onComplete();
} catch (err) {
const errorMessage = errMessage(err, 'Failed to create user.');
setError(errorMessage);
toast.error(errorMessage);
} finally {
setLoading(false);
}
};
return (
Set up {BRAND.name} with a clean privacy line.
The first admin keeps the app healthy. The first user owns the money data. Those roles
stay separate from the start.
Create accounts, reset passwords, notification plumbing, and login mode settings.
Admin tools do not expose bills, payments, spending history, or personal settings.
A restrained setup flow that matches the tracker, settings, and security surfaces.
{[0, 1].map((i) => (
))}
{step === 0 && (
Welcome, Administrator
Before creating your first user, review the admin boundary.
{[
{ can: true, text: 'Create and manage user accounts' },
{ can: true, text: 'Reset user passwords' },
{ can: true, text: 'Configure email notifications' },
{ can: true, text: 'Toggle single-user / multi-user mode' },
{ can: false, text: 'Cannot view bills or financial data' },
{ can: false, text: 'Cannot access user settings or history' },
].map(({ can, text }) => (
{can ? (
) : (
)}
{text}
))}
)}
{step === 1 && (
Create first user
This account will own the tracker, bills, and personal settings.