first commit
This commit is contained in:
280
app/(home)/main/page.tsx
Normal file
280
app/(home)/main/page.tsx
Normal file
@@ -0,0 +1,280 @@
|
||||
"use client"
|
||||
|
||||
import { useState } from "react"
|
||||
import { Card } from "@/components/ui/card"
|
||||
import { Button } from "@/components/ui/button"
|
||||
import {
|
||||
BookOpen,
|
||||
Trophy,
|
||||
Target,
|
||||
TrendingUp,
|
||||
Clock,
|
||||
Award,
|
||||
CheckCircle2,
|
||||
PlayCircle
|
||||
} from "lucide-react"
|
||||
|
||||
export default function Home() {
|
||||
const [activeTab, setActiveTab] = useState("main")
|
||||
|
||||
// Mock data для демонстрации
|
||||
const stats = {
|
||||
coursesInProgress: 3,
|
||||
completedCourses: 12,
|
||||
totalPoints: 2450,
|
||||
rank: "Advanced"
|
||||
}
|
||||
|
||||
const recentCourses = [
|
||||
{ id: 1, title: "Advanced React Patterns", progress: 65, time: "2h 30m left" },
|
||||
{ id: 2, title: "System Design", progress: 40, time: "5h 15m left" },
|
||||
{ id: 3, title: "TypeScript Deep Dive", progress: 85, time: "45m left" }
|
||||
]
|
||||
|
||||
const achievements = [
|
||||
{ id: 1, title: "Fast Learner", icon: Trophy, unlocked: true },
|
||||
{ id: 2, title: "Course Master", icon: Award, unlocked: true },
|
||||
{ id: 3, title: "Consistency King", icon: Target, unlocked: false }
|
||||
]
|
||||
|
||||
return (
|
||||
<div className="min-h-screen bg-[#0a0e1a]">
|
||||
{/* Header */}
|
||||
<header className="bg-[#0d1117] border-b border-cyan-500/30 sticky top-0 z-50 backdrop-blur-sm">
|
||||
<nav className="container mx-auto px-6 py-4">
|
||||
<div className="flex items-center justify-center">
|
||||
<div className="flex items-center gap-12">
|
||||
<button
|
||||
onClick={() => setActiveTab("main")}
|
||||
className={`text-sm font-bold tracking-[0.2em] transition-all duration-200 font-mono uppercase ${
|
||||
activeTab === "main"
|
||||
? "text-cyan-400"
|
||||
: "text-cyan-500/50 hover:text-cyan-400/80"
|
||||
}`}
|
||||
>
|
||||
Main
|
||||
</button>
|
||||
<button
|
||||
onClick={() => setActiveTab("progress")}
|
||||
className={`text-sm font-bold tracking-[0.2em] transition-all duration-200 font-mono uppercase ${
|
||||
activeTab === "progress"
|
||||
? "text-cyan-400"
|
||||
: "text-cyan-500/50 hover:text-cyan-400/80"
|
||||
}`}
|
||||
>
|
||||
Progress
|
||||
</button>
|
||||
<button
|
||||
onClick={() => setActiveTab("profile")}
|
||||
className={`text-sm font-bold tracking-[0.2em] transition-all duration-200 font-mono uppercase ${
|
||||
activeTab === "profile"
|
||||
? "text-cyan-400"
|
||||
: "text-cyan-500/50 hover:text-cyan-400/80"
|
||||
}`}
|
||||
>
|
||||
Profile
|
||||
</button>
|
||||
<button
|
||||
onClick={() => setActiveTab("rules")}
|
||||
className={`text-sm font-bold tracking-[0.2em] transition-all duration-200 font-mono uppercase ${
|
||||
activeTab === "rules"
|
||||
? "text-cyan-400"
|
||||
: "text-cyan-500/50 hover:text-cyan-400/80"
|
||||
}`}
|
||||
>
|
||||
Rules
|
||||
</button>
|
||||
<button
|
||||
onClick={() => setActiveTab("login")}
|
||||
className={`text-sm font-bold tracking-[0.2em] transition-all duration-200 font-mono uppercase ${
|
||||
activeTab === "login"
|
||||
? "text-cyan-400"
|
||||
: "text-cyan-500/50 hover:text-cyan-400/80"
|
||||
}`}
|
||||
>
|
||||
Login
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
</header>
|
||||
|
||||
{/* Main Content */}
|
||||
<main className="container mx-auto px-6 py-8">
|
||||
{/* Stats Grid */}
|
||||
<div className="grid grid-cols-1 md:grid-cols-4 gap-6 mb-8">
|
||||
<Card className="bg-[#0d1117] border-2 border-cyan-500/20 p-6 hover:border-cyan-500/40 transition-all group">
|
||||
<div className="flex items-center justify-between mb-2">
|
||||
<BookOpen className="w-8 h-8 text-cyan-400 group-hover:scale-110 transition-transform" />
|
||||
<span className="text-xs font-mono text-cyan-400/50">IN PROGRESS</span>
|
||||
</div>
|
||||
<div className="text-3xl font-bold text-cyan-400 font-mono">
|
||||
{stats.coursesInProgress}
|
||||
</div>
|
||||
<p className="text-sm text-cyan-400/60 font-mono mt-1">Active Courses</p>
|
||||
</Card>
|
||||
|
||||
<Card className="bg-[#0d1117] border-2 border-cyan-500/20 p-6 hover:border-cyan-500/40 transition-all group">
|
||||
<div className="flex items-center justify-between mb-2">
|
||||
<CheckCircle2 className="w-8 h-8 text-cyan-400 group-hover:scale-110 transition-transform" />
|
||||
<span className="text-xs font-mono text-cyan-400/50">COMPLETED</span>
|
||||
</div>
|
||||
<div className="text-3xl font-bold text-cyan-400 font-mono">
|
||||
{stats.completedCourses}
|
||||
</div>
|
||||
<p className="text-sm text-cyan-400/60 font-mono mt-1">Finished</p>
|
||||
</Card>
|
||||
|
||||
<Card className="bg-[#0d1117] border-2 border-cyan-500/20 p-6 hover:border-cyan-500/40 transition-all group">
|
||||
<div className="flex items-center justify-between mb-2">
|
||||
<Trophy className="w-8 h-8 text-cyan-400 group-hover:scale-110 transition-transform" />
|
||||
<span className="text-xs font-mono text-cyan-400/50">TOTAL</span>
|
||||
</div>
|
||||
<div className="text-3xl font-bold text-cyan-400 font-mono">
|
||||
{stats.totalPoints}
|
||||
</div>
|
||||
<p className="text-sm text-cyan-400/60 font-mono mt-1">Points Earned</p>
|
||||
</Card>
|
||||
|
||||
<Card className="bg-[#0d1117] border-2 border-cyan-500/20 p-6 hover:border-cyan-500/40 transition-all group">
|
||||
<div className="flex items-center justify-between mb-2">
|
||||
<TrendingUp className="w-8 h-8 text-cyan-400 group-hover:scale-110 transition-transform" />
|
||||
<span className="text-xs font-mono text-cyan-400/50">RANK</span>
|
||||
</div>
|
||||
<div className="text-3xl font-bold text-cyan-400 font-mono">
|
||||
{stats.rank}
|
||||
</div>
|
||||
<p className="text-sm text-cyan-400/60 font-mono mt-1">Current Level</p>
|
||||
</Card>
|
||||
</div>
|
||||
|
||||
<div className="grid grid-cols-1 lg:grid-cols-3 gap-6">
|
||||
{/* Continue Learning Section */}
|
||||
<Card className="lg:col-span-2 bg-[#0d1117] border-2 border-cyan-500/30 p-6">
|
||||
<div className="flex items-center justify-between mb-6">
|
||||
<h2 className="text-2xl font-bold text-cyan-400 font-mono">
|
||||
Continue Learning
|
||||
</h2>
|
||||
<Button
|
||||
variant="outline"
|
||||
className="border-cyan-500/50 text-cyan-400 hover:bg-cyan-500/10 font-mono text-xs"
|
||||
>
|
||||
VIEW ALL
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
<div className="space-y-4">
|
||||
{recentCourses.map((course) => (
|
||||
<Card
|
||||
key={course.id}
|
||||
className="bg-[#0a0e1a] border border-cyan-500/20 p-4 hover:border-cyan-500/40 transition-all group cursor-pointer"
|
||||
>
|
||||
<div className="flex items-start justify-between mb-3">
|
||||
<div className="flex-1">
|
||||
<h3 className="text-lg font-bold text-cyan-400 font-mono mb-1 group-hover:text-cyan-300 transition-colors">
|
||||
{course.title}
|
||||
</h3>
|
||||
<div className="flex items-center gap-2 text-xs text-cyan-400/50 font-mono">
|
||||
<Clock className="w-3 h-3" />
|
||||
{course.time}
|
||||
</div>
|
||||
</div>
|
||||
<Button
|
||||
size="sm"
|
||||
className="bg-cyan-500 hover:bg-cyan-400 text-black font-mono"
|
||||
>
|
||||
<PlayCircle className="w-4 h-4 mr-1" />
|
||||
RESUME
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
{/* Progress Bar */}
|
||||
<div className="space-y-2">
|
||||
<div className="flex items-center justify-between text-xs font-mono">
|
||||
<span className="text-cyan-400/60">Progress</span>
|
||||
<span className="text-cyan-400">{course.progress}%</span>
|
||||
</div>
|
||||
<div className="h-2 bg-[#0d1117] rounded-full overflow-hidden">
|
||||
<div
|
||||
className="h-full bg-gradient-to-r from-cyan-500 to-blue-500 rounded-full transition-all duration-500"
|
||||
style={{ width: `${course.progress}%` }}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</Card>
|
||||
))}
|
||||
</div>
|
||||
</Card>
|
||||
|
||||
{/* Achievements Section */}
|
||||
<Card className="bg-[#0d1117] border-2 border-cyan-500/30 p-6">
|
||||
<h2 className="text-2xl font-bold text-cyan-400 font-mono mb-6">
|
||||
Achievements
|
||||
</h2>
|
||||
|
||||
<div className="space-y-4">
|
||||
{achievements.map((achievement) => {
|
||||
const Icon = achievement.icon
|
||||
return (
|
||||
<Card
|
||||
key={achievement.id}
|
||||
className={`p-4 transition-all ${
|
||||
achievement.unlocked
|
||||
? 'bg-cyan-500/10 border-cyan-500/40'
|
||||
: 'bg-[#0a0e1a] border-cyan-500/10 opacity-50'
|
||||
}`}
|
||||
>
|
||||
<div className="flex items-center gap-3">
|
||||
<div className={`w-12 h-12 rounded-lg flex items-center justify-center ${
|
||||
achievement.unlocked
|
||||
? 'bg-cyan-500/20'
|
||||
: 'bg-cyan-500/5'
|
||||
}`}>
|
||||
<Icon className={`w-6 h-6 ${
|
||||
achievement.unlocked
|
||||
? 'text-cyan-400'
|
||||
: 'text-cyan-400/30'
|
||||
}`} />
|
||||
</div>
|
||||
<div className="flex-1">
|
||||
<h3 className={`font-bold font-mono text-sm ${
|
||||
achievement.unlocked
|
||||
? 'text-cyan-400'
|
||||
: 'text-cyan-400/30'
|
||||
}`}>
|
||||
{achievement.title}
|
||||
</h3>
|
||||
<p className="text-xs text-cyan-400/50 font-mono">
|
||||
{achievement.unlocked ? 'Unlocked' : 'Locked'}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</Card>
|
||||
)
|
||||
})}
|
||||
</div>
|
||||
|
||||
<Button
|
||||
className="w-full mt-6 bg-[#0a0e1a] border border-cyan-500/30 text-cyan-400 hover:bg-cyan-500/10 font-mono"
|
||||
variant="outline"
|
||||
>
|
||||
VIEW ALL ACHIEVEMENTS
|
||||
</Button>
|
||||
</Card>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
{/* Subtle grid background */}
|
||||
<div
|
||||
className="fixed inset-0 pointer-events-none -z-10"
|
||||
style={{
|
||||
backgroundImage: `
|
||||
linear-gradient(rgba(6, 182, 212, 0.03) 1px, transparent 1px),
|
||||
linear-gradient(90deg, rgba(6, 182, 212, 0.03) 1px, transparent 1px)
|
||||
`,
|
||||
backgroundSize: '50px 50px'
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
236
app/(home)/main/profile/page.tsx
Normal file
236
app/(home)/main/profile/page.tsx
Normal file
@@ -0,0 +1,236 @@
|
||||
"use client"
|
||||
|
||||
import { useState } from "react"
|
||||
import { Card } from "@/components/ui/card"
|
||||
import { Button } from "@/components/ui/button"
|
||||
import { Progress } from "@/components/ui/progress"
|
||||
import { User, Award, BookOpen, Trophy, Star } from "lucide-react"
|
||||
import Link from "next/link"
|
||||
|
||||
export default function ProfilePage() {
|
||||
const [activeTab, setActiveTab] = useState("profile")
|
||||
|
||||
// Mock user data
|
||||
const userData = {
|
||||
name: "Alex Johnson",
|
||||
level: 5,
|
||||
xp: 2450,
|
||||
maxXp: 3000,
|
||||
rank: "Advanced",
|
||||
achievements: 8,
|
||||
coursesCompleted: 12,
|
||||
totalStudyTime: "124h"
|
||||
}
|
||||
|
||||
const stats = [
|
||||
{ label: "Level", value: userData.level, icon: Star },
|
||||
{ label: "XP", value: `${userData.xp}/${userData.maxXp}`, icon: Trophy },
|
||||
{ label: "Rank", value: userData.rank, icon: Award }
|
||||
]
|
||||
|
||||
const achievements = [
|
||||
{ title: "First Steps", description: "Complete your first course", unlocked: true },
|
||||
{ title: "Quick Learner", description: "Complete a course in under 24h", unlocked: true },
|
||||
{ title: "Dedication", description: "Study 7 days in a row", unlocked: true },
|
||||
{ title: "Master", description: "Complete 10 courses", unlocked: true },
|
||||
{ title: "Expert", description: "Reach level 5", unlocked: true },
|
||||
{ title: "Marathon", description: "Study for 100 hours", unlocked: true },
|
||||
{ title: "Perfectionist", description: "Score 100% on 5 tests", unlocked: false },
|
||||
{ title: "Legend", description: "Reach level 10", unlocked: false }
|
||||
]
|
||||
|
||||
return (
|
||||
<div className="min-h-screen bg-[#0a0e1a]">
|
||||
{/* Header */}
|
||||
<header className="bg-[#0d1117] border-b border-cyan-500/30 sticky top-0 z-50">
|
||||
<nav className="container mx-auto px-6 py-4">
|
||||
<div className="flex items-center justify-center">
|
||||
<div className="flex items-center gap-12">
|
||||
<Link href="/home/main">
|
||||
<button
|
||||
className="text-sm font-bold tracking-[0.2em] transition-all duration-200 font-mono uppercase text-cyan-500/50 hover:text-cyan-400/80"
|
||||
>
|
||||
Main
|
||||
</button>
|
||||
</Link>
|
||||
<Link href="/home/progress">
|
||||
<button
|
||||
className="text-sm font-bold tracking-[0.2em] transition-all duration-200 font-mono uppercase text-cyan-500/50 hover:text-cyan-400/80"
|
||||
>
|
||||
Progress
|
||||
</button>
|
||||
</Link>
|
||||
<button
|
||||
onClick={() => setActiveTab("profile")}
|
||||
className="text-sm font-bold tracking-[0.2em] transition-all duration-200 font-mono uppercase text-cyan-400"
|
||||
>
|
||||
Profile
|
||||
</button>
|
||||
<Link href="/home/rules">
|
||||
<button
|
||||
className="text-sm font-bold tracking-[0.2em] transition-all duration-200 font-mono uppercase text-cyan-500/50 hover:text-cyan-400/80"
|
||||
>
|
||||
Rules
|
||||
</button>
|
||||
</Link>
|
||||
<Link href="/login">
|
||||
<button
|
||||
className="text-sm font-bold tracking-[0.2em] transition-all duration-200 font-mono uppercase text-cyan-500/50 hover:text-cyan-400/80"
|
||||
>
|
||||
Login
|
||||
</button>
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
</header>
|
||||
|
||||
{/* Main Content */}
|
||||
<main className="container mx-auto px-6 py-8 max-w-6xl">
|
||||
<div className="grid grid-cols-1 lg:grid-cols-3 gap-6">
|
||||
{/* User Profile Card */}
|
||||
<Card className="lg:col-span-1 bg-[#0d1117] border-2 border-cyan-500/30 p-6">
|
||||
<div className="text-center">
|
||||
{/* Avatar */}
|
||||
<div className="w-32 h-32 bg-gradient-to-br from-cyan-500/20 to-blue-500/20 rounded-full flex items-center justify-center mx-auto mb-4 border-4 border-cyan-500/30">
|
||||
<User className="w-16 h-16 text-cyan-400" />
|
||||
</div>
|
||||
|
||||
{/* User Info */}
|
||||
<h2 className="text-2xl font-bold text-cyan-400 font-mono mb-1">
|
||||
{userData.name}
|
||||
</h2>
|
||||
<p className="text-cyan-400/60 font-mono text-sm mb-6">
|
||||
{userData.rank} • Level {userData.level}
|
||||
</p>
|
||||
|
||||
{/* XP Progress */}
|
||||
<div className="mb-6">
|
||||
<div className="flex justify-between items-center mb-2">
|
||||
<span className="text-xs font-mono text-cyan-400/60">XP Progress</span>
|
||||
<span className="text-xs font-mono text-cyan-400">
|
||||
{userData.xp}/{userData.maxXp}
|
||||
</span>
|
||||
</div>
|
||||
<Progress
|
||||
value={(userData.xp / userData.maxXp) * 100}
|
||||
className="h-3 bg-[#0a0e1a]"
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* Quick Stats */}
|
||||
<div className="grid grid-cols-2 gap-4 mb-6">
|
||||
<div className="bg-[#0a0e1a] border border-cyan-500/20 rounded-lg p-3">
|
||||
<BookOpen className="w-5 h-5 text-cyan-400 mx-auto mb-1" />
|
||||
<div className="text-xl font-bold text-cyan-400 font-mono">
|
||||
{userData.coursesCompleted}
|
||||
</div>
|
||||
<div className="text-xs text-cyan-400/60 font-mono">Courses</div>
|
||||
</div>
|
||||
<div className="bg-[#0a0e1a] border border-cyan-500/20 rounded-lg p-3">
|
||||
<Award className="w-5 h-5 text-cyan-400 mx-auto mb-1" />
|
||||
<div className="text-xl font-bold text-cyan-400 font-mono">
|
||||
{userData.achievements}
|
||||
</div>
|
||||
<div className="text-xs text-cyan-400/60 font-mono">Badges</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<Button
|
||||
className="w-full bg-cyan-500 hover:bg-cyan-400 text-black font-mono font-bold"
|
||||
>
|
||||
EDIT PROFILE
|
||||
</Button>
|
||||
</div>
|
||||
</Card>
|
||||
|
||||
{/* Stats and Achievements */}
|
||||
<div className="lg:col-span-2 space-y-6">
|
||||
{/* Personal Progress Card */}
|
||||
<Card className="bg-[#0d1117] border-2 border-cyan-500/30 p-6">
|
||||
<h3 className="text-xl font-bold text-cyan-400 font-mono mb-4">
|
||||
Personal progress
|
||||
</h3>
|
||||
<div className="grid grid-cols-3 gap-4">
|
||||
{stats.map((stat, index) => {
|
||||
const Icon = stat.icon
|
||||
return (
|
||||
<div
|
||||
key={index}
|
||||
className="bg-[#0a0e1a] border border-cyan-500/20 rounded-lg p-4 text-center"
|
||||
>
|
||||
<Icon className="w-6 h-6 text-cyan-400 mx-auto mb-2" />
|
||||
<div className="text-2xl font-bold text-cyan-400 font-mono mb-1">
|
||||
{stat.value}
|
||||
</div>
|
||||
<div className="text-xs text-cyan-400/60 font-mono">
|
||||
{stat.label}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
})}
|
||||
</div>
|
||||
</Card>
|
||||
|
||||
{/* Achievements Card */}
|
||||
<Card className="bg-[#0d1117] border-2 border-cyan-500/30 p-6">
|
||||
<h3 className="text-xl font-bold text-cyan-400 font-mono mb-4">
|
||||
Achievements
|
||||
</h3>
|
||||
<div className="grid grid-cols-2 gap-3">
|
||||
{achievements.map((achievement, index) => (
|
||||
<Card
|
||||
key={index}
|
||||
className={`p-4 transition-all ${
|
||||
achievement.unlocked
|
||||
? 'bg-cyan-500/10 border-cyan-500/40 hover:border-cyan-500/60'
|
||||
: 'bg-[#0a0e1a] border-cyan-500/10 opacity-40'
|
||||
}`}
|
||||
>
|
||||
<div className="flex items-start gap-3">
|
||||
<div className={`w-10 h-10 rounded-lg flex items-center justify-center flex-shrink-0 ${
|
||||
achievement.unlocked
|
||||
? 'bg-cyan-500/20'
|
||||
: 'bg-cyan-500/5'
|
||||
}`}>
|
||||
<Trophy className={`w-5 h-5 ${
|
||||
achievement.unlocked
|
||||
? 'text-cyan-400'
|
||||
: 'text-cyan-400/30'
|
||||
}`} />
|
||||
</div>
|
||||
<div className="flex-1 min-w-0">
|
||||
<h4 className={`font-bold font-mono text-sm mb-1 ${
|
||||
achievement.unlocked
|
||||
? 'text-cyan-400'
|
||||
: 'text-cyan-400/30'
|
||||
}`}>
|
||||
{achievement.title}
|
||||
</h4>
|
||||
<p className="text-xs text-cyan-400/50 font-mono line-clamp-2">
|
||||
{achievement.description}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</Card>
|
||||
))}
|
||||
</div>
|
||||
</Card>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
{/* Background grid */}
|
||||
<div
|
||||
className="fixed inset-0 pointer-events-none -z-10"
|
||||
style={{
|
||||
backgroundImage: `
|
||||
linear-gradient(rgba(6, 182, 212, 0.03) 1px, transparent 1px),
|
||||
linear-gradient(90deg, rgba(6, 182, 212, 0.03) 1px, transparent 1px)
|
||||
`,
|
||||
backgroundSize: '50px 50px'
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
286
app/(home)/main/progress/page.tsx
Normal file
286
app/(home)/main/progress/page.tsx
Normal file
@@ -0,0 +1,286 @@
|
||||
"use client"
|
||||
|
||||
import { useState } from "react"
|
||||
import { Card } from "@/components/ui/card"
|
||||
import { Button } from "@/components/ui/button"
|
||||
import { Progress } from "@/components/ui/progress"
|
||||
import Link from "next/link"
|
||||
import { CheckCircle2, Circle, Clock } from "lucide-react"
|
||||
|
||||
export default function ProgressPage() {
|
||||
const [activeTab, setActiveTab] = useState("progress")
|
||||
|
||||
// Mock data
|
||||
const courses = [
|
||||
{ id: 1, name: "React", lessons: 12, completed: 8 },
|
||||
{ id: 2, name: "TypeScript", lessons: 10, completed: 6 },
|
||||
{ id: 3, name: "Next.js", lessons: 15, completed: 4 },
|
||||
{ id: 4, name: "Node.js", lessons: 20, completed: 0 }
|
||||
]
|
||||
|
||||
const assignments = [
|
||||
{ id: 1, course: "React", name: "Build a Todo App", grade: 95, status: "completed" },
|
||||
{ id: 2, course: "TypeScript", name: "Type System", grade: 88, status: "completed" },
|
||||
{ id: 3, course: "Next.js", name: "SSR Project", grade: null, status: "pending" },
|
||||
{ id: 4, course: "Node.js", name: "REST API", grade: null, status: "not_started" }
|
||||
]
|
||||
|
||||
const weekActivity = [
|
||||
{ day: "Mon", hours: 2.5 },
|
||||
{ day: "Tue", hours: 3.2 },
|
||||
{ day: "Wed", hours: 1.8 },
|
||||
{ day: "Thu", hours: 4.1 },
|
||||
{ day: "Fri", hours: 2.9 },
|
||||
{ day: "Sat", hours: 3.5 },
|
||||
{ day: "Sun", hours: 1.2 }
|
||||
]
|
||||
|
||||
const maxHours = Math.max(...weekActivity.map(d => d.hours))
|
||||
|
||||
return (
|
||||
<div className="min-h-screen bg-[#0a0e1a]">
|
||||
{/* Header */}
|
||||
<header className="bg-[#0d1117] border-b border-cyan-500/30 sticky top-0 z-50">
|
||||
<nav className="container mx-auto px-6 py-4">
|
||||
<div className="flex items-center justify-center">
|
||||
<div className="flex items-center gap-12">
|
||||
<Link href="/home/main">
|
||||
<button className="text-sm font-bold tracking-[0.2em] transition-all duration-200 font-mono uppercase text-cyan-500/50 hover:text-cyan-400/80">
|
||||
Main
|
||||
</button>
|
||||
</Link>
|
||||
<button
|
||||
onClick={() => setActiveTab("progress")}
|
||||
className="text-sm font-bold tracking-[0.2em] transition-all duration-200 font-mono uppercase text-cyan-400"
|
||||
>
|
||||
Progress
|
||||
</button>
|
||||
<Link href="/home/profile">
|
||||
<button className="text-sm font-bold tracking-[0.2em] transition-all duration-200 font-mono uppercase text-cyan-500/50 hover:text-cyan-400/80">
|
||||
Profile
|
||||
</button>
|
||||
</Link>
|
||||
<Link href="/home/rules">
|
||||
<button className="text-sm font-bold tracking-[0.2em] transition-all duration-200 font-mono uppercase text-cyan-500/50 hover:text-cyan-400/80">
|
||||
Rules
|
||||
</button>
|
||||
</Link>
|
||||
<Link href="/login">
|
||||
<button className="text-sm font-bold tracking-[0.2em] transition-all duration-200 font-mono uppercase text-cyan-500/50 hover:text-cyan-400/80">
|
||||
Login
|
||||
</button>
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
</header>
|
||||
|
||||
{/* Main Content */}
|
||||
<main className="container mx-auto px-6 py-8 max-w-7xl">
|
||||
<div className="grid grid-cols-1 lg:grid-cols-3 gap-6">
|
||||
{/* Left Column - Course Progress */}
|
||||
<div className="space-y-6">
|
||||
{/* My Courses */}
|
||||
<Card className="bg-[#0d1117] border-2 border-cyan-500/30 p-6">
|
||||
<h3 className="text-xl font-bold text-cyan-400 font-mono mb-4">
|
||||
My courses
|
||||
</h3>
|
||||
<div className="space-y-3">
|
||||
{courses.map((course) => {
|
||||
const progress = (course.completed / course.lessons) * 100
|
||||
return (
|
||||
<Card
|
||||
key={course.id}
|
||||
className="bg-[#0a0e1a] border border-cyan-500/20 p-4 hover:border-cyan-500/40 transition-all"
|
||||
>
|
||||
<div className="flex justify-between items-start mb-2">
|
||||
<h4 className="font-bold text-cyan-400 font-mono text-sm">
|
||||
{course.name}
|
||||
</h4>
|
||||
<span className="text-xs text-cyan-400/60 font-mono">
|
||||
{course.completed}/{course.lessons}
|
||||
</span>
|
||||
</div>
|
||||
<Progress value={progress} className="h-2 bg-[#0d1117]" />
|
||||
</Card>
|
||||
)
|
||||
})}
|
||||
</div>
|
||||
</Card>
|
||||
|
||||
{/* My Grades */}
|
||||
<Card className="bg-[#0d1117] border-2 border-cyan-500/30 p-6">
|
||||
<h3 className="text-xl font-bold text-cyan-400 font-mono mb-4">
|
||||
My grades
|
||||
</h3>
|
||||
<div className="space-y-3">
|
||||
{assignments.slice(0, 3).map((assignment) => (
|
||||
<Card
|
||||
key={assignment.id}
|
||||
className="bg-[#0a0e1a] border border-cyan-500/20 p-3"
|
||||
>
|
||||
<div className="flex justify-between items-center">
|
||||
<div className="flex-1">
|
||||
<div className="text-sm font-bold text-cyan-400 font-mono mb-1">
|
||||
{assignment.course}
|
||||
</div>
|
||||
<div className="text-xs text-cyan-400/60 font-mono">
|
||||
{assignment.name}
|
||||
</div>
|
||||
</div>
|
||||
{assignment.grade ? (
|
||||
<div className="text-xl font-bold text-cyan-400 font-mono">
|
||||
{assignment.grade}%
|
||||
</div>
|
||||
) : (
|
||||
<div className="text-xs text-cyan-400/40 font-mono">
|
||||
Pending
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</Card>
|
||||
))}
|
||||
</div>
|
||||
</Card>
|
||||
|
||||
{/* Mathematics (Separate) */}
|
||||
<Card className="bg-[#0d1117] border-2 border-cyan-500/30 p-6">
|
||||
<h3 className="text-xl font-bold text-cyan-400 font-mono mb-4">
|
||||
Mathematics
|
||||
</h3>
|
||||
<div className="space-y-3">
|
||||
<Card className="bg-[#0a0e1a] border border-cyan-500/20 p-4">
|
||||
<div className="flex justify-between items-start mb-2">
|
||||
<h4 className="font-bold text-cyan-400 font-mono text-sm">
|
||||
Algebra
|
||||
</h4>
|
||||
<span className="text-xs text-cyan-400/60 font-mono">
|
||||
8/10
|
||||
</span>
|
||||
</div>
|
||||
<Progress value={80} className="h-2 bg-[#0d1117]" />
|
||||
</Card>
|
||||
</div>
|
||||
</Card>
|
||||
</div>
|
||||
|
||||
{/* Center Column - Assignments Table */}
|
||||
<Card className="lg:col-span-2 bg-[#0d1117] border-2 border-cyan-500/30 p-6">
|
||||
<h3 className="text-xl font-bold text-cyan-400 font-mono mb-4">
|
||||
All Assignments
|
||||
</h3>
|
||||
|
||||
{/* Table */}
|
||||
<div className="overflow-x-auto">
|
||||
<table className="w-full">
|
||||
<thead>
|
||||
<tr className="border-b border-cyan-500/20">
|
||||
<th className="text-left py-3 px-4 text-xs font-mono text-cyan-400/60 uppercase">
|
||||
#
|
||||
</th>
|
||||
<th className="text-left py-3 px-4 text-xs font-mono text-cyan-400/60 uppercase">
|
||||
Course
|
||||
</th>
|
||||
<th className="text-left py-3 px-4 text-xs font-mono text-cyan-400/60 uppercase">
|
||||
Assignment
|
||||
</th>
|
||||
<th className="text-left py-3 px-4 text-xs font-mono text-cyan-400/60 uppercase">
|
||||
Grade
|
||||
</th>
|
||||
<th className="text-left py-3 px-4 text-xs font-mono text-cyan-400/60 uppercase">
|
||||
Status
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{assignments.map((assignment, index) => (
|
||||
<tr
|
||||
key={assignment.id}
|
||||
className="border-b border-cyan-500/10 hover:bg-cyan-500/5 transition-colors"
|
||||
>
|
||||
<td className="py-3 px-4 text-sm font-mono text-cyan-400">
|
||||
{index + 1}
|
||||
</td>
|
||||
<td className="py-3 px-4 text-sm font-mono text-cyan-400">
|
||||
{assignment.course}
|
||||
</td>
|
||||
<td className="py-3 px-4 text-sm font-mono text-cyan-400">
|
||||
{assignment.name}
|
||||
</td>
|
||||
<td className="py-3 px-4 text-sm font-mono text-cyan-400">
|
||||
{assignment.grade ? `${assignment.grade}%` : '-'}
|
||||
</td>
|
||||
<td className="py-3 px-4">
|
||||
<div className="flex items-center gap-2">
|
||||
{assignment.status === 'completed' ? (
|
||||
<>
|
||||
<CheckCircle2 className="w-4 h-4 text-green-400" />
|
||||
<span className="text-xs font-mono text-green-400">
|
||||
Completed
|
||||
</span>
|
||||
</>
|
||||
) : assignment.status === 'pending' ? (
|
||||
<>
|
||||
<Clock className="w-4 h-4 text-yellow-400" />
|
||||
<span className="text-xs font-mono text-yellow-400">
|
||||
Pending
|
||||
</span>
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<Circle className="w-4 h-4 text-cyan-400/30" />
|
||||
<span className="text-xs font-mono text-cyan-400/30">
|
||||
Not Started
|
||||
</span>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
))}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
{/* Weekly Activity Chart */}
|
||||
<div className="mt-8">
|
||||
<h4 className="text-lg font-bold text-cyan-400 font-mono mb-4">
|
||||
Weekly Activity
|
||||
</h4>
|
||||
<div className="flex items-end justify-between gap-2 h-48">
|
||||
{weekActivity.map((day) => (
|
||||
<div key={day.day} className="flex-1 flex flex-col items-center gap-2">
|
||||
<div className="w-full relative flex-1">
|
||||
<div
|
||||
className="absolute bottom-0 w-full bg-gradient-to-t from-cyan-500 to-cyan-400 rounded-t-lg transition-all hover:from-cyan-400 hover:to-cyan-300"
|
||||
style={{ height: `${(day.hours / maxHours) * 100}%` }}
|
||||
/>
|
||||
</div>
|
||||
<div className="text-xs font-mono text-cyan-400/60">
|
||||
{day.day}
|
||||
</div>
|
||||
<div className="text-xs font-mono text-cyan-400 font-bold">
|
||||
{day.hours}h
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</Card>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
{/* Background grid */}
|
||||
<div
|
||||
className="fixed inset-0 pointer-events-none -z-10"
|
||||
style={{
|
||||
backgroundImage: `
|
||||
linear-gradient(rgba(6, 182, 212, 0.03) 1px, transparent 1px),
|
||||
linear-gradient(90deg, rgba(6, 182, 212, 0.03) 1px, transparent 1px)
|
||||
`,
|
||||
backgroundSize: '50px 50px'
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
137
app/(home)/main/reset-password/page.tsx
Normal file
137
app/(home)/main/reset-password/page.tsx
Normal file
@@ -0,0 +1,137 @@
|
||||
"use client"
|
||||
|
||||
import { useState } from "react"
|
||||
import { Card } from "@/components/ui/card"
|
||||
import { Button } from "@/components/ui/button"
|
||||
import { Input } from "@/components/ui/input"
|
||||
import { Label } from "@/components/ui/label"
|
||||
import Link from "next/link"
|
||||
import { ArrowLeft, Mail } from "lucide-react"
|
||||
|
||||
export default function ResetPasswordPage() {
|
||||
const [email, setEmail] = useState("")
|
||||
const [submitted, setSubmitted] = useState(false)
|
||||
|
||||
const handleSubmit = (e: React.FormEvent) => {
|
||||
e.preventDefault()
|
||||
// Здесь будет логика отправки письма для сброса пароля
|
||||
console.log("Reset password for:", email)
|
||||
setSubmitted(true)
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="min-h-screen bg-[#0a0e1a] flex items-center justify-center p-6">
|
||||
{/* Background grid */}
|
||||
<div
|
||||
className="fixed inset-0 pointer-events-none -z-10"
|
||||
style={{
|
||||
backgroundImage: `
|
||||
linear-gradient(rgba(6, 182, 212, 0.03) 1px, transparent 1px),
|
||||
linear-gradient(90deg, rgba(6, 182, 212, 0.03) 1px, transparent 1px)
|
||||
`,
|
||||
backgroundSize: '50px 50px'
|
||||
}}
|
||||
/>
|
||||
|
||||
{/* Glowing effects */}
|
||||
<div className="fixed top-20 left-20 w-96 h-96 bg-cyan-500/10 rounded-full blur-[120px] animate-pulse" />
|
||||
<div className="fixed bottom-20 right-20 w-96 h-96 bg-blue-500/10 rounded-full blur-[120px] animate-pulse" />
|
||||
|
||||
<Card className="w-full max-w-md bg-[#0d1117] border-2 border-cyan-500/40 shadow-[0_0_50px_rgba(6,182,212,0.2)] relative overflow-hidden">
|
||||
{/* Top accent line */}
|
||||
<div className="absolute top-0 left-0 right-0 h-1 bg-gradient-to-r from-transparent via-cyan-400 to-transparent" />
|
||||
|
||||
<div className="p-8">
|
||||
{/* Back button */}
|
||||
<Link
|
||||
href="/login"
|
||||
className="inline-flex items-center gap-2 text-cyan-400/60 hover:text-cyan-400 font-mono text-sm mb-6 transition-colors group"
|
||||
>
|
||||
<ArrowLeft className="w-4 h-4 group-hover:-translate-x-1 transition-transform" />
|
||||
Back to login
|
||||
</Link>
|
||||
|
||||
{!submitted ? (
|
||||
<>
|
||||
{/* Header */}
|
||||
<div className="text-center mb-8">
|
||||
<div className="w-16 h-16 bg-cyan-500/10 rounded-full flex items-center justify-center mx-auto mb-4">
|
||||
<Mail className="w-8 h-8 text-cyan-400" />
|
||||
</div>
|
||||
<h1 className="text-4xl font-bold text-cyan-400 font-mono mb-2">
|
||||
Reset my password
|
||||
</h1>
|
||||
<p className="text-cyan-400/50 font-mono text-sm">
|
||||
Enter your email to receive reset instructions
|
||||
</p>
|
||||
</div>
|
||||
|
||||
{/* Reset Form */}
|
||||
<form onSubmit={handleSubmit} className="space-y-6">
|
||||
<div className="space-y-2">
|
||||
<Label
|
||||
htmlFor="email"
|
||||
className="text-cyan-400 font-mono text-sm"
|
||||
>
|
||||
Email Address
|
||||
</Label>
|
||||
<Input
|
||||
id="email"
|
||||
type="email"
|
||||
placeholder="your.email@example.com"
|
||||
value={email}
|
||||
onChange={(e) => setEmail(e.target.value)}
|
||||
required
|
||||
className="bg-[#0a0e1a] border-cyan-500/30 text-cyan-400 placeholder:text-cyan-400/30 font-mono focus:border-cyan-400 focus:ring-cyan-400/20"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<Button
|
||||
type="submit"
|
||||
className="w-full bg-cyan-500 hover:bg-cyan-400 text-black font-bold font-mono tracking-wider py-6 text-base shadow-[0_0_30px_rgba(6,182,212,0.3)] hover:shadow-[0_0_50px_rgba(6,182,212,0.5)] transition-all"
|
||||
>
|
||||
SEND RESET LINK
|
||||
</Button>
|
||||
</form>
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
{/* Success State */}
|
||||
<div className="text-center py-8">
|
||||
<div className="w-20 h-20 bg-cyan-500/10 rounded-full flex items-center justify-center mx-auto mb-6 animate-pulse">
|
||||
<Mail className="w-10 h-10 text-cyan-400" />
|
||||
</div>
|
||||
<h2 className="text-3xl font-bold text-cyan-400 font-mono mb-3">
|
||||
Check your email
|
||||
</h2>
|
||||
<p className="text-cyan-400/60 font-mono text-sm mb-6">
|
||||
We've sent password reset instructions to<br />
|
||||
<span className="text-cyan-400">{email}</span>
|
||||
</p>
|
||||
<div className="bg-cyan-500/5 border border-cyan-500/20 rounded-lg p-4 mb-6">
|
||||
<p className="text-cyan-400/70 font-mono text-xs">
|
||||
Didn't receive the email? Check your spam folder or try again in a few minutes.
|
||||
</p>
|
||||
</div>
|
||||
<Link href="/login">
|
||||
<Button
|
||||
className="w-full bg-[#0a0e1a] border-2 border-cyan-500/30 text-cyan-400 hover:bg-cyan-500/10 font-mono"
|
||||
variant="outline"
|
||||
>
|
||||
BACK TO LOGIN
|
||||
</Button>
|
||||
</Link>
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{/* Corner decorations */}
|
||||
<div className="absolute top-2 left-2 w-4 h-4 border-t-2 border-l-2 border-cyan-500/30"></div>
|
||||
<div className="absolute top-2 right-2 w-4 h-4 border-t-2 border-r-2 border-cyan-500/30"></div>
|
||||
<div className="absolute bottom-2 left-2 w-4 h-4 border-b-2 border-l-2 border-cyan-500/30"></div>
|
||||
<div className="absolute bottom-2 right-2 w-4 h-4 border-b-2 border-r-2 border-cyan-500/30"></div>
|
||||
</Card>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user