import { useState } from "react"; import type { Subject, Grade } from "~/types/api"; import { calculateRequiredGrade, type RequiredGradeResult } from "~/utils/gradeCalculations"; import { Button } from "./Button"; import { Input } from "./Input"; interface GradeCalculatorProps { subject: Subject; currentGrades: Grade[]; } export function GradeCalculator({ subject, currentGrades }: GradeCalculatorProps) { const [targetGrade, setTargetGrade] = useState( subject.target_grade?.toString() || "" ); const [maxGradeValue, setMaxGradeValue] = useState( subject.grade_system === "german" ? "6" : "100" ); const [remainingAssignments, setRemainingAssignments] = useState<{ [key: string]: string; }>(() => { const initial: { [key: string]: string } = {}; subject.grading_categories.forEach((cat) => { initial[cat.name] = "1"; }); return initial; }); const [results, setResults] = useState(null); const [showCalculator, setShowCalculator] = useState(false); const handleCalculate = () => { if (!targetGrade || parseFloat(targetGrade) <= 0) { alert("Please enter a valid target grade"); return; } const maxGrade = parseFloat(maxGradeValue); const target = parseFloat(targetGrade); // Convert target to percentage let targetPercentage: number; if (subject.grade_system === "german" && maxGrade === 6) { // For German grades, convert using rough approximation if (target <= 1.5) targetPercentage = 92; else if (target <= 2.5) targetPercentage = 81; else if (target <= 3.5) targetPercentage = 67; else if (target <= 4.0) targetPercentage = 50; else if (target <= 5.0) targetPercentage = 30; else targetPercentage = 0; } else { targetPercentage = (target / maxGrade) * 100; } // Convert remaining assignments to numbers const remaining: { [key: string]: number } = {}; Object.keys(remainingAssignments).forEach((key) => { remaining[key] = parseInt(remainingAssignments[key]) || 0; }); const calculationResults = calculateRequiredGrade( subject, currentGrades, targetPercentage, remaining, maxGrade ); setResults(calculationResults); }; if (!showCalculator) { return (

🎯 What-If Grade Calculator

Calculate what grades you need on remaining assignments to reach your target

); } return (

🎯 What-If Grade Calculator

setTargetGrade(e.target.value)} placeholder={subject.grade_system === "german" ? "2.0" : "85"} step="0.01" />
setMaxGradeValue(e.target.value)} placeholder={subject.grade_system === "german" ? "6" : "100"} step="0.01" />
{subject.grading_categories.map((category) => (
{category.name} ({category.weight}%) setRemainingAssignments({ ...remainingAssignments, [category.name]: e.target.value, }) } min="0" step="1" className="w-20" />
))}
{results && (

Results:

{results.map((result) => (
90 ? "bg-yellow-50 border-yellow-500" : "bg-green-50 border-green-500" }`} >
{result.categoryName}

Weight: {result.categoryWeight}% of final grade

{result.requiredGrade.toFixed(2)} / {result.maxGrade}
({result.requiredPercentage.toFixed(1)}%)

{result.message}

))}

Note: These calculations assume each remaining assignment has equal weight (weight = 1.0) within its category. If your assignments have different weights, adjust accordingly.

)}
); }