Files
gridpilot.gg/apps/website/components/leagues/LeagueOwnershipTransfer.tsx
2026-01-18 23:24:30 +01:00

133 lines
4.5 KiB
TypeScript

import { DriverSummaryPill } from '@/components/drivers/DriverSummaryPillWrapper';
import { DriverViewModel } from '@/lib/view-models/DriverViewModel';
import { LeagueSettingsViewModel } from '@/lib/view-models/LeagueSettingsViewModel';
import { Button } from '@/ui/Button';
import { Card } from '@/ui/Card';
import { Heading } from '@/ui/Heading';
import { Icon } from '@/ui/Icon';
import { Stack } from '@/ui/Stack';
import { Select } from '@/ui/Select';
import { Text } from '@/ui/Text';
import { UserCog } from 'lucide-react';
import { useState } from 'react';
interface LeagueOwnershipTransferProps {
settings: LeagueSettingsViewModel;
currentDriverId: string;
onTransferOwnership: (newOwnerId: string) => Promise<void>;
}
export function LeagueOwnershipTransfer({
settings,
currentDriverId,
onTransferOwnership
}: LeagueOwnershipTransferProps) {
const [showTransferDialog, setShowTransferDialog] = useState(false);
const [selectedNewOwner, setSelectedNewOwner] = useState<string>('');
const [transferring, setTransferring] = useState(false);
const handleTransferOwnership = async () => {
if (!selectedNewOwner) return;
setTransferring(true);
try {
await onTransferOwnership(selectedNewOwner);
setShowTransferDialog(false);
setSelectedNewOwner('');
} catch (err) {
console.error('Failed to transfer ownership:', err);
alert(err instanceof Error ? err.message : 'Failed to transfer ownership');
} finally {
setTransferring(false);
}
};
const ownerSummary = settings.owner;
return (
<Stack gap={4}>
{/* League Owner */}
<Card variant="outline" p={5} rounded="xl" className="bg-panel-gray/40">
<Stack mb={3}>
<Heading level={3}>League Owner</Heading>
</Stack>
{ownerSummary ? (
<DriverSummaryPill
driver={new DriverViewModel({
id: ownerSummary.driver.id,
name: ownerSummary.driver.name,
avatarUrl: ownerSummary.driver.avatarUrl ?? null,
iracingId: ownerSummary.driver.iracingId,
country: ownerSummary.driver.country,
bio: ownerSummary.driver.bio,
joinedAt: ownerSummary.driver.joinedAt,
})}
rating={ownerSummary.rating}
rank={ownerSummary.rank}
/>
) : (
<Text size="sm" color="text-gray-500">Loading owner details...</Text>
)}
</Card>
{/* Transfer Ownership - Owner Only */}
{settings.league.ownerId === currentDriverId && settings.members.length > 0 && (
<Card variant="outline" p={5} rounded="xl" className="bg-panel-gray/40">
<Stack direction="row" align="center" gap={2} mb={3}>
<Icon icon={UserCog} size={4} color="text-gray-400" />
<Heading level={3}>Transfer Ownership</Heading>
</Stack>
<Stack mb={4}>
<Text size="xs" color="text-gray-500">
Transfer league ownership to another active member. You will become an admin.
</Text>
</Stack>
{!showTransferDialog ? (
<Button
variant="secondary"
onClick={() => setShowTransferDialog(true)}
>
Transfer Ownership
</Button>
) : (
<Stack gap={3}>
<Select
value={selectedNewOwner}
onChange={(e) => setSelectedNewOwner(e.target.value)}
options={[
{ value: '', label: 'Select new owner...' },
...settings.members.map((member) => ({
value: member.driver.id,
label: member.driver.name,
})),
]}
/>
<Stack direction="row" gap={2}>
<Button
variant="primary"
onClick={handleTransferOwnership}
disabled={!selectedNewOwner || transferring}
>
{transferring ? 'Transferring...' : 'Confirm Transfer'}
</Button>
<Button
variant="secondary"
onClick={() => {
setShowTransferDialog(false);
setSelectedNewOwner('');
}}
disabled={transferring}
>
Cancel
</Button>
</Stack>
</Stack>
)}
</Card>
)}
</Stack>
);
}