import { useState } from "react"; import type { GradingCategory } from "~/types/api"; import { Button } from "./Button"; import { Input } from "./Input"; interface GradingCategorySelectorProps { categories: GradingCategory[]; onChange: (categories: GradingCategory[]) => void; } const DEFAULT_COLORS = [ "#3b82f6", // blue "#10b981", // green "#f59e0b", // amber "#ef4444", // red "#8b5cf6", // purple "#ec4899", // pink ]; export function GradingCategorySelector({ categories, onChange, }: GradingCategorySelectorProps) { const [error, setError] = useState(""); const addCategory = () => { const newCategory: GradingCategory = { name: "", weight: 0, color: DEFAULT_COLORS[categories.length % DEFAULT_COLORS.length], }; onChange([...categories, newCategory]); }; const updateCategory = (index: number, field: keyof GradingCategory, value: any) => { const updated = [...categories]; updated[index] = { ...updated[index], [field]: value }; onChange(updated); validateWeights(updated); }; const removeCategory = (index: number) => { const updated = categories.filter((_, i) => i !== index); onChange(updated); validateWeights(updated); }; const validateWeights = (cats: GradingCategory[]) => { const total = cats.reduce((sum, cat) => sum + (Number(cat.weight) || 0), 0); if (Math.abs(total - 100) > 0.01 && total > 0) { setError(`Total weight: ${total.toFixed(1)}% (must equal 100%)`); } else { setError(""); } }; const totalWeight = categories.reduce((sum, cat) => sum + (Number(cat.weight) || 0), 0); return (
{categories.map((category, index) => (
updateCategory(index, "name", e.target.value)} className="flex-1" /> updateCategory(index, "weight", parseFloat(e.target.value) || 0) } className="w-24" min="0" max="100" step="0.1" /> updateCategory(index, "color", e.target.value)} className="w-12 h-10 rounded cursor-pointer" title="Category color" />
))}
{categories.length === 0 && (

Add at least one grading category

)}
Total Weight: {totalWeight.toFixed(1)}%
{error &&

{error}

}
); }