mirror of
https://github.com/Sendouc/sendou.ink.git
synced 2026-06-03 06:35:42 -05:00
page titles
This commit is contained in:
parent
36c99c7966
commit
4d68d397aa
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
115
frontend-react/src/components/plus/PlusFAQ.js
Normal file
115
frontend-react/src/components/plus/PlusFAQ.js
Normal 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
|
||||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
31
frontend-react/src/components/root/Page.js
Normal file
31
frontend-react/src/components/root/Page.js
Normal 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
|
||||
|
|
@ -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>
|
||||
)
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
})
|
||||
},
|
||||
},
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user