mirror of
https://github.com/Sendouc/sendou.ink.git
synced 2026-09-10 21:26:08 -05:00
Weapons selector initial
This commit is contained in:
@@ -5,10 +5,17 @@ import clsx from "clsx";
|
||||
import type { Unpacked } from "~/utils/types";
|
||||
import type { UserWithPlusTier } from "~/db/types";
|
||||
import { useUsers } from "~/hooks/swr";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { weaponIds } from "~/modules/in-game-lists";
|
||||
|
||||
const MAX_RESULTS_SHOWN = 6;
|
||||
|
||||
type ComboboxOption<T> = { label: string; value: string } & T;
|
||||
interface ComboboxBaseOption {
|
||||
label: string;
|
||||
value: string;
|
||||
}
|
||||
|
||||
type ComboboxOption<T> = ComboboxBaseOption & T;
|
||||
interface ComboboxProps<T> {
|
||||
options: ComboboxOption<T>[];
|
||||
inputName: string;
|
||||
@@ -162,3 +169,34 @@ export function UserCombobox({
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
export function WeaponCombobox({
|
||||
id,
|
||||
required,
|
||||
className,
|
||||
inputName,
|
||||
onChange,
|
||||
}: Pick<
|
||||
ComboboxProps<ComboboxBaseOption>,
|
||||
"inputName" | "onChange" | "className" | "id" | "required"
|
||||
>) {
|
||||
const { t } = useTranslation("weapons");
|
||||
|
||||
const idToWeapon = (id: typeof weaponIds[number]) => ({
|
||||
value: String(id),
|
||||
label: t(`${id}`),
|
||||
});
|
||||
|
||||
// xxx: weapon images
|
||||
return (
|
||||
<Combobox
|
||||
inputName={inputName}
|
||||
options={weaponIds.map(idToWeapon)}
|
||||
placeholder={t(`${weaponIds[0]}`)}
|
||||
onChange={onChange}
|
||||
className={className}
|
||||
id={id}
|
||||
required={required}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -31,6 +31,7 @@ export const BUILD = {
|
||||
TITLE_MIN_LENGTH: 1,
|
||||
TITLE_MAX_LENGTH: 100,
|
||||
DESCRIPTION_MAX_LENGTH: TWEET_LENGTH_MAX_LENGTH,
|
||||
MAX_WEAPONS_COUNT: 5,
|
||||
} as const;
|
||||
|
||||
export const PLUS_TIERS = [1, 2, 3];
|
||||
|
||||
@@ -7,6 +7,8 @@ import { Form } from "@remix-run/react";
|
||||
import { modesShort } from "~/modules/in-game-lists";
|
||||
import { Image } from "~/components/Image";
|
||||
import { modeImageUrl } from "~/utils/urls";
|
||||
import { WeaponCombobox } from "~/components/Combobox";
|
||||
import { Button } from "~/components/Button";
|
||||
|
||||
export const handle = {
|
||||
i18n: ["weapons", "builds", "gear"],
|
||||
@@ -97,9 +99,47 @@ function ModeCheckboxes() {
|
||||
}
|
||||
|
||||
function WeaponsSelector() {
|
||||
const { t } = useTranslation(["common", "weapons", "builds"]);
|
||||
const [count, setCount] = React.useState(1);
|
||||
|
||||
return (
|
||||
<div>
|
||||
<Label>Weapons</Label>
|
||||
<Label required htmlFor="weapon">
|
||||
{t("builds:forms.weapons")}
|
||||
</Label>
|
||||
<div className="stack sm">
|
||||
{new Array(count).fill(null).map((_, i) => {
|
||||
return (
|
||||
<div key={i} className="stack horizontal sm items-center">
|
||||
<div>
|
||||
<WeaponCombobox inputName="weapon" id="weapon" />
|
||||
</div>
|
||||
{i === count - 1 && (
|
||||
<>
|
||||
<Button
|
||||
tiny
|
||||
disabled={count === BUILD.MAX_WEAPONS_COUNT}
|
||||
onClick={() => setCount((count) => count + 1)}
|
||||
data-cy="add-date-button"
|
||||
>
|
||||
{t("common:actions.add")}
|
||||
</Button>
|
||||
{count > 1 && (
|
||||
<Button
|
||||
tiny
|
||||
onClick={() => setCount((count) => count - 1)}
|
||||
data-cy="remove-date-button"
|
||||
variant="destructive"
|
||||
>
|
||||
{t("common:actions.remove")}
|
||||
</Button>
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -5,5 +5,6 @@
|
||||
"buildCard.edit": "Edit",
|
||||
|
||||
"forms.title": "Title",
|
||||
"forms.modes": "Modes"
|
||||
"forms.modes": "Modes",
|
||||
"forms.weapons": "Weapons"
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user