feat(gyeol): Q1Step (드롭다운) + Q2Step (라디오 5)
- Q1: 나이대 + 상황 두 드롭다운, 둘 다 선택 시 활성 - Q2: 자각 빈도 5 라디오, 보라 활성 스타일 - 라디오 패턴이 이후 Q4/Q5에서 재사용됨 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
62
app/gyeol/components/Q1Step.tsx
Normal file
62
app/gyeol/components/Q1Step.tsx
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
'use client';
|
||||||
|
|
||||||
|
import { useState } from 'react';
|
||||||
|
import { AGE_RANGES, STATUSES } from '@/lib/survey/questions';
|
||||||
|
import type { SurveyResponse } from '@/lib/survey/types';
|
||||||
|
import QuestionLayout from './QuestionLayout';
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
initial: Partial<SurveyResponse>;
|
||||||
|
onPrev: () => void;
|
||||||
|
onNext: (partial: Partial<SurveyResponse>) => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function Q1Step({ initial, onPrev, onNext }: Props) {
|
||||||
|
const [age, setAge] = useState(initial.age_range ?? '');
|
||||||
|
const [status, setStatus] = useState(initial.status ?? '');
|
||||||
|
|
||||||
|
const valid = age && status;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<QuestionLayout
|
||||||
|
step="q1"
|
||||||
|
onPrev={onPrev}
|
||||||
|
onNext={() => onNext({ age_range: age, status })}
|
||||||
|
nextDisabled={!valid}
|
||||||
|
>
|
||||||
|
<div className="space-y-4">
|
||||||
|
<div>
|
||||||
|
<label className="block text-xs text-white/60 mb-2 font-mono tracking-widest uppercase">
|
||||||
|
나이대
|
||||||
|
</label>
|
||||||
|
<select
|
||||||
|
value={age}
|
||||||
|
onChange={(e) => setAge(e.target.value)}
|
||||||
|
className="w-full px-4 py-3 rounded-xl bg-white/[0.04] border border-white/15 text-white focus:border-white/40 focus:outline-none"
|
||||||
|
>
|
||||||
|
<option value="" disabled>선택해주세요</option>
|
||||||
|
{AGE_RANGES.map((a) => (
|
||||||
|
<option key={a} value={a} className="bg-black">{a}</option>
|
||||||
|
))}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<label className="block text-xs text-white/60 mb-2 font-mono tracking-widest uppercase">
|
||||||
|
지금 상황
|
||||||
|
</label>
|
||||||
|
<select
|
||||||
|
value={status}
|
||||||
|
onChange={(e) => setStatus(e.target.value)}
|
||||||
|
className="w-full px-4 py-3 rounded-xl bg-white/[0.04] border border-white/15 text-white focus:border-white/40 focus:outline-none"
|
||||||
|
>
|
||||||
|
<option value="" disabled>선택해주세요</option>
|
||||||
|
{STATUSES.map((s) => (
|
||||||
|
<option key={s} value={s} className="bg-black">{s}</option>
|
||||||
|
))}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</QuestionLayout>
|
||||||
|
);
|
||||||
|
}
|
||||||
55
app/gyeol/components/Q2Step.tsx
Normal file
55
app/gyeol/components/Q2Step.tsx
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
'use client';
|
||||||
|
|
||||||
|
import { useState } from 'react';
|
||||||
|
import { AWARENESS_FREQS } from '@/lib/survey/questions';
|
||||||
|
import type { SurveyResponse } from '@/lib/survey/types';
|
||||||
|
import QuestionLayout from './QuestionLayout';
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
initial: Partial<SurveyResponse>;
|
||||||
|
onPrev: () => void;
|
||||||
|
onNext: (partial: Partial<SurveyResponse>) => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function Q2Step({ initial, onPrev, onNext }: Props) {
|
||||||
|
const [value, setValue] = useState(initial.awareness_freq ?? '');
|
||||||
|
|
||||||
|
return (
|
||||||
|
<QuestionLayout
|
||||||
|
step="q2"
|
||||||
|
onPrev={onPrev}
|
||||||
|
onNext={() => onNext({ awareness_freq: value })}
|
||||||
|
nextDisabled={!value}
|
||||||
|
>
|
||||||
|
<div className="space-y-2">
|
||||||
|
{AWARENESS_FREQS.map((option) => (
|
||||||
|
<label
|
||||||
|
key={option}
|
||||||
|
className={`flex items-center gap-3 px-4 py-3.5 rounded-xl border cursor-pointer transition ${
|
||||||
|
value === option
|
||||||
|
? 'border-violet-400 bg-violet-400/10'
|
||||||
|
: 'border-white/15 bg-white/[0.02] hover:border-white/30'
|
||||||
|
}`}
|
||||||
|
>
|
||||||
|
<input
|
||||||
|
type="radio"
|
||||||
|
name="awareness_freq"
|
||||||
|
value={option}
|
||||||
|
checked={value === option}
|
||||||
|
onChange={() => setValue(option)}
|
||||||
|
className="sr-only"
|
||||||
|
/>
|
||||||
|
<span
|
||||||
|
className={`w-4 h-4 rounded-full border-2 flex items-center justify-center flex-shrink-0 ${
|
||||||
|
value === option ? 'border-violet-400' : 'border-white/30'
|
||||||
|
}`}
|
||||||
|
>
|
||||||
|
{value === option && <span className="w-2 h-2 rounded-full bg-violet-400" />}
|
||||||
|
</span>
|
||||||
|
<span className="text-sm text-white">{option}</span>
|
||||||
|
</label>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</QuestionLayout>
|
||||||
|
);
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user