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

dd

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