mirror of
https://github.com/Sendouc/sendou.ink.git
synced 2026-04-25 15:56:19 -05:00
tournaments progress
This commit is contained in:
parent
4ba688cf03
commit
671287be89
24
frontend-react/package-lock.json
generated
24
frontend-react/package-lock.json
generated
|
|
@ -2100,9 +2100,9 @@
|
|||
}
|
||||
},
|
||||
"@types/jest": {
|
||||
"version": "25.1.3",
|
||||
"resolved": "https://registry.npmjs.org/@types/jest/-/jest-25.1.3.tgz",
|
||||
"integrity": "sha512-jqargqzyJWgWAJCXX96LBGR/Ei7wQcZBvRv0PLEu9ZByMfcs23keUJrKv9FMR6YZf9YCbfqDqgmY+JUBsnqhrg==",
|
||||
"version": "25.1.4",
|
||||
"resolved": "https://registry.npmjs.org/@types/jest/-/jest-25.1.4.tgz",
|
||||
"integrity": "sha512-QDDY2uNAhCV7TMCITrxz+MRk1EizcsevzfeS6LykIlq2V1E5oO4wXG8V2ZEd9w7Snxeeagk46YbMgZ8ESHx3sw==",
|
||||
"requires": {
|
||||
"jest-diff": "^25.1.0",
|
||||
"pretty-format": "^25.1.0"
|
||||
|
|
@ -2120,9 +2120,9 @@
|
|||
}
|
||||
},
|
||||
"@types/yargs": {
|
||||
"version": "15.0.3",
|
||||
"resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-15.0.3.tgz",
|
||||
"integrity": "sha512-XCMQRK6kfpNBixHLyHUsGmXrpEmFFxzMrcnSXFMziHd8CoNJo8l16FkHyQq4x+xbM7E2XL83/O78OD8u+iZTdQ==",
|
||||
"version": "15.0.4",
|
||||
"resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-15.0.4.tgz",
|
||||
"integrity": "sha512-9T1auFmbPZoxHz0enUFlUuKRy3it01R+hlggyVUMtnCTQRunsQYifnSGb8hET4Xo8yiC0o0r1paW3ud5+rbURg==",
|
||||
"requires": {
|
||||
"@types/yargs-parser": "*"
|
||||
}
|
||||
|
|
@ -2216,9 +2216,9 @@
|
|||
"integrity": "sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA=="
|
||||
},
|
||||
"@types/node": {
|
||||
"version": "13.7.7",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-13.7.7.tgz",
|
||||
"integrity": "sha512-Uo4chgKbnPNlxQwoFmYIwctkQVkMMmsAoGGU4JKwLuvBefF0pCq4FybNSnfkfRCpC7ZW7kttcC/TrRtAJsvGtg=="
|
||||
"version": "13.9.0",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-13.9.0.tgz",
|
||||
"integrity": "sha512-0ARSQootUG1RljH2HncpsY2TJBfGQIKOOi7kxzUY6z54ePu/ZD+wJA8zI2Q6v8rol2qpG/rvqsReco8zNMPvhQ=="
|
||||
},
|
||||
"@types/parse-json": {
|
||||
"version": "4.0.0",
|
||||
|
|
@ -2624,9 +2624,9 @@
|
|||
}
|
||||
},
|
||||
"acorn": {
|
||||
"version": "7.1.0",
|
||||
"resolved": "https://registry.npmjs.org/acorn/-/acorn-7.1.0.tgz",
|
||||
"integrity": "sha512-kL5CuoXA/dgxlBbVrflsflzQ3PAas7RYZB52NOm/6839iVYJgKMJ3cQJD+t2i5+qFa8h3MDpEOJiS64E8JLnSQ=="
|
||||
"version": "7.1.1",
|
||||
"resolved": "https://registry.npmjs.org/acorn/-/acorn-7.1.1.tgz",
|
||||
"integrity": "sha512-add7dgA5ppRPxCFJoAGfMDi7PIBXq1RtGo7BhbLaxwrXPOmw8gq48Y9ozT01hUKy9byMjlR20EJhu5zlkErEkg=="
|
||||
},
|
||||
"acorn-globals": {
|
||||
"version": "4.3.4",
|
||||
|
|
|
|||
|
|
@ -13,8 +13,8 @@
|
|||
"@testing-library/jest-dom": "^5.1.1",
|
||||
"@testing-library/react": "^9.5.0",
|
||||
"@testing-library/user-event": "^10.0.0",
|
||||
"@types/jest": "^25.1.3",
|
||||
"@types/node": "^13.7.7",
|
||||
"@types/jest": "^25.1.4",
|
||||
"@types/node": "^13.9.0",
|
||||
"@types/reach__router": "^1.3.0",
|
||||
"@types/react": "^16.9.23",
|
||||
"@types/react-color": "^3.0.1",
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@ const Input: React.FC<InputProps> = ({
|
|||
setValue(event.target.value)
|
||||
|
||||
return (
|
||||
<>
|
||||
<Box>
|
||||
{label && <Label required={required}>{label}</Label>}
|
||||
<InputGroup>
|
||||
{textLeft && <InputLeftAddon>{textLeft}</InputLeftAddon>}
|
||||
|
|
@ -57,7 +57,7 @@ const Input: React.FC<InputProps> = ({
|
|||
{(value ?? "").length}/{limit}
|
||||
</Box>
|
||||
)}
|
||||
</>
|
||||
</Box>
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -90,7 +90,7 @@ const Select: React.FC<SelectProps> = ({
|
|||
}
|
||||
|
||||
return (
|
||||
<Box w={width}>
|
||||
<Box>
|
||||
{label && <Label required={required}>{label}</Label>}
|
||||
<ReactSelect
|
||||
className="basic-single"
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ import {
|
|||
import Error from "../common/Error"
|
||||
import Loading from "../common/Loading"
|
||||
import TournamentCard from "./TournamentCard"
|
||||
import { Box, Flex, Image, Avatar, Icon, Grid } from "@chakra-ui/core"
|
||||
import { Box, Flex, Avatar, Icon, Grid } from "@chakra-ui/core"
|
||||
import Button from "../elements/Button"
|
||||
import { Helmet } from "react-helmet-async"
|
||||
import { FaLongArrowAltLeft } from "react-icons/fa"
|
||||
|
|
|
|||
|
|
@ -1,10 +1,36 @@
|
|||
import React, { useState } from "react"
|
||||
import React, { useState, useContext } from "react"
|
||||
import Button from "../elements/Button"
|
||||
import { Collapse } from "@chakra-ui/core"
|
||||
import { Collapse, Grid, Flex, Box, RadioGroup, Radio } from "@chakra-ui/core"
|
||||
import Input from "../elements/Input"
|
||||
import WeaponSelector from "../common/WeaponSelector"
|
||||
import Select from "../elements/Select"
|
||||
import Label from "../elements/Label"
|
||||
import MyThemeContext from "../../themeContext"
|
||||
import { Weapon } from "../../types"
|
||||
import { maps } from "../../utils/lists"
|
||||
|
||||
interface TournamentFiltersProps {}
|
||||
interface TournamentFiltersProps {
|
||||
forms: {
|
||||
tournament_name?: string
|
||||
region?: string
|
||||
player_name?: string
|
||||
team_name?: string
|
||||
comp?: string[]
|
||||
mode?: string
|
||||
stage?: string
|
||||
}
|
||||
handleChange: (value: Object) => void
|
||||
handleClear: () => void
|
||||
onSubmit: () => void
|
||||
}
|
||||
|
||||
const TournamentFilters: React.FC<TournamentFiltersProps> = ({}) => {
|
||||
const TournamentFilters: React.FC<TournamentFiltersProps> = ({
|
||||
forms,
|
||||
handleChange,
|
||||
handleClear,
|
||||
onSubmit,
|
||||
}) => {
|
||||
const { themeColor } = useContext(MyThemeContext)
|
||||
const [show, setShow] = useState(true)
|
||||
return (
|
||||
<>
|
||||
|
|
@ -12,9 +38,84 @@ const TournamentFilters: React.FC<TournamentFiltersProps> = ({}) => {
|
|||
{show ? "Hide filters" : "Show filters"}
|
||||
</Button>
|
||||
<Collapse mt={4} isOpen={show}>
|
||||
Anim pariatur cliche reprehenderit, enim eiusmod high life accusamus
|
||||
terry richardson ad squid. Nihil anim keffiyeh helvetica, craft beer
|
||||
labore wes anderson cred nesciunt sapiente ea proident.
|
||||
<Grid maxW="500px" gridRowGap="1em" gridTemplateColumns="1fr">
|
||||
<Input
|
||||
label="Tournament"
|
||||
value={forms.tournament_name ?? ""}
|
||||
setValue={(value: string) =>
|
||||
handleChange({ tournament_name: value })
|
||||
}
|
||||
/>
|
||||
<Input
|
||||
label="Team"
|
||||
value={forms.team_name ?? ""}
|
||||
setValue={(value: string) => handleChange({ team_name: value })}
|
||||
/>
|
||||
<Input
|
||||
label="Player"
|
||||
value={forms.player_name ?? ""}
|
||||
setValue={(value: string) => handleChange({ player_name: value })}
|
||||
/>
|
||||
<WeaponSelector
|
||||
label="Comp"
|
||||
value={(forms.comp as Weapon[]) ?? []}
|
||||
setValue={(value: Weapon[]) => handleChange({ comp: value })}
|
||||
isMulti
|
||||
/>
|
||||
<Select
|
||||
label="Map & mode"
|
||||
isSearchable
|
||||
value={
|
||||
forms.stage && forms.mode ? `${forms.stage} (${forms.mode})` : ""
|
||||
}
|
||||
setValue={(value: string) => {
|
||||
const partsArray = value.split(" (")
|
||||
handleChange({
|
||||
stage: partsArray[0],
|
||||
mode: partsArray[1].substring(0, partsArray[1].length - 1),
|
||||
})
|
||||
}}
|
||||
options={maps.reduce(
|
||||
(acc: { label: string; value: string }[], cur: string) => [
|
||||
...acc,
|
||||
{ label: `${cur} (TW)`, value: `${cur} (TW)` },
|
||||
{ label: `${cur} (SZ)`, value: `${cur} (SZ)` },
|
||||
{ label: `${cur} (TC)`, value: `${cur} (TC)` },
|
||||
{ label: `${cur} (RM)`, value: `${cur} (RM)` },
|
||||
{ label: `${cur} (CB)`, value: `${cur} (CB)` },
|
||||
],
|
||||
[]
|
||||
)}
|
||||
/>
|
||||
<Box mt="0.5em">
|
||||
<Label>Mode</Label>
|
||||
<RadioGroup
|
||||
value={forms.region ?? "all"}
|
||||
defaultValue="0"
|
||||
spacing={5}
|
||||
isInline
|
||||
onChange={(e, value: any) => handleChange({ region: value })}
|
||||
>
|
||||
<Radio variantColor={themeColor} value="all">
|
||||
All
|
||||
</Radio>
|
||||
<Radio variantColor={themeColor} value="western">
|
||||
Western only
|
||||
</Radio>
|
||||
<Radio variantColor={themeColor} value="jpn">
|
||||
Japanese only
|
||||
</Radio>
|
||||
</RadioGroup>
|
||||
</Box>
|
||||
<Flex mt="1em">
|
||||
<Button onClick={onSubmit}>Apply</Button>
|
||||
<Box mx="1em">
|
||||
<Button outlined onClick={handleClear}>
|
||||
Clear filters
|
||||
</Button>
|
||||
</Box>
|
||||
</Flex>
|
||||
</Grid>
|
||||
</Collapse>
|
||||
</>
|
||||
)
|
||||
|
|
|
|||
|
|
@ -7,14 +7,17 @@ import {
|
|||
NumberParam,
|
||||
StringParam,
|
||||
ArrayParam,
|
||||
encodeQueryParams,
|
||||
} from "use-query-params"
|
||||
import { useQuery } from "@apollo/react-hooks"
|
||||
import { SEARCH_FOR_TOURNAMENTS } from "../../graphql/queries/searchForTournaments"
|
||||
import Loading from "../common/Loading"
|
||||
import Error from "../common/Error"
|
||||
import TournamentCard from "./TournamentCard"
|
||||
import { Box, Grid } from "@chakra-ui/core"
|
||||
import { Box, Grid, Alert, AlertIcon } from "@chakra-ui/core"
|
||||
import TournamentFilters from "./TournamentFilters"
|
||||
import Pagination from "../common/Pagination"
|
||||
import { stringify } from "querystring"
|
||||
|
||||
interface SearchForTournamentsData {
|
||||
searchForTournaments: {
|
||||
|
|
@ -37,21 +40,26 @@ interface SearchForTournamentsVars {
|
|||
tournament_name?: string
|
||||
region?: string
|
||||
player_name?: string
|
||||
unique_id?: string
|
||||
team_name?: string
|
||||
comp?: string[]
|
||||
page?: number
|
||||
mode?: string
|
||||
stage?: string
|
||||
}
|
||||
|
||||
const TournamentsPage: React.FC<RouteComponentProps> = ({}) => {
|
||||
const [query, setQuery] = useQueryParams({
|
||||
page: NumberParam,
|
||||
tournament_name: StringParam,
|
||||
region: StringParam,
|
||||
team_name: StringParam,
|
||||
player_name: StringParam,
|
||||
comp: ArrayParam,
|
||||
})
|
||||
const queryMap = {
|
||||
page: NumberParam,
|
||||
tournament_name: StringParam,
|
||||
region: StringParam,
|
||||
team_name: StringParam,
|
||||
player_name: StringParam,
|
||||
comp: ArrayParam,
|
||||
mode: StringParam,
|
||||
stage: StringParam,
|
||||
}
|
||||
|
||||
const TournamentsPage: React.FC<RouteComponentProps> = () => {
|
||||
const [query, setQuery] = useQueryParams(queryMap)
|
||||
const [forms, setForms] = useState<SearchForTournamentsVars>({
|
||||
page: query.page,
|
||||
tournament_name: query.tournament_name,
|
||||
|
|
@ -59,9 +67,11 @@ const TournamentsPage: React.FC<RouteComponentProps> = ({}) => {
|
|||
team_name: query.team_name,
|
||||
player_name: query.player_name,
|
||||
comp: query.comp,
|
||||
mode: query.mode,
|
||||
stage: query.stage,
|
||||
})
|
||||
|
||||
const { data, error, loading } = useQuery<
|
||||
const { data, error } = useQuery<
|
||||
SearchForTournamentsData,
|
||||
SearchForTournamentsVars
|
||||
>(SEARCH_FOR_TOURNAMENTS, {
|
||||
|
|
@ -69,29 +79,79 @@ const TournamentsPage: React.FC<RouteComponentProps> = ({}) => {
|
|||
})
|
||||
|
||||
if (error) return <Error errorMessage={error.message} />
|
||||
if (loading || !data) return <Loading />
|
||||
|
||||
const { tournaments } = data.searchForTournaments
|
||||
const handleFormChange = (value: Object) => {
|
||||
setForms({ ...forms, ...value })
|
||||
}
|
||||
|
||||
const handleClear = () => {
|
||||
setForms({})
|
||||
setQuery({}, "replace")
|
||||
}
|
||||
|
||||
const encodedQuery = encodeQueryParams(queryMap, query)
|
||||
const linkSuffix = `?${stringify(encodedQuery)}`
|
||||
|
||||
return (
|
||||
<>
|
||||
<Helmet>
|
||||
<title>Tournaments | sendou.ink</title>
|
||||
</Helmet>
|
||||
<PageHeader title="Tournaments" />
|
||||
<TournamentFilters />
|
||||
<Grid
|
||||
gridGap="1em"
|
||||
gridTemplateColumns="repeat(auto-fit, minmax(260px, 1fr))"
|
||||
mt="1em"
|
||||
>
|
||||
{tournaments.map(tournament => (
|
||||
<Box key={tournament.id}>
|
||||
<Link to={`/tournaments/${tournament.id}`}>
|
||||
<TournamentCard tournament={tournament} styledOnHover />
|
||||
</Link>
|
||||
<TournamentFilters
|
||||
forms={forms}
|
||||
handleChange={handleFormChange}
|
||||
handleClear={handleClear}
|
||||
onSubmit={() => setQuery(forms)}
|
||||
/>
|
||||
{data && data.searchForTournaments.tournaments.length > 0 ? (
|
||||
<>
|
||||
<Box mt="1em">
|
||||
<Pagination
|
||||
currentPage={forms.page ?? 1}
|
||||
pageCount={data?.searchForTournaments.pageCount ?? 999}
|
||||
onChange={page => {
|
||||
setForms({ ...forms, page })
|
||||
setQuery({ ...query, page })
|
||||
}}
|
||||
/>
|
||||
</Box>
|
||||
))}
|
||||
</Grid>
|
||||
{data && data.searchForTournaments ? (
|
||||
<>
|
||||
<Grid
|
||||
gridGap="1em"
|
||||
gridTemplateColumns="repeat(auto-fit, minmax(260px, 1fr))"
|
||||
mt="1em"
|
||||
>
|
||||
{data.searchForTournaments.tournaments.map(tournament => (
|
||||
<Box key={tournament.id}>
|
||||
<Link to={`/tournaments/${tournament.id}${linkSuffix}`}>
|
||||
<TournamentCard tournament={tournament} styledOnHover />
|
||||
</Link>
|
||||
</Box>
|
||||
))}
|
||||
</Grid>
|
||||
<Box mt="1em">
|
||||
<Pagination
|
||||
currentPage={forms.page ?? 1}
|
||||
pageCount={data.searchForTournaments.pageCount}
|
||||
onChange={page => {
|
||||
setForms({ ...forms, page })
|
||||
setQuery({ ...query, page })
|
||||
}}
|
||||
/>
|
||||
</Box>
|
||||
</>
|
||||
) : (
|
||||
<Loading />
|
||||
)}
|
||||
</>
|
||||
) : (
|
||||
<Alert status="info" mt="2em">
|
||||
<AlertIcon />
|
||||
Your doesn't match any tournaments. Try another filter!
|
||||
</Alert>
|
||||
)}
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -84,11 +84,7 @@ const Top500Forms: React.FC<Top500FormsProps> = ({ forms, handleChange }) => {
|
|||
isInline
|
||||
onChange={(e, value: any) => handleChange({ mode: parseInt(value) })}
|
||||
>
|
||||
<Radio
|
||||
variantColor={themeColor}
|
||||
value="0"
|
||||
isChecked={forms.mode === 0 || !forms.mode}
|
||||
>
|
||||
<Radio variantColor={themeColor} value="0">
|
||||
All modes
|
||||
</Radio>
|
||||
<Radio variantColor={themeColor} value="1">
|
||||
|
|
|
|||
|
|
@ -8,6 +8,8 @@ export const SEARCH_FOR_TOURNAMENTS: DocumentNode = gql`
|
|||
$team_name: String
|
||||
$player_name: String
|
||||
$comp: [String]
|
||||
$mode: Mode
|
||||
$stage: String
|
||||
) {
|
||||
searchForTournaments(
|
||||
page: $page
|
||||
|
|
@ -16,6 +18,8 @@ export const SEARCH_FOR_TOURNAMENTS: DocumentNode = gql`
|
|||
team_name: $team_name
|
||||
player_name: $player_name
|
||||
comp: $comp
|
||||
mode: $mode
|
||||
stage: $stage
|
||||
) {
|
||||
tournaments {
|
||||
id
|
||||
|
|
|
|||
|
|
@ -789,6 +789,32 @@ export const continents = {
|
|||
zw: "AF",
|
||||
} as const
|
||||
|
||||
export const maps = [
|
||||
"The Reef",
|
||||
"Musselforge Fitness",
|
||||
"Starfish Mainstage",
|
||||
"Humpback Pump Track",
|
||||
"Inkblot Art Academy",
|
||||
"Sturgeon Shipyard",
|
||||
"Moray Towers",
|
||||
"Port Mackerel",
|
||||
"Manta Maria",
|
||||
"Kelp Dome",
|
||||
"Snapper Canal",
|
||||
"Blackbelly Skatepark",
|
||||
"MakoMart",
|
||||
"Walleye Warehouse",
|
||||
"Shellendorf Institute",
|
||||
"Arowana Mall",
|
||||
"Goby Arena",
|
||||
"Piranha Pit",
|
||||
"Camp Triggerfish",
|
||||
"Wahoo World",
|
||||
"New Albacore Hotel",
|
||||
"Ancho-V Games",
|
||||
"Skipper Pavilion",
|
||||
]
|
||||
|
||||
export const modes = [
|
||||
"",
|
||||
"Splat Zones",
|
||||
|
|
|
|||
|
|
@ -12,6 +12,8 @@ const typeDef = gql`
|
|||
unique_id: String
|
||||
team_name: String
|
||||
comp: [String]
|
||||
stage: String
|
||||
mode: Mode
|
||||
page: Int
|
||||
): TournamentCollection!
|
||||
}
|
||||
|
|
@ -166,6 +168,14 @@ const resolvers = {
|
|||
})
|
||||
}
|
||||
|
||||
if (args.mode) {
|
||||
roundSearchCriteria.mode = args.mode
|
||||
}
|
||||
|
||||
if (args.stage) {
|
||||
roundSearchCriteria.stage = args.stage
|
||||
}
|
||||
|
||||
// if criteria were presented that we have to search
|
||||
// from the Round collection
|
||||
let tournament_ids = null
|
||||
|
|
@ -176,7 +186,15 @@ const resolvers = {
|
|||
if (args.region && args.region === "jpn")
|
||||
tournamentSearchCriteria.jpn = true
|
||||
|
||||
if (roundSearchCriteria.$or.length !== 0) {
|
||||
if (roundSearchCriteria.$or.length === 0) {
|
||||
delete roundSearchCriteria.$or
|
||||
}
|
||||
|
||||
if (
|
||||
roundSearchCriteria.$or ||
|
||||
roundSearchCriteria.stage ||
|
||||
roundSearchCriteria.mode
|
||||
) {
|
||||
tournament_ids = await Round.find(roundSearchCriteria).distinct(
|
||||
"tournament_id"
|
||||
)
|
||||
|
|
|
|||
6
package-lock.json
generated
6
package-lock.json
generated
|
|
@ -828,9 +828,9 @@
|
|||
}
|
||||
},
|
||||
"cross-env": {
|
||||
"version": "7.0.1",
|
||||
"resolved": "https://registry.npmjs.org/cross-env/-/cross-env-7.0.1.tgz",
|
||||
"integrity": "sha512-1+DmLosu38kC4s1H4HzNkcolwdANifu9+5bE6uKQCV4L6jvVdV9qdRAk8vV3GoWRe0x4z+K2fFhgoDMqwNsPqQ==",
|
||||
"version": "7.0.2",
|
||||
"resolved": "https://registry.npmjs.org/cross-env/-/cross-env-7.0.2.tgz",
|
||||
"integrity": "sha512-KZP/bMEOJEDCkDQAyRhu3RL2ZO/SUVrxQVI0G3YEQ+OLbRA3c6zgixe8Mq8a/z7+HKlNEjo8oiLUs8iRijY2Rw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"cross-spawn": "^7.0.1"
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@
|
|||
"webhook-discord": "^3.5.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"cross-env": "^7.0.1",
|
||||
"cross-env": "^7.0.2",
|
||||
"nodemon": "^2.0.2"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user