From 17cb91cd8790e3b190f2ac5f802449cd8d6f4216 Mon Sep 17 00:00:00 2001 From: Sendou Date: Mon, 6 Jan 2020 02:36:12 +0200 Subject: [PATCH] voting summary frontend --- .../src/components/common/Loading.js | 4 +- .../src/components/common/UserAvatar.js | 4 +- frontend-react/src/components/plus/PlusFAQ.js | 2 +- .../src/components/plus/SummaryLists.js | 59 +++++++++++ .../src/components/plus/VotingHistory.js | 98 +++++++++++++++++++ .../src/components/root/MainMenu.js | 7 +- frontend-react/src/components/root/Routes.js | 12 ++- .../src/graphql/queries/summaries.js | 4 + .../src/graphql/queries/userLean.js | 1 + graphql-schemas/plus.js | 6 +- package-lock.json | 6 +- package.json | 2 +- 12 files changed, 190 insertions(+), 15 deletions(-) create mode 100644 frontend-react/src/components/plus/SummaryLists.js create mode 100644 frontend-react/src/components/plus/VotingHistory.js diff --git a/frontend-react/src/components/common/Loading.js b/frontend-react/src/components/common/Loading.js index d6b6acce5..ab233ed7c 100644 --- a/frontend-react/src/components/common/Loading.js +++ b/frontend-react/src/components/common/Loading.js @@ -1,10 +1,10 @@ import React from "react" import { Loader } from "semantic-ui-react" -const Loading = ({ minHeight = "500px" }) => { +const Loading = ({ inverted = false, minHeight = "500px" }) => { return (
- + Loading
diff --git a/frontend-react/src/components/common/UserAvatar.js b/frontend-react/src/components/common/UserAvatar.js index 036dbbc75..c5ab9d89b 100644 --- a/frontend-react/src/components/common/UserAvatar.js +++ b/frontend-react/src/components/common/UserAvatar.js @@ -1,9 +1,11 @@ import React, { useState } from "react" import { Image } from "semantic-ui-react" -const UserAvatar = ({ twitterName }) => { +const UserAvatar = ({ twitterName, paddingIfNull = false }) => { const [imageError, setImageError] = useState(false) + if ((!twitterName || imageError) && paddingIfNull) + return if (!twitterName || imageError) return null return ( diff --git a/frontend-react/src/components/plus/PlusFAQ.js b/frontend-react/src/components/plus/PlusFAQ.js index 6ad50f5f9..51e406e24 100644 --- a/frontend-react/src/components/plus/PlusFAQ.js +++ b/frontend-react/src/components/plus/PlusFAQ.js @@ -101,7 +101,7 @@ const PlusFAQ = () => {
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%. + to join a server. For +1 members this ratio is 90% and for +2 80%. +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. diff --git a/frontend-react/src/components/plus/SummaryLists.js b/frontend-react/src/components/plus/SummaryLists.js new file mode 100644 index 000000000..0f185ced3 --- /dev/null +++ b/frontend-react/src/components/plus/SummaryLists.js @@ -0,0 +1,59 @@ +import React from "react" +import UserAvatar from "../common/UserAvatar" +import { List, Icon, Popup } from "semantic-ui-react" + +const getColor = score => (score < 50 ? { color: "red" } : { color: "green" }) + +const summaryMap = summary => { + console.log("summary", summary) + const { discord_user, score } = summary + return ( + + + + + {discord_user.username}#{discord_user.discriminator}{" "} + + + + {score.total}% + {" "} + (EU {score.eu}% | NA{" "} + {score.na}%) + {summary.vouched && ( + } + /> + )} + + + + ) +} + +const SummaryLists = ({ summaries }) => { + console.log("summaries", summaries) + const members = [] + const suggested = [] + + summaries.forEach(summary => { + if (summary.suggested) suggested.push(summary) + else members.push(summary) + }) + return ( + <> + {members.map(summaryMap)} +

Suggested

+ {suggested.map(summaryMap)} + + ) +} + +export default SummaryLists diff --git a/frontend-react/src/components/plus/VotingHistory.js b/frontend-react/src/components/plus/VotingHistory.js new file mode 100644 index 000000000..19de169de --- /dev/null +++ b/frontend-react/src/components/plus/VotingHistory.js @@ -0,0 +1,98 @@ +import React, { useState, useEffect } from "react" +import { summaries } from "../../graphql/queries/summaries" +import { useQuery } from "@apollo/react-hooks" +import Loading from "../common/Loading" +import { userLean } from "../../graphql/queries/userLean" +import { Redirect } from "react-router-dom" +import Error from "../common/Error" +import { Dropdown } from "semantic-ui-react" +import { months } from "../../utils/lists" +import SummaryLists from "./SummaryLists" + +const VotingHistory = () => { + const { data, loading, error } = useQuery(summaries) + const [monthChoices, setMonthChoices] = useState([]) + const [forms, setForms] = useState({}) + const { + data: userData, + error: userQueryError, + loading: userQueryLoading, + } = useQuery(userLean) + + useEffect(() => { + if (loading || error || userQueryLoading || userQueryError) return + + const monthsYears = data.summaries.reduce( + (acc, cur) => { + const { month, year } = cur + if (!acc.contains[year]) acc.contains[year] = {} + if (!acc.contains[year][month]) { + acc.contains[year][month] = true + const monthString = `${months[month]} ${year}` + acc.monthChoices.push({ + key: monthString, + text: monthString, + value: monthString, + }) + } + return acc + }, + { contains: {}, monthChoices: [] } + ).monthChoices + + setForms({ + plus_server: + userData.user.plus.membership_status === "ONE" ? "ONE" : "TWO", + monthYear: monthsYears[0].value, + }) + setMonthChoices(monthsYears) + }, [data, loading, error, userQueryLoading, userQueryError, userData]) + + if (loading || userQueryLoading || monthChoices.length === 0) + return + if (error) return + if (userQueryError) return + if (!userData.user) return + if (!data.summaries) return + + const parts = forms.monthYear.split(" ") + const month = months.indexOf(parts[0]) + const year = parseInt(parts[1]) + return ( + <> + {userData.user.plus.membership_status === "ONE" && ( + + setForms({ ...forms, plus_server: value }) + } + options={["ONE", "TWO"].map(plus_server => ({ + key: plus_server, + text: plus_server === "ONE" ? "+1" : "+2", + value: plus_server, + }))} + style={{ margin: "0 1em 1em 0" }} + /> + )} + setForms({ ...forms, monthYear: value })} + options={monthChoices} + /> + { + + summary.month === month && + summary.year === year && + summary.plus_server === forms.plus_server + )} + /> + } + + ) +} + +export default VotingHistory diff --git a/frontend-react/src/components/root/MainMenu.js b/frontend-react/src/components/root/MainMenu.js index 07d691240..402e449dc 100644 --- a/frontend-react/src/components/root/MainMenu.js +++ b/frontend-react/src/components/root/MainMenu.js @@ -134,7 +134,8 @@ const MainMenu = () => { - {data?.user?.plus?.membership_status && ( + {(data?.user?.plus?.membership_status || + data?.user?.plus?.vouch_status) && ( { FAQ - {/* + Voting History - */} + )} diff --git a/frontend-react/src/components/root/Routes.js b/frontend-react/src/components/root/Routes.js index f46e33b1a..58ea5b6e3 100644 --- a/frontend-react/src/components/root/Routes.js +++ b/frontend-react/src/components/root/Routes.js @@ -24,6 +24,7 @@ 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 VotingHistory = lazy(() => import("../plus/VotingHistory")) const UserPage = lazy(() => import("../user/UserPage")) const InfoPage = lazy(() => import("./InfoPage")) const AdminPanel = lazy(() => import("../admin/AdminPanel")) @@ -31,7 +32,7 @@ const PleaseLogIn = lazy(() => import("../common/PleaseLogIn")) const Routes = () => { return ( - }> + }> @@ -170,6 +171,15 @@ const Routes = () => { + + + + + { - if (!ctx.user || !ctx.user.plus || ctx.user.plus.membership_status) + if (!ctx.user || !ctx.user.plus || !ctx.user.plus.membership_status) return null const searchCriteria = ctx.user.plus.membership_status === "ONE" ? {} : { plus_server: "TWO" } return Summary.find(searchCriteria) .populate("discord_user") - .sort({ "score.total": "desc" }) + .sort({ "score.total": "desc", year: "desc", month: "desc" }) }, }, Mutation: { @@ -677,7 +677,7 @@ const resolvers = { ) } else if ( arrays_plus_server === "TWO" && - total_score >= 85 && + total_score >= 80 && !can_not_vouch ) { userUpdates.push(() => diff --git a/package-lock.json b/package-lock.json index 1ba06df29..3c6378223 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1610,9 +1610,9 @@ } }, "mongoose": { - "version": "5.8.3", - "resolved": "https://registry.npmjs.org/mongoose/-/mongoose-5.8.3.tgz", - "integrity": "sha512-WnO4WJ8eZ5Hgwp11Gl2dOxkWYJe8xV7oCqDV3ZbTA7j2q1prc0lPWAd9ZK5R6OhQlp55CleEZXqXUPrZnjSEDQ==", + "version": "5.8.4", + "resolved": "https://registry.npmjs.org/mongoose/-/mongoose-5.8.4.tgz", + "integrity": "sha512-jQjLckUILEQUqBuG+ihjtA9OLmrqcIG5n+vaeHpR++TG8/ug5yy5ogkDnybTSq8Ql5OORud3+OCOc2Uw96q32w==", "requires": { "bson": "~1.1.1", "kareem": "2.3.1", diff --git a/package.json b/package.json index 2891b7096..d020940e4 100644 --- a/package.json +++ b/package.json @@ -23,7 +23,7 @@ "express-session": "^1.17.0", "graphql": "^14.5.8", "lodash": "^4.17.15", - "mongoose": "^5.8.3", + "mongoose": "^5.8.4", "mongoose-unique-validator": "^2.0.3", "node-fetch": "^2.6.0", "passport": "^0.4.1",