diff --git a/frontend-react/package-lock.json b/frontend-react/package-lock.json index 9c295f813..2e91b1aab 100644 --- a/frontend-react/package-lock.json +++ b/frontend-react/package-lock.json @@ -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", @@ -2287,6 +2287,14 @@ "@types/react": "*" } }, + "@types/react-paginate": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/@types/react-paginate/-/react-paginate-6.2.1.tgz", + "integrity": "sha512-+q8k1N0WzbMyOCsIEH/p5D6/KQD8dXYLzfvSvriYn//94icd2sqhAL2rWXkgwGvqHGCSTU9AoHtsWCJxPfquUQ==", + "requires": { + "@types/react": "*" + } + }, "@types/react-select": { "version": "3.0.10", "resolved": "https://registry.npmjs.org/@types/react-select/-/react-select-3.0.10.tgz", @@ -11933,9 +11941,9 @@ } }, "react-datepicker": { - "version": "2.13.0", - "resolved": "https://registry.npmjs.org/react-datepicker/-/react-datepicker-2.13.0.tgz", - "integrity": "sha512-vUp3tGGT8SwJX5c6hKnhSJFOFjjBgwKQUv9nl7dkhe/viraxrihLikDr/KVDRGYyj/Q1MBvTpOog4fsSly9o9A==", + "version": "2.14.0", + "resolved": "https://registry.npmjs.org/react-datepicker/-/react-datepicker-2.14.0.tgz", + "integrity": "sha512-9TUDNj0zoeQT3ey6i7Dv4NLcqONyYqXNEOLA3++HwQKR5NK4eRoG4QaohM/5XmWw2tDpJWpl3ByCWP4kWQtqgQ==", "requires": { "classnames": "^2.2.6", "date-fns": "^2.0.1", @@ -12168,6 +12176,14 @@ "resolved": "https://registry.npmjs.org/react-onclickoutside/-/react-onclickoutside-6.9.0.tgz", "integrity": "sha512-8ltIY3bC7oGhj2nPAvWOGi+xGFybPNhJM0V1H8hY/whNcXgmDeaeoCMPPd8VatrpTsUWjb/vGzrmu6SrXVty3A==" }, + "react-paginate": { + "version": "6.3.2", + "resolved": "https://registry.npmjs.org/react-paginate/-/react-paginate-6.3.2.tgz", + "integrity": "sha512-Ch++Njfv8UHpLtIMiQouAPeJQA5Ki86kIYfCer6c1B96Rvn3UF27se+goCilCP8oHNXNsA2R2kxvzanY1YIkyg==", + "requires": { + "prop-types": "^15.6.1" + } + }, "react-popper": { "version": "1.3.7", "resolved": "https://registry.npmjs.org/react-popper/-/react-popper-1.3.7.tgz", diff --git a/frontend-react/package.json b/frontend-react/package.json index ced1caa47..2822792d8 100644 --- a/frontend-react/package.json +++ b/frontend-react/package.json @@ -13,13 +13,14 @@ "@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/jest": "^25.1.4", "@types/reach__router": "^1.3.0", "@types/react": "^16.9.23", "@types/react-color": "^3.0.1", "@types/react-datepicker": "^2.11.0", "@types/react-dom": "^16.9.5", "@types/react-infinite-scroller": "^1.2.1", + "@types/react-paginate": "^6.2.1", "@types/react-select": "^3.0.10", "@types/webpack-env": "^1.15.1", "apollo-boost": "^0.4.7", @@ -29,13 +30,14 @@ "node-sass": "^4.13.1", "react": "^16.13.0", "react-color": "^2.18.0", - "react-datepicker": "^2.13.0", + "react-datepicker": "^2.14.0", "react-dom": "^16.13.0", "react-draggable": "^4.2.0", "react-helmet-async": "^1.0.4", "react-hotkeys-hook": "^1.5.4", "react-icons": "^3.9.0", "react-infinite-scroller": "^1.2.4", + "react-paginate": "^6.3.2", "react-scripts": "^3.4.0", "react-select": "^3.0.8", "react-super-responsive-table": "^5.1.1", diff --git a/frontend-react/src/assets/icons.tsx b/frontend-react/src/assets/icons.tsx index e112a7834..3e88c9a81 100644 --- a/frontend-react/src/assets/icons.tsx +++ b/frontend-react/src/assets/icons.tsx @@ -1,7 +1,6 @@ import React from "react" const customIcons = { - //sz.svg sz: { path: ( + ), + viewBox: "0 0 128 128", + }, } export default customIcons diff --git a/frontend-react/src/components/common/Pagination.css b/frontend-react/src/components/common/Pagination.css index 4ab814e85..4034ecadc 100644 --- a/frontend-react/src/components/common/Pagination.css +++ b/frontend-react/src/components/common/Pagination.css @@ -1,29 +1,21 @@ .pagination { display: inline-block; - border-color: red; -} - -.pagination span { - color: black; - float: left; padding: 8px 16px; text-decoration: none; font-weight: bold; + font-size: 18px; + user-select: none; } -.pagination span:not(.dots) { - cursor: pointer; +.page { + display: inline; + margin: 0.2em; } -.pagination span.active { +.active-page { border-bottom: 3px solid; } -.pagination span:hover:not(.active):not(.dots) { - background-color: rgba(165, 165, 165, 0.15); - border-radius: 5px; -} - -.dots { - user-select: none; +.disabled-page { + display: none; } diff --git a/frontend-react/src/components/common/Pagination.tsx b/frontend-react/src/components/common/Pagination.tsx index 1c8196943..905fbfda8 100644 --- a/frontend-react/src/components/common/Pagination.tsx +++ b/frontend-react/src/components/common/Pagination.tsx @@ -1,7 +1,6 @@ -import React, { useContext } from "react" +import React from "react" import "./Pagination.css" -import { Box } from "@chakra-ui/core" -import MyThemeContext from "../../themeContext" +import ReactPaginate from "react-paginate" interface PaginationProps { pageCount: number @@ -9,55 +8,26 @@ interface PaginationProps { onChange: (page: number) => void } -const Pagination: React.FC = ({ - pageCount, - currentPage, - onChange, -}) => { - const { colorMode, themeColorHex } = useContext(MyThemeContext) +const Pagination: React.FC = ({ pageCount, onChange }) => { return ( - - onChange(currentPage === 1 ? 1 : currentPage - 1)} - > - « - - {[...Array(6)].map((page, index) => { - const pageNumber = index + currentPage - return ( - onChange(pageNumber)} - > - {pageNumber} - - ) - })} - - - onChange(currentPage === pageCount ? pageCount : currentPage + 1) - } - > - » - - + «} + nextLabel={<>»} + breakLabel={"..."} + breakClassName={"page"} + pageCount={pageCount} + marginPagesDisplayed={2} + pageRangeDisplayed={3} + onPageChange={({ selected }) => onChange(selected)} + containerClassName="pagination" + pageClassName="page" + previousClassName="page" + nextClassName="page" + pageLinkClassName="page" + activeLinkClassName="active-page" + disabledClassName="disabled-page" + activeClassName={"active"} + /> ) } diff --git a/frontend-react/src/components/common/UserAvatar.tsx b/frontend-react/src/components/common/UserAvatar.tsx index 39b92d9d2..0f11bc10c 100644 --- a/frontend-react/src/components/common/UserAvatar.tsx +++ b/frontend-react/src/components/common/UserAvatar.tsx @@ -4,7 +4,7 @@ import { Avatar, BoxProps } from "@chakra-ui/core" interface UserAvatarProps { name: string twitterName?: string - size?: undefined | "2xl" | "xs" | "sm" + size?: undefined | "2xl" | "lg" | "xs" | "sm" } const UserAvatar: React.FC = ({ diff --git a/frontend-react/src/components/elements/Input.tsx b/frontend-react/src/components/elements/Input.tsx index 00e7c6719..1da36a573 100644 --- a/frontend-react/src/components/elements/Input.tsx +++ b/frontend-react/src/components/elements/Input.tsx @@ -35,7 +35,7 @@ const Input: React.FC = ({ setValue(event.target.value) return ( - <> + {label && } {textLeft && {textLeft}} @@ -57,7 +57,7 @@ const Input: React.FC = ({ {(value ?? "").length}/{limit} )} - + ) } diff --git a/frontend-react/src/components/elements/Select.tsx b/frontend-react/src/components/elements/Select.tsx index b14bfb330..d50821144 100644 --- a/frontend-react/src/components/elements/Select.tsx +++ b/frontend-react/src/components/elements/Select.tsx @@ -90,7 +90,7 @@ const Select: React.FC = ({ } return ( - + {label && } { + const { activity, description, looking_for, past_experience } = post + if (!activity && !description && !looking_for && !past_experience) { + return false + } + + return true +} + +const FreeAgentCard: React.FC = ({ post }) => { + const [expanded, setExpanded] = useState(false) + const { grayWithShade, themeColorWithShade } = useContext(MyThemeContext) + const { discord_user } = post + const canBeExpanded = hasExtraInfo(post) + return ( + + + + {new Date(parseInt(post.createdAt)).toLocaleDateString()} + + + {discord_user.top500 && ( + x rank top 500 logo + )} + + + + + + + + + {discord_user.username}#{discord_user.discriminator} + + {discord_user.twitter_name && ( + + + + )} + + + + {discord_user.country && ( + <> + + {countries.find(obj => obj.code === discord_user.country)?.name} + + )} + + + + + {discord_user?.weapons && + discord_user.weapons.map(wpn => ( + + + + ))} + + + + + + + + + + + {canBeExpanded && ( + + setExpanded(!expanded)} + /> + + )} + {expanded && ( + + {post.activity && ( + + + Activity + + {post.activity} + + )} + {post.looking_for && ( + + + Looking for + + {post.looking_for} + + )} + {post.past_experience && ( + + + Past experience + + {post.past_experience} + + )} + {post.description && ( + + + Description + + {post.description} + + )} + + )} + + ) +} + +export default FreeAgentCard diff --git a/frontend-react/src/components/freeagents/FreeAgentsPage.tsx b/frontend-react/src/components/freeagents/FreeAgentsPage.tsx index 04f5345c5..30f33886e 100644 --- a/frontend-react/src/components/freeagents/FreeAgentsPage.tsx +++ b/frontend-react/src/components/freeagents/FreeAgentsPage.tsx @@ -11,13 +11,15 @@ import { FREE_AGENT_POSTS } from "../../graphql/queries/freeAgentPosts" import Loading from "../common/Loading" import Error from "../common/Error" import { RouteComponentProps } from "@reach/router" -import PostsAccordion from "./PostsAccordion" +import PostsAccordion from "./Posts" import PageHeader from "../common/PageHeader" import { Helmet } from "react-helmet-async" import WeaponSelector from "../common/WeaponSelector" import RadioGroup from "../elements/RadioGroup" import Box from "../elements/Box" import { continents } from "../../utils/lists" +import { Collapse } from "@chakra-ui/core" +import Button from "../elements/Button" const playstyleToEnum = { "Frontline/Slayer": "FRONTLINE", @@ -27,6 +29,7 @@ const playstyleToEnum = { const FreeAgentsPage: React.FC = () => { const [weapon, setWeapon] = useState(null) + const [show, setShow] = useState(false) const [playstyle, setPlaystyle] = useState< "Any" | "Frontline/Slayer" | "Midline/Support" | "Backline/Anchor" >("Any") @@ -96,35 +99,40 @@ const FreeAgentsPage: React.FC = () => { Free Agents | sendou.ink - - - - - - - - setWeapon(weapon as Weapon)} - clearable - /> - + + + + + + + + + + setWeapon(weapon as Weapon)} + clearable + /> + + ) diff --git a/frontend-react/src/components/freeagents/Posts.tsx b/frontend-react/src/components/freeagents/Posts.tsx new file mode 100644 index 000000000..d35dca664 --- /dev/null +++ b/frontend-react/src/components/freeagents/Posts.tsx @@ -0,0 +1,50 @@ +import React, { useState } from "react" +import { FreeAgentPost } from "../../types" +import { Grid, Box, Heading } from "@chakra-ui/core" +import Alert from "../elements/Alert" +import FreeAgentCard from "./FreeAgentCard" +import InfiniteScroll from "react-infinite-scroller" +import Button from "../elements/Button" + +interface PostsAccordionProps { + posts: FreeAgentPost[] +} + +const Posts: React.FC = ({ posts }) => { + const [agentsToShow, setAgentsToShow] = useState(5) + + if (posts.length === 0) { + return ( + No free agents found with the current filter + ) + } + return ( + <> + + setAgentsToShow(page * 10)} + hasMore={agentsToShow < posts.length} + > + {posts + .filter((post, index) => index < agentsToShow) + .map(post => ( + + + + ))} + + + + No more free agents to show + + + + + + ) +} + +export default Posts diff --git a/frontend-react/src/components/freeagents/PostsAccordion.tsx b/frontend-react/src/components/freeagents/PostsAccordion.tsx deleted file mode 100644 index 5494ae917..000000000 --- a/frontend-react/src/components/freeagents/PostsAccordion.tsx +++ /dev/null @@ -1,165 +0,0 @@ -import React from "react" -import { FreeAgentPost } from "../../types" -import { - Accordion, - AccordionItem, - AccordionHeader, - AccordionIcon, - AccordionPanel, - Box, - Grid, - Flex, - Heading, -} from "@chakra-ui/core" -import { useContext } from "react" -import MyThemeContext from "../../themeContext" -import UserAvatar from "../common/UserAvatar" -import { Link } from "@reach/router" -import Flag from "../common/Flag" -import { countries } from "../../utils/lists" -import { FaTwitter } from "react-icons/fa" -import WeaponImage from "../common/WeaponImage" -import RoleIcons from "./RoleIcons" -import VCIcon from "./VCIcon" -import Alert from "../elements/Alert" - -interface PostsAccordionProps { - posts: FreeAgentPost[] -} - -const hasExtraInfo = (post: FreeAgentPost) => { - const { activity, description, looking_for, past_experience } = post - if (!activity && !description && !looking_for && !past_experience) { - return false - } - - return true -} - -const PostsAccordion: React.FC = ({ posts }) => { - const { darkerBgColor } = useContext(MyThemeContext) - - if (posts.length === 0) { - return ( - No free agents found with the current filter - ) - } - return ( - - {posts.map(post => { - const { discord_user } = post - const canBeExpanded = hasExtraInfo(post) - return ( - - - {canBeExpanded ? ( - - ) : ( - - )} - - - - - - {discord_user.username}#{discord_user.discriminator} - - - - - {discord_user.country && ( - <> - - { - countries.find(obj => obj.code === discord_user.country) - ?.name - } - - )} - - - {discord_user.twitter_name && ( - <> - - - {discord_user.twitter_name} - - - )} - - - {new Date(parseInt(post.createdAt)).toLocaleDateString()} - - - {discord_user?.weapons && - discord_user.weapons.map(wpn => ( - - - - ))} - - - - - - {canBeExpanded && ( - - {post.activity && ( - - Activity - {post.activity} - - )} - {post.looking_for && ( - - Looking for - {post.looking_for} - - )} - {post.past_experience && ( - - Past experience - {post.past_experience} - - )} - {post.description && ( - - Description - {post.description} - - )} - - )} - - ) - })} - - ) -} - -export default PostsAccordion diff --git a/frontend-react/src/components/home/HomePage.tsx b/frontend-react/src/components/home/HomePage.tsx index c036dba31..cba568f7f 100644 --- a/frontend-react/src/components/home/HomePage.tsx +++ b/frontend-react/src/components/home/HomePage.tsx @@ -15,12 +15,14 @@ const HomePage: React.FC = () => { sendou.ink | Competitive Splatoon Hub - - + + = () => { > Sendou.ink + = () => { {userData.user.plus.membership_status === "ONE" && ( - + ({ label: my, value: my }))} diff --git a/frontend-react/src/components/tournaments/TournamentDetailsPage.tsx b/frontend-react/src/components/tournaments/TournamentDetailsPage.tsx index 4814348cb..4e097d0aa 100644 --- a/frontend-react/src/components/tournaments/TournamentDetailsPage.tsx +++ b/frontend-react/src/components/tournaments/TournamentDetailsPage.tsx @@ -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" @@ -17,17 +17,52 @@ import MyThemeContext from "../../themeContext" import { mapIcons } from "../../assets/imageImports" import WeaponImage from "../common/WeaponImage" import AbilityIcon from "../builds/AbilityIcon" -import { Ability } from "../../types" +import { Ability, Weapon } from "../../types" +import { + useQueryParams, + StringParam, + ArrayParam, + encodeQueryParams, +} from "use-query-params" +import { stringify } from "querystring" +import { removeFalsy } from "../../utils/helperFunctions" interface TournamentDetailsPageProps { id?: string } +interface Round { + stage: string + mode: "SZ" | "TC" | "RM" | "CB" | "TW" + round_name: string + round_number: number + game_number: number + winning_team_name: string + winning_team_players: string[] + winning_team_weapons: Weapon[] + winning_team_main_abilities: Ability[][] + losing_team_name: string + losing_team_players: string[] + losing_team_weapons: Weapon[] + losing_team_main_abilities: Ability[][] +} + +const filterMap = { + team_name: StringParam, + player_name: StringParam, + comp: ArrayParam, + mode: StringParam, + stage: StringParam, +} + const TournamentDetailsPage: React.FC = ({ id }) => { - const { themeColorWithShade, grayWithShade, textColor } = useContext( - MyThemeContext - ) + const { + themeColorWithShade, + grayWithShade, + textColor, + darkerBgColor, + } = useContext(MyThemeContext) const { data, error, loading } = useQuery< SearchForTournamentByIdData, SearchForTournamentByIdVars @@ -35,6 +70,7 @@ const TournamentDetailsPage: React.FC if (error) return @@ -52,12 +88,69 @@ const TournamentDetailsPage: React.FC { + const { team_name, player_name, comp, mode, stage } = filter + if (team_name) { + const teamNameUpper = team_name.toUpperCase() + if ( + round.winning_team_name.toUpperCase() === teamNameUpper || + round.losing_team_name.toUpperCase() === teamNameUpper + ) { + return true + } + } + + if (player_name) { + const playerNameUpper = player_name.toUpperCase() + if ( + round.winning_team_players.some( + player => player.toUpperCase() === playerNameUpper + ) || + round.losing_team_players.some( + player => player.toUpperCase() === playerNameUpper + ) + ) { + return true + } + } + + if (comp) { + if ( + comp.every( + weapon => round.winning_team_weapons.indexOf(weapon as any) !== -1 + ) || + comp.every( + weapon => round.losing_team_weapons.indexOf(weapon as any) !== -1 + ) + ) { + return true + } + } + + if (mode && stage) { + if (mode === round.mode && stage === round.stage) { + return true + } + } + + return false + } + + const encoded = encodeQueryParams(filterMap, removeFalsy(filter)) + const linkSuffix = `?${stringify(encoded)}` + + console.log("filter", filter) + return ( <> {tournament.name} | sendou.ink - + @@ -84,6 +177,7 @@ const TournamentDetailsPage: React.FC )} {round.stage} diff --git a/frontend-react/src/components/tournaments/TournamentFilters.tsx b/frontend-react/src/components/tournaments/TournamentFilters.tsx index 66db6c507..49382bd62 100644 --- a/frontend-react/src/components/tournaments/TournamentFilters.tsx +++ b/frontend-react/src/components/tournaments/TournamentFilters.tsx @@ -1,20 +1,121 @@ -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 = ({}) => { - const [show, setShow] = useState(true) +const TournamentFilters: React.FC = ({ + forms, + handleChange, + handleClear, + onSubmit, +}) => { + const { themeColor } = useContext(MyThemeContext) + const [show, setShow] = useState(false) return ( <> - 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. + + + handleChange({ tournament_name: value }) + } + /> + handleChange({ team_name: value })} + /> + handleChange({ player_name: value })} + /> + handleChange({ comp: value })} + isMulti + /> + { - if ( - (!build.headgear || - build.headgear.every(ability => ability === "UNKNOWN")) && - existingGear.hasOwnProperty(headgearItem) - ) { - handleChange({ - headgearItem, - headgear: existingGear[headgearItem], - }) - } else { - handleChange({ headgearItem }) - } - }} - /> + + { - if ( - (!build.clothing || - build.clothing.every(ability => ability === "UNKNOWN")) && - existingGear.hasOwnProperty(clothingItem) - ) { - handleChange({ - clothingItem, - clothing: existingGear[clothingItem], - }) - } else { - handleChange({ clothingItem }) - } - }} - /> + + { - if ( - (!build.shoes || - build.shoes.every(ability => ability === "UNKNOWN")) && - existingGear.hasOwnProperty(shoesItem) - ) { - handleChange({ - shoesItem, - shoes: existingGear[shoesItem], - }) - } else { - handleChange({ shoesItem }) - } - }} - /> + + = ({ forms, handleChange }) => { isInline onChange={(e, value: any) => handleChange({ mode: parseInt(value) })} > - + All modes diff --git a/frontend-react/src/graphql/queries/searchForTournaments.ts b/frontend-react/src/graphql/queries/searchForTournaments.ts index c3ea7fcb9..96549703b 100644 --- a/frontend-react/src/graphql/queries/searchForTournaments.ts +++ b/frontend-react/src/graphql/queries/searchForTournaments.ts @@ -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 diff --git a/frontend-react/src/utils/helperFunctions.ts b/frontend-react/src/utils/helperFunctions.ts index a528148ed..90d791b48 100644 --- a/frontend-react/src/utils/helperFunctions.ts +++ b/frontend-react/src/utils/helperFunctions.ts @@ -25,3 +25,14 @@ export function importAll(r: __WebpackModuleApi.RequireContext) { }) return images } + +// https://coderwall.com/p/urxpsa/remove-falsy-values-or-empty-strings-from-javascript-objects +export const removeFalsy = (obj: { [key: string]: any }) => { + const newObj: { [key: string]: any } = {} + Object.keys(obj).forEach((prop: any) => { + if (obj[prop]) { + newObj[prop] = obj[prop] + } + }) + return newObj +} diff --git a/frontend-react/src/utils/lists.ts b/frontend-react/src/utils/lists.ts index 2f0debd8e..9831365c1 100644 --- a/frontend-react/src/utils/lists.ts +++ b/frontend-react/src/utils/lists.ts @@ -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", diff --git a/graphql-schemas/build.js b/graphql-schemas/build.js index d8d346840..39de06a2e 100644 --- a/graphql-schemas/build.js +++ b/graphql-schemas/build.js @@ -141,14 +141,14 @@ const resolvers = { Mutation: { addBuild: async (root, args, ctx) => { if (!ctx.user) throw new AuthenticationError("Not logged in.") - if (args.title) + if (args.title) { if (args.title.length > 100) throw new UserInputError("Title too long.", { invalidArgs: args, }) - else { - args.title = undefined - } + } else { + args.title = undefined + } if (args.description) { if (args.description.length > 1000) diff --git a/graphql-schemas/tournament.js b/graphql-schemas/tournament.js index 3e4eda9b3..e7b3e3689 100644 --- a/graphql-schemas/tournament.js +++ b/graphql-schemas/tournament.js @@ -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" ) diff --git a/package-lock.json b/package-lock.json index 8a46c02c4..cf8d54b02 100644 --- a/package-lock.json +++ b/package-lock.json @@ -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" diff --git a/package.json b/package.json index c173dcdd6..34e16c4be 100644 --- a/package.json +++ b/package.json @@ -33,7 +33,7 @@ "webhook-discord": "^3.5.1" }, "devDependencies": { - "cross-env": "^7.0.1", + "cross-env": "^7.0.2", "nodemon": "^2.0.2" } }