85 lines
2.2 KiB
TypeScript
85 lines
2.2 KiB
TypeScript
import { Stack, Button, Divider, Group, ComboboxItem, Text } from '@mantine/core';
|
|
import { PlusIcon } from '@phosphor-icons/react';
|
|
import React, { useMemo } from 'react';
|
|
import Typeahead, { TypeaheadOption } from '@/components/typeahead';
|
|
|
|
interface TeamSelectionViewProps {
|
|
options: ComboboxItem[];
|
|
onSelect: (teamId: string | undefined) => void;
|
|
}
|
|
|
|
const TeamSelectionView: React.FC<TeamSelectionViewProps> = React.memo(({
|
|
options,
|
|
onSelect
|
|
}) => {
|
|
const [selectedTeam, setSelectedTeam] = React.useState<ComboboxItem | null>(null);
|
|
|
|
const searchTeams = async (query: string): Promise<TypeaheadOption<ComboboxItem>[]> => {
|
|
if (!query.trim()) return [];
|
|
|
|
const filtered = options.filter(option =>
|
|
option.label.toLowerCase().includes(query.toLowerCase())
|
|
);
|
|
|
|
return filtered.map(option => ({
|
|
id: String(option.value),
|
|
data: option
|
|
}));
|
|
};
|
|
|
|
const handleTeamSelect = (option: TypeaheadOption<ComboboxItem>) => {
|
|
setSelectedTeam(option.data);
|
|
};
|
|
|
|
const renderTeamOption = (option: TypeaheadOption<ComboboxItem>) => {
|
|
return (
|
|
<Group py="xs" px="sm" gap="sm">
|
|
<Text fw={500}>{option.data.label}</Text>
|
|
</Group>
|
|
);
|
|
};
|
|
|
|
const formatTeam = (option: TypeaheadOption<ComboboxItem>) => {
|
|
return option.data.label;
|
|
};
|
|
|
|
const handleCreateNewTeamClicked = () => onSelect(undefined);
|
|
const handleSelectExistingTeam = () => onSelect(selectedTeam?.value);
|
|
|
|
return (
|
|
<Stack gap="md">
|
|
<Button
|
|
leftSection={<PlusIcon weight="bold" />}
|
|
onClick={handleCreateNewTeamClicked}
|
|
variant="light"
|
|
fullWidth
|
|
>
|
|
Create New Team
|
|
</Button>
|
|
|
|
<Divider my="sm" label="or" />
|
|
|
|
<Stack gap="sm">
|
|
<Typeahead
|
|
placeholder="Select one of your existing teams"
|
|
onSelect={handleTeamSelect}
|
|
searchFn={searchTeams}
|
|
renderOption={renderTeamOption}
|
|
format={formatTeam}
|
|
/>
|
|
|
|
<Button
|
|
onClick={handleSelectExistingTeam}
|
|
disabled={!selectedTeam}
|
|
fullWidth
|
|
>
|
|
Enroll Selected Team
|
|
</Button>
|
|
</Stack>
|
|
</Stack>
|
|
);
|
|
});
|
|
|
|
TeamSelectionView.displayName = 'TeamSelectionView';
|
|
|
|
export default TeamSelectionView; |