From 3e01fa47cd72def224b02e6cb9e5a93ce87e14bd Mon Sep 17 00:00:00 2001 From: Nathan Lamy Date: Wed, 20 Aug 2025 18:17:55 +0200 Subject: [PATCH] feat: add radar chart --- app/components/grades/inde.tsx | 729 -------------------------------- app/components/grades/index.tsx | 260 ++++++++---- 2 files changed, 178 insertions(+), 811 deletions(-) delete mode 100644 app/components/grades/inde.tsx diff --git a/app/components/grades/inde.tsx b/app/components/grades/inde.tsx deleted file mode 100644 index 3c08c91..0000000 --- a/app/components/grades/inde.tsx +++ /dev/null @@ -1,729 +0,0 @@ -import { useState } from "react"; -import { Button } from "~/components/ui/button"; -import { Badge } from "~/components/ui/badge"; -import { - ChartContainer, - ChartTooltip, - ChartTooltipContent, -} from "~/components/ui/chart"; -import { - LineChart, - Line, - BarChart, - Bar, - PieChart, - Pie, - Cell, - AreaChart, - Area, - RadarChart, - PolarGrid, - PolarAngleAxis, - PolarRadiusAxis, - Radar, - XAxis, - YAxis, - CartesianGrid, - ResponsiveContainer, - Legend, - Tooltip, - ReferenceLine, -} from "recharts"; -import { - Maximize2, - X, - TrendingUp, - Award, - BookOpen, - Target, -} from "lucide-react"; - -export const gradesTrendData = { - "This Month": [ - { - period: "Week 1", - math: 89, - science: 88, - english: 96, - history: 92, - average: 91.25, - }, - { - period: "Week 2", - math: 91, - science: 89, - english: 97, - history: 93, - average: 92.5, - }, - { - period: "Week 3", - math: 94, - science: 91, - english: 93, - history: 95, - average: 93.25, - }, - { - period: "Week 4", - math: 92, - science: 90, - english: 98, - history: 94, - average: 93.5, - }, - ], - "3 Months": [ - { - period: "Dec", - math: 89, - science: 88, - english: 96, - history: 92, - average: 91.25, - }, - { - period: "Jan", - math: 94, - science: 91, - english: 93, - history: 95, - average: 93.25, - }, - { - period: "Feb", - math: 91, - science: 89, - english: 97, - history: 93, - average: 92.5, - }, - ], - "Whole Year": [ - { - period: "Sep", - math: 85, - science: 78, - english: 92, - history: 88, - average: 85.75, - }, - { - period: "Oct", - math: 88, - science: 82, - english: 89, - history: 91, - average: 87.5, - }, - { - period: "Nov", - math: 92, - science: 85, - english: 94, - history: 89, - average: 90, - }, - { - period: "Dec", - math: 89, - science: 88, - english: 96, - history: 92, - average: 91.25, - }, - { - period: "Jan", - math: 94, - science: 91, - english: 93, - history: 95, - average: 93.25, - }, - { - period: "Feb", - math: 91, - science: 89, - english: 97, - history: 93, - average: 92.5, - }, - ], -}; - -const subjectPerformanceData = { - "This Month": [ - { subject: "Mathematics", grade: 94, target: 90, credits: 4 }, - { subject: "Science", grade: 91, target: 85, credits: 4 }, - { subject: "English", grade: 98, target: 92, credits: 3 }, - { subject: "History", grade: 95, target: 88, credits: 3 }, - { subject: "Art", grade: 96, target: 90, credits: 2 }, - { subject: "PE", grade: 90, target: 85, credits: 1 }, - ], - "3 Months": [ - { subject: "Mathematics", grade: 92, target: 90, credits: 4 }, - { subject: "Science", grade: 90, target: 85, credits: 4 }, - { subject: "English", grade: 96, target: 92, credits: 3 }, - { subject: "History", grade: 93, target: 88, credits: 3 }, - { subject: "Art", grade: 95, target: 90, credits: 2 }, - { subject: "PE", grade: 89, target: 85, credits: 1 }, - ], - "Whole Year": [ - { subject: "Mathematics", grade: 91, target: 90, credits: 4 }, - { subject: "Science", grade: 89, target: 85, credits: 4 }, - { subject: "English", grade: 97, target: 92, credits: 3 }, - { subject: "History", grade: 93, target: 88, credits: 3 }, - { subject: "Art", grade: 95, target: 90, credits: 2 }, - { subject: "PE", grade: 88, target: 85, credits: 1 }, - ], -}; - -const gradeDistributionData = { - "This Month": [ - { grade: "A+", count: 12, percentage: 35 }, - { grade: "A", count: 15, percentage: 44 }, - { grade: "A-", count: 5, percentage: 15 }, - { grade: "B+", count: 2, percentage: 6 }, - { grade: "B", count: 0, percentage: 0 }, - ], - "3 Months": [ - { grade: "A+", count: 10, percentage: 30 }, - { grade: "A", count: 14, percentage: 42 }, - { grade: "A-", count: 6, percentage: 18 }, - { grade: "B+", count: 3, percentage: 9 }, - { grade: "B", count: 1, percentage: 3 }, - ], - "Whole Year": [ - { grade: "A+", count: 8, percentage: 25 }, - { grade: "A", count: 12, percentage: 37.5 }, - { grade: "A-", count: 6, percentage: 18.75 }, - { grade: "B+", count: 4, percentage: 12.5 }, - { grade: "B", count: 2, percentage: 6.25 }, - ], -}; - -const skillsRadar = [ - { skill: "Problem Solving", score: 92 }, - { skill: "Critical Thinking", score: 88 }, - { skill: "Communication", score: 95 }, - { skill: "Creativity", score: 87 }, - { skill: "Collaboration", score: 91 }, - { skill: "Leadership", score: 85 }, -]; - -const COLORS = [ - "#8884d8", - "#82ca9d", - "#ffc658", - "#ff7300", - "#00ff00", - "#ff00ff", -]; -export const chartConfig = { - math: { label: "Mathematics", color: "hsl(var(--chart-1))" }, - science: { label: "Science", color: "hsl(var(--chart-2))" }, - english: { label: "English", color: "hsl(var(--chart-3))" }, - history: { label: "History", color: "hsl(var(--chart-4))" }, - average: { label: "Average", color: "hsl(var(--chart-5))" }, - }; -export default function SchoolStatsPage() { - const [fullscreenChart, setFullscreenChart] = useState(null); - const [selectedPeriod, setSelectedPeriod] = useState< - "This Month" | "3 Months" | "Whole Year" - >("3 Months"); - - const gradesTrend = gradesTrendData[selectedPeriod]; - const subjectPerformance = subjectPerformanceData[selectedPeriod]; - const gradeDistribution = gradeDistributionData[selectedPeriod]; - - - - const FullscreenModal = ({ - chartId, - title, - children, - }: { - chartId: string; - title: string; - children: React.ReactNode; - }) => { - if (fullscreenChart !== chartId) return null; - - return ( -
-
-
-

- {title} -

- -
-
- {children} -
-
-
- ); - }; - - const currentGPA = 3.7; - const totalCredits = 17; - const completedAssignments = 156; - const upcomingTests = 3; - - return ( -
-
- {/* Header */} -
-

Academic Dashboard

-

- Track your grades and progress -

-
- -
-
- {(["This Month", "3 Months", "Whole Year"] as const).map( - (period) => ( - - ) - )} -
-
- - {/* Key Stats - Mobile First Grid */} -
-
-
- - Current GPA - - -
-
{currentGPA}
-
- -
-
- - Credits - - -
-
{totalCredits}
-

This semester

-
- -
-
- - Assignments - - -
-
- {completedAssignments} -
-

Completed

-
- -
-
- - Tests - - -
-
{upcomingTests}
-

Upcoming

-
-
- - {/* Charts - Mobile First Layout */} -
- {/* Grade Trends */} -
-
-
-

- Grade Trends -

-

- {selectedPeriod === "This Month" - ? "Weekly" - : selectedPeriod === "3 Months" - ? "Monthly" - : "Monthly"}{" "} - performance across subjects -

-
- -
-
- - - - - - - } /> - - - - - - - - - -
-
- - {/* Subject Performance */} -
-
-
-

- Subject Performance -

-

- Current grades vs targets -

-
- -
-
- - - - - - - } /> - - - - - - -
-
- - {/* Grade Distribution & Skills - Side by Side on Desktop */} -
- {/* Grade Distribution */} -
-
-
-

- Grade Distribution -

-

- Breakdown of all grades -

-
- -
-
- - - - - `${grade} (${percentage}%)` - } - outerRadius={80} - fill="#8884d8" - dataKey="count" - > - {gradeDistribution.map((entry, index) => ( - - ))} - - } /> - - - -
-
- - {/* Skills Assessment */} -
-
-
-

- Skills Assessment -

-

- Competency across key areas -

-
- -
-
- - - - - - - - } /> - - - -
-
-
-
- - {/* Fullscreen Modals */} - - - - - - - - } /> - - - - - - - - - - - - - - - - - - - } /> - - - - - - - - - - - - - `${grade} (${percentage}%)`} - outerRadius={200} - fill="#8884d8" - dataKey="count" - > - {gradeDistribution.map((entry, index) => ( - - ))} - - } /> - - - - - - - - - - - - - - - } /> - - - - -
-
- ); -} diff --git a/app/components/grades/index.tsx b/app/components/grades/index.tsx index f9e1004..3d038d8 100644 --- a/app/components/grades/index.tsx +++ b/app/components/grades/index.tsx @@ -3,6 +3,11 @@ import { Legend, Line, LineChart, + PolarAngleAxis, + PolarGrid, + PolarRadiusAxis, + Radar, + RadarChart, ResponsiveContainer, XAxis, YAxis, @@ -12,16 +17,33 @@ import { ChartContainer, ChartTooltip, ChartTooltipContent } from "../ui/chart"; import { Award } from "lucide-react"; import { getSubjectColor, getSubjectEmoji } from "~/lib/utils"; import { useEffect, useState } from "react"; +import { Tabs, TabsList, tabsStyle, TabsTrigger } from "../ui/tabs"; + +const periods = [ + { + id: "YEAR", + label: "Cette année", + }, + { + id: "TRIMESTER", + label: "Ce trimestre", + }, + { + id: "MONTH", + label: "Ce mois", + }, +]; export default function GradesPage({ user }: { user: User }) { - // TODO: Error handling, loading state - const { grades, subjects, isLoading, isError } = useGrades("YEAR"); + const [period, setPeriod] = useState(periods[0].id); + + const { grades, subjects, isLoading, isError } = useGrades(period); const { subjectAverages, globalAverage, isLoading: loading, isError: error, - } = useAverages("YEAR"); + } = useAverages(period); const [hiddenSubjects, setHiddenSubjects] = useState([]); const toggleSubjectVisibility = (subject: string) => { @@ -52,90 +74,164 @@ export default function GradesPage({ user }: { user: User }) { return (
{/* Tabs */} + + + {periods.map((period) => ( + + {period.label} + + ))} + + - {/* Global average */} -
-
- - Moyenne générale - - + {isNaN(globalAverage) ? ( +
+ Aucune note disponible pour cette période.
-
{globalAverage} / 20
-
- - {/* Charts - Mobile First Layout */} -
- {/* Grade Trends */} -
-
-
-

- Votre progression -

-

- Suivez vos notes au fil du temps -

+ ) : isLoading || loading ? ( +
+ Chargement... +
+ ) : isError || error ? ( +
+ Une erreur est survenue lors de la récupération des données. +
+ ) : ( + <> + {/* Global average */} +
+
+ + Moyenne générale + + +
+
+ {globalAverage} / 20
-
- - - - - {/* TODO: Custom domain */} - - } /> - { - if (e.dataKey) { - toggleSubjectVisibility(e.dataKey as string); - } - }} - /> - {subjects.map((subject, index) => ( - - ))} - - - + + {/* Charts - Mobile First Layout */} +
+ {/* Grade Trends */} +
+
+
+

+ Votre progression +

+

+ Suivez vos notes au fil du temps +

+
+
+
+ + + + + + } /> + { + if (e.dataKey) { + toggleSubjectVisibility(e.dataKey as string); + } + }} + /> + {subjects.map((subject, index) => ( + + ))} + + + +
+
+ + {/* Radar chart */} +
+
+
+

+ Vos points forts +

+

+ Visualisez vos performances par matière +

+
+
+
+ + + + + + + } /> + + +
+
-
-
+ + )}
); }