Commit 271b0c17 authored by Mahmoud Aglan's avatar Mahmoud Aglan

feat: apply 30 UI/UX improvements across all pages

Game: coordinate labels, player panels, captured pieces, move list,
material advantage, glowing turn indicator, tighter layout.
Home: quick actions, daily tips, better empty state, stat card borders.
Play: chess hero card, larger pills, removed debug button.
BotSelect: back nav, difficulty dots, colored avatar fallback.
Profile: XP fix, section dividers, achievements placeholder, better logout.
Co-Authored-By: 's avatarClaude Opus 4.6 <noreply@anthropic.com>
parent c8dabe57
...@@ -5,7 +5,7 @@ import { PageTransition } from '../components/layout/PageTransition' ...@@ -5,7 +5,7 @@ import { PageTransition } from '../components/layout/PageTransition'
import { Card } from '../components/ui/Card' import { Card } from '../components/ui/Card'
import { Button } from '../components/ui/Button' import { Button } from '../components/ui/Button'
import { fetchBots, getBotPortraitUrl, type Bot } from '../lib/stockfish' import { fetchBots, getBotPortraitUrl, type Bot } from '../lib/stockfish'
import { Cpu, Swords } from 'lucide-react' import { ChevronRight, Swords } from 'lucide-react'
const DIFFICULTY_COLORS: Record<string, string> = { const DIFFICULTY_COLORS: Record<string, string> = {
beginner: '#4ECDC4', beginner: '#4ECDC4',
...@@ -17,6 +17,8 @@ const DIFFICULTY_COLORS: Record<string, string> = { ...@@ -17,6 +17,8 @@ const DIFFICULTY_COLORS: Record<string, string> = {
near_perfect: '#FFD700', near_perfect: '#FFD700',
} }
const TOTAL_STRENGTH_DOTS = 7
export function BotSelectPage() { export function BotSelectPage() {
const navigate = useNavigate() const navigate = useNavigate()
const [bots, setBots] = useState<Bot[]>([]) const [bots, setBots] = useState<Bot[]>([])
...@@ -45,9 +47,16 @@ export function BotSelectPage() { ...@@ -45,9 +47,16 @@ export function BotSelectPage() {
} }
return ( return (
<PageTransition className="px-4 py-6 flex flex-col gap-5"> <PageTransition className="px-4 py-6 flex flex-col gap-5 pb-32">
<div className="flex items-center gap-2"> {/* Header with back button */}
<Cpu size={20} className="text-gold" /> <div className="flex items-center gap-3">
<motion.button
onClick={() => navigate(-1)}
className="w-9 h-9 rounded-full bg-surface-2 border border-border flex items-center justify-center"
whileTap={{ scale: 0.9 }}
>
<ChevronRight size={18} className="text-text-secondary" />
</motion.button>
<h1 className="text-xl font-bold">العب ضد الروبوت</h1> <h1 className="text-xl font-bold">العب ضد الروبوت</h1>
</div> </div>
...@@ -57,6 +66,7 @@ export function BotSelectPage() { ...@@ -57,6 +66,7 @@ export function BotSelectPage() {
{bots.map((bot, i) => { {bots.map((bot, i) => {
const isSelected = selectedBot === bot.id const isSelected = selectedBot === bot.id
const diffColor = DIFFICULTY_COLORS[bot.style] || '#6B6B80' const diffColor = DIFFICULTY_COLORS[bot.style] || '#6B6B80'
const strengthLevel = Math.min(i + 1, TOTAL_STRENGTH_DOTS)
return ( return (
<motion.div <motion.div
...@@ -68,22 +78,34 @@ export function BotSelectPage() { ...@@ -68,22 +78,34 @@ export function BotSelectPage() {
<Card <Card
glow={isSelected} glow={isSelected}
onClick={() => setSelectedBot(bot.id)} onClick={() => setSelectedBot(bot.id)}
className={`flex items-center gap-3 transition-all ${isSelected ? 'border-gold/60' : ''}`} className={`flex items-center gap-3 transition-all ${
isSelected
? 'border-gold/60 scale-[1.02] border-r-4'
: ''
}`}
> >
<div className="relative w-12 h-12 rounded-full overflow-hidden bg-surface-3 flex-shrink-0"> {/* Bot Portrait with colored fallback */}
<div
className="relative w-12 h-12 rounded-full overflow-hidden flex-shrink-0"
style={{ backgroundColor: `${diffColor}20` }}
>
<img <img
src={getBotPortraitUrl(bot.id)} src={getBotPortraitUrl(bot.id)}
alt={bot.name} alt={bot.name}
className="w-full h-full object-cover" className="w-full h-full object-cover relative z-10"
onError={(e) => { onError={(e) => {
(e.target as HTMLImageElement).style.display = 'none' (e.target as HTMLImageElement).style.display = 'none'
}} }}
/> />
<div className="absolute inset-0 flex items-center justify-center"> <div
<Cpu size={18} className="text-text-muted" /> className="absolute inset-0 flex items-center justify-center"
style={{ color: diffColor }}
>
<span className="text-lg font-bold">{bot.name_ar?.charAt(0) || bot.name.charAt(0)}</span>
</div> </div>
</div> </div>
{/* Bot Info */}
<div className="flex-1 min-w-0"> <div className="flex-1 min-w-0">
<div className="flex items-center gap-2"> <div className="flex items-center gap-2">
<h3 className="text-sm font-bold truncate">{bot.name_ar}</h3> <h3 className="text-sm font-bold truncate">{bot.name_ar}</h3>
...@@ -95,13 +117,26 @@ export function BotSelectPage() { ...@@ -95,13 +117,26 @@ export function BotSelectPage() {
</span> </span>
</div> </div>
<p className="text-[11px] text-text-muted truncate mt-0.5">{bot.bio_ar}</p> <p className="text-[11px] text-text-muted truncate mt-0.5">{bot.bio_ar}</p>
<div className="flex items-center gap-2 mt-1"> <div className="flex items-center gap-3 mt-1.5">
<span className="text-[10px] text-text-muted"> <span className="text-[10px] text-text-muted">
{bot.elo_min}-{bot.elo_max} تقييم {bot.elo_min}-{bot.elo_max} تقييم
</span> </span>
{/* Strength dots */}
<div className="flex items-center gap-0.5">
{Array.from({ length: TOTAL_STRENGTH_DOTS }).map((_, dotIndex) => (
<div
key={dotIndex}
className="w-1.5 h-1.5 rounded-full transition-colors"
style={{
backgroundColor: dotIndex < strengthLevel ? diffColor : `${diffColor}30`,
}}
/>
))}
</div>
</div> </div>
</div> </div>
{/* Selection indicator */}
{isSelected && ( {isSelected && (
<motion.div <motion.div
className="w-5 h-5 rounded-full bg-gold flex items-center justify-center flex-shrink-0" className="w-5 h-5 rounded-full bg-gold flex items-center justify-center flex-shrink-0"
...@@ -118,9 +153,10 @@ export function BotSelectPage() { ...@@ -118,9 +153,10 @@ export function BotSelectPage() {
})} })}
</div> </div>
{/* Bottom CTA with safe area */}
{selectedBot && ( {selectedBot && (
<motion.div <motion.div
className="sticky bottom-20 pt-3" className="fixed bottom-0 left-0 right-0 p-4 pb-8 bg-gradient-to-t from-background via-background to-transparent"
initial={{ opacity: 0, y: 20 }} initial={{ opacity: 0, y: 20 }}
animate={{ opacity: 1, y: 0 }} animate={{ opacity: 1, y: 0 }}
transition={{ type: 'spring', stiffness: 400, damping: 25 }} transition={{ type: 'spring', stiffness: 400, damping: 25 }}
......
This diff is collapsed.
import { motion } from 'framer-motion' import { motion } from 'framer-motion'
import { Play, TrendingUp, Swords, Flame } from 'lucide-react' import { Play, TrendingUp, Swords, Flame, Grid3X3, Bot, Users, Lightbulb, Crown } from 'lucide-react'
import { useNavigate } from 'react-router-dom' import { useNavigate } from 'react-router-dom'
import { useAuthStore } from '../stores/authStore' import { useAuthStore } from '../stores/authStore'
import { PageTransition } from '../components/layout/PageTransition' import { PageTransition } from '../components/layout/PageTransition'
import { Card } from '../components/ui/Card' import { Card } from '../components/ui/Card'
const dailyTips = [
'تحكم بالمركز في بداية اللعبة - الاحصنة والفيلة تكون اقوى من المركز',
'لا تحرك نفس القطعة مرتين في الافتتاح - طور قطعك بسرعة',
'قم بالتبييت مبكرا لحماية ملكك وتفعيل القلعة',
'الاحصنة قبل الفيلة - طور الاحصنة اولا لانها تحتاج وقت اكثر',
'لا تخرج الملكة مبكرا - قد تتعرض للهجوم وتضيع وقتك',
'ادرس نهايات اللعب - الكثير من المباريات تحسم في النهاية',
'فكر في خطة خصمك قبل ان تلعب - لا تركز فقط على هجومك',
]
export function HomePage() { export function HomePage() {
const navigate = useNavigate() const navigate = useNavigate()
const { profile } = useAuthStore() const { profile } = useAuthStore()
const todayTip = dailyTips[new Date().getDay()]
return ( return (
<PageTransition className="px-4 py-6 flex flex-col gap-6"> <PageTransition className="px-4 py-6 flex flex-col gap-6">
...@@ -35,6 +46,13 @@ export function HomePage() { ...@@ -35,6 +46,13 @@ export function HomePage() {
className="relative w-full py-8 rounded-3xl bg-gradient-to-bl from-gold via-gold-light to-gold overflow-hidden" className="relative w-full py-8 rounded-3xl bg-gradient-to-bl from-gold via-gold-light to-gold overflow-hidden"
whileTap={{ scale: 0.97 }} whileTap={{ scale: 0.97 }}
transition={{ type: 'spring', stiffness: 400, damping: 20 }} transition={{ type: 'spring', stiffness: 400, damping: 20 }}
animate={{
boxShadow: [
'0 0 20px rgba(212, 175, 55, 0.3)',
'0 0 40px rgba(212, 175, 55, 0.6)',
'0 0 20px rgba(212, 175, 55, 0.3)',
],
}}
> >
<motion.div <motion.div
className="absolute inset-0 bg-gradient-to-r from-transparent via-white/10 to-transparent" className="absolute inset-0 bg-gradient-to-r from-transparent via-white/10 to-transparent"
...@@ -55,42 +73,114 @@ export function HomePage() { ...@@ -55,42 +73,114 @@ export function HomePage() {
{profile && ( {profile && (
<div className="grid grid-cols-3 gap-3"> <div className="grid grid-cols-3 gap-3">
<StatCard <StatCard
icon={<Swords size={18} className="text-cyan" />} icon={<Swords size={20} className="text-cyan" />}
value={profile.total_games_played} value={profile.total_games_played}
label="مباراة" label="مباراة"
delay={0.2} delay={0.2}
accentColor="from-cyan/60 to-cyan/20"
/> />
<StatCard <StatCard
icon={<TrendingUp size={18} className="text-gold" />} icon={<TrendingUp size={20} className="text-gold" />}
value={profile.elo_blitz} value={profile.elo_blitz}
label="تقييم" label="تقييم"
delay={0.3} delay={0.3}
accentColor="from-gold/60 to-gold/20"
/> />
<StatCard <StatCard
icon={<Flame size={18} className="text-coral" />} icon={<Flame size={20} className="text-coral" />}
value={profile.win_streak} value={profile.win_streak}
label="سلسلة فوز" label="سلسلة فوز"
delay={0.4} delay={0.4}
accentColor="from-coral/60 to-coral/20"
/> />
</div> </div>
)} )}
{/* Quick Actions */}
<div className="grid grid-cols-2 gap-3">
<motion.button
onClick={() => navigate('/bot-select')}
className="flex items-center gap-3 p-4 rounded-2xl bg-surface-1 border border-border text-start"
initial={{ opacity: 0, x: -10 }}
animate={{ opacity: 1, x: 0 }}
transition={{ delay: 0.3, type: 'spring', stiffness: 400, damping: 25 }}
whileTap={{ scale: 0.96 }}
>
<div className="w-10 h-10 rounded-xl bg-gradient-to-br from-purple/30 to-cyan/20 flex items-center justify-center">
<Bot size={20} className="text-purple" />
</div>
<div>
<p className="text-sm font-bold">العب ضد روبوت</p>
<p className="text-[10px] text-text-muted">تدريب وتحسين</p>
</div>
</motion.button>
<motion.button
onClick={() => navigate('/friends')}
className="flex items-center gap-3 p-4 rounded-2xl bg-surface-1 border border-border text-start"
initial={{ opacity: 0, x: 10 }}
animate={{ opacity: 1, x: 0 }}
transition={{ delay: 0.4, type: 'spring', stiffness: 400, damping: 25 }}
whileTap={{ scale: 0.96 }}
>
<div className="w-10 h-10 rounded-xl bg-gradient-to-br from-gold/30 to-coral/20 flex items-center justify-center">
<Users size={20} className="text-gold" />
</div>
<div>
<p className="text-sm font-bold">تحدى صديق</p>
<p className="text-[10px] text-text-muted">ارسل دعوة</p>
</div>
</motion.button>
</div>
{/* Recent Matches */}
<div> <div>
<h3 className="text-base font-bold mb-3 text-text-secondary">اخر المباريات</h3> <h3 className="text-base font-bold mb-3 text-text-secondary">اخر المباريات</h3>
<div className="flex flex-col gap-2"> <div className="flex flex-col gap-2">
<Card className="flex items-center justify-between"> <Card className="flex flex-col items-center justify-center py-8 gap-3">
<div className="flex items-center gap-3"> <motion.div
<div className="w-8 h-8 rounded-full bg-surface-3 flex items-center justify-center"> className="w-14 h-14 rounded-2xl bg-surface-3 flex items-center justify-center"
<span className="text-xs font-bold text-text-muted">?</span> animate={{ rotate: [0, 5, -5, 0] }}
</div> transition={{ duration: 4, repeat: Infinity, ease: 'easeInOut' }}
<div> >
<p className="text-sm font-semibold">لا توجد مباريات بعد</p> <Grid3X3 size={28} className="text-text-muted" />
<p className="text-xs text-text-muted">ابدا اللعب الان</p> </motion.div>
</div> <div className="text-center">
<p className="text-sm font-semibold">لا توجد مباريات بعد</p>
<p className="text-xs text-text-muted mt-1">العب اول مباراة وابدا رحلتك</p>
</div> </div>
<motion.button
onClick={() => navigate('/play')}
className="mt-2 px-5 py-2 rounded-xl bg-gold/10 border border-gold/30 text-gold text-sm font-bold"
whileTap={{ scale: 0.95 }}
>
ابدا الان
</motion.button>
</Card> </Card>
</div> </div>
</div> </div>
{/* Daily Tip */}
<motion.div
className="p-4 rounded-2xl bg-surface-1 border border-border relative overflow-hidden"
initial={{ opacity: 0, y: 10 }}
animate={{ opacity: 1, y: 0 }}
transition={{ delay: 0.5, type: 'spring', stiffness: 400, damping: 25 }}
>
<div className="absolute top-0 right-0 w-20 h-20 bg-gradient-to-bl from-gold/5 to-transparent rounded-bl-full" />
<div className="flex items-start gap-3">
<div className="w-9 h-9 rounded-xl bg-gradient-to-br from-gold/20 to-gold/5 flex items-center justify-center flex-shrink-0 mt-0.5">
<Lightbulb size={18} className="text-gold" />
</div>
<div>
<div className="flex items-center gap-2 mb-1">
<h4 className="text-sm font-bold text-gold">نصيحة اليوم</h4>
<Crown size={12} className="text-gold/50" />
</div>
<p className="text-xs text-text-secondary leading-relaxed">{todayTip}</p>
</div>
</div>
</motion.div>
</PageTransition> </PageTransition>
) )
} }
...@@ -100,22 +190,25 @@ function StatCard({ ...@@ -100,22 +190,25 @@ function StatCard({
value, value,
label, label,
delay, delay,
accentColor,
}: { }: {
icon: React.ReactNode icon: React.ReactNode
value: number value: number
label: string label: string
delay: number delay: number
accentColor: string
}) { }) {
return ( return (
<motion.div <motion.div
className="flex flex-col items-center gap-1 p-3 rounded-xl bg-surface-1 border border-border" className="relative flex flex-col items-center gap-1.5 p-3 rounded-xl bg-surface-1 border border-border overflow-hidden"
initial={{ opacity: 0, y: 10 }} initial={{ opacity: 0, y: 10 }}
animate={{ opacity: 1, y: 0 }} animate={{ opacity: 1, y: 0 }}
transition={{ delay, type: 'spring', stiffness: 400, damping: 25 }} transition={{ delay, type: 'spring', stiffness: 400, damping: 25 }}
> >
<div className={`absolute top-0 right-0 bottom-0 w-1 bg-gradient-to-b ${accentColor} rounded-l-full`} />
{icon} {icon}
<span className="text-lg font-bold">{value}</span> <span className="text-xl font-bold">{value}</span>
<span className="text-[10px] text-text-muted">{label}</span> <span className="text-[11px] text-text-muted">{label}</span>
</motion.div> </motion.div>
) )
} }
import { motion } from 'framer-motion' import { motion } from 'framer-motion'
import { Lock, Zap, Timer, Clock, Hourglass, Cpu } from 'lucide-react' import { Lock, Zap, Timer, Clock, Hourglass, Cpu, Crown } from 'lucide-react'
import { useNavigate } from 'react-router-dom' import { useNavigate } from 'react-router-dom'
import { PageTransition } from '../components/layout/PageTransition' import { PageTransition } from '../components/layout/PageTransition'
import { GAMES, TIME_CONTROLS } from '../lib/constants' import { GAMES, TIME_CONTROLS } from '../lib/constants'
...@@ -13,16 +13,44 @@ const CATEGORIES = [ ...@@ -13,16 +13,44 @@ const CATEGORIES = [
{ key: 'classical', label: 'كلاسيكي', icon: Hourglass }, { key: 'classical', label: 'كلاسيكي', icon: Hourglass },
] as const ] as const
const GAME_ICONS: Record<string, React.ReactNode> = {
backgammon: <span className="text-2xl font-bold text-gold">&#x2680;</span>,
dominoes: <span className="text-2xl font-bold text-gold">&#x1F0A1;</span>,
ludo: <span className="text-2xl font-bold text-gold">&#x2684;</span>,
trivia: <span className="text-2xl font-bold text-gold">?</span>,
}
export function PlayPage() { export function PlayPage() {
const navigate = useNavigate() const navigate = useNavigate()
const [selectedTC, setSelectedTC] = useState<string>('blitz_5_0') const [selectedTC, setSelectedTC] = useState<string>('blitz_5_0')
const chessGame = GAMES.find((g) => g.key === 'chess')!
const otherGames = GAMES.filter((g) => g.key !== 'chess')
return ( return (
<PageTransition className="px-4 py-6 flex flex-col gap-6"> <PageTransition className="px-4 py-6 flex flex-col gap-6">
<h1 className="text-xl font-bold">اختر اللعبة</h1> <h1 className="text-xl font-bold">اختر اللعبة</h1>
{/* Chess Hero Card - full width */}
<motion.div
className="relative rounded-2xl overflow-hidden border-2 border-gold/40 bg-gradient-to-br from-surface-2 via-surface-1 to-gold/5 p-5 flex items-center gap-4"
initial={{ opacity: 0, y: 20 }}
animate={{ opacity: 1, y: 0 }}
transition={{ type: 'spring', stiffness: 400, damping: 25 }}
whileTap={{ scale: 0.97 }}
>
<div className="w-14 h-14 rounded-xl bg-gold/10 border border-gold/30 flex items-center justify-center">
<Crown size={28} className="text-gold" />
</div>
<div className="flex-1">
<span className="text-base font-bold">{chessGame.nameAr}</span>
<p className="text-xs text-text-secondary mt-1">العب شطرنج اونلاين ضد لاعبين حقيقيين</p>
</div>
</motion.div>
{/* Other Games 2x2 Grid */}
<div className="grid grid-cols-2 gap-3"> <div className="grid grid-cols-2 gap-3">
{GAMES.map((game, i) => ( {otherGames.map((game, i) => (
<motion.div <motion.div
key={game.key} key={game.key}
className={`relative rounded-2xl overflow-hidden border-2 ${ className={`relative rounded-2xl overflow-hidden border-2 ${
...@@ -32,17 +60,11 @@ export function PlayPage() { ...@@ -32,17 +60,11 @@ export function PlayPage() {
} p-4 flex flex-col items-center gap-2`} } p-4 flex flex-col items-center gap-2`}
initial={{ opacity: 0, y: 20 }} initial={{ opacity: 0, y: 20 }}
animate={{ opacity: 1, y: 0 }} animate={{ opacity: 1, y: 0 }}
transition={{ delay: i * 0.08, type: 'spring', stiffness: 400, damping: 25 }} transition={{ delay: 0.08 + i * 0.08, type: 'spring', stiffness: 400, damping: 25 }}
whileTap={game.available ? { scale: 0.95 } : undefined} whileTap={game.available ? { scale: 0.95 } : undefined}
> >
<div className="w-12 h-12 rounded-xl bg-surface-3 flex items-center justify-center"> <div className="w-12 h-12 rounded-xl bg-surface-3 flex items-center justify-center">
<span className="text-2xl font-bold text-gold"> {GAME_ICONS[game.key] || null}
{game.key === 'chess' && '♚'}
{game.key === 'backgammon' && '⚀'}
{game.key === 'dominoes' && '’'}
{game.key === 'ludo' && '⚄'}
{game.key === 'trivia' && '?'}
</span>
</div> </div>
<span className="text-sm font-bold">{game.nameAr}</span> <span className="text-sm font-bold">{game.nameAr}</span>
{!game.available && ( {!game.available && (
...@@ -55,9 +77,10 @@ export function PlayPage() { ...@@ -55,9 +77,10 @@ export function PlayPage() {
))} ))}
</div> </div>
{/* Time Control Section */}
<div> <div>
<h2 className="text-base font-bold mb-3">نظام الوقت</h2> <h2 className="text-base font-bold mb-3">نظام الوقت</h2>
<div className="flex gap-2 mb-3"> <div className="flex gap-3 mb-3">
{CATEGORIES.map((cat) => { {CATEGORIES.map((cat) => {
const isActive = Object.entries(TIME_CONTROLS).find( const isActive = Object.entries(TIME_CONTROLS).find(
([k]) => k === selectedTC ([k]) => k === selectedTC
...@@ -66,7 +89,7 @@ export function PlayPage() { ...@@ -66,7 +89,7 @@ export function PlayPage() {
return ( return (
<motion.button <motion.button
key={cat.key} key={cat.key}
className={`flex items-center gap-1.5 px-3 py-1.5 rounded-full text-xs font-semibold border ${ className={`flex items-center gap-1.5 px-4 py-2 rounded-full text-xs font-semibold border ${
isActive isActive
? 'bg-gold/10 border-gold/40 text-gold' ? 'bg-gold/10 border-gold/40 text-gold'
: 'bg-surface-2 border-border text-text-muted' : 'bg-surface-2 border-border text-text-muted'
...@@ -109,18 +132,17 @@ export function PlayPage() { ...@@ -109,18 +132,17 @@ export function PlayPage() {
</div> </div>
</div> </div>
<Button onClick={() => navigate('/matchmaking')} className="w-full" size="lg"> {/* Action Buttons */}
البحث عن خصم <div className="flex flex-col gap-3 mt-2">
</Button> <Button onClick={() => navigate('/matchmaking')} className="w-full" size="lg">
البحث عن خصم
</Button>
<Button onClick={() => navigate('/bot-select')} variant="ghost" className="w-full" size="md"> <Button onClick={() => navigate('/bot-select')} variant="ghost" className="w-full" size="md">
<Cpu size={16} /> <Cpu size={16} className="text-gold" />
العب ضد الروبوت العب ضد الروبوت
</Button> </Button>
</div>
<Button onClick={() => navigate('/game')} variant="ghost" className="w-full" size="md">
لعب محلي (تجربة)
</Button>
</PageTransition> </PageTransition>
) )
} }
import { motion } from 'framer-motion' import { motion } from 'framer-motion'
import { Settings, TrendingUp, Target, Flame, Trophy } from 'lucide-react' import { Settings, TrendingUp, Target, Flame, Trophy, LogOut, Lock } from 'lucide-react'
import { useNavigate } from 'react-router-dom' import { useNavigate } from 'react-router-dom'
import { useAuthStore } from '../stores/authStore' import { useAuthStore } from '../stores/authStore'
import { PageTransition } from '../components/layout/PageTransition' import { PageTransition } from '../components/layout/PageTransition'
import { Card } from '../components/ui/Card' import { Card } from '../components/ui/Card'
import { Button } from '../components/ui/Button'
import { supabase } from '../lib/supabase' import { supabase } from '../lib/supabase'
function SectionDivider() {
return (
<div className="w-full h-px bg-gradient-to-l from-transparent via-gold/20 to-transparent" />
)
}
export function ProfilePage() { export function ProfilePage() {
const { profile } = useAuthStore() const { profile } = useAuthStore()
const navigate = useNavigate() const navigate = useNavigate()
...@@ -44,29 +49,34 @@ export function ProfilePage() { ...@@ -44,29 +49,34 @@ export function ProfilePage() {
<motion.button <motion.button
whileTap={{ scale: 0.9 }} whileTap={{ scale: 0.9 }}
onClick={() => navigate('/settings')} onClick={() => navigate('/settings')}
className="p-2 rounded-lg bg-surface-2" className="p-2 rounded-lg bg-surface-2 mr-auto ml-0"
> >
<Settings size={18} className="text-text-muted" /> <Settings size={18} className="text-text-muted" />
</motion.button> </motion.button>
</div> </div>
<Card className="flex items-center gap-3"> <Card className="p-4">
<div className="flex-1 min-w-0"> <div className="flex items-center justify-between mb-3">
<div className="flex items-center justify-between mb-1.5"> <h2 className="text-base font-bold text-text-primary">
<span className="text-xs text-text-muted">المستوى {profile.level}</span> المستوى {profile.level}
<span className="text-xs text-gold font-semibold">{profile.xp} XP</span> </h2>
</div> <span className="text-sm text-gold font-semibold">{profile.xp} XP</span>
<div className="w-full h-2 rounded-full bg-surface-3 overflow-hidden">
<motion.div
className="h-full rounded-full bg-gradient-to-l from-gold to-gold-light"
initial={{ width: 0 }}
animate={{ width: `${Math.min((profile.xp % 500) / 5, 100)}%` }}
transition={{ duration: 1, ease: 'easeOut' }}
/>
</div>
</div> </div>
<div className="w-full h-2.5 rounded-full bg-surface-3 overflow-hidden">
<motion.div
className="h-full rounded-full bg-gradient-to-l from-gold to-gold-light"
initial={{ width: 0 }}
animate={{ width: `${Math.min((profile.xp % 500) / 5, 100)}%` }}
transition={{ duration: 1, ease: 'easeOut' }}
/>
</div>
<p className="text-[11px] text-text-muted mt-2">
{500 - (profile.xp % 500)} XP للمستوى التالي
</p>
</Card> </Card>
<SectionDivider />
<div> <div>
<h2 className="text-sm font-bold text-text-secondary mb-2">التقييمات</h2> <h2 className="text-sm font-bold text-text-secondary mb-2">التقييمات</h2>
<div className="grid grid-cols-2 gap-2"> <div className="grid grid-cols-2 gap-2">
...@@ -95,6 +105,8 @@ export function ProfilePage() { ...@@ -95,6 +105,8 @@ export function ProfilePage() {
</div> </div>
</div> </div>
<SectionDivider />
<div> <div>
<h2 className="text-sm font-bold text-text-secondary mb-2">الاحصائيات</h2> <h2 className="text-sm font-bold text-text-secondary mb-2">الاحصائيات</h2>
<div className="grid grid-cols-4 gap-2"> <div className="grid grid-cols-4 gap-2">
...@@ -105,9 +117,43 @@ export function ProfilePage() { ...@@ -105,9 +117,43 @@ export function ProfilePage() {
</div> </div>
</div> </div>
<Button variant="ghost" onClick={handleLogout} className="mt-4"> <SectionDivider />
تسجيل الخروج
</Button> <div>
<h2 className="text-sm font-bold text-text-secondary mb-2">الانجازات</h2>
<div className="grid grid-cols-3 gap-2">
{[
{ label: 'المحارب' },
{ label: 'البطل' },
{ label: 'الاسطورة' },
].map((badge, i) => (
<motion.div
key={badge.label}
className="flex flex-col items-center gap-2 p-3 rounded-xl bg-surface-1 border border-border/50 opacity-60"
initial={{ opacity: 0, scale: 0.9 }}
animate={{ opacity: 0.6, scale: 1 }}
transition={{ delay: 0.2 + i * 0.08 }}
>
<div className="w-10 h-10 rounded-full bg-surface-3 border border-border flex items-center justify-center">
<Lock size={14} className="text-text-muted" />
</div>
<span className="text-[10px] font-semibold text-text-muted">{badge.label}</span>
<span className="text-[9px] text-gold/60">قريبا</span>
</motion.div>
))}
</div>
</div>
<div className="mt-auto pt-6 flex justify-center">
<motion.button
whileTap={{ scale: 0.95 }}
onClick={handleLogout}
className="flex items-center gap-1.5 px-3 py-1.5 text-xs text-coral/80 hover:text-coral transition-colors"
>
<LogOut size={13} />
<span>تسجيل الخروج</span>
</motion.button>
</div>
</PageTransition> </PageTransition>
) )
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment