mirror of
https://github.com/Sendouc/sendou.ink.git
synced 2026-08-22 11:05:09 -05:00
builds working & http -> https redirect
This commit is contained in:
@@ -1,13 +1,13 @@
|
||||
{
|
||||
"files": {
|
||||
"main.js": "/static/js/main.4c1af679.chunk.js",
|
||||
"main.js.map": "/static/js/main.4c1af679.chunk.js.map",
|
||||
"main.js": "/static/js/main.1141a902.chunk.js",
|
||||
"main.js.map": "/static/js/main.1141a902.chunk.js.map",
|
||||
"runtime~main.js": "/static/js/runtime~main.a8a9905a.js",
|
||||
"runtime~main.js.map": "/static/js/runtime~main.a8a9905a.js.map",
|
||||
"static/js/2.55ce7a59.chunk.js": "/static/js/2.55ce7a59.chunk.js",
|
||||
"static/js/2.55ce7a59.chunk.js.map": "/static/js/2.55ce7a59.chunk.js.map",
|
||||
"static/js/2.15aafc23.chunk.js": "/static/js/2.15aafc23.chunk.js",
|
||||
"static/js/2.15aafc23.chunk.js.map": "/static/js/2.15aafc23.chunk.js.map",
|
||||
"index.html": "/index.html",
|
||||
"precache-manifest.98616b2e0db57de939893fc6d6fa403d.js": "/precache-manifest.98616b2e0db57de939893fc6d6fa403d.js",
|
||||
"precache-manifest.d801c050748c669d50167e0efc29dc61.js": "/precache-manifest.d801c050748c669d50167e0efc29dc61.js",
|
||||
"service-worker.js": "/service-worker.js",
|
||||
"static/media/ancho-v_games.png": "/static/media/ancho-v_games.07d5d0f6.png",
|
||||
"static/media/arowana_mall.png": "/static/media/arowana_mall.26cf0823.png",
|
||||
|
||||
@@ -1 +1 @@
|
||||
<!doctype html><html lang="en"><head><meta charset="utf-8"/><link rel="shortcut icon" href="/favicon.ico"/><link rel="stylesheet" href="//cdn.jsdelivr.net/npm/semantic-ui@2.4.2/dist/semantic.min.css"/><meta name="viewport" content="width=device-width,initial-scale=1"/><meta name="theme-color" content="#000000"/><link rel="manifest" href="/manifest.json"/><title>sendou.ink</title></head><body><noscript>You need to enable JavaScript to run this app.</noscript><div id="root"></div><script>!function(l){function e(e){for(var r,t,n=e[0],o=e[1],u=e[2],f=0,i=[];f<n.length;f++)t=n[f],p[t]&&i.push(p[t][0]),p[t]=0;for(r in o)Object.prototype.hasOwnProperty.call(o,r)&&(l[r]=o[r]);for(s&&s(e);i.length;)i.shift()();return c.push.apply(c,u||[]),a()}function a(){for(var e,r=0;r<c.length;r++){for(var t=c[r],n=!0,o=1;o<t.length;o++){var u=t[o];0!==p[u]&&(n=!1)}n&&(c.splice(r--,1),e=f(f.s=t[0]))}return e}var t={},p={1:0},c=[];function f(e){if(t[e])return t[e].exports;var r=t[e]={i:e,l:!1,exports:{}};return l[e].call(r.exports,r,r.exports,f),r.l=!0,r.exports}f.m=l,f.c=t,f.d=function(e,r,t){f.o(e,r)||Object.defineProperty(e,r,{enumerable:!0,get:t})},f.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},f.t=function(r,e){if(1&e&&(r=f(r)),8&e)return r;if(4&e&&"object"==typeof r&&r&&r.__esModule)return r;var t=Object.create(null);if(f.r(t),Object.defineProperty(t,"default",{enumerable:!0,value:r}),2&e&&"string"!=typeof r)for(var n in r)f.d(t,n,function(e){return r[e]}.bind(null,n));return t},f.n=function(e){var r=e&&e.__esModule?function(){return e.default}:function(){return e};return f.d(r,"a",r),r},f.o=function(e,r){return Object.prototype.hasOwnProperty.call(e,r)},f.p="/";var r=window.webpackJsonp=window.webpackJsonp||[],n=r.push.bind(r);r.push=e,r=r.slice();for(var o=0;o<r.length;o++)e(r[o]);var s=n;a()}([])</script><script src="/static/js/2.55ce7a59.chunk.js"></script><script src="/static/js/main.4c1af679.chunk.js"></script></body></html>
|
||||
<!doctype html><html lang="en"><head><meta charset="utf-8"/><link rel="shortcut icon" href="/favicon.ico"/><link rel="stylesheet" href="//cdn.jsdelivr.net/npm/semantic-ui@2.4.2/dist/semantic.min.css"/><meta name="viewport" content="width=device-width,initial-scale=1"/><meta name="theme-color" content="#000000"/><link rel="manifest" href="/manifest.json"/><title>sendou.ink</title></head><body><noscript>You need to enable JavaScript to run this app.</noscript><div id="root"></div><script>!function(l){function e(e){for(var r,t,n=e[0],o=e[1],u=e[2],f=0,i=[];f<n.length;f++)t=n[f],p[t]&&i.push(p[t][0]),p[t]=0;for(r in o)Object.prototype.hasOwnProperty.call(o,r)&&(l[r]=o[r]);for(s&&s(e);i.length;)i.shift()();return c.push.apply(c,u||[]),a()}function a(){for(var e,r=0;r<c.length;r++){for(var t=c[r],n=!0,o=1;o<t.length;o++){var u=t[o];0!==p[u]&&(n=!1)}n&&(c.splice(r--,1),e=f(f.s=t[0]))}return e}var t={},p={1:0},c=[];function f(e){if(t[e])return t[e].exports;var r=t[e]={i:e,l:!1,exports:{}};return l[e].call(r.exports,r,r.exports,f),r.l=!0,r.exports}f.m=l,f.c=t,f.d=function(e,r,t){f.o(e,r)||Object.defineProperty(e,r,{enumerable:!0,get:t})},f.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},f.t=function(r,e){if(1&e&&(r=f(r)),8&e)return r;if(4&e&&"object"==typeof r&&r&&r.__esModule)return r;var t=Object.create(null);if(f.r(t),Object.defineProperty(t,"default",{enumerable:!0,value:r}),2&e&&"string"!=typeof r)for(var n in r)f.d(t,n,function(e){return r[e]}.bind(null,n));return t},f.n=function(e){var r=e&&e.__esModule?function(){return e.default}:function(){return e};return f.d(r,"a",r),r},f.o=function(e,r){return Object.prototype.hasOwnProperty.call(e,r)},f.p="/";var r=window.webpackJsonp=window.webpackJsonp||[],n=r.push.bind(r);r.push=e,r=r.slice();for(var o=0;o<r.length;o++)e(r[o]);var s=n;a()}([])</script><script src="/static/js/2.15aafc23.chunk.js"></script><script src="/static/js/main.1141a902.chunk.js"></script></body></html>
|
||||
@@ -1,15 +1,15 @@
|
||||
self.__precacheManifest = (self.__precacheManifest || []).concat([
|
||||
{
|
||||
"revision": "263c0c76db10fbf668b70280425ae71c",
|
||||
"revision": "0d2f115e143635d48d2d2ec0524efa03",
|
||||
"url": "/index.html"
|
||||
},
|
||||
{
|
||||
"revision": "ba394d26abe9b15f2753",
|
||||
"url": "/static/js/2.55ce7a59.chunk.js"
|
||||
"revision": "88368028096f05972b1b",
|
||||
"url": "/static/js/2.15aafc23.chunk.js"
|
||||
},
|
||||
{
|
||||
"revision": "5813558134488f70b3eb",
|
||||
"url": "/static/js/main.4c1af679.chunk.js"
|
||||
"revision": "0e0627ec3efbe9a79bd4",
|
||||
"url": "/static/js/main.1141a902.chunk.js"
|
||||
},
|
||||
{
|
||||
"revision": "42ac5946195a7306e2a5",
|
||||
@@ -14,7 +14,7 @@
|
||||
importScripts("https://storage.googleapis.com/workbox-cdn/releases/4.3.0/workbox-sw.js");
|
||||
|
||||
importScripts(
|
||||
"/precache-manifest.98616b2e0db57de939893fc6d6fa403d.js"
|
||||
"/precache-manifest.d801c050748c669d50167e0efc29dc61.js"
|
||||
);
|
||||
|
||||
self.addEventListener('message', (event) => {
|
||||
|
||||
2
build/static/js/2.15aafc23.chunk.js
Normal file
2
build/static/js/2.15aafc23.chunk.js
Normal file
File diff suppressed because one or more lines are too long
1
build/static/js/2.15aafc23.chunk.js.map
Normal file
1
build/static/js/2.15aafc23.chunk.js.map
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
2
build/static/js/main.1141a902.chunk.js
Normal file
2
build/static/js/main.1141a902.chunk.js
Normal file
File diff suppressed because one or more lines are too long
1
build/static/js/main.1141a902.chunk.js.map
Normal file
1
build/static/js/main.1141a902.chunk.js.map
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
43
index.js
43
index.js
@@ -147,8 +147,8 @@ const typeDefs = gql`
|
||||
discriminator: String!
|
||||
avatar: String
|
||||
discord_id: String!
|
||||
twitch_name: String!
|
||||
twitter_name: String!
|
||||
twitch_name: String
|
||||
twitter_name: String
|
||||
custom_url: String
|
||||
}
|
||||
|
||||
@@ -217,6 +217,7 @@ const typeDefs = gql`
|
||||
user: User
|
||||
searchForUser(discord_id: String!): User
|
||||
searchForBuilds(discord_id: String!): [Build]!
|
||||
deleteBuild(id: ID!): Boolean
|
||||
}
|
||||
|
||||
type Mutation {
|
||||
@@ -235,6 +236,9 @@ const typeDefs = gql`
|
||||
clothing: [Ability!]!
|
||||
shoes: [Ability!]!
|
||||
): Build
|
||||
deleteBuild(
|
||||
id: ID!
|
||||
): Boolean
|
||||
}
|
||||
`
|
||||
|
||||
@@ -435,7 +439,10 @@ const resolvers = {
|
||||
playerInfo: async (root, args) => {
|
||||
let searchCriteria = {}
|
||||
if (args.uid) searchCriteria = { "unique_id": args.uid }
|
||||
if (args.twitter) searchCriteria = { "twitter": args.twitter.toLowerCase()}
|
||||
else if (args.twitter) searchCriteria = { "twitter": args.twitter.toLowerCase()}
|
||||
else throw new UserInputError('no id or twitter provided', {
|
||||
invalidArgs: args,
|
||||
})
|
||||
const player = await Player
|
||||
.findOne(searchCriteria)
|
||||
.catch(e => {
|
||||
@@ -575,13 +582,29 @@ const resolvers = {
|
||||
})
|
||||
|
||||
const build = new Build({ ...args, discord_id: ctx.user.discord_id })
|
||||
console.log('build', build)
|
||||
return build.save()
|
||||
.catch(e => {
|
||||
throw new UserInputError, {
|
||||
invalidArgs: args,
|
||||
}
|
||||
})
|
||||
},
|
||||
deleteBuild: async (root, args, ctx) => {
|
||||
if (!ctx.user) throw new AuthenticationError('not authenticated')
|
||||
|
||||
const build = await Build.findOne({ _id: args.id})
|
||||
|
||||
if (ctx.user.discord_id !== build.discord_id) throw new AuthenticationError('no privileges')
|
||||
|
||||
try {
|
||||
await Build.findByIdAndDelete({ _id: args.id })
|
||||
} catch (error) {
|
||||
throw new UserInputError(error.message, {
|
||||
invalidArgs: args,
|
||||
})
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -599,6 +622,18 @@ const app = express()
|
||||
app.use(cors())
|
||||
app.use(express.static('build'))
|
||||
|
||||
//https://stackoverflow.com/questions/8605720/how-to-force-ssl-https-in-express-js/31144924#31144924
|
||||
|
||||
function requireHTTPS(req, res, next) {
|
||||
// The 'x-forwarded-proto' check is for Heroku
|
||||
if (!req.secure && req.get('x-forwarded-proto') !== 'https' && process.env.NODE_ENV !== "development") {
|
||||
return res.redirect('https://' + req.get('host') + req.url)
|
||||
}
|
||||
next()
|
||||
}
|
||||
|
||||
app.use(requireHTTPS)
|
||||
|
||||
app.use(session({
|
||||
secret: process.env.SESSION_SECRET,
|
||||
resave: false,
|
||||
|
||||
32
react-ui/src/components/Misc/MainMenu.js
vendored
32
react-ui/src/components/Misc/MainMenu.js
vendored
@@ -1,5 +1,5 @@
|
||||
import React, { useState } from 'react'
|
||||
import { Menu, Segment, Button, Icon, Image, Popup } from 'semantic-ui-react'
|
||||
import { Menu, Segment, Button, Image, Dropdown } from 'semantic-ui-react'
|
||||
import { useQuery } from 'react-apollo-hooks'
|
||||
import { userLean } from '../../graphql/queries/userLean'
|
||||
import { withRouter } from 'react-router-dom'
|
||||
@@ -31,23 +31,25 @@ const MainMenu = withRouter(({ history, menuSelection, setMenuSelection }) => {
|
||||
|
||||
const user = data.user
|
||||
|
||||
const userMenuOptions = [
|
||||
{ key: 'user', text: 'User Page', icon: 'user', onClick: () => history.push(`/u/${user.discord_id}`) },
|
||||
//{ key: 'settings', text: 'Settings', icon: 'settings', onClick: () => history.push('/u/settings') },
|
||||
{ key: 'sign-out', text: 'Sign Out', icon: 'sign out', onClick: () => window.location.assign('/logout') },
|
||||
]
|
||||
|
||||
const userMenuTrigger = (
|
||||
<span>
|
||||
<span style={{"paddingRight": "5px"}}>{user.username}</span>
|
||||
<Image src={user.avatar ?
|
||||
`https://cdn.discordapp.com/avatars/${user.discord_id}/${user.avatar}.png` :
|
||||
'https://cdn.discordapp.com/avatars/455039198672453645/088ae3838cc3b08b73f79aab0fefec2f.png'} avatar /> {/* If User has no avatar defaults to N-Zap user's avatar*/}
|
||||
</span>
|
||||
)
|
||||
|
||||
return (
|
||||
<div>
|
||||
<Menu.Item>
|
||||
<span style={{"paddingRight": "3px"}}>{user.username}</span>
|
||||
<Image src={`https://cdn.discordapp.com/avatars/${user.discord_id}/${user.avatar}.png`} avatar />
|
||||
<span style={{"paddingLeft": "10px"}}>
|
||||
<Popup
|
||||
position='bottom center'
|
||||
flowing
|
||||
hoverable
|
||||
trigger={<Icon name='log out' circular />}
|
||||
>
|
||||
<a href='/logout'>
|
||||
<Button secondary>Log Out</Button>
|
||||
</a>
|
||||
</Popup>
|
||||
</span>
|
||||
<Dropdown item icon={null} options={userMenuOptions} trigger={userMenuTrigger}/>
|
||||
</Menu.Item>
|
||||
</div>
|
||||
)
|
||||
|
||||
27
react-ui/src/components/SoloLadder/Build.js
vendored
27
react-ui/src/components/SoloLadder/Build.js
vendored
@@ -1,6 +1,6 @@
|
||||
/* eslint-disable jsx-a11y/alt-text */
|
||||
import React from 'react'
|
||||
import { Header, Segment, List, Grid } from 'semantic-ui-react'
|
||||
import { Header, Segment, List, Grid, Button, Popup } from 'semantic-ui-react'
|
||||
import weaponDict from '../../utils/english_internal.json'
|
||||
|
||||
import BDU from '../img/abilityIcons/BDU.png'
|
||||
@@ -30,7 +30,7 @@ import TI from '../img/abilityIcons/TI.png'
|
||||
import OS from '../img/abilityIcons/OS.png'
|
||||
import EMPTY from '../img/abilityIcons/EMPTY.png'
|
||||
|
||||
const Build = ({ build, existingAbilities, setAbilities }) => {
|
||||
const Build = ({ build, existingAbilities, setAbilities, removeBuildFunction }) => {
|
||||
|
||||
const lineStyle = {
|
||||
"display": "inline-block",
|
||||
@@ -114,6 +114,8 @@ const Build = ({ build, existingAbilities, setAbilities }) => {
|
||||
</span>
|
||||
)
|
||||
}
|
||||
|
||||
const buildTitle = !build.title || build.title === "" ? `${build.weapon} Build` : build.title
|
||||
|
||||
return (
|
||||
<div>
|
||||
@@ -122,30 +124,39 @@ const Build = ({ build, existingAbilities, setAbilities }) => {
|
||||
<Header size='huge' inverted>
|
||||
<img
|
||||
src={imageSource}
|
||||
/> {!build.title || build.title === "" ? `${build.weapon} Build` : build.title}
|
||||
/> {buildTitle}
|
||||
</Header>
|
||||
</div>
|
||||
<div style={{"paddingLeft": "13px"}}>
|
||||
<Grid stackable columns={4}>
|
||||
<Grid.Column>
|
||||
<div>
|
||||
<div style={{'float': 'none', 'whiteSpace': 'nowrap'}}>
|
||||
{build.headgear.map(abilityMap, {gearIndex: 0})}
|
||||
</div>
|
||||
<div>
|
||||
<div style={{'float': 'none', 'whiteSpace': 'nowrap'}}>
|
||||
{build.clothing.map(abilityMap, {gearIndex: 1})}
|
||||
</div>
|
||||
<div>
|
||||
<div style={{'float': 'none', 'whiteSpace': 'nowrap'}}>
|
||||
{build.shoes.map(abilityMap, {gearIndex: 2})}
|
||||
</div>
|
||||
</Grid.Column>
|
||||
<Grid.Column></Grid.Column>
|
||||
<Grid.Column>
|
||||
<List>
|
||||
{arrayOfSortedAbilityPoints().map(a => <List.Item key={a.fullName}>{a.ap} {a.fullName}</List.Item>)}
|
||||
</List>
|
||||
</Grid.Column>
|
||||
<Grid.Column></Grid.Column>
|
||||
<Grid.Column verticalAlign='bottom'>
|
||||
<i>Added {new Date(parseInt(build.createdAt)).toLocaleString('en-GB')}</i>
|
||||
{setAbilities ? null : <i>Added {new Date(parseInt(build.createdAt)).toLocaleString('en-GB')}</i>}
|
||||
{removeBuildFunction ?
|
||||
<span style={{'paddingLeft': '10px'}}>
|
||||
<Popup
|
||||
trigger={<Button circular size='mini' icon='trash' />}
|
||||
hoverable
|
||||
position='bottom right'
|
||||
><Button negative onClick={ () => removeBuildFunction(build) }>{'Delete'}</Button></Popup>
|
||||
</span>
|
||||
: null}
|
||||
</Grid.Column>
|
||||
</Grid>
|
||||
</div>
|
||||
|
||||
@@ -30,8 +30,8 @@ const BuildForm = ({ addBuild, setShowForm, setSuccessMsg }) => {
|
||||
setWeaponForm('')
|
||||
setTitle('')
|
||||
setAbilities([["", "", "", ""], ["", "", "", ""], ["", "", "", ""]])
|
||||
setSuccessMsg(true)
|
||||
setTimeout(() => { setSuccessMsg(false) }, 5000)
|
||||
setSuccessMsg('New build succesfully added!')
|
||||
setTimeout(() => { setSuccessMsg(null) }, 10000)
|
||||
setShowForm(false)
|
||||
}
|
||||
|
||||
|
||||
34
react-ui/src/components/SoloLadder/BuildTab.js
vendored
34
react-ui/src/components/SoloLadder/BuildTab.js
vendored
@@ -1,17 +1,19 @@
|
||||
import React, { useState } from 'react'
|
||||
import { useQuery, useMutation } from 'react-apollo-hooks'
|
||||
import { Button, Loader, Message } from 'semantic-ui-react'
|
||||
import { Button, Loader, Message, Popup } from 'semantic-ui-react'
|
||||
|
||||
import { addBuild } from '../../graphql/mutations/addBuild'
|
||||
import { searchForBuilds } from '../../graphql/queries/searchForBuilds'
|
||||
import { deleteBuild } from '../../graphql/mutations/deleteBuild'
|
||||
import BuildForm from './BuildForm'
|
||||
import Build from './Build'
|
||||
|
||||
const BuildTab = ({ user, userViewed }) => {
|
||||
const { data, error, loading } = useQuery(searchForBuilds, {variables: { discord_id: userViewed.discord_id }})
|
||||
const [ errorMsg, setErrorMsg ] = useState(null)
|
||||
const [ successMsg, setSuccessMsg ] = useState(false)
|
||||
const [ successMsg, setSuccessMsg ] = useState(null)
|
||||
const [ showForm, setShowForm ] = useState(false)
|
||||
const [ deleteConfirm, setDeleteConfirm ] = useState(false)
|
||||
|
||||
const handleError = (error) => {
|
||||
errorMsg(error.graphQLErrors[0].message)
|
||||
@@ -25,6 +27,23 @@ const BuildTab = ({ user, userViewed }) => {
|
||||
refetchQueries: [{ query: searchForBuilds, variables: { discord_id: userViewed.discord_id }} ]
|
||||
})
|
||||
|
||||
const deleteBuildMutation = useMutation(deleteBuild, {
|
||||
onError: handleError,
|
||||
refetchQueries: [{ query: searchForBuilds, variables: { discord_id: userViewed.discord_id }} ]
|
||||
})
|
||||
|
||||
const deleteBuildById = async ({ id, title, weapon }) => {
|
||||
await deleteBuildMutation({
|
||||
variables: { id }
|
||||
})
|
||||
|
||||
const buildTitle = title ? title : `${weapon} build`
|
||||
|
||||
setDeleteConfirm(false)
|
||||
setSuccessMsg(`Succesfully deleted ${buildTitle}`)
|
||||
setTimeout(() => { setSuccessMsg(null) }, 10000)
|
||||
}
|
||||
|
||||
if (loading) {
|
||||
return <div style={{"paddingTop": "25px", "paddingBottom": "20000px"}} ><Loader active inline='centered' /></div>
|
||||
}
|
||||
@@ -39,19 +58,22 @@ const BuildTab = ({ user, userViewed }) => {
|
||||
<div style={{"paddingBottom": "10px"}}>
|
||||
<Message
|
||||
success
|
||||
content='Adding the new build was succesful'
|
||||
content={successMsg}
|
||||
/>
|
||||
</div> : null}
|
||||
<div>
|
||||
{data.searchForBuilds.length >= 20 && user && user.discord_id === userViewed.discord_id ? 'Looks like you have 20 buids. Insane flex. Delete a build before adding a new one.' : null}
|
||||
{!user || user.discord_id !== userViewed.discord_id || data.searchForBuilds.length >= 20 ?
|
||||
null :
|
||||
<Button circular size='tiny' icon={showForm ? 'minus' : 'plus'} onClick={ () => setShowForm(!showForm) }
|
||||
/>}
|
||||
<Button circular size='tiny' icon={showForm ? 'minus' : 'plus'} onClick={ () => setShowForm(!showForm) } />
|
||||
}
|
||||
{showForm ? <div style={{"paddingTop": "10px"}}><BuildForm addBuild={addBuildMutation} setShowForm={setShowForm} setSuccessMsg={setSuccessMsg}/></div> : null}
|
||||
</div>
|
||||
<div style={{"paddingTop": "10px"}}>
|
||||
{data.searchForBuilds.map(b => <div key={b.id} style={{"paddingTop": "10px"}}><Build build={b}/></div>)}
|
||||
{data.searchForBuilds.map(b =>
|
||||
<div key={b.id} style={{"paddingTop": "10px"}}>
|
||||
<Build build={b} removeBuildFunction={deleteBuildById} />
|
||||
</div>)}
|
||||
{data.searchForBuilds.length === 0 ? 'So far this user has no builds!' : null}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -63,7 +63,7 @@ const UserPage = ({ userIdOrName }) => {
|
||||
<Grid stackable>
|
||||
<Grid.Column width={3}>
|
||||
<Image
|
||||
src={`https://cdn.discordapp.com/avatars/${userData.discord_id}/${userData.avatar}.png`}
|
||||
src={userData.avatar ? `https://cdn.discordapp.com/avatars/${userData.discord_id}/${userData.avatar}.png` : 'https://cdn.discordapp.com/avatars/455039198672453645/088ae3838cc3b08b73f79aab0fefec2f.png'}
|
||||
rounded
|
||||
/>
|
||||
</Grid.Column>
|
||||
@@ -75,7 +75,6 @@ const UserPage = ({ userIdOrName }) => {
|
||||
</List.Item>
|
||||
{twitchDiscord()}
|
||||
{/* "Member of Team Olive // Captain of Team Olive" */}
|
||||
{/* Weapons?" */}
|
||||
</List>
|
||||
</Grid.Column>
|
||||
</Grid>
|
||||
|
||||
76
react-ui/src/components/XSearch/InfoPlayer.js
vendored
76
react-ui/src/components/XSearch/InfoPlayer.js
vendored
@@ -1,6 +1,6 @@
|
||||
import React, { useEffect, useState } from 'react'
|
||||
import { useQuery } from 'react-apollo-hooks'
|
||||
import { Loader, Header, Image, Icon } from 'semantic-ui-react'
|
||||
import { Loader, Header, Image, Icon, List } from 'semantic-ui-react'
|
||||
|
||||
import { playerInfo } from '../../graphql/queries/playerInfo'
|
||||
import TopPlacementTable from './TopPlacementsTable'
|
||||
@@ -21,42 +21,62 @@ const InfoPlayer = ({ uid, setMenuSelection, twitter }) => {
|
||||
|
||||
if (setMenuSelection) { //if we're on /xsearch
|
||||
setMenuSelection('search')
|
||||
document.title = `${data.playerInfo.player.alias ? data.playerInfo.player.alias : data.playerInfo.player.name} Top 500 X Rank - sendou.ink`
|
||||
}
|
||||
const placements = data.playerInfo.placements
|
||||
if (data.playerInfo) {
|
||||
const placements = data.playerInfo.placements
|
||||
|
||||
//reducing placements to top sz, tc etc. rank and x power
|
||||
const tops = ["", "szTop", "tcTop", "rmTop", "cbTop"]
|
||||
const exs = ["", "szX", "tcX", "rmX", "cbX"]
|
||||
setTop(placements.reduce((acc, cur) => {
|
||||
const topKey = tops[cur.mode]
|
||||
const xKey = exs[cur.mode]
|
||||
if (!acc[xKey]) {
|
||||
acc[xKey] = cur
|
||||
acc[topKey] = cur
|
||||
return acc
|
||||
}
|
||||
if (acc[xKey].x_power < cur.x_power) {
|
||||
acc[xKey] = cur
|
||||
}
|
||||
if (acc[topKey].rank > cur.rank) {
|
||||
acc[topKey] = cur
|
||||
}
|
||||
|
||||
//reducing placements to top sz, tc etc. rank and x power
|
||||
const tops = ["", "szTop", "tcTop", "rmTop", "cbTop"]
|
||||
const exs = ["", "szX", "tcX", "rmX", "cbX"]
|
||||
setTop(placements.reduce((acc, cur) => {
|
||||
const topKey = tops[cur.mode]
|
||||
const xKey = exs[cur.mode]
|
||||
if (!acc[xKey]) {
|
||||
acc[xKey] = cur
|
||||
acc[topKey] = cur
|
||||
return acc
|
||||
}
|
||||
if (acc[xKey].x_power < cur.x_power) {
|
||||
acc[xKey] = cur
|
||||
}
|
||||
if (acc[topKey].rank > cur.rank) {
|
||||
acc[topKey] = cur
|
||||
}
|
||||
|
||||
return acc
|
||||
}, {
|
||||
szX: null, szTop: null,
|
||||
tcX: null, tcTop: null,
|
||||
rmX: null, rmTop: null,
|
||||
cbX: null, cbTop: null
|
||||
}))
|
||||
}, {
|
||||
szX: null, szTop: null,
|
||||
tcX: null, tcTop: null,
|
||||
rmX: null, rmTop: null,
|
||||
cbX: null, cbTop: null
|
||||
}))
|
||||
}
|
||||
|
||||
}, [data, loading, setMenuSelection])
|
||||
|
||||
if (loading || top.length === 0) {
|
||||
const addXRankHelp = (
|
||||
<div>
|
||||
This user has no X Rank profile set up. If you are the owner of this user page here is how you can set it up:
|
||||
<div style={{'paddingTop': "5px"}}>
|
||||
<List ordered>
|
||||
<List.Item>Finish an X rank season in the Top 500 in at least one mode.</List.Item>
|
||||
<List.Item>Send your Twitter handle to Sendou via DM.</List.Item>
|
||||
<List.Item>Add your Twitter account to your profile on Discord, verify it and make sure it's set to appear publicly.</List.Item>
|
||||
<List.Item>Log in to sendou.ink</List.Item>
|
||||
</List>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
|
||||
if (!uid && !twitter) return addXRankHelp
|
||||
|
||||
if (loading) {
|
||||
return <div style={{"paddingTop": "25px", "paddingBottom": "20000px"}} ><Loader active inline='centered' /></div>
|
||||
}
|
||||
if (error) {
|
||||
if (error.message === 'GraphQL error: player not found') {
|
||||
return addXRankHelp
|
||||
}
|
||||
return <div style={{"color": "red"}}>{error.message}</div>
|
||||
}
|
||||
const playerData = data.playerInfo.player
|
||||
|
||||
7
react-ui/src/graphql/mutations/deleteBuild.js
vendored
Normal file
7
react-ui/src/graphql/mutations/deleteBuild.js
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
import { gql } from 'apollo-boost'
|
||||
|
||||
export const deleteBuild = gql`
|
||||
mutation deleteBuild ($id: ID!) {
|
||||
deleteBuild(id: $id)
|
||||
}
|
||||
`
|
||||
Reference in New Issue
Block a user