Migrate game modes.

main
Joshua Potter 2023-12-06 08:50:57 -07:00
parent 2660cac8a8
commit 283bf59546
5 changed files with 92 additions and 13 deletions

View File

@ -0,0 +1,48 @@
import * as React from "react"
import clsx from "clsx"
import {
Input as BaseInput,
InputOwnerState,
InputProps,
MultiLineInputProps,
} from "@mui/base/Input"
import { FieldContext } from "./FieldSet"
import { resolveSlotProps } from "../utils/props"
export type CheckBoxProps = Omit<InputProps, keyof MultiLineInputProps>
export const CheckBox = React.forwardRef<HTMLInputElement, CheckBoxProps>(
function CheckBox(
props: CheckBoxProps,
ref: React.ForwardedRef<HTMLInputElement>
) {
const fieldContext = React.useContext(FieldContext)
const { disabled = fieldContext?.disabled, className, ...other } = props
const inputSlotProps = (ownerState: InputOwnerState) => {
const resolved = resolveSlotProps(props.slotProps?.input, ownerState)
return {
...resolved,
className: clsx(
"w-5 h-5 accent-black cursor-pointer -translate-y-[3px]",
resolved?.className
),
style: {
color: "black",
},
}
}
return (
<BaseInput
ref={ref}
{...other}
type="checkbox"
className={clsx("h-5 w-5", { "opacity-60": disabled }, className)}
slotProps={{ input: inputSlotProps }}
disabled={disabled}
/>
)
}
)

View File

@ -2,10 +2,12 @@ import * as React from "react"
import { Controller, useForm } from "react-hook-form" import { Controller, useForm } from "react-hook-form"
import { Button } from "./Button" import { Button } from "./Button"
import { Field } from "./FieldSet" import { CheckBox } from "./CheckBox"
import { Field, FieldSet } from "./FieldSet"
import { Input } from "./Input" import { Input } from "./Input"
import { Label } from "./Label" import { Label } from "./Label"
import { Modal } from "./Modal" import { Modal } from "./Modal"
import { Mode, getModeName } from "../types/Mode"
import { SelectLanguage, SelectLanguageProps } from "./SelectLanguage" import { SelectLanguage, SelectLanguageProps } from "./SelectLanguage"
import { Slider } from "./Slider" import { Slider } from "./Slider"
@ -77,7 +79,8 @@ export function FilterModal({
}, },
} }
const controlFIDERating = register("fideRating") const registerRating = register("rating")
const registerModes = register("modes")
return ( return (
<Modal <Modal
@ -116,17 +119,17 @@ export function FilterModal({
</Field> </Field>
<Field> <Field>
<Label htmlFor={`${idPrefix}-fideRating`}>FIDE Rating:</Label> <Label htmlFor={`${idPrefix}-rating`}>FIDE Rating:</Label>
<p className="py-2 text-sm"> <p className="py-2 text-sm">
Find coaches that have a rating within the specified range. Keep in Find coaches that have a rating within the specified range. Keep in
mind, a higher rating does not necessarily mean a better coach{" "} mind, a higher rating does not necessarily mean a better coach{" "}
<i>for you</i>. If you are unsure of this or do not have any <i>for you</i>. If you are unsure of this or do not have any
preference, leave as is. preference, leave as is.
</p> </p>
<div id={`${idPrefix}-fideRating`} className="mt-2 w-full px-4"> <div id={`${idPrefix}-rating`} className="mt-2 w-full px-4">
<Controller <Controller
control={control} control={control}
name={controlFIDERating.name} name={registerRating.name}
render={({ field: { onChange, onBlur, value, ref } }) => ( render={({ field: { onChange, onBlur, value, ref } }) => (
<Slider <Slider
ref={ref} ref={ref}
@ -134,8 +137,8 @@ export function FilterModal({
onBlur={onBlur} onBlur={onBlur}
onChange={(event, newValue: any) => { onChange={(event, newValue: any) => {
event && onChange(event) event && onChange(event)
setValue("fideRating.0", newValue[0]) setValue("rating.0", newValue[0])
setValue("fideRating.1", newValue[1]) setValue("rating.1", newValue[1])
}} }}
step={10} step={10}
min={FIDE_RATING_MIN} min={FIDE_RATING_MIN}
@ -154,17 +157,32 @@ export function FilterModal({
<label className="text-neutral-850 text-sm font-medium"> <label className="text-neutral-850 text-sm font-medium">
Min: Min:
</label> </label>
<Input value={watch("fideRating.0")} disabled /> <Input value={watch("rating.0")} disabled />
</div> </div>
<div> <div>
<label className="text-neutral-850 text-sm font-medium"> <label className="text-neutral-850 text-sm font-medium">
Max: Max:
</label> </label>
<Input value={watch("fideRating.1")} disabled /> <Input value={watch("rating.1")} disabled />
</div> </div>
</div> </div>
</div> </div>
</Field> </Field>
<FieldSet className="text-sm text-neutral-600">
<p className="py-2">
Prefer a specific game mode? We{"'"}ll prioritize coaches that
specialize in the modes selected.
</p>
<div className="grid grid-cols-3 pt-3">
{(Object.keys(Mode) as Mode[]).map((m) => (
<div key={m} className="col-span-1 flex items-center gap-x-2">
<CheckBox value={m} {...registerModes} />
<div>{getModeName(m)}</div>
</div>
))}
</div>
</FieldSet>
</div> </div>
</Modal> </Modal>
) )

View File

@ -21,10 +21,10 @@ const filters: FilterOption[] = [
title: "FIDE 2000+", title: "FIDE 2000+",
Icon: RisingGraphIcon, Icon: RisingGraphIcon,
enable: (p) => { enable: (p) => {
p.fideRating[0] = Math.max(2000, p.fideRating[0]) p.rating[0] = Math.max(2000, p.rating[0])
return p return p
}, },
isEnabled: (p) => p.fideRating[0] >= 2000, isEnabled: (p) => p.rating[0] >= 2000,
}, },
{ {
title: "English Speaking", title: "English Speaking",

View File

@ -0,0 +1,9 @@
export enum Mode {
RAPID = "RAPID",
BLITZ = "BLITZ",
BULLET = "BULLET",
}
export const getModeName = (m: Mode) => {
return m.charAt(0) + m.toLowerCase().slice(1)
}

View File

@ -1,5 +1,8 @@
import { Mode } from "./Mode"
export type SearchParams = { export type SearchParams = {
fideRating: [number, number] rating: [number, number]
modes: Mode[]
languages: string[] languages: string[]
} }
@ -7,6 +10,7 @@ export const FIDE_RATING_MIN = 1500
export const FIDE_RATING_MAX = 3200 export const FIDE_RATING_MAX = 3200
export const defaultSearchParams: SearchParams = { export const defaultSearchParams: SearchParams = {
fideRating: [FIDE_RATING_MIN, FIDE_RATING_MAX], rating: [FIDE_RATING_MIN, FIDE_RATING_MAX],
modes: [Mode.RAPID, Mode.BLITZ, Mode.BULLET],
languages: [], languages: [],
} }