edit build feature

This commit is contained in:
Sendou
2019-06-18 18:22:26 +03:00
parent 20a6e6c651
commit c1a744f402
16 changed files with 113 additions and 30 deletions

View File

@@ -1,13 +1,13 @@
{
"files": {
"main.js": "/static/js/main.86ccd324.chunk.js",
"main.js.map": "/static/js/main.86ccd324.chunk.js.map",
"main.js": "/static/js/main.97e5d573.chunk.js",
"main.js.map": "/static/js/main.97e5d573.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.b7b85dbc.chunk.js": "/static/js/2.b7b85dbc.chunk.js",
"static/js/2.b7b85dbc.chunk.js.map": "/static/js/2.b7b85dbc.chunk.js.map",
"static/js/2.baa711f5.chunk.js": "/static/js/2.baa711f5.chunk.js",
"static/js/2.baa711f5.chunk.js.map": "/static/js/2.baa711f5.chunk.js.map",
"index.html": "/index.html",
"precache-manifest.20a9428738b056e2cc2990106f62ee68.js": "/precache-manifest.20a9428738b056e2cc2990106f62ee68.js",
"precache-manifest.412823941c1ccf3139d775a84a7aea26.js": "/precache-manifest.412823941c1ccf3139d775a84a7aea26.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",

View File

@@ -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.b7b85dbc.chunk.js"></script><script src="/static/js/main.86ccd324.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.baa711f5.chunk.js"></script><script src="/static/js/main.97e5d573.chunk.js"></script></body></html>

View File

@@ -1,15 +1,15 @@
self.__precacheManifest = (self.__precacheManifest || []).concat([
{
"revision": "53f86b82e3795ff354650567432f27ef",
"revision": "4d4b01bf8c7a464d45912d60be429d52",
"url": "/index.html"
},
{
"revision": "9af65b6b4828554f857a",
"url": "/static/js/2.b7b85dbc.chunk.js"
"revision": "f9266b6cfbee5aa9a84d",
"url": "/static/js/2.baa711f5.chunk.js"
},
{
"revision": "208269270514d2309ed1",
"url": "/static/js/main.86ccd324.chunk.js"
"revision": "fb1e9d096c18eff7828f",
"url": "/static/js/main.97e5d573.chunk.js"
},
{
"revision": "42ac5946195a7306e2a5",

View File

@@ -14,7 +14,7 @@
importScripts("https://storage.googleapis.com/workbox-cdn/releases/4.3.0/workbox-sw.js");
importScripts(
"/precache-manifest.20a9428738b056e2cc2990106f62ee68.js"
"/precache-manifest.412823941c1ccf3139d775a84a7aea26.js"
);
self.addEventListener('message', (event) => {

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

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

File diff suppressed because one or more lines are too long

View File

@@ -240,6 +240,14 @@ const typeDefs = gql`
deleteBuild(
id: ID!
): Boolean
updateBuild(
id: ID!
weapon: String!
title: String
headgear: [Ability!]!
clothing: [Ability!]!
shoes: [Ability!]!
): Boolean
}
`
@@ -649,6 +657,9 @@ const resolvers = {
const build = await Build.findOne({ _id: args.id})
if (!build) throw new UserInputError('no build found with the id', {
invalidArgs: args,
})
if (ctx.user.discord_id !== build.discord_id) throw new AuthenticationError('no privileges')
try {
@@ -659,6 +670,25 @@ const resolvers = {
})
}
return true
},
updateBuild: async (root, args, ctx) => {
if (!ctx.user) throw new AuthenticationError('not authenticated')
const build = await Build.findOne({ _id: args.id})
if (!build) throw new UserInputError('no build found with the id', {
invalidArgs: args,
})
if (ctx.user.discord_id !== build.discord_id) throw new AuthenticationError('no privileges to edit the build')
await Build.findByIdAndUpdate(build._id, { ...args })
.catch(e => {
throw new UserInputError(error.message, {
invalidArgs: args,
})
})
return true
}
},

View File

@@ -1,7 +1,8 @@
/* eslint-disable jsx-a11y/alt-text */
import React from 'react'
import React, { useState } from 'react'
import { Header, Segment, List, Grid, Button, Popup } from 'semantic-ui-react'
import weaponDict from '../../utils/english_internal.json'
import BuildForm from './BuildForm'
import BDU from '../img/abilityIcons/BDU.png'
import BRU from '../img/abilityIcons/BRU.png'
@@ -30,7 +31,10 @@ 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, removeBuildFunction }) => {
const Build = ({ build, existingAbilities, setAbilities, removeBuildFunction, editBuildFunction }) => {
const [showEdit, setShowEdit] = useState(false)
if (showEdit) return <BuildForm existingBuild={build} setShowEdit={setShowEdit} editBuildFunction={editBuildFunction} />
const lineStyle = {
"display": "inline-block",
@@ -148,10 +152,15 @@ const Build = ({ build, existingAbilities, setAbilities, removeBuildFunction })
</Grid.Column>
<Grid.Column verticalAlign='bottom'>
{setAbilities ? null : <i>Added {new Date(parseInt(build.createdAt)).toLocaleString('en-GB')}</i>}
{removeBuildFunction ?
<span style={{'paddingLeft': '10px'}}>
{removeBuildFunction ? //if they can remove they can edit
<span style={{'paddingLeft': '10px', 'float': 'none', 'whiteSpace': 'nowrap'}}>
<Popup
trigger={<Button circular size='mini' icon='trash' />}
trigger={<Button circular size='mini' icon='edit' />}
hoverable
position='bottom right'
><Button onClick={ () => setShowEdit(true) }>{'Edit'}</Button></Popup>
<Popup
trigger={<Button circular size='mini' negative icon='trash' />}
hoverable
position='bottom right'
><Button negative onClick={ () => removeBuildFunction(build) }>{'Delete'}</Button></Popup>

View File

@@ -4,12 +4,13 @@ import WeaponForm from '../XSearch/WeaponForm'
import Build from './Build'
import AbilityButtons from './AbilityButtons'
const BuildForm = ({ addBuild, setShowForm, setSuccessMsg }) => {
const [weaponForm, setWeaponForm] = useState('')
const [title, setTitle] = useState('')
const [abilities, setAbilities] = useState([["", "", "", ""], ["", "", "", ""], ["", "", "", ""]])
const BuildForm = ({ addBuild, setShowForm, setSuccessMsg, existingBuild, setShowEdit, editBuildFunction }) => {
const [weaponForm, setWeaponForm] = useState(existingBuild ? existingBuild.weapon : '')
const [title, setTitle] = useState(existingBuild ? existingBuild.title : '')
const [abilities, setAbilities] = useState(existingBuild ? [[...existingBuild.headgear], [...existingBuild.clothing], [...existingBuild.shoes]] : [["", "", "", ""], ["", "", "", ""], ["", "", "", ""]])
const build = {
id: existingBuild ? existingBuild.id : null,
weapon: weaponForm,
title,
headgear: abilities[0],
@@ -34,7 +35,7 @@ const BuildForm = ({ addBuild, setShowForm, setSuccessMsg }) => {
setTimeout(() => { setSuccessMsg(null) }, 10000)
setShowForm(false)
}
function isBuildComplete() {
if (title.length > 100) return false
if (weaponForm === '') return false
@@ -73,7 +74,15 @@ const BuildForm = ({ addBuild, setShowForm, setSuccessMsg }) => {
<AbilityButtons abilities={abilities} setAbilities={setAbilities} />
</div>
<div style={{"paddingTop": "10px"}}>
{editBuildFunction ?
<><Button disabled={!isBuildComplete()} onClick={() => {
editBuildFunction(build)
setShowEdit(false)
window.scrollTo(0, 0)
}}>Edit build</Button>
<Button negative onClick={() => setShowEdit(false)}>Cancel</Button></> :
<Button disabled={!isBuildComplete()} onClick={submit}>Add build</Button>
}
</div>
</div>
)

View File

@@ -5,6 +5,7 @@ import { Button, Loader, Message } from 'semantic-ui-react'
import { addBuild } from '../../graphql/mutations/addBuild'
import { searchForBuilds } from '../../graphql/queries/searchForBuilds'
import { deleteBuild } from '../../graphql/mutations/deleteBuild'
import { updateBuild } from '../../graphql/mutations/updateBuild'
import BuildForm from './BuildForm'
import Build from './Build'
@@ -31,6 +32,11 @@ const BuildTab = ({ user, userViewed }) => {
refetchQueries: [{ query: searchForBuilds, variables: { discord_id: userViewed.discord_id }} ]
})
const editBuildMutation = useMutation(updateBuild, {
onError: handleError,
refetchQueries: [{ query: searchForBuilds, variables: { discord_id: userViewed.discord_id }} ]
})
const deleteBuildById = async ({ id, title, weapon }) => {
await deleteBuildMutation({
variables: { id }
@@ -38,7 +44,16 @@ const BuildTab = ({ user, userViewed }) => {
const buildTitle = title ? title : `${weapon} build`
setSuccessMsg(`Succesfully deleted ${buildTitle}`)
setSuccessMsg(`Successfully deleted ${buildTitle}`)
setTimeout(() => { setSuccessMsg(null) }, 10000)
}
const editBuildById = async (build) => {
await editBuildMutation({
variables: { ...build }
})
setSuccessMsg('Build successfully edited')
setTimeout(() => { setSuccessMsg(null) }, 10000)
}
@@ -51,6 +66,7 @@ const BuildTab = ({ user, userViewed }) => {
}
const removeBuildFunction = user && user.discord_id === userViewed.discord_id ? deleteBuildById : null
const editBuildFunction = user && user.discord_id === userViewed.discord_id ? editBuildById : null
return (
<div>
@@ -72,7 +88,12 @@ const BuildTab = ({ user, userViewed }) => {
<div style={{"paddingTop": "10px"}}>
{data.searchForBuilds.map(b =>
<div key={b.id} style={{"paddingTop": "10px"}}>
<Build build={b} removeBuildFunction={removeBuildFunction} setSuccessMsg={setSuccessMsg} />
<Build
build={b}
removeBuildFunction={removeBuildFunction}
editBuildFunction={editBuildFunction}
setSuccessMsg={setSuccessMsg}
/>
</div>)}
{data.searchForBuilds.length === 0 ? 'So far this user has no builds!' : null}
</div>

View File

@@ -0,0 +1,14 @@
import { gql } from 'apollo-boost'
export const updateBuild = gql`
mutation updateBuild ($id: ID!, $weapon: String!, $title: String, $headgear: [Ability!]!, $clothing: [Ability!]!, $shoes: [Ability!]!) {
updateBuild(
id: $id,
weapon: $weapon,
title: $title,
headgear: $headgear,
clothing: $clothing,
shoes: $shoes
)
}
`