page wrapper
This commit is contained in:
@@ -58,18 +58,16 @@ interface LeagueSliderProps {
|
||||
icon: React.ElementType;
|
||||
description: string;
|
||||
leagues: LeagueSummaryViewModel[];
|
||||
onLeagueClick: (id: string) => void;
|
||||
autoScroll?: boolean;
|
||||
iconColor?: string;
|
||||
scrollSpeedMultiplier?: number;
|
||||
scrollDirection?: 'left' | 'right';
|
||||
}
|
||||
|
||||
import Link from 'next/link';
|
||||
|
||||
interface LeaguesTemplateProps {
|
||||
leagues: LeagueSummaryViewModel[];
|
||||
loading?: boolean;
|
||||
onLeagueClick: (id: string) => void;
|
||||
onCreateLeagueClick: () => void;
|
||||
data: LeagueSummaryViewModel[];
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
@@ -183,7 +181,6 @@ function LeagueSlider({
|
||||
icon: Icon,
|
||||
description,
|
||||
leagues,
|
||||
onLeagueClick,
|
||||
autoScroll = true,
|
||||
iconColor = 'text-primary-blue',
|
||||
scrollSpeedMultiplier = 1,
|
||||
@@ -372,7 +369,9 @@ function LeagueSlider({
|
||||
`}</style>
|
||||
{leagues.map((league) => (
|
||||
<div key={league.id} className="flex-shrink-0 w-[320px] h-full">
|
||||
<LeagueCard league={league} onClick={() => onLeagueClick(league.id)} />
|
||||
<Link href={`/leagues/${league.id}`} className="block h-full">
|
||||
<LeagueCard league={league} />
|
||||
</Link>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
@@ -386,17 +385,14 @@ function LeagueSlider({
|
||||
// ============================================================================
|
||||
|
||||
export function LeaguesTemplate({
|
||||
leagues,
|
||||
loading = false,
|
||||
onLeagueClick,
|
||||
onCreateLeagueClick,
|
||||
data,
|
||||
}: LeaguesTemplateProps) {
|
||||
const [searchQuery, setSearchQuery] = useState('');
|
||||
const [activeCategory, setActiveCategory] = useState<CategoryId>('all');
|
||||
const [showFilters, setShowFilters] = useState(false);
|
||||
|
||||
// Filter by search query
|
||||
const searchFilteredLeagues = leagues.filter((league) => {
|
||||
const searchFilteredLeagues = data.filter((league: LeagueSummaryViewModel) => {
|
||||
if (!searchQuery) return true;
|
||||
const query = searchQuery.toLowerCase();
|
||||
return (
|
||||
@@ -416,7 +412,7 @@ export function LeaguesTemplate({
|
||||
const leaguesByCategory = CATEGORIES.reduce(
|
||||
(acc, category) => {
|
||||
// First try to use the dedicated category field, fall back to scoring-based filtering
|
||||
acc[category.id] = searchFilteredLeagues.filter((league) => {
|
||||
acc[category.id] = searchFilteredLeagues.filter((league: LeagueSummaryViewModel) => {
|
||||
// If league has a category field, use it directly
|
||||
if (league.category) {
|
||||
return league.category === category.id;
|
||||
@@ -440,19 +436,6 @@ export function LeaguesTemplate({
|
||||
{ id: 'sprint', speed: 1.2, direction: 'right' },
|
||||
];
|
||||
|
||||
if (loading) {
|
||||
return (
|
||||
<div className="max-w-7xl mx-auto px-4">
|
||||
<div className="flex items-center justify-center min-h-[400px]">
|
||||
<div className="flex flex-col items-center gap-4">
|
||||
<div className="w-10 h-10 border-2 border-primary-blue border-t-transparent rounded-full animate-spin" />
|
||||
<p className="text-gray-400">Loading leagues...</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="max-w-7xl mx-auto px-4 pb-12">
|
||||
{/* Hero Section */}
|
||||
@@ -480,7 +463,7 @@ export function LeaguesTemplate({
|
||||
<div className="flex items-center gap-2">
|
||||
<div className="w-2 h-2 rounded-full bg-performance-green animate-pulse" />
|
||||
<span className="text-sm text-gray-400">
|
||||
<span className="text-white font-semibold">{leagues.length}</span> active leagues
|
||||
<span className="text-white font-semibold">{data.length}</span> active leagues
|
||||
</span>
|
||||
</div>
|
||||
<div className="flex items-center gap-2">
|
||||
@@ -500,14 +483,10 @@ export function LeaguesTemplate({
|
||||
|
||||
{/* CTA */}
|
||||
<div className="flex flex-col gap-4">
|
||||
<Button
|
||||
variant="primary"
|
||||
onClick={onCreateLeagueClick}
|
||||
className="flex items-center gap-2 px-6 py-3"
|
||||
>
|
||||
<Link href="/leagues/create" className="flex items-center gap-2 px-6 py-3 bg-primary-blue text-white rounded-lg hover:bg-blue-600 transition-colors">
|
||||
<Plus className="w-5 h-5" />
|
||||
<span>Create League</span>
|
||||
</Button>
|
||||
</Link>
|
||||
<p className="text-xs text-gray-500 text-center">Set up your own racing series</p>
|
||||
</div>
|
||||
</div>
|
||||
@@ -574,7 +553,7 @@ export function LeaguesTemplate({
|
||||
</div>
|
||||
|
||||
{/* Content */}
|
||||
{leagues.length === 0 ? (
|
||||
{data.length === 0 ? (
|
||||
/* Empty State */
|
||||
<Card className="text-center py-16">
|
||||
<div className="max-w-md mx-auto">
|
||||
@@ -587,14 +566,10 @@ export function LeaguesTemplate({
|
||||
<p className="text-gray-400 mb-8">
|
||||
Be the first to create a racing series. Start your own league and invite drivers to compete for glory.
|
||||
</p>
|
||||
<Button
|
||||
variant="primary"
|
||||
onClick={onCreateLeagueClick}
|
||||
className="flex items-center gap-2 mx-auto"
|
||||
>
|
||||
<Link href="/leagues/create" className="inline-flex items-center gap-2 px-6 py-3 bg-primary-blue text-white rounded-lg hover:bg-blue-600 transition-colors">
|
||||
<Sparkles className="w-4 h-4" />
|
||||
Create Your First League
|
||||
</Button>
|
||||
</Link>
|
||||
</div>
|
||||
</Card>
|
||||
) : activeCategory === 'all' && !searchQuery ? (
|
||||
@@ -613,7 +588,6 @@ export function LeaguesTemplate({
|
||||
icon={category.icon}
|
||||
description={category.description}
|
||||
leagues={leaguesByCategory[category.id]}
|
||||
onLeagueClick={onLeagueClick}
|
||||
autoScroll={true}
|
||||
iconColor={category.color || 'text-primary-blue'}
|
||||
scrollSpeedMultiplier={speed}
|
||||
@@ -640,7 +614,9 @@ export function LeaguesTemplate({
|
||||
</div>
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
|
||||
{categoryFilteredLeagues.map((league) => (
|
||||
<LeagueCard key={league.id} league={league} onClick={() => onLeagueClick(league.id)} />
|
||||
<Link key={league.id} href={`/leagues/${league.id}`} className="block h-full">
|
||||
<LeagueCard league={league} />
|
||||
</Link>
|
||||
))}
|
||||
</div>
|
||||
</>
|
||||
|
||||
Reference in New Issue
Block a user