feat(v3): restructure project + add complete frontend
- Restructure: move backend from new_project/ to backend/ - Add full React/TypeScript frontend (37 pages, 17 services, 16 type defs, 11 query hooks) - Add docs/ with SRS specs, user stories, and workflow documentation - Update .gitignore for new directory layout Workflows implemented: WF1 User Signup, WF2 Placement Test, WF3 Exam Configuration, WF4 General English Exam, WF5 Course Generation, WF6 Entity Student Onboarding, AI Course Generation, Adaptive Learning Engine UI, White-Label Branding, Score Release Made-with: Cursor
This commit is contained in:
79
src/pages/StudentPerformancePage.tsx
Normal file
79
src/pages/StudentPerformancePage.tsx
Normal file
@@ -0,0 +1,79 @@
|
||||
import { Card, CardContent } from "@/components/ui/card";
|
||||
import { Badge } from "@/components/ui/badge";
|
||||
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
|
||||
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table";
|
||||
import { Switch } from "@/components/ui/switch";
|
||||
import { Label } from "@/components/ui/label";
|
||||
import { useState } from "react";
|
||||
import AiStudyCoach from "@/components/ai/AiStudyCoach";
|
||||
import AiGradeExplainer from "@/components/ai/AiGradeExplainer";
|
||||
|
||||
const students = [
|
||||
{ name: "Sarah Johnson", entity: "Acme Corp", reading: 7.5, listening: 8.0, writing: 7.0, speaking: 7.5, overall: 7.5, level: "B2" },
|
||||
{ name: "Ahmed Hassan", entity: "Global Ltd", reading: 5.5, listening: 6.0, writing: 5.0, speaking: 5.5, overall: 5.5, level: "A2" },
|
||||
{ name: "Maria Garcia", entity: "Acme Corp", reading: 8.5, listening: 8.0, writing: 8.0, speaking: 8.5, overall: 8.25, level: "C1" },
|
||||
{ name: "Li Wei", entity: "Tech Co", reading: 6.5, listening: 6.0, writing: 6.0, speaking: 6.5, overall: 6.25, level: "B1" },
|
||||
{ name: "Emma Brown", entity: "Acme Corp", reading: 4.5, listening: 5.0, writing: 4.0, speaking: 4.5, overall: 4.5, level: "A1" },
|
||||
{ name: "John Park", entity: "Global Ltd", reading: 7.0, listening: 7.5, writing: 6.5, speaking: 7.0, overall: 7.0, level: "B2" },
|
||||
];
|
||||
|
||||
function ScoreBadge({ score }: { score: number }) {
|
||||
const color = score >= 7.5 ? "bg-success/10 text-success" : score >= 6.0 ? "bg-warning/10 text-warning" : "bg-destructive/10 text-destructive";
|
||||
return <span className={`inline-flex items-center rounded-md px-2 py-0.5 text-xs font-semibold ${color}`}>{score.toFixed(1)}</span>;
|
||||
}
|
||||
|
||||
export default function StudentPerformancePage() {
|
||||
const [showUtilisation, setShowUtilisation] = useState(false);
|
||||
|
||||
return (
|
||||
<div className="space-y-6">
|
||||
<div>
|
||||
<h1 className="text-2xl font-bold tracking-tight">Student Performance</h1>
|
||||
<p className="text-muted-foreground">Track student scores across all IELTS modules.</p>
|
||||
</div>
|
||||
|
||||
<AiStudyCoach />
|
||||
|
||||
<div className="flex flex-wrap gap-3 items-center">
|
||||
<Select><SelectTrigger className="w-[160px]"><SelectValue placeholder="All Entities" /></SelectTrigger>
|
||||
<SelectContent><SelectItem value="all">All Entities</SelectItem><SelectItem value="acme">Acme Corp</SelectItem><SelectItem value="global">Global Ltd</SelectItem></SelectContent>
|
||||
</Select>
|
||||
<div className="flex items-center gap-2 ml-auto">
|
||||
<Switch id="util" checked={showUtilisation} onCheckedChange={setShowUtilisation} />
|
||||
<Label htmlFor="util" className="text-sm">Show Utilisation</Label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<Card className="border-0 shadow-sm">
|
||||
<CardContent className="p-0">
|
||||
<Table>
|
||||
<TableHeader>
|
||||
<TableRow>
|
||||
<TableHead>Student</TableHead><TableHead>Entity</TableHead><TableHead>Level</TableHead>
|
||||
<TableHead className="text-center">Reading</TableHead><TableHead className="text-center">Listening</TableHead>
|
||||
<TableHead className="text-center">Writing</TableHead><TableHead className="text-center">Speaking</TableHead>
|
||||
<TableHead className="text-center">Overall</TableHead>
|
||||
<TableHead className="w-10">AI</TableHead>
|
||||
</TableRow>
|
||||
</TableHeader>
|
||||
<TableBody>
|
||||
{students.map((s) => (
|
||||
<TableRow key={s.name}>
|
||||
<TableCell className="font-medium">{s.name}</TableCell>
|
||||
<TableCell>{s.entity}</TableCell>
|
||||
<TableCell><Badge variant="outline">{s.level}</Badge></TableCell>
|
||||
<TableCell className="text-center"><ScoreBadge score={s.reading} /></TableCell>
|
||||
<TableCell className="text-center"><ScoreBadge score={s.listening} /></TableCell>
|
||||
<TableCell className="text-center"><ScoreBadge score={s.writing} /></TableCell>
|
||||
<TableCell className="text-center"><ScoreBadge score={s.speaking} /></TableCell>
|
||||
<TableCell className="text-center"><ScoreBadge score={s.overall} /></TableCell>
|
||||
<TableCell><AiGradeExplainer studentName={s.name} /></TableCell>
|
||||
</TableRow>
|
||||
))}
|
||||
</TableBody>
|
||||
</Table>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user