Files
gridpilot.gg/apps/website/components/teams/CreateTeamForm.tsx
2026-01-15 17:12:24 +01:00

152 lines
4.6 KiB
TypeScript

'use client';
import React, { useState } from 'react';
import { Button } from '@/ui/Button';
import { Input } from '@/ui/Input';
import { TextArea } from '@/ui/TextArea';
import { useCreateTeam } from "@/hooks/team/useCreateTeam";
import { Box } from '@/ui/Box';
import { Stack } from '@/ui/Stack';
import { Text } from '@/ui/Text';
import { InfoBanner } from '@/ui/InfoBanner';
interface CreateTeamFormProps {
onCancel?: () => void;
onSuccess?: (teamId: string) => void;
onNavigate: (teamId: string) => void;
}
export function CreateTeamForm({ onCancel, onSuccess, onNavigate }: CreateTeamFormProps) {
const createTeamMutation = useCreateTeam();
const [formData, setFormData] = useState({
name: '',
tag: '',
description: '',
});
const [errors, setErrors] = useState<Record<string, string>>({});
const validateForm = () => {
const newErrors: Record<string, string> = {};
if (!formData.name.trim()) {
newErrors.name = 'Team name is required';
} else if (formData.name.length < 3) {
newErrors.name = 'Team name must be at least 3 characters';
}
if (!formData.tag.trim()) {
newErrors.tag = 'Team tag is required';
} else if (formData.tag.length > 4) {
newErrors.tag = 'Team tag must be 4 characters or less';
}
if (!formData.description.trim()) {
newErrors.description = 'Description is required';
} else if (formData.description.length < 10) {
newErrors.description = 'Description must be at least 10 characters';
}
setErrors(newErrors);
return Object.keys(newErrors).length === 0;
};
const handleSubmit = async (e: React.FormEvent) => {
e.preventDefault();
if (!validateForm()) {
return;
}
createTeamMutation.mutate(
{
name: formData.name,
tag: formData.tag.toUpperCase(),
description: formData.description,
},
{
onSuccess: (result) => {
const teamId = result.id;
if (onSuccess) {
onSuccess(teamId);
} else {
onNavigate(teamId);
}
},
onError: (error) => {
alert(error instanceof Error ? error.message : 'Failed to create team');
},
}
);
};
return (
<Box as="form" onSubmit={handleSubmit}>
<Stack gap={6}>
<Input
label="Team Name *"
type="text"
value={formData.name}
onChange={(e) => setFormData({ ...formData, name: e.target.value })}
placeholder="Enter team name..."
disabled={createTeamMutation.isPending}
variant={errors.name ? 'error' : 'default'}
errorMessage={errors.name}
/>
<Input
label="Team Tag *"
type="text"
value={formData.tag}
onChange={(e) => setFormData({ ...formData, tag: e.target.value.toUpperCase() })}
placeholder="e.g., APEX"
maxLength={4}
disabled={createTeamMutation.isPending}
variant={errors.tag ? 'error' : 'default'}
errorMessage={errors.tag}
/>
<TextArea
label="Description *"
rows={4}
value={formData.description}
onChange={(e) => setFormData({ ...formData, description: e.target.value })}
placeholder="Describe your team's goals and racing style..."
disabled={createTeamMutation.isPending}
variant={errors.description ? 'error' : 'default'}
errorMessage={errors.description}
/>
<InfoBanner title="About Team Creation">
<Stack as="ul" gap={1}>
<Text as="li" size="sm" color="text-gray-400"> You will be assigned as the team owner</Text>
<Text as="li" size="sm" color="text-gray-400"> You can invite other drivers to join your team</Text>
<Text as="li" size="sm" color="text-gray-400"> Team standings are calculated across leagues</Text>
<Text as="li" size="sm" color="text-gray-400"> This is alpha data - it resets on page reload</Text>
</Stack>
</InfoBanner>
<Box display="flex" gap={3}>
<Button
type="submit"
variant="primary"
disabled={createTeamMutation.isPending}
fullWidth
>
{createTeamMutation.isPending ? 'Creating Team...' : 'Create Team'}
</Button>
{onCancel && (
<Button
type="button"
variant="secondary"
onClick={onCancel}
disabled={createTeamMutation.isPending}
>
Cancel
</Button>
)}
</Box>
</Stack>
</Box>
);
}