From 60f63a1df368ae7797d9b2931cc479aef6bd9e1b Mon Sep 17 00:00:00 2001 From: Sendou Date: Wed, 8 Jan 2020 14:49:51 +0200 Subject: [PATCH] vouching frontend --- .../src/components/plus/PlusPage.js | 2 +- .../src/components/plus/SuggestionForm.js | 125 +++++++++++++----- .../src/components/plus/Suggestions.js | 58 +++++++- .../src/graphql/mutations/addVouch.js | 7 + .../src/graphql/queries/userLean.js | 2 + frontend-react/src/graphql/queries/vouches.js | 20 +++ graphql-schemas/plus.js | 12 ++ mongoose-models/user.js | 7 + 8 files changed, 198 insertions(+), 35 deletions(-) create mode 100644 frontend-react/src/graphql/mutations/addVouch.js create mode 100644 frontend-react/src/graphql/queries/vouches.js diff --git a/frontend-react/src/components/plus/PlusPage.js b/frontend-react/src/components/plus/PlusPage.js index 7aec12b7c..001f87d02 100644 --- a/frontend-react/src/components/plus/PlusPage.js +++ b/frontend-react/src/components/plus/PlusPage.js @@ -38,7 +38,7 @@ const getAction = (success, onClick) => { } const PlusPage = () => { - const [showSuggestionForm, setShowSuggestionForm] = useState(false) + const [showSuggestionForm, setShowSuggestionForm] = useState(true) const plusOneRef = useRef(null) const [plusOneCopySuccess, setPlusOneCopySuccess] = useState(false) const plusTwoRef = useRef(null) diff --git a/frontend-react/src/components/plus/SuggestionForm.js b/frontend-react/src/components/plus/SuggestionForm.js index 735c503c3..9949fb4dd 100644 --- a/frontend-react/src/components/plus/SuggestionForm.js +++ b/frontend-react/src/components/plus/SuggestionForm.js @@ -7,15 +7,20 @@ import UserSearch from "../common/UserSearch" import TextAreaWithLimit from "../common/TextAreaWithLimit" import { addSuggestion } from "../../graphql/mutations/addSuggestion" import { suggestions } from "../../graphql/queries/suggestions" +import { vouches } from "../../graphql/queries/vouches" +import { addVouch } from "../../graphql/mutations/addVouch" const SuggestionForm = ({ plusServer, hideForm, handleSuccess, handleError, + canSuggest, + canVouch, + canVouchFor, }) => { const [selectedUser, setSelectedUser] = useState(null) - const [form, setForm] = useState({}) + const [form, setForm] = useState({ type: !canSuggest ? "VOUCH" : "SUGGEST" }) const [addSuggestionMutation] = useMutation(addSuggestion, { onError: handleError, @@ -27,19 +32,61 @@ const SuggestionForm = ({ ], }) + const [addVouchMutation] = useMutation(addVouch, { + onError: handleError, + onCompleted: () => + handleSuccess( + "Vouch successfully added. Let them know and send them an invite link to the server!" + ), + refetchQueries: [ + { + query: vouches, + }, + ], + }) + const handleSubmit = async event => { event.preventDefault() - await addSuggestionMutation({ - variables: { ...form, discord_id: selectedUser.id }, - }) + if (form.type === "SUGGEST") { + await addSuggestionMutation({ + variables: { ...form, discord_id: selectedUser.id }, + }) + } else { + await addVouchMutation({ + variables: { ...form, discord_id: selectedUser.id }, + }) + } } + console.log("CanVouchFor", canVouchFor) + return ( <> {selectedUser ? (
+ + + setForm({ type: "SUGGEST" })} + /> + + + setForm({ type: "VOUCH" })} + /> + + -

Suggesting

+ {form.type === "SUGGEST" &&

Suggesting

} + {form.type === "VOUCH" &&

Vouching

}
@@ -53,11 +100,7 @@ const SuggestionForm = ({ {selectedUser.description && (
- + setForm({ ...form, server: "ONE" })} @@ -91,6 +137,11 @@ const SuggestionForm = ({ + + If the player doesn't live in either Europe or The Americas you + can choose the region based on who they are playing more often + with. + setForm({ ...form, region: "NA" })} /> - - If the player suggested doesn't live in either Europe or The - Americas you can choose the region based on who they are playing - more often with. + + {form.type === "SUGGEST" && ( + + + + setForm({ ...form, description: value })} + limit={1000} + /> + - - - + )} + {form.type === "SUGGEST" ? ( - setForm({ ...form, description: value })} - limit={1000} - /> + + You can't edit or delete a suggestion after you have submitted + it. One suggestion per month. + - - - - You can't edit or delete a suggestion after you have submitted it. - One suggestion per month. - - + ) : ( + + + You can't change or delete a vouch after you have submitted it. + One vouch per player active at any given time. If your vouch + gets kicked in their first voting you may not vouch for the next + 6 months. + + + )} diff --git a/frontend-react/src/components/plus/Suggestions.js b/frontend-react/src/components/plus/Suggestions.js index 2cdcbc45f..cee52e0ab 100644 --- a/frontend-react/src/components/plus/Suggestions.js +++ b/frontend-react/src/components/plus/Suggestions.js @@ -6,6 +6,8 @@ import SuggestionForm from "./SuggestionForm" import { suggestions } from "../../graphql/queries/suggestions" import Loading from "../common/Loading" import Error from "../common/Error" +import { vouches } from "../../graphql/queries/vouches" +import UserAvatar from "../common/UserAvatar" const SuggestionList = ({ suggestionsArray }) => { if (suggestionsArray.length === 0) return null @@ -81,21 +83,39 @@ const Suggestions = ({ handleError, }) => { const { data, error, loading } = useQuery(suggestions) + const { + data: vouchesData, + error: vouchesError, + loading: vouchesLoading, + } = useQuery(vouches) - if (loading) return + if (loading || vouchesLoading) return if (error) return + if (vouchesError) return const ownSuggestion = data.suggestions.find( suggestion => suggestion.suggester_discord_user.discord_id === user.discord_id ) + const canSuggest = !ownSuggestion + + const canVouch = Boolean( + user.plus.can_vouch && !user.plus.can_vouch_again_after + ) + + const getButtonText = () => { + if (canSuggest && canVouch) return "Suggest or vouch a player" + else if (canSuggest) return "Suggest a player" + else if (canVouch) return "Vouch a player" + } + return ( <> - {!showSuggestionForm && !ownSuggestion && ( + {!showSuggestionForm && (canSuggest || canVouch) && (
)} @@ -105,8 +125,40 @@ const Suggestions = ({ hideForm={() => setShowSuggestionForm(false)} handleSuccess={handleSuccess} handleError={handleError} + canSuggest={canSuggest} + canVouch={canVouch} + canVouchFor={user.plus.can_vouch} /> )} + {vouchesData.vouches.length > 0 && ( + <> +

Vouched

+ + {vouchesData.vouches.map(vouch => { + return ( + + + + + {vouch.username}#{vouch.discriminator}{" "} + + + Vouched by {vouch.plus.voucher_user.username}# + {vouch.plus.voucher_user.discriminator} to{" "} + {vouch.plus.vouch_status === "ONE" ? "+1" : "+2"} + + + + ) + })} + + + )} ) diff --git a/frontend-react/src/graphql/mutations/addVouch.js b/frontend-react/src/graphql/mutations/addVouch.js new file mode 100644 index 000000000..c643cc78b --- /dev/null +++ b/frontend-react/src/graphql/mutations/addVouch.js @@ -0,0 +1,7 @@ +import { gql } from "apollo-boost" + +export const addVouch = gql` + mutation addVouch($discord_id: String!, $server: String!, $region: String!) { + addVouch(discord_id: $discord_id, server: $server, region: $region) + } +` diff --git a/frontend-react/src/graphql/queries/userLean.js b/frontend-react/src/graphql/queries/userLean.js index 1ed96a575..47c835093 100644 --- a/frontend-react/src/graphql/queries/userLean.js +++ b/frontend-react/src/graphql/queries/userLean.js @@ -12,6 +12,8 @@ export const userLean = gql` membership_status plus_region vouch_status + can_vouch + can_vouch_again_after } } } diff --git a/frontend-react/src/graphql/queries/vouches.js b/frontend-react/src/graphql/queries/vouches.js new file mode 100644 index 000000000..1a98addd1 --- /dev/null +++ b/frontend-react/src/graphql/queries/vouches.js @@ -0,0 +1,20 @@ +import { gql } from "apollo-boost" + +export const vouches = gql` + { + vouches { + username + discriminator + twitter_name + discord_id + plus { + voucher_user { + username + discriminator + discord_id + } + vouch_status + } + } + } +` diff --git a/graphql-schemas/plus.js b/graphql-schemas/plus.js index 47a07411e..9c6460ee8 100644 --- a/graphql-schemas/plus.js +++ b/graphql-schemas/plus.js @@ -15,6 +15,7 @@ const typeDef = gql` plusInfo: PlusGeneralInfo hasAccess(discord_id: String!, server: String!): Boolean! suggestions: [Suggested!]! + vouches: [User!] usersForVoting: UsersForVoting! summaries: [Summary!] } @@ -70,6 +71,7 @@ const typeDef = gql` plus_region: PlusRegion can_vouch: PlusServer voucher_discord_id: String + voucher_user: User can_vouch_again_after: String } @@ -286,6 +288,16 @@ const resolvers = { }) }) }, + vouches: (root, args, { user }) => { + if (!user || !user.plus) return null + const searchCriteria = + user.plus.membership_status === "ONE" + ? { "plus.vouch_status": { $ne: null } } + : { "plus.vouch_status": "TWO" } + return User.find(searchCriteria) + .sort({ "plus.vouch_status": "asc" }) + .populate("plus.voucher_user") + }, summaries: (root, args, ctx) => { if (!ctx.user || !ctx.user.plus || !ctx.user.plus.membership_status) return null diff --git a/mongoose-models/user.js b/mongoose-models/user.js index 7990e5cf0..2d3679616 100644 --- a/mongoose-models/user.js +++ b/mongoose-models/user.js @@ -24,4 +24,11 @@ const userSchema = new mongoose.Schema({ }, }) +userSchema.virtual("plus.voucher_user", { + ref: "User", + localField: "plus.voucher_discord_id", + foreignField: "discord_id", + justOne: true, +}) + module.exports = mongoose.model("User", userSchema)