← back to ClawCoder
src/components/onboarding/review-screen.tsx
104 lines
'use client'
import { motion } from 'framer-motion'
import { ONBOARDING_QUESTIONS } from '@/lib/onboarding/questions'
import { resolveProfile, answerLabel } from '@/lib/onboarding/resolver'
interface ReviewScreenProps {
answers: Record<string, string>
onEdit: (step: number) => void
onGenerate: () => void
}
export function ReviewScreen({
answers,
onEdit,
onGenerate,
}: ReviewScreenProps) {
const profile = resolveProfile(answers)
// Show steps 1-8 (skip the "finish" question)
const reviewQuestions = ONBOARDING_QUESTIONS.filter((q) => q.id !== 'finish')
return (
<div className="flex min-h-screen flex-col items-center justify-center px-4 py-12">
<motion.div
initial={{ opacity: 0, y: 20 }}
animate={{ opacity: 1, y: 0 }}
transition={{ duration: 0.3 }}
className="w-full max-w-2xl"
>
<h1 className="mb-2 text-center text-3xl font-bold tracking-tight text-slate-900">
Review your answers
</h1>
<p className="mb-8 text-center text-slate-500">
Make sure everything looks right before we generate your setup.
</p>
{/* Detected profile badge */}
<div className="mb-8 flex flex-col items-center gap-2 rounded-2xl border border-blue-200 bg-blue-50 p-6">
<p className="text-sm font-medium uppercase tracking-wider text-blue-500">
Your detected profile
</p>
<h2 className="text-xl font-bold text-blue-900">
{profile.displayName}
</h2>
<p className="max-w-md text-center text-sm text-blue-700">
{profile.persona}
</p>
<div className="mt-2 flex gap-3 text-xs text-blue-600">
<span className="rounded-full bg-blue-100 px-3 py-1">
{profile.ageGroup.replace('_', ' ')}
</span>
<span className="rounded-full bg-blue-100 px-3 py-1">
{profile.skillLevel}
</span>
<span className="rounded-full bg-blue-100 px-3 py-1">
{profile.skillBundle.length} skills
</span>
</div>
</div>
{/* Answer list */}
<div className="divide-y divide-slate-200 rounded-2xl border border-slate-200 bg-white">
{reviewQuestions.map((q) => {
const val = answers[q.id]
return (
<div
key={q.id}
className="flex items-center justify-between px-6 py-4"
>
<div className="min-w-0 flex-1">
<p className="text-sm font-medium text-slate-500">
{q.question}
</p>
<p className="mt-0.5 text-base font-semibold text-slate-900">
{val ? answerLabel(q.id, val) : '(not answered)'}
</p>
</div>
<button
type="button"
onClick={() => onEdit(q.step)}
className="ml-4 shrink-0 rounded-lg border border-slate-200 px-3 py-1.5 text-sm font-medium text-blue-600 transition-colors hover:bg-blue-50 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-blue-500"
>
Edit
</button>
</div>
)
})}
</div>
{/* Generate button */}
<div className="mt-8 flex justify-center">
<button
type="button"
onClick={onGenerate}
className="min-h-[56px] rounded-xl bg-blue-600 px-12 py-3 text-lg font-semibold text-white transition-colors hover:bg-blue-700 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-blue-500"
>
Generate my setup!
</button>
</div>
</motion.div>
</div>
)
}