Incorporate titles into the search.
parent
eb812d8366
commit
75e915e71c
|
@ -9,8 +9,9 @@ import { Label } from "./Label"
|
|||
import { Modal } from "./Modal"
|
||||
import { Mode, getModeName } from "../types/Mode"
|
||||
import { SelectLanguage, SelectLanguageProps } from "./SelectLanguage"
|
||||
import { SelectTitle, SelectTitleProps } from "./SelectTitle"
|
||||
import { Slider } from "./Slider"
|
||||
|
||||
import { Title } from "../types/Title"
|
||||
import {
|
||||
FIDE_RATING_MIN as RATING_MIN,
|
||||
FIDE_RATING_MAX as RATING_MAX,
|
||||
|
@ -94,6 +95,16 @@ export function FilterModal({
|
|||
required: "Please select at least one mode.",
|
||||
})
|
||||
|
||||
const proxyTitles = register("titles")
|
||||
const registerTitles: Pick<SelectTitleProps, "defaultValue" | "onChange"> = {
|
||||
...proxyTitles,
|
||||
defaultValue: defaultValues.titles,
|
||||
onChange: (event, value) => {
|
||||
event && proxyTitles.onChange(event)
|
||||
setValue("titles", (value ?? []) as Title[])
|
||||
},
|
||||
}
|
||||
|
||||
return (
|
||||
<Modal
|
||||
open={open}
|
||||
|
@ -134,13 +145,29 @@ export function FilterModal({
|
|||
/>
|
||||
</Field>
|
||||
|
||||
<Field>
|
||||
<Label htmlFor={`${idPrefix}-titles`}>Titles:</Label>
|
||||
<p className="py-2 text-sm">
|
||||
Prioritize coaches with one or more of the following titles. That
|
||||
said, this is usually not an aspect of a coach that is important to
|
||||
focus on.
|
||||
</p>
|
||||
<SelectTitle
|
||||
id={`${idPrefix}-titles`}
|
||||
slotProps={{
|
||||
root: { className: "w-full" },
|
||||
}}
|
||||
{...registerTitles}
|
||||
multiple
|
||||
/>
|
||||
</Field>
|
||||
|
||||
<Field>
|
||||
<Label htmlFor={`${idPrefix}-rating`}>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.
|
||||
Find coaches that have a rating within the specified range. A higher
|
||||
rating does not necessarily correspond to a better coach. If you are
|
||||
unsure of this or do not have any preference, leave as is.
|
||||
</p>
|
||||
<div id={`${idPrefix}-rating`} className="mt-2 w-full px-4">
|
||||
<Controller
|
||||
|
|
|
@ -10,8 +10,10 @@ import LightningIcon from "../icons/Lightning"
|
|||
import RabbitIcon from "../icons/Rabbit"
|
||||
import RightArrowIcon from "../icons/RightArrow"
|
||||
import RisingGraphIcon from "../icons/RisingGraph"
|
||||
import TrophyIcon from "../icons/Trophy"
|
||||
import { Button } from "./Button"
|
||||
import { Mode } from "../types/Mode"
|
||||
import { Title } from "../types/Title"
|
||||
|
||||
interface FilterOption {
|
||||
title: string
|
||||
|
@ -73,6 +75,15 @@ const filters: FilterOption[] = [
|
|||
},
|
||||
isEnabled: (p) => p.modes.length === 1 && p.modes.includes(Mode.BULLET),
|
||||
},
|
||||
{
|
||||
title: "Titled Player",
|
||||
Icon: TrophyIcon,
|
||||
enable: (p) => {
|
||||
p.titles = Object.keys(Title)
|
||||
return p
|
||||
},
|
||||
isEnabled: (p) => p.titles.length > 0,
|
||||
},
|
||||
]
|
||||
|
||||
enum Direction {
|
||||
|
|
|
@ -0,0 +1,42 @@
|
|||
import * as React from "react"
|
||||
import { SelectProps } from "@mui/base/Select"
|
||||
|
||||
import { Select, Option } from "./Select"
|
||||
import { Title } from "../types/Title"
|
||||
|
||||
interface TitleOption {
|
||||
value: Title | ""
|
||||
label: string
|
||||
}
|
||||
|
||||
const options: TitleOption[] = [
|
||||
{ value: Title.GM, label: "Grandmaster" },
|
||||
{ value: Title.IM, label: "International Master" },
|
||||
{ value: Title.FM, label: "FIDE Master" },
|
||||
{ value: Title.CM, label: "Candidate Master" },
|
||||
{ value: Title.NM, label: "National Master" },
|
||||
{ value: Title.WGM, label: "Woman Grandmaster" },
|
||||
{ value: Title.WIM, label: "Woman International Master" },
|
||||
{ value: Title.WFM, label: "Woman FIDE Master" },
|
||||
{ value: Title.WCM, label: "Woman Candidate Master" },
|
||||
{ value: Title.WNM, label: "Woman National Master" },
|
||||
]
|
||||
|
||||
export type SelectTitleProps = SelectProps<{}, boolean>
|
||||
|
||||
export const SelectTitle = React.forwardRef(function SelectTitle(
|
||||
props: SelectTitleProps,
|
||||
ref: React.ForwardedRef<HTMLButtonElement>
|
||||
) {
|
||||
return (
|
||||
<Select ref={ref} {...props}>
|
||||
{options.map((entry, index) => {
|
||||
return (
|
||||
<Option key={index} value={entry.value}>
|
||||
{entry.label}
|
||||
</Option>
|
||||
)
|
||||
})}
|
||||
</Select>
|
||||
)
|
||||
})
|
|
@ -0,0 +1,16 @@
|
|||
import * as React from "react"
|
||||
|
||||
const SvgComponet = ({ ...props }) => (
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlSpace="preserve"
|
||||
width={800}
|
||||
height={800}
|
||||
viewBox="0 0 100 100"
|
||||
{...props}
|
||||
>
|
||||
<path d="M82.296 23.931a1.918 1.918 0 0 0-1.918-1.918h-8.074v-6.998c.004-.061.018-.118.018-.179a2.935 2.935 0 0 0-2.934-2.935c-.036 0-.07.009-.106.011v-.011H30.365v.054a2.925 2.925 0 0 0-2.696 2.911c0 .062.014.119.018.179v6.967H19.62a1.914 1.914 0 0 0-1.909 1.839h-.007v.073l-.001.007.001.007v26.038l-.001.004.001.009V50h.001c.01 1.051.863 1.9 1.916 1.9h8.328c1.354 9.109 8.197 16.422 17.069 18.449v12.746h-9.969a2.493 2.493 0 0 0 0 4.988v.017h29.894v-.017a2.493 2.493 0 0 0 0-4.988h-9.969V70.353c8.881-2.02 15.733-9.337 17.087-18.453h8.318c1.028 0 1.86-.81 1.909-1.825h.011V23.931h-.003zM27.687 46.913H22.69V27h4.997v19.913zm49.623 0h-5.007V27h5.007v19.913z" />
|
||||
</svg>
|
||||
)
|
||||
|
||||
export default SvgComponet
|
|
@ -1,9 +1,11 @@
|
|||
import { Mode } from "./Mode"
|
||||
import { Title } from "./Title"
|
||||
|
||||
export type SearchParams = {
|
||||
rating: [number, number]
|
||||
modes: Mode[]
|
||||
languages: string[]
|
||||
titles: Title[]
|
||||
}
|
||||
|
||||
export const FIDE_RATING_MIN = 1500
|
||||
|
@ -13,6 +15,7 @@ export const defaultSearchParams: SearchParams = {
|
|||
rating: [FIDE_RATING_MIN, FIDE_RATING_MAX],
|
||||
modes: [Mode.RAPID, Mode.BLITZ, Mode.BULLET],
|
||||
languages: [],
|
||||
titles: [],
|
||||
}
|
||||
|
||||
export function toQueryParams(p: SearchParams) {
|
||||
|
@ -27,5 +30,9 @@ export function toQueryParams(p: SearchParams) {
|
|||
queryParams["languages"] = p.languages.join(",")
|
||||
}
|
||||
|
||||
if (p.titles) {
|
||||
queryParams["titles"] = p.titles.join(",")
|
||||
}
|
||||
|
||||
return queryParams
|
||||
}
|
||||
|
|
|
@ -0,0 +1,12 @@
|
|||
export enum Title {
|
||||
GM = "GM",
|
||||
IM = "IM",
|
||||
FM = "FM",
|
||||
CM = "CM",
|
||||
NM = "NM",
|
||||
WGM = "WGM",
|
||||
WIM = "WIM",
|
||||
WFM = "WFM",
|
||||
WCM = "WCM",
|
||||
WNM = "WNM",
|
||||
}
|
|
@ -49,6 +49,7 @@ defmodule BoardWise.Coaches do
|
|||
:bullet_gte => bullet_gte,
|
||||
:bullet_lte => bullet_lte,
|
||||
:languages => languages,
|
||||
:titles => titles,
|
||||
:page_no => page_no,
|
||||
:page_size => page_size
|
||||
}) do
|
||||
|
@ -65,7 +66,8 @@ defmodule BoardWise.Coaches do
|
|||
? +
|
||||
? +
|
||||
? +
|
||||
(5 * (SELECT COUNT(*) FROM UNNEST(?) WHERE UNNEST = ANY(?)))
|
||||
(5 * (SELECT COUNT(*) FROM UNNEST(?) WHERE UNNEST = ANY(?))) +
|
||||
CASE WHEN ? = ANY(?) THEN 5 ELSE 0 END
|
||||
""",
|
||||
c.name,
|
||||
c.image_url,
|
||||
|
@ -73,7 +75,9 @@ defmodule BoardWise.Coaches do
|
|||
rating_fragment(c.blitz, ^blitz_gte, ^blitz_lte),
|
||||
rating_fragment(c.bullet, ^bullet_gte, ^bullet_lte),
|
||||
type(^languages, {:array, :string}),
|
||||
c.languages
|
||||
c.languages,
|
||||
c.title,
|
||||
type(^titles, {:array, :string})
|
||||
)
|
||||
|> selected_as(:score)
|
||||
}
|
||||
|
|
|
@ -6,6 +6,7 @@ defmodule BoardWise.Coaches.QueryParams do
|
|||
:blitz_lte,
|
||||
:bullet_gte,
|
||||
:bullet_lte,
|
||||
:titles,
|
||||
:languages,
|
||||
page_no: 1,
|
||||
page_size: 15
|
||||
|
|
|
@ -14,6 +14,7 @@ defmodule BoardWiseWeb.CoachController do
|
|||
|> override_param(:bullet_gte, params, :integer)
|
||||
|> override_param(:bullet_lte, params, :integer)
|
||||
|> override_param(:languages, params, :strlist)
|
||||
|> override_param(:titles, params, :strlist)
|
||||
|> override_param(:page_no, params, :integer)
|
||||
|> override_param(:page_size, params, :integer)
|
||||
|
||||
|
|
Loading…
Reference in New Issue