builds browsers done

This commit is contained in:
Sendou
2019-11-09 17:07:15 +02:00
parent 0a8f642836
commit 24604d3780
6 changed files with 976 additions and 714 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -3,19 +3,20 @@
"version": "0.1.0",
"private": true,
"dependencies": {
"@apollo/react-hooks": "^3.1.1",
"@apollo/react-hooks": "^3.1.3",
"apollo-boost": "^0.4.4",
"graphql": "^14.5.8",
"jstz": "^2.1.1",
"react": "^16.10.1",
"react": "^16.11.0",
"react-color": "^2.17.3",
"react-dom": "^16.10.1",
"react-dom": "^16.11.0",
"react-router-dom": "^5.1.2",
"react-scripts": "3.1.2",
"react-scripts": "^3.2.0",
"react-sketch": "^0.5.1",
"recharts": "^1.7.1",
"recharts": "^1.8.5",
"semantic-ui-css": "^2.4.1",
"semantic-ui-react": "^0.88.1"
"semantic-ui-react": "^0.88.1",
"use-query-params": "^0.4.3"
},
"scripts": {
"start": "react-scripts start",

View File

@@ -1,44 +1,27 @@
import React, { useState, useEffect } from "react"
import { useLocation } from "react-router-dom"
import useUrlParamQuery from "../../hooks/useUrlParamQuery"
import React from "react"
import { useQuery } from "@apollo/react-hooks"
import { useQueryParams, StringParam, NumberParam } from "use-query-params"
import WeaponDropdown from "../common/WeaponDropdown"
import { searchForBuildsByWeapon } from "../../graphql/queries/searchForBuildsByWeapon"
import Loading from "../common/Loading"
import Error from "../common/Error"
import { Card, Header } from "semantic-ui-react"
import { Card, Header, Pagination, Icon } from "semantic-ui-react"
import BuildCard from "../common/BuildCard"
import WpnImage from "../common/WpnImage"
const BuildsBrowser = () => {
const location = useLocation()
const weaponFromUrl = () => {
const searchParams = new URLSearchParams(location.search)
if (searchParams.has("weapon")) return searchParams.get("weapon")
return ""
}
const [weapon, setWeapon] = useState(weaponFromUrl())
console.log("weapon", weapon)
const { data, error, loading, filter, fireQuery } = useUrlParamQuery(
searchForBuildsByWeapon,
{
weapon
}
)
const handleFormChange = (e, { value }) => {
setWeapon(value)
fireQuery({ ...filter, weapon: value })
}
useEffect(() => {
if (!weapon) document.title = "Builds - sendou.ink"
document.title = `${weapon} Builds - sendou.ink`
}, [weapon])
const [query, setQuery] = useQueryParams({
weapon: StringParam,
page: NumberParam
})
const { page = 1, weapon } = query
const { data, error, loading } = useQuery(searchForBuildsByWeapon, {
variables: query
})
const weaponsList = () => {
if (loading || !data) return <Loading />
if (loading) return <Loading />
if (error) return <Error errorMessage={error.message} />
console.log("data", data)
return (
<>
<Header as="h2">
@@ -50,18 +33,40 @@ const BuildsBrowser = () => {
<>Latest Builds</>
)}
</Header>
<Pagination
activePage={page}
onPageChange={(e, { activePage }) => setQuery({ page: activePage })}
totalPages={data.searchForBuildsByWeapon.pageCount}
firstItem={null}
lastItem={null}
prevItem={{ content: <Icon name="angle left" />, icon: true }}
nextItem={{ content: <Icon name="angle right" />, icon: true }}
/>
<Card.Group style={{ marginTop: "1em" }}>
{data.searchForBuildsByWeapon.builds.map(build => {
return <BuildCard key={build.id} build={build} showWeapon={false} />
})}
</Card.Group>
<Pagination
style={{ marginTop: "1.5em" }}
activePage={page}
onPageChange={(e, { activePage }) => setQuery({ page: activePage })}
totalPages={data.searchForBuildsByWeapon.pageCount}
firstItem={null}
lastItem={null}
prevItem={{ content: <Icon name="angle left" />, icon: true }}
nextItem={{ content: <Icon name="angle right" />, icon: true }}
/>
</>
)
}
return (
<>
<WeaponDropdown value={filter.weapon} onChange={handleFormChange} />
<WeaponDropdown
value={weapon}
onChange={(e, { value }) => setQuery({ weapon: value, page: 1 })}
/>
<div style={{ marginTop: "1em" }}>{weaponsList()}</div>
</>
)

View File

@@ -1,7 +1,7 @@
import { gql } from "apollo-boost"
export const searchForBuildsByWeapon = gql`
query searchForBuildsByWeapon($weapon: String!, $page: Int) {
query searchForBuildsByWeapon($weapon: String, $page: Int) {
searchForBuildsByWeapon(weapon: $weapon, page: $page) {
builds {
id

11
react-ui/src/index.js vendored
View File

@@ -3,8 +3,9 @@ import ReactDOM from "react-dom"
import App from "./components/root/App"
import * as serviceWorker from "./serviceWorker"
import { ApolloProvider } from "@apollo/react-hooks"
import { QueryParamProvider } from "use-query-params"
import ApolloClient from "apollo-boost"
import { BrowserRouter as Router } from "react-router-dom"
import { BrowserRouter as Router, Route } from "react-router-dom"
import "semantic-ui-css/semantic.min.css"
import "./index.css"
@@ -18,9 +19,11 @@ const client = new ApolloClient({
ReactDOM.render(
<Router>
<ApolloProvider client={client}>
<App />
</ApolloProvider>
<QueryParamProvider ReactRouterRoute={Route}>
<ApolloProvider client={client}>
<App />
</ApolloProvider>
</QueryParamProvider>
</Router>,
document.getElementById("root")
)

View File

@@ -12,7 +12,8 @@ const gear = require("../utils/gear")
const typeDef = gql`
extend type Query {
searchForBuilds(discord_id: String!): [Build]!
searchForBuildsByWeapon(weapon: String!, page: Int): BuildCollection!
"Returns builds by given weapon. If weapon is omitted returns latest builds instead."
searchForBuildsByWeapon(weapon: String, page: Int): BuildCollection!
}
extend type Mutation {
addBuild(
@@ -101,15 +102,14 @@ const resolvers = {
})
},
searchForBuildsByWeapon: async (root, args) => {
const buildsPerPage = 20
const buildsPerPage = 18
const currentPage = args.page ? args.page - 1 : 0
const searchCriteria = { weapon: args.weapon }
const searchCriteria = !args.weapon ? {} : { weapon: args.weapon }
const buildCount = await Build.countDocuments(searchCriteria).catch(e => {
throw new UserInputError(e.message, {
invalidArgs: args
})
})
const pageCount = Math.ceil(buildCount / buildsPerPage)
// if 0 documents we don't care if the page is wrong
if (buildCount !== 0) {
@@ -122,7 +122,7 @@ const resolvers = {
const builds = await Build.find(searchCriteria)
.skip(buildsPerPage * currentPage)
.limit(buildsPerPage)
.sort({ top: "desc", updatedAt: "desc" })
.sort({ top: !args.weapon ? null : "desc", updatedAt: "desc" })
.populate("discord_user")
.catch(e => {
throw new UserInputError(e.message, {