Files
gridpilot.gg/apps/website/components/leagues/LeagueBasicsSection.tsx
2025-12-11 00:57:32 +01:00

163 lines
5.9 KiB
TypeScript

'use client';
import React from 'react';
import { FileText, Gamepad2, AlertCircle, Check } from 'lucide-react';
import Input from '@/components/ui/Input';
import type {
LeagueConfigFormModel,
} from '@gridpilot/racing/application';
interface LeagueBasicsSectionProps {
form: LeagueConfigFormModel;
onChange?: (form: LeagueConfigFormModel) => void;
errors?: {
name?: string;
description?: string;
};
readOnly?: boolean;
}
export function LeagueBasicsSection({
form,
onChange,
errors,
readOnly,
}: LeagueBasicsSectionProps) {
const basics = form.basics;
const disabled = readOnly || !onChange;
const updateBasics = (patch: Partial<typeof basics>) => {
if (!onChange) return;
onChange({
...form,
basics: {
...form.basics,
...patch,
},
});
};
return (
<div className="space-y-8">
{/* Emotional header for the step */}
<div className="text-center pb-2">
<h3 className="text-lg font-semibold text-white mb-2">
Every great championship starts with a name
</h3>
<p className="text-sm text-gray-400 max-w-lg mx-auto">
This is where legends begin. Give your league an identity that drivers will remember.
</p>
</div>
{/* League name */}
<div className="space-y-3">
<label className="flex items-center gap-2 text-sm font-medium text-gray-300">
<FileText className="w-4 h-4 text-primary-blue" />
League name *
</label>
<Input
value={basics.name}
onChange={(e) => updateBasics({ name: e.target.value })}
placeholder="e.g., GridPilot Sprint Series"
error={!!errors?.name}
errorMessage={errors?.name}
disabled={disabled}
autoFocus
/>
<div className="space-y-2">
<p className="text-xs text-gray-500">
Make it memorable this is what drivers will see first
</p>
<div className="flex flex-wrap gap-2">
<span className="text-xs text-gray-500">Try:</span>
<button
type="button"
onClick={() => updateBasics({ name: 'Sunday Showdown Series' })}
className="text-xs px-2 py-0.5 rounded-full bg-primary-blue/10 text-primary-blue hover:bg-primary-blue/20 transition-colors"
disabled={disabled}
>
Sunday Showdown Series
</button>
<button
type="button"
onClick={() => updateBasics({ name: 'Midnight Endurance League' })}
className="text-xs px-2 py-0.5 rounded-full bg-primary-blue/10 text-primary-blue hover:bg-primary-blue/20 transition-colors"
disabled={disabled}
>
Midnight Endurance League
</button>
<button
type="button"
onClick={() => updateBasics({ name: 'GT Masters Championship' })}
className="text-xs px-2 py-0.5 rounded-full bg-primary-blue/10 text-primary-blue hover:bg-primary-blue/20 transition-colors"
disabled={disabled}
>
GT Masters Championship
</button>
</div>
</div>
</div>
{/* Description - Now Required */}
<div className="space-y-3">
<label className="flex items-center gap-2 text-sm font-medium text-gray-300">
<FileText className="w-4 h-4 text-primary-blue" />
Tell your story *
</label>
<textarea
value={basics.description ?? ''}
onChange={(e) =>
updateBasics({
description: e.target.value,
})
}
rows={4}
disabled={disabled}
className={`block w-full rounded-md border-0 px-4 py-3 bg-iron-gray text-white shadow-sm ring-1 ring-inset placeholder:text-gray-500 focus:ring-2 focus:ring-inset focus:ring-primary-blue text-sm disabled:opacity-60 disabled:cursor-not-allowed transition-all duration-150 ${
errors?.description ? 'ring-warning-amber' : 'ring-charcoal-outline'
}`}
placeholder="What makes your league special? Tell drivers what to expect..."
/>
{errors?.description && (
<p className="text-xs text-warning-amber flex items-center gap-1.5">
<AlertCircle className="w-3 h-3" />
{errors.description}
</p>
)}
<div className="rounded-lg bg-iron-gray/50 border border-charcoal-outline/50 p-4 space-y-3">
<p className="text-xs text-gray-400">
<span className="font-medium text-gray-300">Great descriptions include:</span>
</p>
<div className="grid grid-cols-1 sm:grid-cols-3 gap-3">
<div className="flex items-start gap-2">
<Check className="w-3.5 h-3.5 text-performance-green shrink-0 mt-0.5" />
<span className="text-xs text-gray-400">Racing style & pace</span>
</div>
<div className="flex items-start gap-2">
<Check className="w-3.5 h-3.5 text-performance-green shrink-0 mt-0.5" />
<span className="text-xs text-gray-400">Schedule & timezone</span>
</div>
<div className="flex items-start gap-2">
<Check className="w-3.5 h-3.5 text-performance-green shrink-0 mt-0.5" />
<span className="text-xs text-gray-400">Community vibe</span>
</div>
</div>
</div>
</div>
{/* Game Platform */}
<div className="space-y-2">
<label className="flex items-center gap-2 text-sm font-medium text-gray-300">
<Gamepad2 className="w-4 h-4 text-gray-400" />
Game platform
</label>
<div className="relative">
<Input value="iRacing" disabled />
<div className="absolute right-3 top-1/2 -translate-y-1/2 text-xs text-gray-500">
More platforms soon
</div>
</div>
</div>
</div>
);
}