Commit 932ff403 authored by Mahmoud Aglan's avatar Mahmoud Aglan

dd

parent 0c0bcb97
import { Outlet } from 'react-router-dom' import { Outlet } from 'react-router-dom'
import { Header } from './Header' import { Header } from './Header'
import { BottomNav } from './BottomNav' import { BottomNav } from './BottomNav'
import { DecorativeBackground } from './DecorativeBackground'
import { ToastContainer } from '../ui/ToastContainer' import { ToastContainer } from '../ui/ToastContainer'
import { usePresence } from '../../hooks/usePresence' import { usePresence } from '../../hooks/usePresence'
import { useNotifications } from '../../hooks/useNotifications' import { useNotifications } from '../../hooks/useNotifications'
...@@ -11,15 +10,12 @@ export function AppShell() { ...@@ -11,15 +10,12 @@ export function AppShell() {
useNotifications() useNotifications()
return ( return (
<div className="relative flex flex-col min-h-dvh overflow-hidden"> <div className="flex flex-col min-h-dvh bg-background">
<DecorativeBackground /> <Header />
<div className="relative z-10 flex flex-col min-h-dvh"> <main className="flex-1 overflow-y-auto">
<Header /> <Outlet />
<main className="flex-1 pb-28 overflow-y-auto"> </main>
<Outlet /> <BottomNav />
</main>
<BottomNav />
</div>
<ToastContainer /> <ToastContainer />
</div> </div>
) )
......
import { motion } from 'framer-motion'
import { Home, Gamepad2, Trophy, Users, User } from 'lucide-react' import { Home, Gamepad2, Trophy, Users, User } from 'lucide-react'
import { useLocation, useNavigate } from 'react-router-dom' import { useLocation, useNavigate } from 'react-router-dom'
...@@ -15,38 +14,25 @@ export function BottomNav() { ...@@ -15,38 +14,25 @@ export function BottomNav() {
const navigate = useNavigate() const navigate = useNavigate()
return ( return (
<nav className="fixed bottom-0 left-0 right-0 z-50 bg-surface-1 border-t border-border"> <nav className="fixed bottom-0 left-0 right-0 z-50 bg-background border-t border-border safe-area-pb">
<div className="flex items-center justify-around px-4 py-2 max-w-[480px] mx-auto"> <div className="flex items-stretch justify-around max-w-[480px] mx-auto">
{NAV_ITEMS.map((item) => { {NAV_ITEMS.map((item) => {
const isActive = location.pathname === item.path const isActive = location.pathname === item.path
const Icon = item.icon const Icon = item.icon
return ( return (
<motion.button <button
key={item.path} key={item.path}
onClick={() => navigate(item.path)} onClick={() => navigate(item.path)}
className="relative flex flex-col items-center gap-1 py-1 min-w-[44px] min-h-[44px] justify-center" className={`flex flex-col items-center justify-center gap-0.5 py-2 px-3 min-w-[56px] min-h-[56px] transition-colors ${
whileTap={{ scale: 0.9 }} isActive ? 'text-gold' : 'text-text-muted'
transition={{ duration: 0.15 }} }`}
> >
<Icon <Icon size={22} strokeWidth={isActive ? 2.5 : 1.8} />
size={22} <span className={`text-[10px] ${isActive ? 'font-semibold' : 'font-normal'}`}>
className={isActive ? 'text-gold' : 'text-text-muted'}
strokeWidth={isActive ? 2.5 : 2}
/>
<span
className={`text-[11px] font-semibold ${isActive ? 'text-gold' : 'text-text-muted'}`}
>
{item.label} {item.label}
</span> </span>
{isActive && ( </button>
<motion.div
className="absolute -bottom-2 w-6 h-[3px] rounded-full bg-gold"
layoutId="nav-indicator"
transition={{ duration: 0.2 }}
/>
)}
</motion.button>
) )
})} })}
</div> </div>
......
import { motion } from 'framer-motion'
import { Bell, Coins, Gem } from 'lucide-react' import { Bell, Coins, Gem } from 'lucide-react'
import { useNotificationStore } from '../../stores/notificationStore' import { useNotificationStore } from '../../stores/notificationStore'
import { useAuthStore } from '../../stores/authStore' import { useAuthStore } from '../../stores/authStore'
...@@ -10,55 +9,49 @@ export function Header() { ...@@ -10,55 +9,49 @@ export function Header() {
const navigate = useNavigate() const navigate = useNavigate()
return ( return (
<header className="sticky top-0 z-50 bg-surface-1/95 backdrop-blur-sm border-b border-border"> <header className="sticky top-0 z-50 bg-background border-b border-border">
<div className="app-container flex items-center justify-between h-14"> <div className="flex items-center justify-between h-14 px-4 max-w-[1440px] mx-auto">
{/* Logo */} {/* Logo */}
<div className="flex items-center gap-2"> <div className="flex items-center gap-3">
<span className="text-lg font-bold text-gold tracking-wide"> <span className="text-xl font-bold tracking-tight text-text-primary">
EL3AB EL3AB
</span> </span>
{profile && ( {profile && (
<div className="flex items-center justify-center w-7 h-7 rounded-full bg-surface-2 border border-border"> <span className="text-xs font-medium text-text-muted bg-surface-2 px-2 py-0.5 rounded-[var(--radius-tiny)]">
<span className="text-[11px] font-bold text-gold"> Lv.{profile.level || 1}
{profile.level || 1} </span>
</span>
</div>
)} )}
</div> </div>
{/* Resources + Bell */} {/* Right: currency + notifications */}
<div className="flex items-center gap-3"> <div className="flex items-center gap-2">
{profile && ( {profile && (
<> <>
<div className="flex items-center gap-1.5 px-3 py-1.5 rounded-[var(--radius-tiny)] bg-surface-2 border border-border"> <div className="flex items-center gap-1.5 px-2.5 py-1.5 bg-surface-2 rounded-[var(--radius-tiny)]">
<Coins size={14} className="text-gold" /> <Coins size={14} className="text-gold" />
<span className="text-xs font-semibold text-text-primary">{profile.coins}</span> <span className="text-xs font-semibold text-text-primary tabular-nums">{profile.coins}</span>
</div> </div>
{profile.gems > 0 && ( {(profile.gems ?? 0) > 0 && (
<div className="flex items-center gap-1.5 px-3 py-1.5 rounded-[var(--radius-tiny)] bg-surface-2 border border-border"> <div className="flex items-center gap-1.5 px-2.5 py-1.5 bg-surface-2 rounded-[var(--radius-tiny)]">
<Gem size={12} className="text-purple" /> <Gem size={12} className="text-purple" />
<span className="text-xs font-semibold text-text-primary">{profile.gems}</span> <span className="text-xs font-semibold text-text-primary tabular-nums">{profile.gems}</span>
</div> </div>
)} )}
</> </>
)} )}
<motion.button <button
className="relative flex items-center justify-center w-10 h-10 rounded-[var(--radius-tiny)] bg-surface-2 border border-border" className="relative flex items-center justify-center w-10 h-10 rounded-[var(--radius-tiny)] hover:bg-surface-2 transition-colors"
onClick={() => navigate('/notifications')} onClick={() => navigate('/notifications')}
whileTap={{ scale: 0.9 }}
transition={{ duration: 0.15 }}
> >
<Bell size={18} className="text-text-secondary" /> <Bell size={20} className="text-text-secondary" />
{unreadCount > 0 && ( {unreadCount > 0 && (
<div className="absolute -top-1 -right-1 w-5 h-5 rounded-full bg-coral flex items-center justify-center"> <span className="absolute top-1 right-1 w-4 h-4 rounded-full bg-coral text-[9px] font-bold text-white flex items-center justify-center">
<span className="text-[10px] font-bold text-white"> {unreadCount > 9 ? '9+' : unreadCount}
{unreadCount > 9 ? '9+' : unreadCount} </span>
</span>
</div>
)} )}
</motion.button> </button>
</div> </div>
</div> </div>
</header> </header>
......
...@@ -9,7 +9,7 @@ interface PageTransitionProps { ...@@ -9,7 +9,7 @@ interface PageTransitionProps {
export function PageTransition({ children, className = '' }: PageTransitionProps) { export function PageTransition({ children, className = '' }: PageTransitionProps) {
return ( return (
<motion.div <motion.div
className={`app-container py-6 pb-24 ${className}`} className={`px-4 py-6 pb-28 max-w-[1440px] mx-auto w-full md:px-6 lg:px-8 ${className}`}
initial={{ opacity: 0 }} initial={{ opacity: 0 }}
animate={{ opacity: 1 }} animate={{ opacity: 1 }}
exit={{ opacity: 0 }} exit={{ opacity: 0 }}
......
...@@ -281,3 +281,7 @@ body { ...@@ -281,3 +281,7 @@ body {
.bg-surface-1 { background-color: var(--color-surface-1); } .bg-surface-1 { background-color: var(--color-surface-1); }
.bg-surface-2 { background-color: var(--color-surface-2); } .bg-surface-2 { background-color: var(--color-surface-2); }
.bg-surface-3 { background-color: var(--color-surface-3); } .bg-surface-3 { background-color: var(--color-surface-3); }
.safe-area-pb {
padding-bottom: env(safe-area-inset-bottom, 0px);
}
This diff is collapsed.
...@@ -13,16 +13,6 @@ const CATEGORIES = [ ...@@ -13,16 +13,6 @@ const CATEGORIES = [
{ key: 'classical', label: 'كلاسيكي', icon: Hourglass }, { key: 'classical', label: 'كلاسيكي', icon: Hourglass },
] as const ] as const
const stagger = {
hidden: {},
show: { transition: { staggerChildren: 0.06 } },
}
const fadeUp = {
hidden: { opacity: 0, y: 12 },
show: { opacity: 1, y: 0, transition: { duration: 0.2 } },
}
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')
...@@ -36,68 +26,56 @@ export function PlayPage() { ...@@ -36,68 +26,56 @@ export function PlayPage() {
return ( return (
<PageTransition> <PageTransition>
<motion.div <div className="flex flex-col gap-8">
variants={stagger}
initial="hidden"
animate="show"
className="flex flex-col gap-6"
>
{/* Page Title */} {/* Page Title */}
<motion.div variants={fadeUp}> <h1 className="text-2xl font-bold text-text-primary">العب</h1>
<h1 className="text-2xl font-bold text-text-primary">اختر اللعبة</h1>
</motion.div>
{/* Featured Game: Chess */} {/* Game Selection */}
<motion.div variants={fadeUp} className="card border-gold/20"> <section className="flex flex-col gap-3">
<div className="flex items-center gap-4"> {/* Chess - primary */}
<div className="w-14 h-14 rounded-[var(--radius-standard)] bg-gold/10 border border-gold/20 flex items-center justify-center"> <div className="bg-surface-2 rounded-[var(--radius-standard)] p-4 flex items-center gap-4 border border-gold/20">
<span className="text-2xl">♟️</span> <div className="w-12 h-12 rounded-[var(--radius-tiny)] bg-gold/10 flex items-center justify-center text-2xl">
♟️
</div> </div>
<div className="flex-1"> <div className="flex-1">
<span className="text-lg font-bold text-text-primary">{chessGame.nameAr}</span> <p className="font-semibold text-text-primary">{chessGame.nameAr}</p>
<p className="text-sm text-text-secondary mt-0.5"> <div className="flex items-center gap-1.5 mt-1">
العب شطرنج اونلاين ضد لاعبين حقيقيين <span className="w-2 h-2 rounded-full bg-online" />
</p> <span className="text-xs text-text-muted">متاح الان</span>
<div className="flex items-center gap-2 mt-2">
<div className="w-2 h-2 rounded-full bg-online animate-pulse-soft" />
<span className="text-xs text-online font-medium">اونلاين</span>
</div> </div>
</div> </div>
</div> </div>
</motion.div>
{/* Other Games (locked) */} {/* Other games - locked row */}
<motion.div variants={fadeUp} className="grid grid-cols-2 gap-3"> <div className="grid grid-cols-4 gap-2">
{otherGames.map((game) => ( {otherGames.map((game) => (
<div <div
key={game.key} key={game.key}
className="card flex items-center gap-2 py-3 px-3 opacity-50" className="bg-surface-2 rounded-[var(--radius-tiny)] py-3 flex flex-col items-center gap-1 opacity-40"
> >
<Lock size={14} className="text-text-muted" /> <Lock size={14} className="text-text-muted" />
<div> <span className="text-[10px] text-text-muted">{game.nameAr}</span>
<span className="text-sm font-medium text-text-muted block">{game.nameAr}</span>
<span className="text-[11px] text-text-muted">قريبا</span>
</div> </div>
</div> ))}
))} </div>
</motion.div> </section>
{/* Time Control */} {/* Time Control */}
<motion.div variants={fadeUp} className="space-y-4"> <section className="flex flex-col gap-4">
<h2 className="text-lg font-bold text-text-primary">نظام الوقت</h2> <h2 className="text-lg font-semibold text-text-primary">الوقت</h2>
{/* Category Tabs */} {/* Category tabs */}
<div className="flex gap-2"> <div className="flex gap-2 overflow-x-auto">
{CATEGORIES.map((cat) => { {CATEGORIES.map((cat) => {
const isActive = activeCategory === cat.key const isActive = activeCategory === cat.key
const Icon = cat.icon const Icon = cat.icon
return ( return (
<button <button
key={cat.key} key={cat.key}
className={`flex items-center gap-1.5 px-4 py-2 rounded-[var(--radius-tiny)] text-sm font-semibold transition-all ${ className={`flex items-center gap-1.5 px-3 py-2 rounded-[var(--radius-tiny)] text-sm font-medium whitespace-nowrap transition-colors ${
isActive isActive
? 'bg-gold text-background' ? 'bg-gold text-background'
: 'bg-surface-2 text-text-muted border border-border' : 'bg-surface-2 text-text-muted'
}`} }`}
onClick={() => { onClick={() => {
playSound('tap') playSound('tap')
...@@ -112,39 +90,37 @@ export function PlayPage() { ...@@ -112,39 +90,37 @@ export function PlayPage() {
})} })}
</div> </div>
{/* Time Options Grid */} {/* Time options */}
<div className="grid grid-cols-3 gap-3"> <div className="grid grid-cols-3 gap-2">
{Object.entries(TIME_CONTROLS) {Object.entries(TIME_CONTROLS)
.filter(([, v]) => v.category === activeCategory) .filter(([, v]) => v.category === activeCategory)
.map(([key, tc]) => { .map(([key, tc]) => {
const isSelected = selectedTC === key const isSelected = selectedTC === key
return ( return (
<motion.button <button
key={key} key={key}
className={`py-4 px-3 text-center font-bold rounded-[var(--radius-standard)] border transition-all ${ className={`py-4 text-center font-semibold rounded-[var(--radius-standard)] transition-all ${
isSelected isSelected
? 'border-gold bg-gold/10 text-gold' ? 'bg-gold/10 border-2 border-gold text-gold'
: 'border-border bg-surface-1 text-text-secondary' : 'bg-surface-2 border border-transparent text-text-secondary hover:bg-surface-3'
}`} }`}
whileTap={{ scale: 0.95 }}
transition={{ duration: 0.15 }}
onClick={() => { onClick={() => {
playSound('tap') playSound('tap')
setSelectedTC(key) setSelectedTC(key)
}} }}
> >
{tc.labelAr} {tc.labelAr}
</motion.button> </button>
) )
})} })}
</div> </div>
</motion.div> </section>
{/* Action Buttons */} {/* Actions */}
<motion.div variants={fadeUp} className="flex flex-col gap-3 mt-2"> <section className="flex flex-col gap-3">
<motion.button <motion.button
className="btn-gold w-full py-5 rounded-[var(--radius-large)] text-lg font-bold" className="w-full flex items-center justify-center gap-3 py-5 bg-gold rounded-[var(--radius-large)] text-background text-lg font-bold"
whileTap={{ scale: 0.96, y: 2 }} whileTap={{ scale: 0.97 }}
transition={{ duration: 0.15 }} transition={{ duration: 0.15 }}
onClick={() => { onClick={() => {
playSound('tap') playSound('tap')
...@@ -152,12 +128,12 @@ export function PlayPage() { ...@@ -152,12 +128,12 @@ export function PlayPage() {
}} }}
> >
<Swords size={22} /> <Swords size={22} />
<span>البحث عن خصم</span> البحث عن خصم
</motion.button> </motion.button>
<motion.button <motion.button
className="btn-ghost w-full py-4 rounded-[var(--radius-large)] text-base font-semibold" className="w-full flex items-center justify-center gap-3 py-4 bg-surface-2 border border-border rounded-[var(--radius-large)] text-text-primary text-base font-medium"
whileTap={{ scale: 0.96 }} whileTap={{ scale: 0.97 }}
transition={{ duration: 0.15 }} transition={{ duration: 0.15 }}
onClick={() => { onClick={() => {
playSound('tap') playSound('tap')
...@@ -165,10 +141,10 @@ export function PlayPage() { ...@@ -165,10 +141,10 @@ export function PlayPage() {
}} }}
> >
<Cpu size={20} className="text-purple" /> <Cpu size={20} className="text-purple" />
<span>العب ضد الروبوت</span> ضد الروبوت
</motion.button> </motion.button>
</motion.div> </section>
</motion.div> </div>
</PageTransition> </PageTransition>
) )
} }
This diff is collapsed.
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