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:
96
src/pages/VocabularyPage.tsx
Normal file
96
src/pages/VocabularyPage.tsx
Normal 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>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user