← 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>
  )
}