import { useState, useEffect } from 'react'; import { Download, Trash2, RefreshCw, AlertCircle } from 'lucide-react'; import jsPDF from 'jspdf'; export default function ClusterCalculator() { const [grades, setGrades] = useState({ mathematics: '', english: '', kiswahili: '', chemistry: '', biology: '', physics: '', geography: '', history: '', cre: '', ire: '', hre: '', homeScience: '', agriculture: '', computerStudies: '', aviation: '', woodwork: '', metalwork: '', building: '', art: '', business: '', german: '', french: '', music: '', }); const [totalPoints, setTotalPoints] = useState(''); const [clusterPoints, setClusterPoints] = useState(null); const [error, setError] = useState(''); const [isCalculating, setIsCalculating] = useState(false); const gradeToPoints = { 'A': 12, 'A-': 11, 'B+': 10, 'B': 9, 'B-': 8, 'C+': 7, 'C': 6, 'C-': 5, 'D+': 4, 'D': 3, 'D-': 2, 'E': 1 }; const subjectGroups = { compulsory: ['mathematics', 'english', 'kiswahili'], sciences: ['chemistry', 'biology', 'physics'], humanities: ['geography', 'history', 'cre', 'ire', 'hre'], technical: ['homeScience', 'agriculture', 'computerStudies', 'aviation', 'woodwork', 'metalwork', 'building', 'art'], others: ['business', 'german', 'french', 'music'] }; const handleGradeChange = (subject, value) => { setGrades(prev => ({ ...prev, [subject]: value })); setError(''); }; const validateInputs = () => { const selectedSubjects = Object.entries(grades).filter(([_, grade]) => grade !== '').length; if (selectedSubjects < 7) { setError('Please select at least 7 subjects including all compulsory subjects'); return false; } if (!totalPoints) { setError('Please enter your total points'); return false; } return true; }; const getPoints = (subject) => grades[subject] ? gradeToPoints[grades[subject]] || 0 : 0; const getMaxPoints = (subjects) => { return Math.max(...subjects.map(subject => getPoints(subject)), 0); }; const calculateCluster = (subjectSelections) => { const r = subjectSelections.reduce((sum, points) => sum + points, 0); const R = 48; const t = parseInt(totalPoints); const T = 84; if (!t || r === 0) return 0; return Math.sqrt((r/R) * (t/T)) * 48; }; const calculateAllClusters = () => { if (!validateInputs()) return; setIsCalculating(true); const results = {}; // Calculate for all 23 clusters // Example for a few clusters (you would implement all 23 following similar pattern): // Cluster 1 results['Cluster 1'] = calculateCluster([ Math.max(getPoints('english'), getPoints('kiswahili')), getPoints('mathematics'), getMaxPoints(['geography', 'history', 'cre', 'ire', 'hre']), getMaxPoints([...subjectGroups.sciences, ...subjectGroups.humanities, ...subjectGroups.technical, ...subjectGroups.others]) ]); // Cluster 2 results['Cluster 2'] = calculateCluster([ Math.max(getPoints('english'), getPoints('kiswahili')), getPoints('mathematics'), getMaxPoints([...subjectGroups.sciences, ...subjectGroups.humanities]), getMaxPoints([...subjectGroups.sciences, ...subjectGroups.humanities, ...subjectGroups.technical, ...subjectGroups.others]) ]); // Add calculations for remaining clusters... setClusterPoints(results); setIsCalculating(false); }; const downloadPDF = () => { const doc = new jsPDF(); doc.setFontSize(16); doc.text('KCSE Cluster Points Results', 20, 20); doc.setFontSize(12); let yPos = 40; Object.entries(clusterPoints).forEach(([cluster, points]) => { doc.text(`${cluster}: ${points.toFixed(4)}`, 20, yPos); yPos += 10; }); doc.save('cluster-points.pdf'); }; const clearAll = () => { setGrades({}); setTotalPoints(''); setClusterPoints(null); setError(''); }; return (

KCSE Cluster Points Calculator

{error && (

{error}

)}
{/* Group I: Compulsory Subjects */}

Group I: Compulsory

{subjectGroups.compulsory.map(subject => (
))}
{/* Group II: Sciences */}

Group II: Sciences

{subjectGroups.sciences.map(subject => (
))}
{/* Add remaining subject groups with similar styling */}
setTotalPoints(e.target.value)} className="mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-blue-500 focus:ring-blue-500 transition-all duration-300" placeholder="Enter total points" />
{clusterPoints && ( )}
{clusterPoints && (

Results

{Object.entries(clusterPoints).map(([cluster, points]) => (

{cluster}

{points.toFixed(4)}

))}
)}
); }