boxy/app/boxes/page.tsx
2025-06-25 01:10:53 +05:30

209 lines
7.4 KiB
TypeScript

'use client';
import { useState } from 'react';
import { useAuth } from '../context/AuthContext';
import Header from '../components/Header';
import PaymentModal from '../components/PaymentModal';
// Mock data for boxes - replace with actual data from your backend
const MOCK_BOXES = [
{
id: '1',
tier: 'Small',
price: 100,
color: 'from-blue-500 to-blue-600',
image: '/box-small.png',
description: 'Perfect for beginners. Contains common to rare items.',
},
{
id: '2',
tier: 'Medium',
price: 1000,
color: 'from-purple-500 to-purple-600',
image: '/box-medium.png',
description: 'For serious collectors. Contains rare to epic items.',
},
{
id: '3',
tier: 'Big',
price: 10000,
color: 'from-pink-500 to-pink-600',
image: '/box-big.png',
description: 'Premium boxes with epic to legendary items.',
},
];
type SortOption = 'price-asc' | 'price-desc';
type FilterTier = 'all' | 'small' | 'medium' | 'big';
export default function BoxesPage() {
const { user } = useAuth();
const [sortBy, setSortBy] = useState<SortOption>('price-asc');
const [filterTier, setFilterTier] = useState<FilterTier>('all');
const [selectedBox, setSelectedBox] = useState<typeof MOCK_BOXES[0] | null>(null);
const [isPaymentModalOpen, setIsPaymentModalOpen] = useState(false);
const filteredAndSortedBoxes = MOCK_BOXES
.filter(box => filterTier === 'all' || box.tier.toLowerCase() === filterTier)
.sort((a, b) => {
switch (sortBy) {
case 'price-asc':
return a.price - b.price;
case 'price-desc':
return b.price - a.price;
default:
return 0;
}
});
const handleOpenBox = (box: typeof MOCK_BOXES[0]) => {
if (!user) {
// Redirect to login or show login modal
return;
}
setSelectedBox(box);
setIsPaymentModalOpen(true);
};
const handleClosePaymentModal = () => {
setIsPaymentModalOpen(false);
setSelectedBox(null);
};
return (
<>
<Header />
<div className="min-h-screen bg-gradient-to-b from-background to-background/95 pt-16">
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-8">
{/* Page Header */}
<div className="mb-8">
<h1 className="text-3xl font-bold mb-2">Mystery Boxes</h1>
<p className="text-foreground/60">
Choose your box and discover amazing prizes
</p>
</div>
{/* Filters and Sort */}
<div className="flex flex-col sm:flex-row gap-4 mb-8">
{/* Tier Filter */}
<div className="flex gap-2">
<button
onClick={() => setFilterTier('all')}
className={`px-4 py-2 rounded-lg text-sm font-medium transition-colors ${
filterTier === 'all'
? 'bg-purple-600 text-white'
: 'bg-foreground/5 hover:bg-foreground/10'
}`}
>
All
</button>
<button
onClick={() => setFilterTier('small')}
className={`px-4 py-2 rounded-lg text-sm font-medium transition-colors ${
filterTier === 'small'
? 'bg-blue-600 text-white'
: 'bg-foreground/5 hover:bg-foreground/10'
}`}
>
Small
</button>
<button
onClick={() => setFilterTier('medium')}
className={`px-4 py-2 rounded-lg text-sm font-medium transition-colors ${
filterTier === 'medium'
? 'bg-purple-600 text-white'
: 'bg-foreground/5 hover:bg-foreground/10'
}`}
>
Medium
</button>
<button
onClick={() => setFilterTier('big')}
className={`px-4 py-2 rounded-lg text-sm font-medium transition-colors ${
filterTier === 'big'
? 'bg-pink-600 text-white'
: 'bg-foreground/5 hover:bg-foreground/10'
}`}
>
Big
</button>
</div>
{/* Sort Dropdown */}
<select
value={sortBy}
onChange={(e) => setSortBy(e.target.value as SortOption)}
className="ml-auto px-4 py-2 rounded-lg bg-foreground/5 border border-foreground/10 text-sm focus:outline-none focus:ring-2 focus:ring-purple-500"
>
<option value="price-asc">Price: Low to High</option>
<option value="price-desc">Price: High to Low</option>
</select>
</div>
{/* Boxes Grid */}
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
{filteredAndSortedBoxes.map((box) => (
<div
key={box.id}
className="relative group rounded-2xl overflow-hidden bg-gradient-to-br p-[1px] hover:scale-[1.02] transition-transform"
>
<div className={`absolute inset-0 bg-gradient-to-br ${box.color} opacity-20`} />
<div className="relative bg-background/95 p-6 rounded-2xl">
{/* Box Image */}
<div className="aspect-square mb-4 rounded-lg bg-foreground/5 flex items-center justify-center">
<div className="text-4xl">🎁</div>
</div>
{/* Box Info */}
<div className="space-y-4">
<div>
<h3 className="text-2xl font-bold mb-1">{box.tier} Box</h3>
<p className="text-foreground/60 text-sm">{box.description}</p>
</div>
{/* Price and Action */}
<div className="flex items-center justify-between pt-2">
<div className="flex items-center gap-2">
<span className="text-lg font-semibold">${box.price}</span>
<span className="text-foreground/60 text-sm">USD</span>
</div>
<button
onClick={() => handleOpenBox(box)}
className={`px-4 py-2 rounded-full text-sm font-medium transition-opacity ${
user
? 'bg-gradient-to-r from-purple-600 to-pink-600 text-white hover:opacity-90'
: 'bg-foreground/10 text-foreground/60 cursor-not-allowed'
}`}
disabled={!user}
>
{user ? 'Open Box' : 'Sign in to Open'}
</button>
</div>
</div>
</div>
</div>
))}
</div>
{/* Empty State */}
{filteredAndSortedBoxes.length === 0 && (
<div className="text-center py-12">
<div className="text-4xl mb-4">🔍</div>
<h3 className="text-xl font-semibold mb-2">No boxes found</h3>
<p className="text-foreground/60">
Try adjusting your filters to see more boxes
</p>
</div>
)}
</div>
</div>
{/* Payment Modal */}
<PaymentModal
isOpen={isPaymentModalOpen}
onClose={handleClosePaymentModal}
box={selectedBox}
/>
</>
);
}