mirror of
https://github.com/Sendouc/sendou.ink.git
synced 2026-10-01 07:37:55 -05:00
top 500 progress
This commit is contained in:
33
frontend-react/package-lock.json
generated
33
frontend-react/package-lock.json
generated
@@ -12160,6 +12160,11 @@
|
||||
"prop-types": "^15.5.8"
|
||||
}
|
||||
},
|
||||
"react-super-responsive-table": {
|
||||
"version": "5.1.1",
|
||||
"resolved": "https://registry.npmjs.org/react-super-responsive-table/-/react-super-responsive-table-5.1.1.tgz",
|
||||
"integrity": "sha512-YKynBZSUA4QcN+CJgQYvb4RSv8eXHO/8J2cJPAycW5DwdENRd0KgtE7myclnjQeDMxafiFTDILV73DIX2fRRXw=="
|
||||
},
|
||||
"react-transition-group": {
|
||||
"version": "2.9.0",
|
||||
"resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-2.9.0.tgz",
|
||||
@@ -13065,6 +13070,26 @@
|
||||
"resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-2.1.2.tgz",
|
||||
"integrity": "sha512-rs9OggEUF0V4jUSecXazOYsLfu7OGK2qIn3c7IPBiffz32XniEp/TX9Xmc9LQfK2nQ2QKHvZ2oygKUGU0lG4jQ=="
|
||||
},
|
||||
"serialize-query-params": {
|
||||
"version": "0.3.0",
|
||||
"resolved": "https://registry.npmjs.org/serialize-query-params/-/serialize-query-params-0.3.0.tgz",
|
||||
"integrity": "sha512-gtarsAa5B7L+v2mxbm0zTq8WjqwjgYHZmLsyvxGnlSfW2bWkokV0QKzRxLCGHF2aDqbQYCCNaj1/NP6DqbcEKQ==",
|
||||
"requires": {
|
||||
"query-string": "^5.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"query-string": {
|
||||
"version": "5.1.1",
|
||||
"resolved": "https://registry.npmjs.org/query-string/-/query-string-5.1.1.tgz",
|
||||
"integrity": "sha512-gjWOsm2SoGlgLEdAGt7a6slVOk9mGiXmPFMqrEhLQ68rhQuBnpfs3+EmlvqKyxnCo9/PPlF+9MtY02S1aFg+Jw==",
|
||||
"requires": {
|
||||
"decode-uri-component": "^0.2.0",
|
||||
"object-assign": "^4.1.0",
|
||||
"strict-uri-encode": "^1.0.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"serve-index": {
|
||||
"version": "1.9.1",
|
||||
"resolved": "https://registry.npmjs.org/serve-index/-/serve-index-1.9.1.tgz",
|
||||
@@ -14597,6 +14622,14 @@
|
||||
"@use-it/event-listener": "^0.1.2"
|
||||
}
|
||||
},
|
||||
"use-query-params": {
|
||||
"version": "0.6.0",
|
||||
"resolved": "https://registry.npmjs.org/use-query-params/-/use-query-params-0.6.0.tgz",
|
||||
"integrity": "sha512-AEZm0+TTYuV3/l/IC+Iyqkvol1muXWJd2hlgY2erFESvtZNIpU4BrsTo6jnOBFd/t6rTOQuFjKSmW/+TAy8mzQ==",
|
||||
"requires": {
|
||||
"serialize-query-params": "^0.3.0"
|
||||
}
|
||||
},
|
||||
"use-sidecar": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/use-sidecar/-/use-sidecar-1.0.2.tgz",
|
||||
|
||||
@@ -38,8 +38,10 @@
|
||||
"react-infinite-scroller": "^1.2.4",
|
||||
"react-scripts": "^3.4.0",
|
||||
"react-select": "^3.0.8",
|
||||
"react-super-responsive-table": "^5.1.1",
|
||||
"react-tweet-embed": "^1.2.2",
|
||||
"typescript": "^3.8.2"
|
||||
"typescript": "^3.8.2",
|
||||
"use-query-params": "^0.6.0"
|
||||
},
|
||||
"scripts": {
|
||||
"start": "react-scripts start",
|
||||
|
||||
21
frontend-react/src/components/common/Pagination.css
Normal file
21
frontend-react/src/components/common/Pagination.css
Normal file
@@ -0,0 +1,21 @@
|
||||
.pagination {
|
||||
display: inline-block;
|
||||
border-color: red;
|
||||
}
|
||||
|
||||
.pagination a {
|
||||
color: black;
|
||||
float: left;
|
||||
padding: 8px 16px;
|
||||
text-decoration: none;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.pagination a.active {
|
||||
border-bottom: 3px solid;
|
||||
}
|
||||
|
||||
.pagination a:hover:not(.active) {
|
||||
background-color: rgba(165, 165, 165, 0.15);
|
||||
border-radius: 5px;
|
||||
}
|
||||
36
frontend-react/src/components/common/Pagination.tsx
Normal file
36
frontend-react/src/components/common/Pagination.tsx
Normal file
@@ -0,0 +1,36 @@
|
||||
import React, { useContext } from "react"
|
||||
import "./Pagination.css"
|
||||
import { Box } from "@chakra-ui/core"
|
||||
import { Link } from "@reach/router"
|
||||
import MyThemeContext from "../../themeContext"
|
||||
|
||||
interface PaginationProps {}
|
||||
|
||||
const Pagination: React.FC<PaginationProps> = ({}) => {
|
||||
const { colorMode, themeColorHex } = useContext(MyThemeContext)
|
||||
return (
|
||||
<Box className="pagination">
|
||||
<Link to="/" style={{ color: colorMode === "light" ? "black" : "white" }}>
|
||||
«
|
||||
</Link>
|
||||
<Link to="/" style={{ color: colorMode === "light" ? "black" : "white" }}>
|
||||
1
|
||||
</Link>
|
||||
<Link
|
||||
to="/"
|
||||
className="active"
|
||||
style={{
|
||||
color: colorMode === "light" ? "black" : "white",
|
||||
borderBottomColor: themeColorHex,
|
||||
}}
|
||||
>
|
||||
2
|
||||
</Link>
|
||||
<Link to="/" style={{ color: colorMode === "light" ? "black" : "white" }}>
|
||||
»
|
||||
</Link>
|
||||
</Box>
|
||||
)
|
||||
}
|
||||
|
||||
export default Pagination
|
||||
@@ -4,7 +4,7 @@ import { Avatar, BoxProps } from "@chakra-ui/core"
|
||||
interface UserAvatarProps {
|
||||
name: string
|
||||
twitterName?: string
|
||||
size?: undefined | "2xl"
|
||||
size?: undefined | "2xl" | "sm"
|
||||
}
|
||||
|
||||
const UserAvatar: React.FC<UserAvatarProps & BoxProps> = ({
|
||||
|
||||
@@ -11,6 +11,7 @@ const CalendarPage = lazy(() => import("../calendar/CalendarPage"))
|
||||
const MapPlannerPage = lazy(() => import("../plans/MapPlannerPage"))
|
||||
const FreeAgentsPage = lazy(() => import("../freeagents/FreeAgentsPage"))
|
||||
const TeamPage = lazy(() => import("../team/TeamPage"))
|
||||
const XSearch = lazy(() => import("../xsearch/Top500BrowserPage"))
|
||||
const About = lazy(() => import("./About"))
|
||||
const Links = lazy(() => import("./Links"))
|
||||
|
||||
@@ -26,6 +27,7 @@ const Routes: React.FC = () => {
|
||||
<MapPlannerPage path="/plans" />
|
||||
<CalendarPage path="/calendar" />
|
||||
<FreeAgentsPage path="/freeagents" />
|
||||
<XSearch path="/xsearch" />
|
||||
<About path="/about" />
|
||||
<Links path="/links" />
|
||||
<NotFound default />
|
||||
|
||||
@@ -10,27 +10,13 @@ import { IconButton } from "@chakra-ui/core"
|
||||
import { FaTwitter } from "react-icons/fa"
|
||||
import TweetEmbed from "react-tweet-embed"
|
||||
import useBreakPoints from "../../hooks/useBreakPoints"
|
||||
import { ordinal_suffix_of } from "../../utils/helperFunctions"
|
||||
|
||||
interface ResultsProps {
|
||||
results: TournamentResult[]
|
||||
canAddResults: boolean
|
||||
}
|
||||
|
||||
function ordinal_suffix_of(i: number) {
|
||||
var j = i % 10,
|
||||
k = i % 100
|
||||
if (j === 1 && k !== 11) {
|
||||
return "st"
|
||||
}
|
||||
if (j === 2 && k !== 12) {
|
||||
return "nd"
|
||||
}
|
||||
if (j === 3 && k !== 13) {
|
||||
return "rd"
|
||||
}
|
||||
return "th"
|
||||
}
|
||||
|
||||
const Results: React.FC<ResultsProps> = ({ results, canAddResults }) => {
|
||||
const [showModal, setShowModal] = useState(false)
|
||||
const [expandedTweets, setExpandedTweets] = useState<{
|
||||
@@ -39,7 +25,6 @@ const Results: React.FC<ResultsProps> = ({ results, canAddResults }) => {
|
||||
const { grayWithShade } = useContext(MyThemeContext)
|
||||
const isSmall = useBreakPoints(350)
|
||||
|
||||
console.log("results", results)
|
||||
return (
|
||||
<>
|
||||
{showModal && <AddResultModal closeModal={() => setShowModal(false)} />}
|
||||
|
||||
11
frontend-react/src/components/xsearch/Top500BrowserPage.css
Normal file
11
frontend-react/src/components/xsearch/Top500BrowserPage.css
Normal file
@@ -0,0 +1,11 @@
|
||||
tr:nth-child(even) {
|
||||
background-color: rgba(165, 165, 165, 0.15);
|
||||
}
|
||||
|
||||
tr {
|
||||
border-radius: 5px;
|
||||
}
|
||||
|
||||
.responsiveTable tbody tr {
|
||||
border: none;
|
||||
}
|
||||
217
frontend-react/src/components/xsearch/Top500BrowserPage.tsx
Normal file
217
frontend-react/src/components/xsearch/Top500BrowserPage.tsx
Normal file
@@ -0,0 +1,217 @@
|
||||
import React, { useState, useContext } from "react"
|
||||
import { useQuery } from "@apollo/react-hooks"
|
||||
import { useQueryParams, StringParam, NumberParam } from "use-query-params"
|
||||
|
||||
import Loading from "../common/Loading"
|
||||
import Error from "../common/Error"
|
||||
import { SEARCH_FOR_PLACEMENTS } from "../../graphql/queries/searchForPlacements"
|
||||
//import Top500Forms from "./Top500Forms"
|
||||
import WpnImage from "../common/WeaponImage"
|
||||
import { months, modesShort } from "../../utils/lists"
|
||||
import { RouteComponentProps } from "@reach/router"
|
||||
import { Helmet } from "react-helmet-async"
|
||||
import { Box, Flex, Icon } from "@chakra-ui/core"
|
||||
import { Table, Thead, Tbody, Tr, Th, Td } from "react-super-responsive-table"
|
||||
import "react-super-responsive-table/dist/SuperResponsiveTableStyle.css"
|
||||
import { ordinal_suffix_of } from "../../utils/helperFunctions"
|
||||
import { Weapon } from "../../types"
|
||||
import UserAvatar from "../common/UserAvatar"
|
||||
import MyThemeContext from "../../themeContext"
|
||||
import useBreakPoints from "../../hooks/useBreakPoints"
|
||||
import "./Top500BrowserPage.css"
|
||||
import Pagination from "../common/Pagination"
|
||||
|
||||
/*<Icon
|
||||
name={key as any}
|
||||
color={themeColorWithShade}
|
||||
size="5em"
|
||||
/>*/
|
||||
|
||||
interface Placement {
|
||||
id: string
|
||||
mode: number
|
||||
name: string
|
||||
player?: {
|
||||
twitter: string
|
||||
}
|
||||
rank: number
|
||||
unique_id: string
|
||||
weapon: string
|
||||
x_power: number
|
||||
month: number
|
||||
year: number
|
||||
}
|
||||
|
||||
interface SearchForPlacementsData {
|
||||
searchForPlacements: {
|
||||
placements: Placement[]
|
||||
pageCount: number
|
||||
}
|
||||
}
|
||||
|
||||
interface SearchForPlacementsVars {
|
||||
page?: number
|
||||
name?: string
|
||||
weapon?: string
|
||||
mode?: number
|
||||
unique_id?: string
|
||||
month?: number
|
||||
year?: number
|
||||
}
|
||||
|
||||
const Top500BrowserPage: React.FC<RouteComponentProps> = () => {
|
||||
const { themeColorWithShade } = useContext(MyThemeContext)
|
||||
const isSmall = useBreakPoints(640)
|
||||
const [query, setQuery] = useQueryParams({
|
||||
page: NumberParam,
|
||||
name: StringParam,
|
||||
weapon: StringParam,
|
||||
mode: NumberParam,
|
||||
unique_id: StringParam,
|
||||
month: NumberParam,
|
||||
year: NumberParam,
|
||||
})
|
||||
const [forms, setForms] = useState<SearchForPlacementsVars>({
|
||||
page: query.page ?? 1,
|
||||
name: query.name,
|
||||
weapon: query.weapon,
|
||||
mode: query.mode,
|
||||
unique_id: query.unique_id,
|
||||
month: query.month,
|
||||
year: query.year,
|
||||
})
|
||||
|
||||
const { data, error, loading } = useQuery<
|
||||
SearchForPlacementsData,
|
||||
SearchForPlacementsVars
|
||||
>(SEARCH_FOR_PLACEMENTS, {
|
||||
variables: query,
|
||||
})
|
||||
|
||||
const handleClear = () => {
|
||||
setForms({})
|
||||
}
|
||||
|
||||
if (error) return <Error errorMessage={error.message} />
|
||||
if (loading || !data) return <Loading />
|
||||
|
||||
const placements = data.searchForPlacements.placements
|
||||
|
||||
console.log("placements[0]", placements)
|
||||
|
||||
return (
|
||||
<>
|
||||
<Helmet>
|
||||
<title>Top 500 Browser</title>
|
||||
</Helmet>
|
||||
{/*<Box mt="1em">
|
||||
<Top500Forms
|
||||
forms={forms}
|
||||
setForms={setForms}
|
||||
onSubmit={() => setQuery(forms)}
|
||||
onClear={handleClear}
|
||||
/>
|
||||
</Box>*/}
|
||||
<Pagination />
|
||||
<Box textAlign="center">
|
||||
<Table>
|
||||
<Thead>
|
||||
<Tr>
|
||||
<Th>Name</Th>
|
||||
<Th>Weapon</Th>
|
||||
<Th>X Power</Th>
|
||||
<Th>Placement</Th>
|
||||
<Th>Mode</Th>
|
||||
<Th>Month</Th>
|
||||
<Th>Year</Th>
|
||||
</Tr>
|
||||
</Thead>
|
||||
<Tbody>
|
||||
{placements.map(placement => (
|
||||
<Tr key={placement.id}>
|
||||
<Td>
|
||||
<Flex alignItems="center">
|
||||
{placement.player?.twitter && (
|
||||
<UserAvatar
|
||||
name={placement.name}
|
||||
twitterName={placement.player.twitter}
|
||||
size="sm"
|
||||
/>
|
||||
)}
|
||||
<Box
|
||||
as="span"
|
||||
ml={placement.player?.twitter ? "0.5em" : undefined}
|
||||
>
|
||||
{placement.name}
|
||||
</Box>
|
||||
</Flex>
|
||||
</Td>
|
||||
<Td>
|
||||
<Flex alignItems="center">
|
||||
<Box
|
||||
ml={isSmall ? undefined : "auto"}
|
||||
mr={isSmall ? undefined : "auto"}
|
||||
>
|
||||
<WpnImage
|
||||
englishName={placement.weapon as Weapon}
|
||||
size="SMALL"
|
||||
/>
|
||||
</Box>
|
||||
</Flex>
|
||||
</Td>
|
||||
<Td>{placement.x_power}</Td>
|
||||
<Td>
|
||||
{placement.rank}
|
||||
{ordinal_suffix_of(placement.rank)}
|
||||
</Td>
|
||||
<Td>
|
||||
<Icon
|
||||
name={modesShort[placement.mode] as any}
|
||||
color={themeColorWithShade}
|
||||
size="2em"
|
||||
/>
|
||||
</Td>
|
||||
<Td>{months[placement.month]}</Td>
|
||||
<Td>{placement.year}</Td>
|
||||
</Tr>
|
||||
))}
|
||||
</Tbody>
|
||||
</Table>
|
||||
</Box>
|
||||
|
||||
<Pagination />
|
||||
|
||||
{/*<div style={{ margin: "1em 0 1em 0" }}>
|
||||
<Pagination
|
||||
activePage={forms.page}
|
||||
onPageChange={(e, { activePage }) => {
|
||||
setForms({ ...forms, page: activePage })
|
||||
setQuery({ ...query, page: activePage })
|
||||
}}
|
||||
totalPages={data.searchForPlacements.pageCount}
|
||||
firstItem={null}
|
||||
lastItem={null}
|
||||
prevItem={{ content: <Icon name="angle left" />, icon: true }}
|
||||
nextItem={{ content: <Icon name="angle right" />, icon: true }}
|
||||
/>
|
||||
</div>*/}
|
||||
{/*<div style={{ margin: "1em 0 1em 0" }}>
|
||||
<Pagination
|
||||
activePage={forms.page}
|
||||
onPageChange={(e, { activePage }) => {
|
||||
setForms({ ...forms, page: activePage })
|
||||
setQuery({ ...query, page: activePage })
|
||||
window.scrollTo(0, 0)
|
||||
}}
|
||||
totalPages={data.searchForPlacements.pageCount}
|
||||
firstItem={null}
|
||||
lastItem={null}
|
||||
prevItem={{ content: <Icon name="angle left" />, icon: true }}
|
||||
nextItem={{ content: <Icon name="angle right" />, icon: true }}
|
||||
/>
|
||||
</div>*/}
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
export default Top500BrowserPage
|
||||
@@ -1,40 +0,0 @@
|
||||
import { gql } from 'apollo-boost'
|
||||
|
||||
export const searchForPlacements = gql`
|
||||
query searchForPlacements(
|
||||
$name: String
|
||||
$weapon: String
|
||||
$mode: Int
|
||||
$unique_id: String
|
||||
$month: Int
|
||||
$year: Int
|
||||
$page: Int
|
||||
) {
|
||||
searchForPlacements(
|
||||
name: $name
|
||||
weapon: $weapon
|
||||
mode: $mode
|
||||
unique_id: $unique_id
|
||||
month: $month
|
||||
year: $year
|
||||
page: $page
|
||||
) {
|
||||
placements {
|
||||
name
|
||||
x_power
|
||||
weapon
|
||||
rank
|
||||
id
|
||||
unique_id
|
||||
month
|
||||
year
|
||||
mode
|
||||
player {
|
||||
twitter
|
||||
}
|
||||
}
|
||||
pageCount
|
||||
}
|
||||
}
|
||||
|
||||
`
|
||||
39
frontend-react/src/graphql/queries/searchForPlacements.ts
Normal file
39
frontend-react/src/graphql/queries/searchForPlacements.ts
Normal file
@@ -0,0 +1,39 @@
|
||||
import { gql, DocumentNode } from "apollo-boost"
|
||||
|
||||
export const SEARCH_FOR_PLACEMENTS: DocumentNode = gql`
|
||||
query searchForPlacements(
|
||||
$name: String
|
||||
$weapon: String
|
||||
$mode: Int
|
||||
$unique_id: String
|
||||
$month: Int
|
||||
$year: Int
|
||||
$page: Int
|
||||
) {
|
||||
searchForPlacements(
|
||||
name: $name
|
||||
weapon: $weapon
|
||||
mode: $mode
|
||||
unique_id: $unique_id
|
||||
month: $month
|
||||
year: $year
|
||||
page: $page
|
||||
) {
|
||||
placements {
|
||||
name
|
||||
x_power
|
||||
weapon
|
||||
rank
|
||||
id
|
||||
unique_id
|
||||
month
|
||||
year
|
||||
mode
|
||||
player {
|
||||
twitter
|
||||
}
|
||||
}
|
||||
pageCount
|
||||
}
|
||||
}
|
||||
`
|
||||
1
frontend-react/src/react-app-env.d.ts
vendored
1
frontend-react/src/react-app-env.d.ts
vendored
@@ -6,3 +6,4 @@ declare module "*.png" {
|
||||
}
|
||||
|
||||
declare module "@sendou/react-sketch"
|
||||
declare module "react-super-responsive-table"
|
||||
|
||||
@@ -2,3 +2,18 @@ export function choose(choices: any[]) {
|
||||
var index = Math.floor(Math.random() * choices.length)
|
||||
return choices[index]
|
||||
}
|
||||
|
||||
export function ordinal_suffix_of(i: number) {
|
||||
var j = i % 10,
|
||||
k = i % 100
|
||||
if (j === 1 && k !== 11) {
|
||||
return "st"
|
||||
}
|
||||
if (j === 2 && k !== 12) {
|
||||
return "nd"
|
||||
}
|
||||
if (j === 3 && k !== 13) {
|
||||
return "rd"
|
||||
}
|
||||
return "th"
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user