130 lines
4.0 KiB
TypeScript
130 lines
4.0 KiB
TypeScript
import { useState, FormEventHandler, useMemo } from 'react';
|
|
import { ArrowLeftIcon } from '@phosphor-icons/react';
|
|
import { Autocomplete, Divider, Flex, Text, TextInput, Title, UnstyledButton } from '@mantine/core';
|
|
import ExistingPlayerButton from './existing-player-button';
|
|
import NewPlayerButton from './new-player-button';
|
|
import { Player } from '@/features/players/types';
|
|
import toast from '@/lib/sonner'
|
|
import { useUnassociatedPlayers } from '@/features/players/queries';
|
|
import useCreateUser from '../../hooks/use-create-user';
|
|
import Button from '@/components/button';
|
|
|
|
enum PlayerPromptStage {
|
|
returning = 'returning',
|
|
new = 'new'
|
|
}
|
|
|
|
const PlayerPrompt = () => {
|
|
const [stage, setStage] = useState<PlayerPromptStage>();
|
|
const playersQuery = useUnassociatedPlayers();
|
|
const { mutate: createUser, isPending } = useCreateUser();
|
|
const players = playersQuery.data;
|
|
const [player, setPlayer] = useState<Player>();
|
|
const [value, setValue] = useState('');
|
|
const [error, setError] = useState('');
|
|
|
|
|
|
const parsedPlayers = useMemo(() => players?.map(p => ({ label: `${p.first_name} ${p.last_name}`, value: p})), [players])
|
|
const autocompleteOptions = [...new Set(parsedPlayers?.map(p => p.label))]
|
|
|
|
|
|
const formSubmitHandler = (callback: () => void): FormEventHandler<HTMLFormElement> => {
|
|
return async (event) => {
|
|
event.preventDefault();
|
|
await callback();
|
|
}
|
|
}
|
|
|
|
const handleNewPlayerSubmit = () => {
|
|
const first_name = value.split(' ').slice(0, -1).join(' ');
|
|
const last_name = value.split(' ').slice(-1).join(' ');
|
|
|
|
// check if player already exists
|
|
if (!!parsedPlayers?.find(p => p.label === value)) {
|
|
toast.error("Player already exists");
|
|
return;
|
|
}
|
|
|
|
createUser({
|
|
first_name,
|
|
last_name
|
|
});
|
|
}
|
|
|
|
const handlePlayerSubmit = () => {
|
|
if (player) {
|
|
setError('');
|
|
createUser(player.id!);
|
|
} else {
|
|
setError('You must select a player from the dropdown. If you don\'t see yourself, please go back and select \'New Player\'');
|
|
}
|
|
}
|
|
|
|
const handleNewPlayerChange = (event: React.ChangeEvent<HTMLInputElement>) => {
|
|
setValue(event.target.value);
|
|
}
|
|
|
|
const handleReturningPlayerChange = (player: string) => {
|
|
const selected = parsedPlayers?.find(p => p.label === player);
|
|
if (selected) {
|
|
setError('');
|
|
setPlayer(selected.value);
|
|
} else {
|
|
setPlayer(undefined);
|
|
}
|
|
}
|
|
|
|
if (!stage) {
|
|
return <>
|
|
<Title order={3}>Have you played before?</Title>
|
|
<Text size='xs' mb='sm'>If this is your first time participating, please select <i>New Player</i>, otherwise select <i>Returning Player</i></Text>
|
|
<Flex justify='space-around'>
|
|
<ExistingPlayerButton onClick={() => setStage(PlayerPromptStage.returning)} />
|
|
<Divider orientation='vertical' variant="dashed" />
|
|
<NewPlayerButton onClick={() => setStage(PlayerPromptStage.new)} />
|
|
</Flex>
|
|
</>
|
|
}
|
|
|
|
return <>
|
|
<UnstyledButton
|
|
onClick={() => setStage(undefined)}
|
|
style={{
|
|
position: 'absolute',
|
|
top: 24,
|
|
left: 24,
|
|
}}
|
|
>
|
|
<Flex align='center' gap='xs'>
|
|
<ArrowLeftIcon size={24} />
|
|
</Flex>
|
|
</UnstyledButton>
|
|
{
|
|
stage === PlayerPromptStage.new ?
|
|
<>
|
|
<form onSubmit={formSubmitHandler(handleNewPlayerSubmit)}>
|
|
<TextInput
|
|
label='Enter your name'
|
|
placeholder='Salah Atiyeh'
|
|
value={value}
|
|
onChange={handleNewPlayerChange}
|
|
/>
|
|
<Button type='submit' mt='10px' color='green' variant='filled'>Submit</Button>
|
|
</form>
|
|
</> :
|
|
<form onSubmit={formSubmitHandler(handlePlayerSubmit)}>
|
|
<Autocomplete
|
|
label='Enter your name'
|
|
placeholder='Salah Atiyeh'
|
|
data={autocompleteOptions}
|
|
onChange={handleReturningPlayerChange}
|
|
error={error}
|
|
/>
|
|
<Button type='submit' mt='10px' color='green' variant='filled'>Submit</Button>
|
|
</form>
|
|
}
|
|
</>
|
|
|
|
};
|
|
|
|
export default PlayerPrompt; |