page titles

This commit is contained in:
Sendou 2020-01-04 18:08:04 +02:00
parent 36c99c7966
commit 4d68d397aa
8 changed files with 313 additions and 40 deletions

View File

@ -35,7 +35,7 @@ const BuildsBrowser = () => {
if (error) return <Error errorMessage={error.message} />
return (
<>
<Header as="h2">
<Header as="h3">
{weapon ? (
<>
<WpnImage weapon={weapon} /> {weapon} Builds

View File

@ -15,8 +15,8 @@ const Links = () => {
return (
<>
<div style={{ padding: "5px" }}>
<div style={{ paddingTop: "10px" }}>
<div>
<div>
<Header as="h1">
<Icon name="discord" />
<Header.Content>Discord</Header.Content>

View File

@ -0,0 +1,115 @@
import React, { useState } from "react"
import { Accordion, Icon } from "semantic-ui-react"
const PlusFAQ = () => {
const [active, setActive] = useState(-1)
const handleClick = (e, titleProps) => {
const { index } = titleProps
const newIndex = active === index ? -1 : index
setActive(newIndex)
}
return (
<>
<Accordion>
<Accordion.Title active={active === 0} index={0} onClick={handleClick}>
<Icon name="dropdown" />
<h4 style={{ display: "inline", userSelect: "none" }}>
What are +1 and +2?
</h4>
</Accordion.Title>
<Accordion.Content active={active === 0}>
<div style={{ marginLeft: "1.5em" }}>
They are private Splatoon 2 Discord servers made for LFG purposes.
Typically people use them to find pick-ups to play with, a team to
play against in a scrim or just general chatting. All +1 members
have access to +2 but not the other way around.
</div>
</Accordion.Content>
<Accordion.Title active={active === 1} index={1} onClick={handleClick}>
<Icon name="dropdown" />
<h4 style={{ display: "inline", userSelect: "none" }}>
How can I join?
</h4>
</Accordion.Title>
<Accordion.Content active={active === 1}>
<div style={{ marginLeft: "1.5em" }}>
There are two ways to join:
<ul>
<li>
Get suggested by someone already in the server and pass the
monthly voting
</li>
<li>Get vouched by someone who is eligible to do so</li>
</ul>
</div>
</Accordion.Content>
<Accordion.Title active={active === 2} index={2} onClick={handleClick}>
<Icon name="dropdown" />
<h4 style={{ display: "inline", userSelect: "none" }}>
What is the voting?
</h4>
</Accordion.Title>
<Accordion.Content active={active === 2}>
<div style={{ marginLeft: "1.5em" }}>
Every month (first weekend starting on Friday) a voting is held on
each server to decide the roster. The members vote on each other as
well as any new suggestions. You need to get 50% or better to get
access or stay in the server.
</div>
</Accordion.Content>
<Accordion.Title active={active === 3} index={3} onClick={handleClick}>
<Icon name="dropdown" />
<h4 style={{ display: "inline", userSelect: "none" }}>
How is the percentage calculated in the voting?
</h4>
</Accordion.Title>
<Accordion.Content active={active === 3}>
<div style={{ marginLeft: "1.5em" }}>
Best score you can get is everyone of your own region giving you +2
and of the opposite region giving you +1. This would translate to
100%. Similarly 0% would mean everyone gave you the worst possible
score. Example of 50% could be a situation where you got -0.5 from
your own region but +0.5 from the opposite.
</div>
</Accordion.Content>
<Accordion.Title active={active === 4} index={4} onClick={handleClick}>
<Icon name="dropdown" />
<h4 style={{ display: "inline", userSelect: "none" }}>
Why can I only give +1 or -1 to members of the opposite region?
</h4>
</Accordion.Title>
<Accordion.Content active={active === 4}>
<div style={{ marginLeft: "1.5em" }}>
This is because due to time zones you typically play the most with
people living close to your own time zones so you have a better idea
about those players. The idea is that you have more of a say about
people who you regularly play with. Of course there are exceptions
and people might play at odd hours (and indeed not everyone lives in
Europe or the Americas) but through testing we noticed this system
gives better results.
</div>
</Accordion.Content>
<Accordion.Title active={active === 5} index={5} onClick={handleClick}>
<Icon name="dropdown" />
<h4 style={{ display: "inline", userSelect: "none" }}>
How does the vouching work?
</h4>
</Accordion.Title>
<Accordion.Content active={active === 5}>
<div style={{ marginLeft: "1.5em" }}>
If you got a high score in the latest voting you can vouch someone
to join a server. For +1 members this ratio is 90% and for +2 85%.
+1 members can choose to vouch someone to either +1 or +2. If the
person you vouched gets kicked in their first voting you can't vouch
anyone for 6 months.
</div>
</Accordion.Content>
</Accordion>
</>
)
}
export default PlusFAQ

View File

@ -9,16 +9,7 @@ const App = () => {
<div style={{ paddingTop: "0.3em" }}>
<MainMenu />
<Container>
<div
style={{
background: "white",
padding: "2em 3em",
margin: "0 -2em 0 -2em",
borderRadius: "7px",
}}
>
<Routes />
</div>
<Routes />
</Container>
<Footer />
</div>

View File

@ -135,9 +135,22 @@ const MainMenu = () => {
</Dropdown.Menu>
</Dropdown>
{data?.user?.plus?.membership_status && (
<Menu.Item as={NavLink} to="/plus">
{data.user.plus.membership_status === "ONE" ? "+1" : "+2"}
</Menu.Item>
<Dropdown
item
text={data.user.plus.membership_status === "ONE" ? "+1" : "+2"}
>
<Dropdown.Menu style={dropdownStyle}>
<Dropdown.Item as={NavLink} exact to="/plus">
Home
</Dropdown.Item>
<Dropdown.Item as={NavLink} to="/plus/faq">
FAQ
</Dropdown.Item>
{/*<Dropdown.Item as={NavLink} to="/plus/history">
Voting History
</Dropdown.Item>*/}
</Dropdown.Menu>
</Dropdown>
)}
{logInOrAva()}
</Container>

View File

@ -0,0 +1,31 @@
import React from "react"
import { Header, Icon } from "semantic-ui-react"
const Page = ({ title, subtitle, icon, children }) => {
return (
<div
style={{
background: "white",
padding: "2em 3em",
margin: "0 -2em 0 -2em",
borderRadius: "7px",
}}
>
<div>
{title && !subtitle && <Header as="h3">{title}</Header>}
{title && subtitle && (
<Header as="h2">
{icon && <Icon name={icon} />}
<Header.Content>
{title}
<Header.Subheader>{subtitle}</Header.Subheader>
</Header.Content>
</Header>
)}
</div>
<div style={{ marginTop: !title ? null : "1.5em" }}>{children}</div>
</div>
)
}
export default Page

View File

@ -2,6 +2,7 @@ import React, { Suspense, lazy } from "react"
import { Route, Switch } from "react-router-dom"
import Loading from "../common/Loading"
import NotFound from "../common/NotFound"
import Page from "./Page"
const HomePage = lazy(() => import("../root/HomePage"))
const MapListGenerator = lazy(() => import("../maps/MapListGenerator"))
@ -22,6 +23,7 @@ const TournamentSearchPage = lazy(() =>
const BuildsBrowser = lazy(() => import("../builds/BuildsBrowser"))
const FreeAgentBrowser = lazy(() => import("../freeagents/FreeAgentBrowser"))
const PlusPage = lazy(() => import("../plus/PlusPage"))
const PlusFAQ = lazy(() => import("../plus/PlusFAQ"))
const UserPage = lazy(() => import("../user/UserPage"))
const InfoPage = lazy(() => import("./InfoPage"))
const AdminPanel = lazy(() => import("../admin/AdminPanel"))
@ -32,64 +34,177 @@ const Routes = () => {
<Suspense fallback={<Loading />}>
<Switch>
<Route exact path="/">
<HomePage />
<Page>
<HomePage />
</Page>
</Route>
<Route path="/maps">
<MapListGenerator />
<Page
title="Map list generator"
subtitle="Generate a map list to use while scrimming. Use exactly the map pool you are practicing right now. Also check out the .maps command with Lohi on Discord!"
icon="sync"
>
<MapListGenerator />
</Page>
</Route>
<Route path="/rotation">
<Rotations />
<Page
title="Rotations"
subtitle="Current and upcoming solo queue and league battle rotations. Also check out the .rot command with Lohi on Discord!"
icon="sync"
>
<Rotations />
</Page>
</Route>
<Route path="/plans">
<MapPlanner />
<Page
title="Map planner"
subtitle="Draw on maps with various tools and make your perfect battle plan."
icon="pencil square"
>
<MapPlanner />
</Page>
</Route>
<Route path="/calendar">
<Calendar />
<Page
title="Competitive calendar"
subtitle="Upcoming events around competitive Splatoon. Managed by Kbot."
icon="calendar alternate"
>
<Calendar />
</Page>
</Route>
<Route path="/links">
<Links />
<Page
title="Links"
subtitle="Useful Splatoon resources from all over."
icon="linkify"
>
<Links />
</Page>
</Route>
<Route path="/xleaderboard">
<XLeaderboard />
<Page
title="X Rank leaderboards"
subtitle="Best players of X Rank by weapon class. Criteria used is top 4 X Powers."
icon="chess king"
>
<XLeaderboard />
</Page>
</Route>
<Route exact path="/xsearch">
<Top500Browser />
<Page
title="X Rank search"
subtitle="Browser through all the X Rank top 500 placements of the past with whatever filter you can think of."
icon="list"
>
<Top500Browser />
</Page>
</Route>
<Route path="/xsearch/p/:uid">
<PlayerXRankStats />
<Page>
<PlayerXRankStats />
</Page>
</Route>
<Route path="/trends">
<XTrends />
<Page
title="X Rank trends"
subtitle="Compare weapons based on their X Rank top 500 appearances. Combine weapons to see for example how the popularity of blasters as a class has changed over time."
icon="line graph"
>
<XTrends />
</Page>
</Route>
<Route exact path="/tournaments">
<TournamentSearchPage />
<Page
title="Tournaments"
subtitle="Browser through tournaments of the past. Search for a team comp to see how it has fared in the past. Find your favorite player or team."
icon="trophy"
>
<TournamentSearchPage />
</Page>
</Route>
<Route path="/tournaments/:id">
<TournamentDetailsPage />
<Page title="Tournaments" subtitle="" icon="th">
<TournamentDetailsPage />
</Page>
</Route>
<Route path="/builds">
<BuildsBrowser />
<Page
title="Builds"
subtitle="Search for a weapon and find out what kind of builds people are running. Players who have reached top 500 with the weapon in question are listed first."
icon="th"
>
<BuildsBrowser />
</Page>
</Route>
<Route path="/freeagents">
<FreeAgentBrowser />
<Page
title="Free agents"
subtitle="Discover the next best teammate of yours! Currently not in a team? Don't hesitate to make a free agent post."
icon="spy"
>
<FreeAgentBrowser />
</Page>
</Route>
<Route path="/u/:id">
<UserPage />
<Page>
<UserPage />
</Page>
</Route>
<Route path="/plus">
<PlusPage />
<Route exact path="/plus">
<Page
title="Plus servers home"
subtitle="Grab a link to rejoin the server. Suggest or vouch new players. Vote in the monthly votings."
icon="plus"
>
<PlusPage />
</Page>
</Route>
<Route exact path="/plus/faq">
<Page
title="Plus servers FAQ"
subtitle="Answering questions you might have about the plus servers. Feel free to ask if the below leaves you wondering."
icon="question circle"
>
<PlusFAQ />
</Page>
</Route>
<Route path="/about">
<InfoPage />
<Page
title="Information about this website"
subtitle="Thank you for visiting sendou.ink! Special shout-outs to the people below who helped in making this site."
icon="info"
>
<InfoPage />
</Page>
</Route>
<Route path="/admin">
<AdminPanel />
<Page>
<AdminPanel />
</Page>
</Route>
<Route path="/access">
<PleaseLogIn />
<Page>
<PleaseLogIn />
</Page>
</Route>
<Route path="/404" render={() => <NotFound />} />
<Route path="*" render={() => <NotFound />} />
<Route
path="/404"
render={() => (
<Page>
<NotFound />
</Page>
)}
/>
<Route
path="*"
render={() => (
<Page>
<NotFound />
</Page>
)}
/>
</Switch>
</Suspense>
)

View File

@ -202,7 +202,7 @@ const resolvers = {
votedIds.add(vote.voter_discord_id)
})
const users = await User.find({
const eligible_voters = await User.countDocuments({
"plus.membership_status": ctx.user.plus.membership_status,
})
@ -212,7 +212,7 @@ const resolvers = {
plus_two_invite_link: process.env.PLUS_TWO_LINK,
voting_ends: state.voting_ends,
voter_count: votedIds.size,
eligible_voters: users.length,
eligible_voters,
}
},
usersForVoting: async (root, args, ctx) => {
@ -440,6 +440,14 @@ const resolvers = {
if (!ctx.user) throw new AuthenticationError("Not logged in.")
if (ctx.user.discord_id !== process.env.ADMIN_ID)
throw new AuthenticationError("Not admin.")
const date = new Date()
const year = date.getFullYear()
const month = date.getMonth() + 1
const votes = await VotedPerson.find({
month,
year,
})
},
},
}