React 18 + TypeScript + Vite 5 + Tailwind CSS + shadcn/ui frontend: - Multi-role auth: student, teacher, admin, corporate, agent, developer - Student portal: dashboard, courses, adaptive learning, exams, placement - Teacher portal: courses, assignments, grading, attendance, AI workbench - Admin portal: 60+ management pages (LMS, exams, users, entities, AI) - AI-powered features: study coach, generation page, gap analysis, TTS - Exam system: session, auto-save, results, grading queue - Full IELTS workflow: reading/listening/writing/speaking modules Made-with: Cursor
95 lines
5.2 KiB
TypeScript
95 lines
5.2 KiB
TypeScript
import { useState } from "react";
|
|
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
|
|
import { Progress } from "@/components/ui/progress";
|
|
import { Badge } from "@/components/ui/badge";
|
|
import { Switch } from "@/components/ui/switch";
|
|
import { Label } from "@/components/ui/label";
|
|
import { CheckCircle, PenTool, Sparkles } from "lucide-react";
|
|
import AiTipBanner from "@/components/ai/AiTipBanner";
|
|
|
|
const grammarItems = [
|
|
{ rule: "Conditional Sentences (Type 2 & 3)", description: "If + past simple / past perfect for hypothetical situations", level: "B2", completed: true },
|
|
{ rule: "Passive Voice in Academic Writing", description: "Using passive constructions in formal reports", level: "B2", completed: false },
|
|
{ rule: "Relative Clauses", description: "Defining vs non-defining relative clauses", level: "B1", completed: true },
|
|
{ rule: "Subject-Verb Agreement", description: "Complex subjects with prepositional phrases", level: "B1", completed: false },
|
|
{ rule: "Modal Verbs for Speculation", description: "Must have, could have, might have + past participle", level: "C1", completed: false },
|
|
{ rule: "Reported Speech", description: "Tense changes and time references in indirect speech", level: "B2", completed: true },
|
|
];
|
|
|
|
export default function GrammarPage() {
|
|
const [showCompleted, setShowCompleted] = useState(false);
|
|
const completed = grammarItems.filter(g => g.completed).length;
|
|
const filtered = showCompleted ? grammarItems : grammarItems.filter(g => !g.completed);
|
|
|
|
return (
|
|
<div className="space-y-6">
|
|
<div>
|
|
<h1 className="text-2xl font-bold tracking-tight">Grammar Training</h1>
|
|
<p className="text-muted-foreground">Master grammar rules essential for IELTS.</p>
|
|
</div>
|
|
|
|
<AiTipBanner context="grammar" variant="recommendation" />
|
|
|
|
<div className="grid grid-cols-1 lg:grid-cols-3 gap-6">
|
|
<div className="lg:col-span-2 space-y-4">
|
|
<Card className="border-0 shadow-sm">
|
|
<CardHeader className="pb-3">
|
|
<div className="flex items-center justify-between">
|
|
<CardTitle className="text-base">Progress</CardTitle>
|
|
<span className="text-sm text-muted-foreground">{completed}/{grammarItems.length} completed</span>
|
|
</div>
|
|
</CardHeader>
|
|
<CardContent>
|
|
<Progress value={(completed / grammarItems.length) * 100} className="h-3" />
|
|
</CardContent>
|
|
</Card>
|
|
|
|
<div className="flex items-center gap-2">
|
|
<Switch id="show" checked={showCompleted} onCheckedChange={setShowCompleted} />
|
|
<Label htmlFor="show" className="text-sm">Show completed</Label>
|
|
</div>
|
|
|
|
<div className="space-y-2">
|
|
{filtered.map((g) => (
|
|
<Card key={g.rule} className="border-0 shadow-sm">
|
|
<CardContent className="p-4 flex items-center justify-between">
|
|
<div className="flex items-center gap-3">
|
|
{g.completed && <CheckCircle className="h-4 w-4 text-success shrink-0" />}
|
|
<div>
|
|
<p className="font-semibold text-sm">{g.rule}</p>
|
|
<p className="text-xs text-muted-foreground">{g.description}</p>
|
|
</div>
|
|
</div>
|
|
<Badge variant="outline">{g.level}</Badge>
|
|
</CardContent>
|
|
</Card>
|
|
))}
|
|
</div>
|
|
</div>
|
|
|
|
<div className="space-y-4">
|
|
<Card className="border-0 shadow-sm">
|
|
<CardHeader className="pb-3">
|
|
<CardTitle className="text-base flex items-center gap-2"><Sparkles className="h-4 w-4 text-primary" /> AI Recommendations</CardTitle>
|
|
</CardHeader>
|
|
<CardContent>
|
|
<ul className="space-y-2">
|
|
<li className="text-sm text-muted-foreground flex items-start gap-2"><span className="text-primary font-bold">•</span>Practice passive voice transformations — high exam frequency</li>
|
|
<li className="text-sm text-muted-foreground flex items-start gap-2"><span className="text-primary font-bold">•</span>Review modal verbs for IELTS Writing Task 1</li>
|
|
<li className="text-sm text-muted-foreground flex items-start gap-2"><span className="text-primary font-bold">•</span>Focus on complex sentence structures for C1 readiness</li>
|
|
<li className="text-sm text-muted-foreground flex items-start gap-2"><span className="text-primary font-bold">•</span>Your conditional sentences are strong — try advanced mixed conditionals</li>
|
|
</ul>
|
|
</CardContent>
|
|
</Card>
|
|
<Card className="border-0 shadow-sm border-primary/20 bg-primary/5">
|
|
<CardContent className="p-4">
|
|
<p className="text-xs font-semibold text-primary flex items-center gap-1 mb-2"><Sparkles className="h-3 w-3" /> AI Study Plan</p>
|
|
<p className="text-sm text-muted-foreground">Based on your progress, complete Passive Voice and Subject-Verb Agreement this week. At your current pace, you'll finish all B2 grammar by April 15.</p>
|
|
</CardContent>
|
|
</Card>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|