Rename filter to sort.
parent
c54f832935
commit
8d7a2e4853
|
@ -13,11 +13,7 @@ import { SelectTitle, SelectTitleProps } from "./SelectTitle"
|
||||||
import { Site, getSiteName } from "../types/Site"
|
import { Site, getSiteName } from "../types/Site"
|
||||||
import { Slider } from "./Slider"
|
import { Slider } from "./Slider"
|
||||||
import { Title } from "../types/Title"
|
import { Title } from "../types/Title"
|
||||||
import {
|
import { RATING_MIN, RATING_MAX, SearchParams } from "../types/SearchParams"
|
||||||
FIDE_RATING_MIN as RATING_MIN,
|
|
||||||
FIDE_RATING_MAX as RATING_MAX,
|
|
||||||
SearchParams,
|
|
||||||
} from "../types/SearchParams"
|
|
||||||
|
|
||||||
const computeStepLabels = (
|
const computeStepLabels = (
|
||||||
min: number,
|
min: number,
|
||||||
|
@ -42,19 +38,19 @@ const computeStepLabels = (
|
||||||
return labels
|
return labels
|
||||||
}
|
}
|
||||||
|
|
||||||
interface FilterModalProps {
|
interface SortModalProps {
|
||||||
open: boolean
|
open: boolean
|
||||||
defaultValues: SearchParams
|
defaultValues: SearchParams
|
||||||
onClose: () => void
|
onClose: () => void
|
||||||
onSubmit: (p: SearchParams) => void
|
onSubmit: (p: SearchParams) => void
|
||||||
}
|
}
|
||||||
|
|
||||||
export function FilterModal({
|
export function SortModal({
|
||||||
open,
|
open,
|
||||||
defaultValues,
|
defaultValues,
|
||||||
onClose,
|
onClose,
|
||||||
onSubmit,
|
onSubmit,
|
||||||
}: FilterModalProps) {
|
}: SortModalProps) {
|
||||||
const idPrefix = React.useId()
|
const idPrefix = React.useId()
|
||||||
|
|
||||||
const {
|
const {
|
||||||
|
@ -117,14 +113,14 @@ export function FilterModal({
|
||||||
closeAfterTransition
|
closeAfterTransition
|
||||||
frame={{
|
frame={{
|
||||||
as: "form",
|
as: "form",
|
||||||
title: "Filters",
|
title: "Sort Coaches",
|
||||||
footer: (
|
footer: (
|
||||||
<Button
|
<Button
|
||||||
className="float-right py-2"
|
className="float-right py-2"
|
||||||
type="submit"
|
type="submit"
|
||||||
disabled={Object.keys(errors).length > 0}
|
disabled={Object.keys(errors).length > 0}
|
||||||
>
|
>
|
||||||
Search coaches
|
Submit
|
||||||
</Button>
|
</Button>
|
||||||
),
|
),
|
||||||
onSubmit: handleSubmit(onSubmit),
|
onSubmit: handleSubmit(onSubmit),
|
|
@ -5,7 +5,7 @@ import type { SearchParams } from "../types/SearchParams"
|
||||||
|
|
||||||
import BulletIcon from "../icons/Bullet"
|
import BulletIcon from "../icons/Bullet"
|
||||||
import EnglishIcon from "../icons/English"
|
import EnglishIcon from "../icons/English"
|
||||||
import FilterIcon from "../icons/Filter"
|
import SortIcon from "../icons/Sort"
|
||||||
import KnightIcon from "../icons/Knight"
|
import KnightIcon from "../icons/Knight"
|
||||||
import LightningIcon from "../icons/Lightning"
|
import LightningIcon from "../icons/Lightning"
|
||||||
import PawnIcon from "../icons/Pawn"
|
import PawnIcon from "../icons/Pawn"
|
||||||
|
@ -18,22 +18,31 @@ import { Mode } from "../types/Mode"
|
||||||
import { Site } from "../types/Site"
|
import { Site } from "../types/Site"
|
||||||
import { Title } from "../types/Title"
|
import { Title } from "../types/Title"
|
||||||
|
|
||||||
interface FilterOption {
|
interface SortOption {
|
||||||
title: string
|
title: string
|
||||||
Icon: ({ ...props }: { [x: string]: any }) => React.JSX.Element
|
Icon: ({ ...props }: { [x: string]: any }) => React.JSX.Element
|
||||||
enable: (p: SearchParams) => SearchParams
|
enable: (p: SearchParams) => SearchParams
|
||||||
isEnabled: (p: SearchParams) => boolean
|
isEnabled: (p: SearchParams) => boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
const filters: FilterOption[] = [
|
const filters: SortOption[] = [
|
||||||
{
|
{
|
||||||
title: "FIDE 2000+",
|
title: "On Lichess",
|
||||||
Icon: RisingGraphIcon,
|
Icon: KnightIcon,
|
||||||
enable: (p) => {
|
enable: (p) => {
|
||||||
p.rating[0] = Math.max(2000, p.rating[0])
|
p.sites.push(Site.LICHESS)
|
||||||
return p
|
return p
|
||||||
},
|
},
|
||||||
isEnabled: (p) => p.rating[0] >= 2000,
|
isEnabled: (p) => p.sites.includes(Site.LICHESS),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "On Chess.com",
|
||||||
|
Icon: PawnIcon,
|
||||||
|
enable: (p) => {
|
||||||
|
p.sites.push(Site.CHESSCOM)
|
||||||
|
return p
|
||||||
|
},
|
||||||
|
isEnabled: (p) => p.sites.includes(Site.CHESSCOM),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: "English Speaking",
|
title: "English Speaking",
|
||||||
|
@ -51,6 +60,15 @@ const filters: FilterOption[] = [
|
||||||
isEnabled: (p) =>
|
isEnabled: (p) =>
|
||||||
p.languages.includes("en-US") || p.languages.includes("en-GB"),
|
p.languages.includes("en-US") || p.languages.includes("en-GB"),
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
title: "ELO 2000+",
|
||||||
|
Icon: RisingGraphIcon,
|
||||||
|
enable: (p) => {
|
||||||
|
p.rating[0] = Math.max(2000, p.rating[0])
|
||||||
|
return p
|
||||||
|
},
|
||||||
|
isEnabled: (p) => p.rating[0] >= 2000,
|
||||||
|
},
|
||||||
{
|
{
|
||||||
title: "Rapid Specialty",
|
title: "Rapid Specialty",
|
||||||
Icon: RabbitIcon,
|
Icon: RabbitIcon,
|
||||||
|
@ -78,24 +96,6 @@ const filters: FilterOption[] = [
|
||||||
},
|
},
|
||||||
isEnabled: (p) => p.modes.length === 1 && p.modes.includes(Mode.BULLET),
|
isEnabled: (p) => p.modes.length === 1 && p.modes.includes(Mode.BULLET),
|
||||||
},
|
},
|
||||||
{
|
|
||||||
title: "On Chess.com",
|
|
||||||
Icon: PawnIcon,
|
|
||||||
enable: (p) => {
|
|
||||||
p.sites.push(Site.CHESSCOM)
|
|
||||||
return p
|
|
||||||
},
|
|
||||||
isEnabled: (p) => p.sites.includes(Site.CHESSCOM),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: "On Lichess",
|
|
||||||
Icon: KnightIcon,
|
|
||||||
enable: (p) => {
|
|
||||||
p.sites.push(Site.LICHESS)
|
|
||||||
return p
|
|
||||||
},
|
|
||||||
isEnabled: (p) => p.sites.includes(Site.LICHESS),
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
title: "Titled Player",
|
title: "Titled Player",
|
||||||
Icon: TrophyIcon,
|
Icon: TrophyIcon,
|
||||||
|
@ -112,13 +112,13 @@ enum Direction {
|
||||||
RIGHT,
|
RIGHT,
|
||||||
}
|
}
|
||||||
|
|
||||||
interface FilterScrollProps {
|
interface SortScrollProps {
|
||||||
params: SearchParams
|
params: SearchParams
|
||||||
onModal: () => void
|
onModal: () => void
|
||||||
onSelect: (p: SearchParams) => void
|
onSelect: (p: SearchParams) => void
|
||||||
}
|
}
|
||||||
|
|
||||||
export function FilterScroll({ params, onModal, onSelect }: FilterScrollProps) {
|
export function SortScroll({ params, onModal, onSelect }: SortScrollProps) {
|
||||||
const viewport = React.useRef<HTMLDivElement>(null)
|
const viewport = React.useRef<HTMLDivElement>(null)
|
||||||
const [isFlush, setIsFlush] = React.useState([true, false])
|
const [isFlush, setIsFlush] = React.useState([true, false])
|
||||||
|
|
||||||
|
@ -190,8 +190,8 @@ export function FilterScroll({ params, onModal, onSelect }: FilterScrollProps) {
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<Button className="flex gap-x-2 py-4" onClick={onModal}>
|
<Button className="flex gap-x-2 py-4" onClick={onModal}>
|
||||||
<FilterIcon className="h-6 w-6 fill-white" />
|
<SortIcon className="h-6 w-6 fill-white" />
|
||||||
<span className="font-display">Filter</span>
|
<span className="font-display">Sort</span>
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
|
@ -1,14 +0,0 @@
|
||||||
import * as React from "react"
|
|
||||||
|
|
||||||
const SvgComponent = ({ ...props }) => (
|
|
||||||
<svg
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
xmlSpace="preserve"
|
|
||||||
viewBox="0 0 32 32"
|
|
||||||
{...props}
|
|
||||||
>
|
|
||||||
<path d="M8 9.142V4H6v5.142c-1.72.447-3 2-3 3.858s1.28 3.411 3 3.858v10.096h2V16.858c1.72-.447 3-2 3-3.858S9.72 9.589 8 9.142zM7 15a2 2 0 1 1-.001-3.999A2 2 0 0 1 7 15zm10 1.142V4h-2v12.142c-1.72.447-3 2-3 3.858s1.28 3.411 3 3.858v3.096h2v-3.096c1.72-.447 3-2 3-3.858s-1.28-3.411-3-3.858zM16 22a2 2 0 1 1-.001-3.999A2 2 0 0 1 16 22zm13-6c0-1.858-1.28-3.411-3-3.858V4h-2v8.142c-1.72.447-3 2-3 3.858s1.28 3.411 3 3.858v7.096h2v-7.096c1.72-.447 3-2 3-3.858zm-4 2a2 2 0 1 1-.001-3.999A2 2 0 0 1 25 18z" />
|
|
||||||
</svg>
|
|
||||||
)
|
|
||||||
|
|
||||||
export default SvgComponent
|
|
|
@ -0,0 +1,14 @@
|
||||||
|
import * as React from "react"
|
||||||
|
|
||||||
|
const SvgComponent = ({ ...props }) => (
|
||||||
|
<svg
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
fill="none"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
{...props}
|
||||||
|
>
|
||||||
|
<path d="M6.293 4.293a1 1 0 0 1 1.414 0l4 4a1 1 0 0 1-1.414 1.414L8 7.414V19a1 1 0 1 1-2 0V7.414L3.707 9.707a1 1 0 0 1-1.414-1.414l4-4zM16 16.586V5a1 1 0 1 1 2 0v11.586l2.293-2.293a1 1 0 0 1 1.414 1.414l-4 4a1 1 0 0 1-1.414 0l-4-4a1 1 0 0 1 1.414-1.414L16 16.586z" />
|
||||||
|
</svg>
|
||||||
|
)
|
||||||
|
|
||||||
|
export default SvgComponent
|
|
@ -5,10 +5,10 @@ import type { SearchParams } from "../types/SearchParams"
|
||||||
import { Container } from "../components/Container"
|
import { Container } from "../components/Container"
|
||||||
import { FadeIn } from "../components/FadeIn"
|
import { FadeIn } from "../components/FadeIn"
|
||||||
import { FallbackMessage } from "../components/FallbackMessage"
|
import { FallbackMessage } from "../components/FallbackMessage"
|
||||||
import { FilterModal } from "../components/FilterModal"
|
|
||||||
import { FilterScroll } from "../components/FilterScroll"
|
|
||||||
import { Loading } from "../components/Loading"
|
import { Loading } from "../components/Loading"
|
||||||
import { SearchResult } from "../components/SearchResult"
|
import { SearchResult } from "../components/SearchResult"
|
||||||
|
import { SortModal } from "../components/SortModal"
|
||||||
|
import { SortScroll } from "../components/SortScroll"
|
||||||
import { defaultSearchParams } from "../types/SearchParams"
|
import { defaultSearchParams } from "../types/SearchParams"
|
||||||
import { useCoachesInfiniteQuery } from "../utils/queries"
|
import { useCoachesInfiniteQuery } from "../utils/queries"
|
||||||
|
|
||||||
|
@ -79,12 +79,12 @@ export function Search() {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Container className="pt-8">
|
<Container className="pt-8">
|
||||||
<FilterScroll
|
<SortScroll
|
||||||
params={searchParams}
|
params={searchParams}
|
||||||
onSelect={setSearchParams}
|
onSelect={setSearchParams}
|
||||||
onModal={() => setModalOpen(true)}
|
onModal={() => setModalOpen(true)}
|
||||||
/>
|
/>
|
||||||
<FilterModal
|
<SortModal
|
||||||
open={modalOpen}
|
open={modalOpen}
|
||||||
defaultValues={searchParams}
|
defaultValues={searchParams}
|
||||||
onClose={() => setModalOpen(false)}
|
onClose={() => setModalOpen(false)}
|
||||||
|
|
|
@ -10,15 +10,15 @@ export type SearchParams = {
|
||||||
sites: Site[]
|
sites: Site[]
|
||||||
}
|
}
|
||||||
|
|
||||||
export const FIDE_RATING_MIN = 1500
|
export const RATING_MIN = 1500
|
||||||
export const FIDE_RATING_MAX = 3200
|
export const RATING_MAX = 3200
|
||||||
|
|
||||||
export const defaultSearchParams: SearchParams = {
|
export const defaultSearchParams: SearchParams = {
|
||||||
rating: [FIDE_RATING_MIN, FIDE_RATING_MAX],
|
rating: [RATING_MIN, RATING_MAX],
|
||||||
modes: [Mode.RAPID, Mode.BLITZ, Mode.BULLET],
|
modes: [Mode.RAPID, Mode.BLITZ, Mode.BULLET],
|
||||||
languages: [],
|
languages: [],
|
||||||
titles: [],
|
titles: [],
|
||||||
sites: [Site.CHESSCOM, Site.LICHESS],
|
sites: [Site.LICHESS],
|
||||||
}
|
}
|
||||||
|
|
||||||
export function toQueryParams(p: SearchParams) {
|
export function toQueryParams(p: SearchParams) {
|
||||||
|
|
Loading…
Reference in New Issue