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 { Button } from "./Button"
import { Field } from "./FieldSet"
import { CheckBox } from "./CheckBox"
import { Field, FieldSet } from "./FieldSet"
import { Input } from "./Input"
import { Label } from "./Label"
import { Modal } from "./Modal"
import { Mode, getModeName } from "../types/Mode"
import { SelectLanguage, SelectLanguageProps } from "./SelectLanguage"
import { Slider } from "./Slider"
@ -77,7 +79,8 @@ export function FilterModal({
},
}
const controlFIDERating = register("fideRating")
const registerRating = register("rating")
const registerModes = register("modes")
return (
<Modal
@ -116,17 +119,17 @@ export function FilterModal({
</Field>
<Field>
<Label htmlFor={`${idPrefix}-fideRating`}>FIDE Rating:</Label>
<Label htmlFor={`${idPrefix}-rating`}>FIDE Rating:</Label>
<p className="py-2 text-sm">
Find coaches that have a rating within the specified range. Keep in
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
preference, leave as is.
</p>
<div id={`${idPrefix}-fideRating`} className="mt-2 w-full px-4">
<div id={`${idPrefix}-rating`} className="mt-2 w-full px-4">
<Controller
control={control}
name={controlFIDERating.name}
name={registerRating.name}
render={({ field: { onChange, onBlur, value, ref } }) => (
<Slider
ref={ref}
@ -134,8 +137,8 @@ export function FilterModal({
onBlur={onBlur}
onChange={(event, newValue: any) => {
event && onChange(event)
setValue("fideRating.0", newValue[0])
setValue("fideRating.1", newValue[1])
setValue("rating.0", newValue[0])
setValue("rating.1", newValue[1])
}}
step={10}
min={FIDE_RATING_MIN}
@ -154,17 +157,32 @@ export function FilterModal({
<label className="text-neutral-850 text-sm font-medium">
Min:
</label>
<Input value={watch("fideRating.0")} disabled />
<Input value={watch("rating.0")} disabled />
</div>
<div>
<label className="text-neutral-850 text-sm font-medium">
Max:
</label>
<Input value={watch("fideRating.1")} disabled />
<Input value={watch("rating.1")} disabled />
</div>
</div>
</div>
</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>
</Modal>
)

View File

@ -21,10 +21,10 @@ const filters: FilterOption[] = [
title: "FIDE 2000+",
Icon: RisingGraphIcon,
enable: (p) => {
p.fideRating[0] = Math.max(2000, p.fideRating[0])
p.rating[0] = Math.max(2000, p.rating[0])
return p
},
isEnabled: (p) => p.fideRating[0] >= 2000,
isEnabled: (p) => p.rating[0] >= 2000,
},
{
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 = {
fideRating: [number, number]
rating: [number, number]
modes: Mode[]
languages: string[]
}
@ -7,6 +10,7 @@ export const FIDE_RATING_MIN = 1500
export const FIDE_RATING_MAX = 3200
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: [],
}