File name
Commit message
Commit date
File name
Commit message
Commit date
File name
Commit message
Commit date
File name
Commit message
Commit date
File name
Commit message
Commit date
File name
Commit message
Commit date
'use client';
import { useState } from 'react';
import { FoxChip } from '@fox/core/components/fox-chip';
import { FoxChipArea } from '@fox/core/components/fox-chip-area';
import { FoxHelperText } from '@fox/core/components/fox-helper-text';
import { FoxSelect } from '@fox/core/components/fox-select';
import {
DEFAULT_SCHOOL_LEVEL,
SCHOOL_LEVEL_OPTIONS,
findSchoolLevel,
gradeOptionsOf,
} from '@/lib/domain/content';
import styles from './content-form.module.scss';
interface ContentGradeFieldProps {
defaultSchoolLevel?: string;
defaultGrades?: readonly string[];
schoolLevelError?: string;
gradesError?: string;
}
/**
* 학년선택 — 학교급을 고르면 그 학교급의 학년 칩이 열리고 여러 개를 고를 수 있다.
* 전체연령은 학년이 없어 칩을 그리지 않는다(기획 "전체 연령 선택 시 학년 선택 비활성").
*/
export function ContentGradeField({
defaultSchoolLevel,
defaultGrades = [],
schoolLevelError,
gradesError,
}: ContentGradeFieldProps) {
const [schoolLevel, setSchoolLevel] = useState(
defaultSchoolLevel || DEFAULT_SCHOOL_LEVEL
);
const [grades, setGrades] = useState<string[]>([...defaultGrades]);
const gradeOptions = gradeOptionsOf(schoolLevel);
const hasGrades = (findSchoolLevel(schoolLevel)?.gradeCount ?? 0) > 0;
function changeSchoolLevel(next: string) {
setSchoolLevel(next);
// 학교급이 바뀌면 이전 학교급의 학년은 남길 수 없다(초 4학년 → 중학교).
setGrades([]);
}
function toggleGrade(grade: string) {
setGrades((current) =>
current.includes(grade)
? current.filter((value) => value !== grade)
: [...current, grade].sort()
);
}
return (
<div className={styles.grades}>
<div className={styles.inline}>
<FoxSelect
size="md"
options={SCHOOL_LEVEL_OPTIONS.map((option) => ({
value: option.value,
label: option.label,
}))}
value={schoolLevel}
onValueChange={changeSchoolLevel}
error={Boolean(schoolLevelError)}
/>
{hasGrades && (
<FoxChipArea size="md" label="학년" wrap>
{gradeOptions.map((grade) => (
<FoxChip
key={grade}
type="check"
label={`${grade}학년`}
checked={grades.includes(grade)}
onCheckedChange={() => toggleGrade(grade)}
/>
))}
</FoxChipArea>
)}
</div>
<input type="hidden" name="schoolLevel" value={schoolLevel} />
<input type="hidden" name="grades" value={grades.join(',')} />
{(schoolLevelError || gradesError) && (
<FoxHelperText
type="danger"
message={schoolLevelError ?? gradesError ?? ''}
/>
)}
</div>
);
}