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:
Yamen Ahmad
2026-04-10 17:26:42 +04:00
commit 11a7265460
392 changed files with 62287 additions and 0 deletions

View File

@@ -0,0 +1,96 @@
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, BookA, Sparkles } from "lucide-react";
import AiTipBanner from "@/components/ai/AiTipBanner";
const vocabItems = [
{ word: "Ubiquitous", meaning: "Present, appearing, or found everywhere", level: "C1", completed: true },
{ word: "Pragmatic", meaning: "Dealing with things sensibly and realistically", level: "B2", completed: true },
{ word: "Eloquent", meaning: "Fluent or persuasive in speaking or writing", level: "C1", completed: false },
{ word: "Meticulous", meaning: "Showing great attention to detail", level: "B2", completed: false },
{ word: "Ambiguous", meaning: "Open to more than one interpretation", level: "B2", completed: false },
{ word: "Coherent", meaning: "Logical and consistent", level: "B1", completed: false },
{ word: "Versatile", meaning: "Able to adapt to many different functions", level: "B2", completed: true },
{ word: "Concise", meaning: "Giving a lot of information in few words", level: "B1", completed: false },
];
export default function VocabularyPage() {
const [showCompleted, setShowCompleted] = useState(false);
const completed = vocabItems.filter(v => v.completed).length;
const filtered = showCompleted ? vocabItems : vocabItems.filter(v => !v.completed);
return (
<div className="space-y-6">
<div>
<h1 className="text-2xl font-bold tracking-tight">Vocabulary Training</h1>
<p className="text-muted-foreground">Build your vocabulary for IELTS success.</p>
</div>
<AiTipBanner context="vocabulary" 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}/{vocabItems.length} completed</span>
</div>
</CardHeader>
<CardContent>
<Progress value={(completed / vocabItems.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((v) => (
<Card key={v.word} className="border-0 shadow-sm">
<CardContent className="p-4 flex items-center justify-between">
<div className="flex items-center gap-3">
{v.completed && <CheckCircle className="h-4 w-4 text-success shrink-0" />}
<div>
<p className="font-semibold text-sm">{v.word}</p>
<p className="text-xs text-muted-foreground">{v.meaning}</p>
</div>
</div>
<Badge variant="outline">{v.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>Learn "coherent" + "concise" together they share academic writing context</li>
<li className="text-sm text-muted-foreground flex items-start gap-2"><span className="text-primary font-bold"></span>Review C1-level vocabulary for IELTS Task 2</li>
<li className="text-sm text-muted-foreground flex items-start gap-2"><span className="text-primary font-bold"></span>Focus on collocations with 'make' and 'do'</li>
<li className="text-sm text-muted-foreground flex items-start gap-2"><span className="text-primary font-bold"></span>Try using "meticulous" in your next writing practice</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 Vocabulary Goal</p>
<p className="text-sm text-muted-foreground">At 2 words/day, you'll complete this set by March 15. AI recommends adding 10 more domain-specific words from your upcoming exam topics.</p>
</CardContent>
</Card>
</div>
</div>
</div>
);
}