plus page basically working

This commit is contained in:
Sendou
2020-02-28 14:30:46 +02:00
parent c048b93815
commit 882af5bfbd
16 changed files with 482 additions and 136 deletions

View File

@@ -1090,9 +1090,9 @@
}
},
"@emotion/core": {
"version": "10.0.27",
"resolved": "https://registry.npmjs.org/@emotion/core/-/core-10.0.27.tgz",
"integrity": "sha512-XbD5R36pVbohQMnKfajHv43g8EbN4NHdF6Zh9zg/C0nr0jqwOw3gYnC07Xj3yG43OYSRyrGsoQ5qPwc8ycvLZw==",
"version": "10.0.28",
"resolved": "https://registry.npmjs.org/@emotion/core/-/core-10.0.28.tgz",
"integrity": "sha512-pH8UueKYO5jgg0Iq+AmCLxBsvuGtvlmiDCOuv8fGNYn3cowFpLN98L8zO56U0H1PjDIyAlXymgL3Wu7u7v6hbA==",
"requires": {
"@babel/runtime": "^7.5.5",
"@emotion/cache": "^10.0.27",
@@ -1451,9 +1451,9 @@
"integrity": "sha512-a1USH7L3bEfDdPN4iNZGvMEFuBfkdG+QNybeyDv8RloVFgZYRoM+KGXyy2KOfEnTUM8QWDRSROwaL3+ts5Angg=="
},
"@reach/router": {
"version": "1.3.1",
"resolved": "https://registry.npmjs.org/@reach/router/-/router-1.3.1.tgz",
"integrity": "sha512-Ov1j1J+pSgXliJHFL7XWhjyREwc6GxeWfgBTa5MMH5eRmYtHbPhaovba4xKo7aTVCg8fxkt2yDMNSpvwfUP+pA==",
"version": "1.3.3",
"resolved": "https://registry.npmjs.org/@reach/router/-/router-1.3.3.tgz",
"integrity": "sha512-gOIAiFhWdiVGSVjukKeNKkCRBLmnORoTPyBihI/jLunICPgxdP30DroAvPQuf1eVfQbfGJQDJkwhJXsNPMnVWw==",
"requires": {
"create-react-context": "0.3.0",
"invariant": "^2.2.3",

View File

@@ -5,9 +5,9 @@
"dependencies": {
"@apollo/react-hooks": "^3.1.3",
"@chakra-ui/core": "^0.6.1",
"@emotion/core": "^10.0.27",
"@emotion/core": "^10.0.28",
"@emotion/styled": "^10.0.27",
"@reach/router": "^1.3.1",
"@reach/router": "^1.3.3",
"@rehooks/local-storage": "^2.2.2",
"@sendou/react-sketch": "^0.5.2",
"@testing-library/jest-dom": "^5.1.1",

View File

@@ -0,0 +1,49 @@
import React from "react"
import { useQuery } from "@apollo/react-hooks"
import { USERS } from "../../graphql/queries/users"
import Error from "./Error"
import Select from "../elements/Select"
interface UsersData {
users: {
discord_id: string
discriminator: string
twitter_name?: string
username: string
}[]
}
interface UserSelectorProps {
id?: string
setValue?: (value: string) => void
}
const UserSelector: React.FC<UserSelectorProps> = ({ setValue }) => {
const { data, error, loading } = useQuery<UsersData>(USERS)
if (error) return <Error errorMessage={error.message} />
return (
<>
<Select
isSearchable
options={
!loading && data
? data.users.map(user => ({
label: `${user.username}#${user.discriminator}`,
value: user.discord_id,
}))
: undefined
}
setValue={setValue}
clearable
hideMenuBeforeTyping
isLoading={loading}
isDisabled={loading}
/>
</>
)
return null
}
export default UserSelector

View File

@@ -6,12 +6,11 @@ import { IconType } from "react-icons/lib/cjs"
interface ButtonProps {
children: string | string[]
onClick: () => void
onClick?: () => void
size?: "xs" | "sm" | "lg" | "md"
icon?: IconType
outlined?: boolean
disabled?: boolean
negative?: boolean
}
const Button: React.FC<ButtonProps> = ({

View File

@@ -1,12 +1,14 @@
import React, { useContext } from "react"
import React, { useContext, useState } from "react"
import ReactSelect, { OptionsType, GroupedOptionsType } from "react-select"
import MyThemeContext from "../../themeContext"
import { SelectComponents } from "react-select/src/components"
import Box from "./Box"
import Label from "./Label"
import { Flex } from "@chakra-ui/core"
import Button from "./Button"
interface SelectProps {
options:
options?:
| OptionsType<{
label: string
value: string
@@ -16,7 +18,7 @@ interface SelectProps {
value: string
}>
width?: string
label: string
label?: string
required?: boolean
value?:
| {
@@ -26,7 +28,7 @@ interface SelectProps {
| string
| string[]
| null
setValue: (value: any) => void
setValue?: (value: any) => void
autoFocus?: boolean
components?: Partial<
SelectComponents<{
@@ -36,7 +38,10 @@ interface SelectProps {
>
clearable?: boolean
isMulti?: boolean
isLoading?: boolean
isDisabled?: boolean
isSearchable?: boolean
hideMenuBeforeTyping?: boolean
}
const Select: React.FC<SelectProps> = ({
@@ -49,7 +54,10 @@ const Select: React.FC<SelectProps> = ({
label,
required,
isMulti,
isLoading,
isDisabled,
isSearchable,
hideMenuBeforeTyping,
width = "290px",
}) => {
const {
@@ -58,8 +66,10 @@ const Select: React.FC<SelectProps> = ({
themeColorHex,
themeColorHexLighter,
} = useContext(MyThemeContext)
const [inputValue, setInputValue] = useState("")
const handleChange = (selectedOption: any) => {
if (!setValue || !selectedOption) return
if (Array.isArray(selectedOption)) {
setValue(selectedOption.map(obj => obj.value))
} else {
@@ -84,16 +94,31 @@ const Select: React.FC<SelectProps> = ({
className="basic-single"
classNamePrefix="select"
value={getValue()}
inputValue={inputValue}
onInputChange={newValue => setInputValue(newValue)}
menuIsOpen={
hideMenuBeforeTyping ? !!(inputValue.length >= 3) : undefined
}
onChange={handleChange}
placeholder={null}
isSearchable={!!isSearchable}
isMulti={!!isMulti}
isLoading={isLoading}
isDisabled={isDisabled}
isClearable={isMulti ? false : clearable}
options={options}
components={{
IndicatorSeparator: () => null,
...components,
}}
components={
hideMenuBeforeTyping
? {
IndicatorSeparator: () => null,
DropdownIndicator: () => null,
...components,
}
: {
IndicatorSeparator: () => null,
...components,
}
}
theme={theme => ({
...theme,
borderRadius: 5,
@@ -102,6 +127,7 @@ const Select: React.FC<SelectProps> = ({
primary25: `${themeColorHexLighter}`,
primary: `${themeColorHex}`,
neutral0: darkerBgColor,
neutral5: darkerBgColor,
},
})}
autoFocus={autoFocus}

View File

@@ -7,9 +7,10 @@ import MyThemeContext from "../../themeContext"
interface TextAreaProps {
value?: string
setValue: (value: string) => void
label: string
label?: string
limit?: number
required?: boolean
id?: string
}
const TextArea: React.FC<TextAreaProps> = ({

View File

@@ -1,4 +1,4 @@
import React, { useState } from "react"
import React from "react"
import { useQuery } from "@apollo/react-hooks"
import Suggestions from "./Suggestions"
@@ -7,8 +7,11 @@ import Error from "../common/Error"
import { PLUS_INFO } from "../../graphql/queries/plusInfo"
import { USER } from "../../graphql/queries/user"
//import Voting from "./Voting"
import { Redirect, RouteComponentProps } from "@reach/router"
import { Redirect, RouteComponentProps, Link } from "@reach/router"
import PageHeader from "../common/PageHeader"
import { FaHistory } from "react-icons/fa"
import Button from "../elements/Button"
import { Helmet } from "react-helmet-async"
interface PlusInfoData {
plusInfo: {
@@ -19,8 +22,6 @@ interface PlusInfoData {
}
const PlusPage: React.FC<RouteComponentProps> = () => {
const [showSuggestionForm, setShowSuggestionForm] = useState(false)
const { data, error, loading } = useQuery<PlusInfoData>(PLUS_INFO)
const {
data: userData,
@@ -36,8 +37,10 @@ const PlusPage: React.FC<RouteComponentProps> = () => {
return (
<>
<Helmet>
<title>Plus Server Home | sendou.ink</title>
</Helmet>
<PageHeader title="Plus Server" />
{/*Inv link here*/}
{/*data.plusInfo.voting_ends && userData.user.plus?.membership_status ? (
<Voting
user={userData.user}
@@ -61,6 +64,11 @@ const PlusPage: React.FC<RouteComponentProps> = () => {
handleError={handleError}
/>
)*/}
<Link to="/plus/history">
<Button outlined icon={FaHistory}>
Show voting history
</Button>
</Link>
<Suggestions user={userData.user} />
</>
)

View File

@@ -0,0 +1,257 @@
import React, { useState, useContext } from "react"
import Modal from "../elements/Modal"
import UserSelector from "../common/UserSelector"
import { ADD_SUGGESTION } from "../../graphql/mutations/addSuggestion"
import { ADD_VOUCH } from "../../graphql/mutations/addVouch"
import { useMutation } from "@apollo/react-hooks"
import {
useToast,
FormControl,
FormLabel,
FormHelperText,
RadioGroup,
Radio,
Flex,
Box,
FormErrorMessage,
} from "@chakra-ui/core"
import MyThemeContext from "../../themeContext"
import TextArea from "../elements/TextArea"
import Button from "../elements/Button"
import { SUGGESTIONS } from "../../graphql/queries/suggestions"
import { VOUCHES } from "../../graphql/queries/vouches"
import { USER } from "../../graphql/queries/user"
interface AddSuggestionVars {
discord_id: string
region: string
server: string
description: string
}
interface AddVouchVars {
discord_id: string
region: string
server: string
}
interface SuggestionVouchModalProps {
closeModal: () => void
canSuggest: boolean
canVouch: boolean
plusServer: "ONE" | "TWO"
}
const SuggestionVouchModal: React.FC<SuggestionVouchModalProps> = ({
closeModal,
canSuggest,
canVouch,
plusServer,
}) => {
const [form, setForm] = useState<Partial<AddSuggestionVars>>({})
const [actionType, setActionType] = useState<string>(
!canSuggest ? "VOUCH" : "SUGGEST"
)
const [showErrors, setShowErrors] = useState(false)
const toast = useToast()
const { themeColor } = useContext(MyThemeContext)
const [addSuggestion] = useMutation<boolean, AddSuggestionVars>(
ADD_SUGGESTION,
{
variables: { ...(form as AddSuggestionVars) },
onCompleted: data => {
closeModal()
toast({
description: `Suggestion added`,
position: "top-right",
status: "success",
duration: 10000,
})
},
onError: error => {
toast({
title: "An error occurred",
description: error.message,
position: "top-right",
status: "error",
duration: 10000,
})
},
refetchQueries: [{ query: SUGGESTIONS }],
}
)
const [addVouch] = useMutation<boolean, AddVouchVars>(ADD_VOUCH, {
variables: { ...(form as AddVouchVars) },
onCompleted: data => {
closeModal()
toast({
description: `Player vouched`,
position: "top-right",
status: "success",
duration: 10000,
})
},
onError: error => {
toast({
title: "An error occurred",
description: error.message,
position: "top-right",
status: "error",
duration: 10000,
})
},
refetchQueries: [{ query: VOUCHES }, { query: USER }],
})
const handleChange = (newValueObject: Partial<AddSuggestionVars>) => {
setForm({ ...form, ...newValueObject })
}
const handleSubmit = () => {
if (!form.discord_id || !form.region || !form.server) {
setShowErrors(true)
return
}
if (
(!form.description ||
(form.description && form.description.length > 1000)) &&
actionType === "SUGGEST"
) {
setShowErrors(true)
return
}
if (actionType === "SUGGEST") addSuggestion()
if (actionType === "VOUCH") addVouch()
}
return (
<Modal title={"Suggesting or vouching a player"} closeModal={closeModal}>
<FormControl isRequired isInvalid={showErrors && !form.discord_id}>
<FormLabel htmlFor="user">Discord username</FormLabel>
<UserSelector
id="user"
setValue={value => handleChange({ discord_id: value })}
/>
<FormErrorMessage>Required field</FormErrorMessage>
<FormHelperText>
Only people who have logged in to sendou.ink at least once shown
</FormHelperText>
</FormControl>
<FormControl isRequired mt="1em">
<FormLabel htmlFor="server">Action</FormLabel>
<RadioGroup
spacing={5}
isInline
onChange={(e, value) => setActionType(value as string)}
value={actionType}
>
<Radio
variantColor={themeColor}
value="SUGGEST"
isDisabled={!canSuggest}
>
Suggest
</Radio>
<Radio variantColor={themeColor} value="VOUCH" isDisabled={!canVouch}>
Vouch
</Radio>
</RadioGroup>
<FormHelperText>
Vouching only possible if you got high enough ratio in the last voting
</FormHelperText>
</FormControl>
<FormControl isRequired isInvalid={showErrors && !form.server} mt="1em">
<FormLabel htmlFor="server">Server</FormLabel>
<RadioGroup
id="server"
spacing={5}
isInline
onChange={(e, value) => handleChange({ server: value as string })}
value={form.server}
>
<Radio
variantColor={themeColor}
value="ONE"
isDisabled={plusServer !== "ONE"}
>
+1
</Radio>
<Radio variantColor={themeColor} value="TWO">
+2
</Radio>
<FormErrorMessage>Required field</FormErrorMessage>
</RadioGroup>
</FormControl>
<FormControl isRequired isInvalid={showErrors && !form.region} mt="1em">
<FormLabel htmlFor="region">Region</FormLabel>
<RadioGroup
id="region"
spacing={5}
isInline
onChange={(e, value) => handleChange({ region: value as string })}
value={form.region}
>
<Radio
variantColor={themeColor}
value="EU"
isDisabled={plusServer !== "ONE"}
>
Europe
</Radio>
<Radio variantColor={themeColor} value="NA">
The Americas
</Radio>
</RadioGroup>
<FormErrorMessage>Required field</FormErrorMessage>
<FormHelperText>
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
</FormHelperText>
</FormControl>
{actionType === "SUGGEST" && (
<FormControl
isRequired
isInvalid={
!!(
(showErrors && !form.description) ||
(form.description && form.description.length > 1000)
)
}
mt="1em"
>
<FormLabel htmlFor="description">Description</FormLabel>
<TextArea
id="description"
setValue={(value: string) =>
handleChange({ description: value as string })
}
value={form.description}
limit={1000}
/>
<FormErrorMessage>
{!form.description
? "Required field"
: "Description can't be more than 1000 characters"}
</FormErrorMessage>
</FormControl>
)}
<Flex flexWrap="wrap" mt="1em">
<Box mr="1em">
<Button onClick={() => handleSubmit()}>Submit</Button>
</Box>
<Button outlined onClick={() => closeModal()}>
Cancel
</Button>
</Flex>
</Modal>
)
}
export default SuggestionVouchModal

View File

@@ -1,7 +1,5 @@
import React, { useContext } from "react"
import React, { useContext, useState } from "react"
import { useQuery } from "@apollo/react-hooks"
//import SuggestionForm from "./SuggestionForm"
import { SUGGESTIONS } from "../../graphql/queries/suggestions"
import Loading from "../common/Loading"
import Error from "../common/Error"
@@ -23,57 +21,8 @@ import {
import { Link } from "@reach/router"
import MyThemeContext from "../../themeContext"
import { IoIosChatbubbles } from "react-icons/io"
/*const SuggestionList = ({ suggestionsArray }) => {
if (suggestionsArray.length === 0) return null
const suggestionLists = suggestionsArray.map(suggestion => (
<React.Fragment key={suggestion.suggester_discord_user.discord_id}>
<List.Item>
<List.Content>
{suggestion.discord_user.twitter_name && (
<Image
avatar
size="mini"
src={`https://avatars.io/twitter/${suggestion.discord_user.twitter_name}`}
/>
)}
<List.Header as="a" href={`/u/${suggestion.discord_user.discord_id}`}>
{suggestion.discord_user.username}#
{suggestion.discord_user.discriminator}
</List.Header>
<List.Description>
<div style={{ marginTop: "0.5em" }}>
<b>
{suggestion.plus_region} | Suggested to join{" "}
{suggestion.plus_server === "ONE" ? "+1 " : "+2 "} by{" "}
<a href={`/u/${suggestion.suggester_discord_user.discord_id}`}>
{suggestion.suggester_discord_user.username}#
{suggestion.suggester_discord_user.discriminator}
</a>
</b>
</div>
</List.Description>
<List.Description style={{ whiteSpace: "pre-wrap" }}>
{suggestion.description}
</List.Description>
</List.Content>
</List.Item>
<Divider />
</React.Fragment>
))
return (
<>
{suggestionLists.length > 0 && (
<>
<h2>Suggested</h2>
{suggestionLists}
</>
)}
</>
)
}*/
import Button from "../elements/Button"
import SuggestionVouchModal from "./SuggestionVouchModal"
interface SuggestionsProps {
user: UserLean
@@ -120,14 +69,11 @@ interface VouchesData {
vouches: VouchUser[]
}
const Suggestions: React.FC<SuggestionsProps> = ({
user,
//showSuggestionForm,
//setShowSuggestionForm,
}) => {
const Suggestions: React.FC<SuggestionsProps> = ({ user }) => {
const { grayWithShade, themeColor, darkerBgColor } = useContext(
MyThemeContext
)
const [showSuggestionForm, setShowSuggestionForm] = useState(false)
const { data, error, loading } = useQuery<SuggestionsData>(SUGGESTIONS)
const {
data: vouchesData,
@@ -244,6 +190,10 @@ const Suggestions: React.FC<SuggestionsProps> = ({
)
}
const buttonText = getButtonText()
console.log("data", data)
return (
<>
{/*!showSuggestionForm && (canSuggest || canVouch) && (
@@ -264,34 +214,52 @@ const Suggestions: React.FC<SuggestionsProps> = ({
canVouchFor={user.plus.can_vouch}
/>
)*/}
{vouchesData.vouches.length > 0 && (
<>
<Flex flexWrap="wrap">
<Box mr="2em" mb="1em">
{plusOneVouches.length > 0 && (
{showSuggestionForm && (
<SuggestionVouchModal
closeModal={() => setShowSuggestionForm(false)}
canSuggest={canSuggest}
canVouch={canVouch}
plusServer={user.plus.membership_status!}
/>
)}
<Box mt="1em">
{buttonText && (
<Button onClick={() => setShowSuggestionForm(true)}>
{buttonText}
</Button>
)}
{vouchesData.vouches.length > 0 && (
<Flex flexWrap="wrap" mt="1em">
{plusOneVouches.length > 0 && (
<Box mr="2em" mb="1em">
<Heading size="md">Vouched players to +1</Heading>
)}
<Grid
gridRowGap="0.5em"
gridTemplateColumns="min-content 1fr"
mt="1em"
>
{plusOneVouches.map(vouchMap)}
</Grid>
</Box>
<Box>
{plusOneVouches.length > 0 && (
<Grid
gridRowGap="0.5em"
gridTemplateColumns="min-content 1fr"
mt="1em"
>
{plusOneVouches.map(vouchMap)}
</Grid>
</Box>
)}
{plusTwoVouches.length > 0 && (
<Box>
<Heading size="md">Vouched players to +2</Heading>
)}
<Grid
gridRowGap="0.5em"
gridTemplateColumns="min-content 1fr"
mt="1em"
>
{plusTwoVouches.map(vouchMap)}
</Grid>
</Box>
<Grid
gridRowGap="0.5em"
gridTemplateColumns="min-content 1fr"
mt="1em"
>
{plusTwoVouches.map(vouchMap)}
</Grid>
</Box>
)}
</Flex>
)}
{data.suggestions.length > 0 && (
<Flex flexWrap="wrap" mt="2em">
<Box mr="2em" mb="1em">
{plusOneSuggested.length > 0 && (
@@ -318,8 +286,8 @@ const Suggestions: React.FC<SuggestionsProps> = ({
</Grid>
</Box>
</Flex>
</>
)}
)}
</Box>
</>
)
}

View File

@@ -1,9 +1,21 @@
import React, { useContext } from "react"
import UserAvatar from "../common/UserAvatar"
import { Summary } from "./VotingHistoryPage"
import { Heading, Box, Grid, Flex } from "@chakra-ui/core"
import {
Heading,
Box,
Grid,
Flex,
Popover,
PopoverTrigger,
IconButton,
PopoverContent,
PopoverArrow,
PopoverBody,
} from "@chakra-ui/core"
import { Link } from "@reach/router"
import MyThemeContext from "../../themeContext"
import { FaBolt } from "react-icons/fa"
const getColor = (score: number) =>
score < 50 ? { color: "red" } : { color: "green" }
@@ -50,7 +62,9 @@ interface SummariesProps {
}
const Summaries: React.FC<SummariesProps> = ({ summaries }) => {
const { grayWithShade } = useContext(MyThemeContext)
const { grayWithShade, themeColor, darkerBgColor } = useContext(
MyThemeContext
)
const members: Summary[] = []
const suggested: Summary[] = []
@@ -88,12 +102,30 @@ const Summaries: React.FC<SummariesProps> = ({ summaries }) => {
<Count count={score.na_count} />)
</>
)}
{/*summary.vouched && (
<Popup
content="User was vouched to the server last month"
trigger={<Icon name="bolt" color="teal" size="large" />}
/>
)*/}
{summary.vouched && (
<Popover placement="top">
<PopoverTrigger>
<IconButton
variant="ghost"
isRound
variantColor={themeColor}
aria-label="Show description"
fontSize="20px"
icon={FaBolt}
/>
</PopoverTrigger>
<PopoverContent
zIndex={4}
width="220px"
backgroundColor={darkerBgColor}
>
<PopoverArrow />
<PopoverBody textAlign="center">
User was voted to the server this month
</PopoverBody>
</PopoverContent>
</Popover>
)}
</Box>
</Box>
</React.Fragment>

View File

@@ -6,11 +6,15 @@ import { USER } from "../../graphql/queries/user"
import Error from "../common/Error"
import { months } from "../../utils/lists"
//import SummaryLists from "./SummaryLists"
import { Redirect, RouteComponentProps } from "@reach/router"
import { Redirect, RouteComponentProps, Link } from "@reach/router"
import { UserLean, UserData } from "../../types"
import { Flex, Box } from "@chakra-ui/core"
import Select from "../elements/Select"
import Summaries from "./Summaries"
import PageHeader from "../common/PageHeader"
import Button from "../elements/Button"
import { FaHistory } from "react-icons/fa"
import { Helmet } from "react-helmet-async"
export interface Summary {
discord_user: {
@@ -109,6 +113,10 @@ const VotingHistoryPage: React.FC<RouteComponentProps> = () => {
const year = parseInt(parts[1])
return (
<>
<Helmet>
<title>Plus Server Voting History | sendou.ink</title>
</Helmet>
<PageHeader title="Voting History" />
<Flex flexWrap="wrap" justifyContent="center">
{userData.user.plus.membership_status === "ONE" && (
<Box m="0.5em">

View File

@@ -24,13 +24,11 @@ const UserItem: React.FC<{ data?: UserData }> = ({ data }) => {
if (!data || !data.user) {
// prolly need to do href here
return (
<List>
<NavItem
to="auth/discord"
Icon={FaSignInAlt}
title="Log in via Discord"
/>
</List>
<NavItem
to="auth/discord"
Icon={FaSignInAlt}
title="Log in via Discord"
/>
)
}
@@ -77,7 +75,7 @@ export const SideNavContent: React.FC<SideNavProps> = ({ showLogo = true }) => {
</Flex>
)}
<Flex>
<List spacing={4} mt="2em">
<List mt="2em">
<NavItem to="plans" Icon={FaMap} title="Map Planner" />
<NavItem to="calendar" Icon={FaCalendarAlt} title="Calendar" />
<NavItem to="builds" Icon={FaTshirt} title="Builds" />

View File

@@ -79,7 +79,7 @@ const BuildFormModal: React.FC<BuildFormModalProps> = ({
title: "An error occurred",
description: error.message,
position: "top-right",
status: "success",
status: "error",
duration: 10000,
})
},
@@ -104,7 +104,7 @@ const BuildFormModal: React.FC<BuildFormModalProps> = ({
title: "An error occurred",
description: error.message,
position: "top-right",
status: "success",
status: "error",
duration: 10000,
})
},

View File

@@ -1,6 +1,6 @@
import { gql } from "apollo-boost"
import { gql, DocumentNode } from "apollo-boost"
export const addSuggestion = gql`
export const ADD_SUGGESTION: DocumentNode = gql`
mutation addSuggestion(
$discord_id: String!
$region: String!

View File

@@ -1,6 +1,6 @@
import { gql } from "apollo-boost"
import { gql, DocumentNode } from "apollo-boost"
export const addVouch = gql`
export const ADD_VOUCH: DocumentNode = gql`
mutation addVouch($discord_id: String!, $server: String!, $region: String!) {
addVouch(discord_id: $discord_id, server: $server, region: $region)
}

View File

@@ -1,12 +1,12 @@
import { gql } from "apollo-boost"
import { gql, DocumentNode } from "apollo-boost"
export const users = gql`
export const USERS: DocumentNode = gql`
{
users {
username
discriminator
twitter_name
discord_id
twitter_name
}
}
`