import { useState, useEffect, type FormEvent } from "react"; import { useNavigate, Link } from "react-router"; import { ProtectedRoute } from "~/components/ProtectedRoute"; import { Button } from "~/components/Button"; import { Input } from "~/components/Input"; import { GradingCategorySelector } from "~/components/GradingCategorySelector"; import { api } from "~/api/client"; import type { GradingCategory } from "~/types/api"; import { GRADE_SYSTEMS, type GradeSystem } from "~/utils/gradeSystems"; const getMaxGradeForSystem = (system: GradeSystem): string => { switch (system) { case "german": return "6"; case "us-letter": case "percentage": default: return "100"; } }; export default function NewSubject() { const navigate = useNavigate(); const [name, setName] = useState(""); const [teacher, setTeacher] = useState(""); const [color, setColor] = useState("#3b82f6"); const [gradeSystem, setGradeSystem] = useState("percentage"); const [targetGrade, setTargetGrade] = useState(""); const [targetMaxGrade, setTargetMaxGrade] = useState("100"); // Auto-update max grade when grade system changes useEffect(() => { setTargetMaxGrade(getMaxGradeForSystem(gradeSystem)); }, [gradeSystem]); const [categories, setCategories] = useState([ { name: "Written", weight: 50, color: "#3b82f6" }, { name: "Oral", weight: 50, color: "#10b981" }, ]); const [error, setError] = useState(""); const [loading, setLoading] = useState(false); const handleSubmit = async (e: FormEvent) => { e.preventDefault(); setError(""); if (!name.trim()) { setError("Subject name is required"); return; } if (categories.length === 0) { setError("Add at least one grading category"); return; } const totalWeight = categories.reduce((sum, cat) => sum + cat.weight, 0); if (Math.abs(totalWeight - 100) > 0.01) { setError("Category weights must sum to 100%"); return; } if (categories.some((cat) => !cat.name.trim())) { setError("All categories must have a name"); return; } setLoading(true); try { await api.createSubject({ name: name.trim(), teacher: teacher.trim() || undefined, color, grade_system: gradeSystem, grading_categories: categories, target_grade: targetGrade ? parseFloat(targetGrade) : undefined, target_grade_max: targetMaxGrade ? parseFloat(targetMaxGrade) : undefined, }); navigate("/subjects"); } catch (err) { setError(err instanceof Error ? err.message : "Failed to create subject"); } finally { setLoading(false); } }; return (
← Back to Subjects

Create New Subject

setName(e.target.value)} placeholder="e.g., Mathematics, English, Biology" required /> setTeacher(e.target.value)} placeholder="e.g., Mrs. Smith" />
setColor(e.target.value)} className="w-20 h-10 rounded cursor-pointer border border-gray-300" />

Choose how grades will be displayed for this subject

Target Grade (Optional)

setTargetGrade(e.target.value)} placeholder={gradeSystem === "german" ? "e.g., 2.0" : "e.g., 85"} />
{targetMaxGrade}

Auto-set by grade system

Set a target grade to track your progress. Leave empty if not needed.

{error && (
{error}
)}
); }