Skip to content

Commit

Permalink
Style requestscrimmodal
Browse files Browse the repository at this point in the history
  • Loading branch information
acrantel committed Mar 9, 2024
1 parent fbde132 commit 90e627b
Show file tree
Hide file tree
Showing 6 changed files with 131 additions and 75 deletions.
2 changes: 1 addition & 1 deletion frontend2/src/components/EpisodeSwitcher.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ const EpisodeSwitcher: React.FC = () => {
queryFn: async () => await getEpisodeInfo({ id: newEpisodeId }),
}))().catch((e) => toast.error((e as Error).message));
setEpisodeId(newEpisodeId);
navigate(`${newEpisodeId}/home`);
navigate(`/${newEpisodeId}/home`);
}}
>
<div className="relative">
Expand Down
44 changes: 44 additions & 0 deletions frontend2/src/components/elements/Checkbox.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import React from "react";
import Icon from "./Icon";
import { Switch } from "@headlessui/react";
import FormLabel from "./FormLabel";

interface CheckboxProps {
disabled?: boolean;
checked?: boolean;
onChange: (checked: boolean) => void;
label?: string;
}

const Checkbox: React.FC<CheckboxProps> = ({
disabled = false,
checked = false,
onChange,
label,
}) => {
return (
<Switch.Group as="div" className="flex flex-row items-center gap-2">
{label !== undefined && (
<Switch.Label>
<FormLabel label={label} />
</Switch.Label>
)}
<Switch
checked={checked}
onChange={onChange}
disabled={disabled}
className={`inline-flex h-5 w-5 items-center justify-center rounded
ring-2 ring-inset ring-cyan-600/50 focus:outline-none
focus:ring-2 ui-checked:bg-cyan-500 ui-checked:ring-0`}
>
<Icon
size="xs"
name="check"
className={checked ? "text-cyan-100 opacity-100" : "opacity-0"}
/>
</Switch>
</Switch.Group>
);
};

export default Checkbox;
8 changes: 4 additions & 4 deletions frontend2/src/components/elements/Pill.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import Icon from "./Icon";
interface PillProps {
text: string;
deletable?: boolean;
onDelete?: (ev?: React.MouseEvent<HTMLButtonElement, MouseEvent>) => void;
onDelete?: (ev?: React.MouseEvent<HTMLDivElement, MouseEvent>) => void;
className?: string;
}

Expand All @@ -20,15 +20,15 @@ const Pill: React.FC<PillProps> = ({
>
<span>{text}</span>
{deletable && (
<button
<div
onClick={(ev) => {
onDelete?.(ev);
ev.stopPropagation();
}}
className="cursor-pointer items-center rounded "
className="cursor-pointer items-center rounded hover:text-cyan-950"
>
<Icon name="x_mark" size="xs" />
</button>
</div>
)}
</div>
);
Expand Down
2 changes: 1 addition & 1 deletion frontend2/src/components/elements/SelectMenu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ function SelectMenu<T extends React.Key | null | undefined>({
</span>
<div
className="absolute inset-y-0 right-0 mr-2 flex transform items-center
transition duration-300 ui-open:rotate-180"
transition duration-300 ui-open:rotate-180 ui-not-open:rotate-0"
>
<Icon name="chevron_down" size="sm" />
</div>
Expand Down
4 changes: 2 additions & 2 deletions frontend2/src/components/elements/SelectMultipleMenu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ function SelectMultipleMenu<T extends React.Key | null | undefined>({
</div>
<div
className="flex transform items-center
transition duration-300 ui-open:rotate-180"
transition duration-300 ui-open:rotate-180 ui-not-open:rotate-0"
>
<Icon name="chevron_down" size="sm" />
</div>
Expand All @@ -101,7 +101,7 @@ function SelectMultipleMenu<T extends React.Key | null | undefined>({
value={option.value}
>
<div className="overflow-x-auto pr-2">{option.label}</div>
<span className=" hidden items-center text-cyan-900 ui-selected:flex">
<span className="hidden items-center text-cyan-900 ui-selected:flex">
<Icon name="check" size="sm" />
</span>
</Listbox.Option>
Expand Down
146 changes: 79 additions & 67 deletions frontend2/src/components/tables/scrimmaging/RequestScrimModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,7 @@ import { clone } from "lodash";
import SelectMenu from "components/elements/SelectMenu";
import SelectMultipleMenu from "components/elements/SelectMultipleMenu";
import Button from "components/elements/Button";
import DescriptiveCheckbox, {
CheckboxState,
} from "components/elements/DescriptiveCheckbox";
import Checkbox from "components/elements/Checkbox";

interface RequestScrimModalProps {
teamToRequest: TeamPublic;
Expand All @@ -24,7 +22,7 @@ interface RequestScrimModalProps {
closeModal: () => void;
}

// Team statuses that allow for ranked scrims.
// Only allow ranked scrims against "Regular" teams.
const ALLOWS_RANKED = Status526Enum.R;
const MAX_MAPS_PER_SCRIM = 10;
const ORDER_OPTIONS = [
Expand Down Expand Up @@ -73,82 +71,96 @@ const RequestScrimModal: React.FC<RequestScrimModalProps> = ({
title={`Request scrimmage with ${teamToRequest.name}`}
>
{
<div className="mt-4 flex flex-col gap-2">
<SelectMenu
disabled={ranked}
label="Player Order"
options={ORDER_OPTIONS}
value={selectedOrder}
onChange={(newOrder) => {
setSelectedOrder(newOrder);
}}
/>
<SelectMultipleMenu<string>
errorMessage={mapErrorMessage}
disabled={ranked}
label="Select Maps"
placeholder={ranked ? "Random 3 maps!" : "Select up to 10 maps..."}
options={
maps.map((map) => ({
value: map.name,
label: map.name,
})) ?? []
}
value={selectedMapNames}
onChange={(newMapNames) => {
if (newMapNames.length > MAX_MAPS_PER_SCRIM) {
setMapErrorMessage("You can only select up to 10 maps.");
return;
}
setMapErrorMessage(undefined);
setSelectedMapNames(newMapNames);
}}
/>
<Button
disabled={ranked}
label={"Use random 3 maps"}
onClick={() => {
setSelectedMapNames(getRandomMaps());
}}
/>
<DescriptiveCheckbox
status={ranked ? CheckboxState.CHECKED : CheckboxState.UNCHECKED}
title="Ranked?"
<div className="mt-4 flex flex-col gap-4">
<Checkbox
disabled={teamToRequest.status !== ALLOWS_RANKED}
description="Request a ranked scrimmage. All ranked scrimmages are played with alternating player order on 3 random maps."
checked={ranked}
onChange={(checked) => {
if (checked) {
setSelectedOrder(PlayerOrderEnum.QuestionMark);
setSelectedMapNames([]);
setMapErrorMessage(undefined);
} else {
setSelectedMapNames(getRandomMaps());
}
setRanked(checked);
}}
label="Ranked?"
/>
<Button
label="Request Scrimmage"
fullWidth
loading={request.isPending}
onClick={() => {
void request
.mutateAsync({
episodeId,
scrimmageRequestRequest: {
requested_to: teamToRequest.id,
is_ranked: ranked,
map_names: selectedMapNames,
player_order: selectedOrder,
},
})
.then(() => {
closeModal();
})
.catch((err: string) => {
console.error(`Error requesting scrimmage: ${err}`);
});
<SelectMenu
disabled={ranked}
label="Player order"
options={ORDER_OPTIONS}
value={selectedOrder}
onChange={(newOrder): void => {
setSelectedOrder(newOrder);
}}
/>
<div className="flex flex-col gap-2">
<SelectMultipleMenu<string>
errorMessage={mapErrorMessage}
disabled={ranked}
label="Maps"
placeholder={
ranked ? "Random 3 maps!" : "Select up to 10 maps..."
}
options={
maps.map((map) => ({
value: map.name,
label: map.name,
})) ?? []
}
value={ranked ? [] : selectedMapNames}
onChange={(newMapNames) => {
setSelectedMapNames(newMapNames);
if (newMapNames.length > MAX_MAPS_PER_SCRIM) {
setMapErrorMessage("You can only select up to 10 maps.");
} else if (newMapNames.length === 0) {
setMapErrorMessage("You must select at least one map");
} else {
setMapErrorMessage(undefined);
}
}}
/>
<div
hidden={ranked}
onClick={() => {
setMapErrorMessage(undefined);
setSelectedMapNames(getRandomMaps());
}}
className="mt-0 cursor-pointer text-sm text-cyan-600"
>
[Click to use 3 random maps]
</div>
</div>
<div className="mt-2 flex flex-row gap-4">
<Button
label="Request Scrimmage"
variant="dark"
fullWidth
disabled={mapErrorMessage !== undefined}
loading={request.isPending}
onClick={() => {
void request
.mutateAsync({
episodeId,
scrimmageRequestRequest: {
requested_to: teamToRequest.id,
is_ranked: ranked,
map_names: selectedMapNames,
player_order: selectedOrder,
},
})
.then(() => {
closeModal();
})
.catch((err: string) => {
console.error(`Error requesting scrimmage: ${err}`);
});
}}
/>
<Button fullWidth label="Cancel" onClick={closeModal} />
</div>
</div>
}
</Modal>
Expand Down

0 comments on commit 90e627b

Please sign in to comment.