Merge pull request #3 from jedmund/routing-refactor
Refactor routing to use Next.js routing instead of react-router-dom
This commit is contained in:
commit
fd428e8af7
19 changed files with 294 additions and 365 deletions
|
|
@ -1,29 +0,0 @@
|
|||
import React from 'react'
|
||||
import { Route, Routes, useNavigate } from 'react-router-dom'
|
||||
|
||||
import Header from '~components/Header'
|
||||
|
||||
import NewRoute from '~routes/NewRoute'
|
||||
import PartyRoute from '~routes/PartyRoute'
|
||||
import PartiesRoute from '~routes/PartiesRoute'
|
||||
import ProfileRoute from '~routes/ProfileRoute'
|
||||
|
||||
|
||||
const App = () => {
|
||||
const navigate = useNavigate()
|
||||
const route = (pathname: string) => navigate(pathname)
|
||||
|
||||
return (
|
||||
<div>
|
||||
<Header navigate={route} />
|
||||
<Routes>
|
||||
<Route path='/' element={<NewRoute />} />
|
||||
<Route path='/parties/' element={<PartiesRoute />} />
|
||||
<Route path='/p/:hash' element={<PartyRoute />} />
|
||||
<Route path='/:username' element={<ProfileRoute />} />
|
||||
</Routes>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default App
|
||||
|
|
@ -1,36 +1,36 @@
|
|||
.Header {
|
||||
#Header {
|
||||
display: flex;
|
||||
height: 34px;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.Header .right {
|
||||
#right {
|
||||
display: flex;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.Header .push {
|
||||
margin-left: auto;
|
||||
}
|
||||
|
||||
.dropdown {
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.dropdown:hover {
|
||||
&:hover {
|
||||
padding-right: 50px;
|
||||
padding-bottom: 16px;
|
||||
}
|
||||
|
||||
.dropdown:hover .Button .icon {
|
||||
.Button .icon {
|
||||
color: #2360C5;
|
||||
}
|
||||
|
||||
.dropdown:hover .Button .text {
|
||||
.Button .text {
|
||||
color: #555;
|
||||
}
|
||||
|
||||
.dropdown:hover .Menu {
|
||||
.Menu {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.push {
|
||||
margin-left: auto;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,29 +1,30 @@
|
|||
import React, { useEffect, useState } from 'react'
|
||||
import { useNavigate, useLocation } from 'react-router-dom'
|
||||
import React, { useContext, useEffect, useState } from 'react'
|
||||
import { useCookies } from 'react-cookie'
|
||||
import { useRouter } from 'next/router'
|
||||
|
||||
import AppContext from '~context/AppContext'
|
||||
|
||||
import Button from '~components/Button'
|
||||
import HeaderMenu from '~components/HeaderMenu'
|
||||
|
||||
import './index.scss'
|
||||
|
||||
interface Props {
|
||||
navigate: (pathname: string) => void
|
||||
}
|
||||
interface Props {}
|
||||
|
||||
const Header = (props: Props) => {
|
||||
const { editable, setEditable, setAuthenticated } = useContext(AppContext)
|
||||
|
||||
const [username, setUsername] = useState(undefined)
|
||||
const [cookies, setCookie, removeCookie] = useCookies(['user'])
|
||||
const [cookies, _, removeCookie] = useCookies(['user'])
|
||||
|
||||
let navigate = useNavigate()
|
||||
let location = useLocation()
|
||||
|
||||
const route = (pathname: string) => props.navigate(pathname)
|
||||
const router = useRouter()
|
||||
|
||||
useEffect(() => {
|
||||
if (cookies.user) {
|
||||
setUsername(cookies.user.username)
|
||||
console.log(`Logged in as user "${cookies.user.username}"`)
|
||||
} else {
|
||||
console.log('You are currently not logged in.')
|
||||
}
|
||||
}, [cookies])
|
||||
|
||||
|
|
@ -39,29 +40,34 @@ const Header = (props: Props) => {
|
|||
}
|
||||
|
||||
function newParty() {
|
||||
navigate('/')
|
||||
router.push('/')
|
||||
}
|
||||
|
||||
function logout() {
|
||||
removeCookie('user')
|
||||
window.history.replaceState(null, `Grid Tool`, `/`)
|
||||
navigate(0)
|
||||
|
||||
setAuthenticated(false)
|
||||
if (editable) setEditable(false)
|
||||
|
||||
// How can we log out without navigating to root
|
||||
router.push('/')
|
||||
return false
|
||||
}
|
||||
|
||||
return (
|
||||
<nav className="Header">
|
||||
<div className="left">
|
||||
<nav id="Header">
|
||||
<div id="left">
|
||||
<div className="dropdown">
|
||||
<Button type="menu">Menu</Button>
|
||||
<HeaderMenu username={username} logout={logout} />
|
||||
</div>
|
||||
</div>
|
||||
<div className="push" />
|
||||
<div className="right">
|
||||
{/* { (location.pathname.includes('/p/')) ?
|
||||
<div id="right">
|
||||
{ (editable && router.route === '/p/[slug]') ?
|
||||
<Button color="red" type="link" click={() => {}}>Delete</Button> : ''
|
||||
} */}
|
||||
{ (location.pathname.includes('/p/')) ?
|
||||
}
|
||||
{ (router.route === '/p/[slug]') ?
|
||||
<Button type="link" click={copyToClipboard}>Copy link</Button> : ''
|
||||
}
|
||||
<Button type="new" click={newParty}>New</Button>
|
||||
|
|
|
|||
|
|
@ -1,24 +1,29 @@
|
|||
import React from 'react'
|
||||
import './index.scss'
|
||||
|
||||
import React, { useContext } from 'react'
|
||||
import Link from 'next/link'
|
||||
|
||||
import LoginModal from '~components/LoginModal'
|
||||
import SignupModal from '~components/SignupModal'
|
||||
|
||||
import AppContext from '~context/AppContext'
|
||||
|
||||
import { useModal as useSignupModal } from '~utils/useModal'
|
||||
import { useModal as useLoginModal } from '~utils/useModal'
|
||||
import { useModal as useAboutModal } from '~utils/useModal'
|
||||
|
||||
import { Link, Route } from 'react-router-dom'
|
||||
import Profile from '~routes/ProfileRoute'
|
||||
import AboutModal from '~components/AboutModal'
|
||||
|
||||
|
||||
interface Props {
|
||||
username?: string
|
||||
username: string,
|
||||
logout: () => void
|
||||
}
|
||||
|
||||
const HeaderMenu = (props: Props) => {
|
||||
const { authenticated } = useContext(AppContext)
|
||||
|
||||
const { open: signupOpen, openModal: openSignupModal, closeModal: closeSignupModal } = useSignupModal()
|
||||
const { open: loginOpen, openModal: openLoginModal, closeModal: closeLoginModal } = useLoginModal()
|
||||
const { open: aboutOpen, openModal: openAboutModal, closeModal: closeAboutModal } = useAboutModal()
|
||||
|
|
@ -29,7 +34,7 @@ const HeaderMenu = (props: Props) => {
|
|||
<ul className="Menu auth">
|
||||
<div className="MenuGroup">
|
||||
<li className="MenuItem">
|
||||
<Link to={`/${props.username}` || ''}>My Parties</Link>
|
||||
<Link href={`/${props.username}` || ''}>My Parties</Link>
|
||||
</li>
|
||||
</div>
|
||||
<div className="MenuGroup">
|
||||
|
|
@ -38,9 +43,9 @@ const HeaderMenu = (props: Props) => {
|
|||
<AboutModal close={closeAboutModal} />
|
||||
) : null}
|
||||
|
||||
{/* <li className="MenuItem">
|
||||
<Link to='/guides'>Guides</Link>
|
||||
</li> */}
|
||||
<li className="MenuItem">
|
||||
<Link href='/guides'>Guides</Link>
|
||||
</li>
|
||||
</div>
|
||||
<div className="MenuGroup">
|
||||
<li className="MenuItem" onClick={props.logout}>Logout</li>
|
||||
|
|
@ -79,7 +84,7 @@ const HeaderMenu = (props: Props) => {
|
|||
)
|
||||
}
|
||||
|
||||
return (props.username !== undefined) ? authItems() : unauthItems()
|
||||
return (authenticated) ? authItems() : unauthItems()
|
||||
}
|
||||
|
||||
export default HeaderMenu
|
||||
17
components/Layout/index.tsx
Normal file
17
components/Layout/index.tsx
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
import type { ReactElement } from 'react'
|
||||
import Header from '~components/Header'
|
||||
|
||||
interface Props {
|
||||
children: ReactElement
|
||||
}
|
||||
|
||||
const Layout = ({children}: Props) => {
|
||||
return (
|
||||
<>
|
||||
<Header />
|
||||
<main>{children}</main>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
export default Layout
|
||||
|
|
@ -1,6 +1,8 @@
|
|||
import React, { useState } from 'react'
|
||||
import React, { useContext, useState } from 'react'
|
||||
import { withCookies, Cookies } from 'react-cookie'
|
||||
import { createPortal } from 'react-dom'
|
||||
|
||||
import AppContext from '~context/AppContext'
|
||||
import api from '~utils/api'
|
||||
|
||||
import Button from '~components/Button'
|
||||
|
|
@ -26,6 +28,8 @@ interface ErrorMap {
|
|||
const emailRegex = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/
|
||||
|
||||
const LoginModal = (props: Props) => {
|
||||
const { setAuthenticated } = useContext(AppContext)
|
||||
|
||||
const emailInput: React.RefObject<HTMLInputElement> = React.createRef()
|
||||
const passwordInput: React.RefObject<HTMLInputElement> = React.createRef()
|
||||
const form: React.RefObject<HTMLInputElement>[] = [emailInput, passwordInput]
|
||||
|
|
@ -98,6 +102,8 @@ const LoginModal = (props: Props) => {
|
|||
}
|
||||
|
||||
cookies.set('user', cookieObj, { path: '/'})
|
||||
setAuthenticated(true)
|
||||
|
||||
props.close()
|
||||
}, (error) => {
|
||||
console.error(error)
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@ interface Props {
|
|||
}
|
||||
|
||||
const Party = (props: Props) => {
|
||||
const [cookies, setCookie] = useCookies(['user'])
|
||||
const [cookies, _] = useCookies(['user'])
|
||||
|
||||
const headers = (cookies.user != null) ? {
|
||||
headers: {
|
||||
|
|
|
|||
|
|
@ -67,7 +67,7 @@ const PartySegmentedControl = (props: Props) => {
|
|||
|
||||
{
|
||||
(() => {
|
||||
if (props.selectedTab == GridType.Weapon) {
|
||||
if (props.editable && props.selectedTab == GridType.Weapon) {
|
||||
return extraToggle
|
||||
}
|
||||
})()
|
||||
|
|
|
|||
10
context/AppContext.tsx
Normal file
10
context/AppContext.tsx
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
import { createContext } from 'react'
|
||||
|
||||
const AppContext = createContext({
|
||||
authenticated: false,
|
||||
editable: false,
|
||||
setAuthenticated: (auth: boolean) => {},
|
||||
setEditable: (editable: boolean) => {}
|
||||
})
|
||||
|
||||
export default AppContext
|
||||
|
|
@ -1,11 +1,20 @@
|
|||
/** @type {import('next').NextConfig} */
|
||||
const path = require('path')
|
||||
|
||||
module.exports = {reactStrictMode: true,
|
||||
module.exports = {
|
||||
reactStrictMode: true,
|
||||
sassOptions: {
|
||||
prependData: '@import "variables";',
|
||||
includePaths: [path.join(__dirname, 'styles')],
|
||||
},
|
||||
async rewrites() {
|
||||
return [
|
||||
{
|
||||
source: '/',
|
||||
destination: '/new'
|
||||
}
|
||||
]
|
||||
},
|
||||
webpack(config) {
|
||||
config.module.rules.push({
|
||||
test: /\.svg$/,
|
||||
|
|
@ -18,4 +27,3 @@ module.exports = {reactStrictMode: true,
|
|||
return config;
|
||||
},
|
||||
};
|
||||
|
||||
|
|
|
|||
58
package-lock.json
generated
58
package-lock.json
generated
|
|
@ -20,7 +20,6 @@
|
|||
"react-cookie": "^4.1.1",
|
||||
"react-dom": "^17.0.2",
|
||||
"react-i18next": "^11.15.3",
|
||||
"react-router-dom": "^6.2.1",
|
||||
"sass": "^1.49.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
|
@ -4776,14 +4775,6 @@
|
|||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/history": {
|
||||
"version": "5.2.0",
|
||||
"resolved": "https://registry.npmjs.org/history/-/history-5.2.0.tgz",
|
||||
"integrity": "sha512-uPSF6lAJb3nSePJ43hN3eKj1dTWpN9gMod0ZssbFTIsen+WehTmEadgL+kg78xLJFdRfrrC//SavDzmRVdE+Ig==",
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.7.6"
|
||||
}
|
||||
},
|
||||
"node_modules/hoist-non-react-statics": {
|
||||
"version": "3.3.2",
|
||||
"resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz",
|
||||
|
|
@ -5891,30 +5882,6 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"node_modules/react-router": {
|
||||
"version": "6.2.1",
|
||||
"resolved": "https://registry.npmjs.org/react-router/-/react-router-6.2.1.tgz",
|
||||
"integrity": "sha512-2fG0udBtxou9lXtK97eJeET2ki5//UWfQSl1rlJ7quwe6jrktK9FCCc8dQb5QY6jAv3jua8bBQRhhDOM/kVRsg==",
|
||||
"dependencies": {
|
||||
"history": "^5.2.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": ">=16.8"
|
||||
}
|
||||
},
|
||||
"node_modules/react-router-dom": {
|
||||
"version": "6.2.1",
|
||||
"resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.2.1.tgz",
|
||||
"integrity": "sha512-I6Zax+/TH/cZMDpj3/4Fl2eaNdcvoxxHoH1tYOREsQ22OKDYofGebrNm6CTPUcvLvZm63NL/vzCYdjf9CUhqmA==",
|
||||
"dependencies": {
|
||||
"history": "^5.2.0",
|
||||
"react-router": "6.2.1"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": ">=16.8",
|
||||
"react-dom": ">=16.8"
|
||||
}
|
||||
},
|
||||
"node_modules/react-style-singleton": {
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/react-style-singleton/-/react-style-singleton-2.1.1.tgz",
|
||||
|
|
@ -10095,14 +10062,6 @@
|
|||
"has-symbols": "^1.0.2"
|
||||
}
|
||||
},
|
||||
"history": {
|
||||
"version": "5.2.0",
|
||||
"resolved": "https://registry.npmjs.org/history/-/history-5.2.0.tgz",
|
||||
"integrity": "sha512-uPSF6lAJb3nSePJ43hN3eKj1dTWpN9gMod0ZssbFTIsen+WehTmEadgL+kg78xLJFdRfrrC//SavDzmRVdE+Ig==",
|
||||
"requires": {
|
||||
"@babel/runtime": "^7.7.6"
|
||||
}
|
||||
},
|
||||
"hoist-non-react-statics": {
|
||||
"version": "3.3.2",
|
||||
"resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz",
|
||||
|
|
@ -10893,23 +10852,6 @@
|
|||
"tslib": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"react-router": {
|
||||
"version": "6.2.1",
|
||||
"resolved": "https://registry.npmjs.org/react-router/-/react-router-6.2.1.tgz",
|
||||
"integrity": "sha512-2fG0udBtxou9lXtK97eJeET2ki5//UWfQSl1rlJ7quwe6jrktK9FCCc8dQb5QY6jAv3jua8bBQRhhDOM/kVRsg==",
|
||||
"requires": {
|
||||
"history": "^5.2.0"
|
||||
}
|
||||
},
|
||||
"react-router-dom": {
|
||||
"version": "6.2.1",
|
||||
"resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.2.1.tgz",
|
||||
"integrity": "sha512-I6Zax+/TH/cZMDpj3/4Fl2eaNdcvoxxHoH1tYOREsQ22OKDYofGebrNm6CTPUcvLvZm63NL/vzCYdjf9CUhqmA==",
|
||||
"requires": {
|
||||
"history": "^5.2.0",
|
||||
"react-router": "6.2.1"
|
||||
}
|
||||
},
|
||||
"react-style-singleton": {
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/react-style-singleton/-/react-style-singleton-2.1.1.tgz",
|
||||
|
|
|
|||
|
|
@ -25,7 +25,6 @@
|
|||
"react-cookie": "^4.1.1",
|
||||
"react-dom": "^17.0.2",
|
||||
"react-i18next": "^11.15.3",
|
||||
"react-router-dom": "^6.2.1",
|
||||
"sass": "^1.49.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
|
|
|||
|
|
@ -1,15 +1,10 @@
|
|||
import React, { useEffect, useState } from 'react'
|
||||
import { withCookies, useCookies } from 'react-cookie'
|
||||
import { useParams, useNavigate } from 'react-router-dom'
|
||||
import { useRouter } from 'next/router'
|
||||
|
||||
import api from '~utils/api'
|
||||
|
||||
import GridRep from '~components/GridRep'
|
||||
import GridRepCollection from '~components/GridRepCollection'
|
||||
import { composeInitialProps } from 'react-i18next'
|
||||
|
||||
interface Props {
|
||||
username: string
|
||||
}
|
||||
|
||||
interface User {
|
||||
id: string
|
||||
|
|
@ -24,10 +19,8 @@ interface Party {
|
|||
}
|
||||
|
||||
const ProfileRoute: React.FC = () => {
|
||||
const params = useParams()
|
||||
const navigate = useNavigate()
|
||||
|
||||
const [cookies, setCookie] = useCookies(['user'])
|
||||
const router = useRouter()
|
||||
const { username } = router.query
|
||||
|
||||
const [found, setFound] = useState(false)
|
||||
const [loading, setLoading] = useState(true)
|
||||
|
|
@ -38,12 +31,10 @@ const ProfileRoute: React.FC = () => {
|
|||
granblueId: 0
|
||||
})
|
||||
|
||||
const username = params.username || ''
|
||||
|
||||
useEffect(() => {
|
||||
console.log(`Fetching profile for ${username}...`)
|
||||
fetchProfile(username)
|
||||
}, [])
|
||||
fetchProfile(username as string)
|
||||
}, [username])
|
||||
|
||||
async function fetchProfile(username: string) {
|
||||
api.endpoints.users.getOne({ id: username })
|
||||
|
|
@ -81,7 +72,7 @@ const ProfileRoute: React.FC = () => {
|
|||
}
|
||||
|
||||
function goTo(shortcode: string) {
|
||||
navigate(`/p/${shortcode}`)
|
||||
router.push(`/p/${shortcode}`)
|
||||
}
|
||||
|
||||
function renderGrids() {
|
||||
|
|
@ -126,7 +117,4 @@ const ProfileRoute: React.FC = () => {
|
|||
}
|
||||
}
|
||||
|
||||
export default
|
||||
withCookies(
|
||||
ProfileRoute
|
||||
)
|
||||
export default ProfileRoute
|
||||
|
|
@ -1,9 +1,25 @@
|
|||
import '../styles/globals.scss'
|
||||
|
||||
import { useState } from 'react'
|
||||
import { CookiesProvider } from 'react-cookie'
|
||||
|
||||
import Layout from '~components/Layout'
|
||||
import AppContext from '~context/AppContext'
|
||||
|
||||
import type { AppProps } from 'next/app'
|
||||
|
||||
function MyApp({ Component, pageProps }: AppProps) {
|
||||
return <Component {...pageProps} />
|
||||
const [authenticated, setAuthenticated] = useState(false)
|
||||
const [editable, setEditable] = useState(false)
|
||||
return (
|
||||
<CookiesProvider>
|
||||
<AppContext.Provider value={{ authenticated, setAuthenticated, editable, setEditable }}>
|
||||
<Layout>
|
||||
<Component {...pageProps} />
|
||||
</Layout>
|
||||
</AppContext.Provider>
|
||||
</CookiesProvider>
|
||||
)
|
||||
}
|
||||
|
||||
export default MyApp
|
||||
|
|
|
|||
|
|
@ -1,23 +0,0 @@
|
|||
import type { NextPage } from 'next'
|
||||
import Head from 'next/head'
|
||||
import styles from '../styles/Home.module.css'
|
||||
|
||||
import { CookiesProvider } from 'react-cookie'
|
||||
import { BrowserRouter } from 'react-router-dom'
|
||||
|
||||
import App from '~/components/App'
|
||||
|
||||
const Home: NextPage = () => {
|
||||
if (typeof window === "undefined")
|
||||
return null
|
||||
|
||||
return (
|
||||
<BrowserRouter>
|
||||
<CookiesProvider>
|
||||
<App />
|
||||
</CookiesProvider>
|
||||
</BrowserRouter>
|
||||
)
|
||||
}
|
||||
|
||||
export default Home
|
||||
158
pages/p/[party].tsx
Normal file
158
pages/p/[party].tsx
Normal file
|
|
@ -0,0 +1,158 @@
|
|||
import React, { useContext, useEffect, useState } from 'react'
|
||||
import { withCookies, useCookies } from 'react-cookie'
|
||||
import { useRouter } from 'next/router'
|
||||
|
||||
import AppContext from '~context/AppContext'
|
||||
import api from '~utils/api'
|
||||
|
||||
import Party from '~components/Party'
|
||||
import Button from '~components/Button'
|
||||
|
||||
interface Props {
|
||||
hash: string
|
||||
}
|
||||
|
||||
const PartyRoute: React.FC = () => {
|
||||
const router = useRouter()
|
||||
const { party: slug } = router.query
|
||||
|
||||
const { setEditable: setEditableContext } = useContext(AppContext)
|
||||
|
||||
const [found, setFound] = useState(false)
|
||||
const [loading, setLoading] = useState(true)
|
||||
const [editable, setEditable] = useState(false)
|
||||
|
||||
const [characters, setCharacters] = useState<GridArray<Character>>({})
|
||||
const [weapons, setWeapons] = useState<GridArray<Weapon>>({})
|
||||
const [summons, setSummons] = useState<GridArray<Summon>>({})
|
||||
|
||||
const [mainWeapon, setMainWeapon] = useState<Weapon>()
|
||||
const [mainSummon, setMainSummon] = useState<Summon>()
|
||||
const [friendSummon, setFriendSummon] = useState<Summon>()
|
||||
|
||||
const [partyId, setPartyId] = useState('')
|
||||
const [extra, setExtra] = useState<boolean>(false)
|
||||
const [cookies, _] = useCookies(['user'])
|
||||
|
||||
useEffect(() => {
|
||||
async function fetchGrid(shortcode: string) {
|
||||
return api.endpoints.parties.getOne({ id: shortcode })
|
||||
.then(response => {
|
||||
const party = response.data.party
|
||||
|
||||
const partyUser = (party.user_id) ? party.user_id : undefined
|
||||
const loggedInUser = (cookies.user) ? cookies.user.user_id : ''
|
||||
|
||||
if (partyUser != undefined && loggedInUser != undefined && partyUser === loggedInUser) {
|
||||
setEditable(true)
|
||||
setEditableContext(true)
|
||||
}
|
||||
|
||||
const characters = populateCharacters(party.characters)
|
||||
const weapons = populateWeapons(party.weapons)
|
||||
const summons = populateSummons(party.summons)
|
||||
|
||||
setExtra(response.data.party.is_extra)
|
||||
setFound(true)
|
||||
setLoading(false)
|
||||
setCharacters(characters)
|
||||
setWeapons(weapons)
|
||||
setSummons(summons)
|
||||
setPartyId(party.id)
|
||||
})
|
||||
.catch(error => {
|
||||
if (error.response != null) {
|
||||
if (error.response.status == 404) {
|
||||
setFound(false)
|
||||
setLoading(false)
|
||||
}
|
||||
} else {
|
||||
console.error(error)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
function populateCharacters(list: [GridCharacter]) {
|
||||
let characters: GridArray<Character> = {}
|
||||
|
||||
list.forEach((object: GridCharacter) => {
|
||||
if (object.position != null)
|
||||
characters[object.position] = object.character
|
||||
})
|
||||
|
||||
return characters
|
||||
}
|
||||
|
||||
function populateWeapons(list: [GridWeapon]) {
|
||||
let weapons: GridArray<Weapon> = {}
|
||||
|
||||
list.forEach((object: GridWeapon) => {
|
||||
if (object.mainhand)
|
||||
setMainWeapon(object.weapon)
|
||||
else if (!object.mainhand && object.position != null)
|
||||
weapons[object.position] = object.weapon
|
||||
})
|
||||
|
||||
return weapons
|
||||
}
|
||||
|
||||
function populateSummons(list: [GridSummon]) {
|
||||
let summons: GridArray<Summon> = {}
|
||||
|
||||
list.forEach((object: GridSummon) => {
|
||||
if (object.main)
|
||||
setMainSummon(object.summon)
|
||||
else if (object.friend)
|
||||
setFriendSummon(object.summon)
|
||||
else if (!object.main && !object.friend && object.position != null)
|
||||
summons[object.position] = object.summon
|
||||
})
|
||||
|
||||
return summons
|
||||
}
|
||||
|
||||
const shortcode: string = slug as string
|
||||
fetchGrid(shortcode)
|
||||
}, [slug, cookies.user, setEditableContext])
|
||||
|
||||
function render() {
|
||||
return (
|
||||
<div id="Content">
|
||||
<Party
|
||||
partyId={partyId}
|
||||
mainWeapon={mainWeapon}
|
||||
mainSummon={mainSummon}
|
||||
friendSummon={friendSummon}
|
||||
characters={characters}
|
||||
weapons={weapons}
|
||||
summons={summons}
|
||||
editable={editable}
|
||||
exists={found}
|
||||
extra={extra}
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
function renderNotFound() {
|
||||
return (
|
||||
<div id="NotFound">
|
||||
<h2>There's no grid here.</h2>
|
||||
<Button type="new">New grid</Button>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
if (!found && !loading) {
|
||||
return renderNotFound()
|
||||
} else if (found && !loading) {
|
||||
return render()
|
||||
} else {
|
||||
return (<div />)
|
||||
}
|
||||
}
|
||||
|
||||
export default
|
||||
withCookies(
|
||||
PartyRoute
|
||||
)
|
||||
|
|
@ -1,39 +0,0 @@
|
|||
import React from 'react'
|
||||
|
||||
interface State {
|
||||
parties: {id: string, hash: string}[]
|
||||
}
|
||||
|
||||
class PartiesRoute extends React.Component {
|
||||
state: State
|
||||
|
||||
constructor(props: any) {
|
||||
super(props)
|
||||
this.state = {
|
||||
parties: []
|
||||
}
|
||||
}
|
||||
|
||||
getParties() {
|
||||
fetch('http://localhost:3001/parties/')
|
||||
.then(response => response.json())
|
||||
.then(parties => this.setState({
|
||||
parties: parties
|
||||
}))
|
||||
}
|
||||
|
||||
render() {
|
||||
this.getParties()
|
||||
const items = this.state.parties.map((party: {id: string, hash: string }) =>
|
||||
<li key={party.id}><a href={'../' + party.hash}>{party.hash}</a></li>
|
||||
)
|
||||
return (
|
||||
<div>
|
||||
<h1>A list of parties</h1>
|
||||
<ul>{items}</ul>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
export default PartiesRoute
|
||||
|
|
@ -1,135 +0,0 @@
|
|||
import React, { useEffect, useState } from 'react'
|
||||
import { withCookies, useCookies } from 'react-cookie'
|
||||
import { useParams } from 'react-router-dom'
|
||||
import api from '~utils/api'
|
||||
|
||||
import Party from '~components/Party'
|
||||
import Button from '~components/Button'
|
||||
|
||||
interface Props {
|
||||
hash: string
|
||||
}
|
||||
|
||||
|
||||
const PartyRoute: React.FC = () => {
|
||||
const params = useParams()
|
||||
|
||||
const [found, setFound] = useState(false)
|
||||
const [loading, setLoading] = useState(true)
|
||||
const [editable, setEditable] = useState(false)
|
||||
|
||||
const [characters, setCharacters] = useState<GridArray<Character>>({})
|
||||
const [weapons, setWeapons] = useState<GridArray<Weapon>>({})
|
||||
const [summons, setSummons] = useState<GridArray<Summon>>({})
|
||||
|
||||
const [mainWeapon, setMainWeapon] = useState<Weapon>()
|
||||
const [mainSummon, setMainSummon] = useState<Summon>()
|
||||
const [friendSummon, setFriendSummon] = useState<Summon>()
|
||||
|
||||
const [partyId, setPartyId] = useState('')
|
||||
const [extra, setExtra] = useState<boolean>(false)
|
||||
const [cookies, setCookie] = useCookies(['user'])
|
||||
const shortcode = params.hash || ''
|
||||
|
||||
|
||||
useEffect(() => {
|
||||
fetchGrid(shortcode)
|
||||
}, [])
|
||||
|
||||
async function fetchGrid(shortcode: string) {
|
||||
return api.endpoints.parties.getOne({ id: shortcode })
|
||||
.then(response => {
|
||||
const party = response.data.party
|
||||
|
||||
const partyUser = party.user_id
|
||||
const loggedInUser = (cookies.user) ? cookies.user.user_id : ''
|
||||
|
||||
if (partyUser != undefined && loggedInUser != undefined && partyUser === loggedInUser)
|
||||
setEditable(true)
|
||||
|
||||
let characters: GridArray<Character> = {}
|
||||
let weapons: GridArray<Weapon> = {}
|
||||
let summons: GridArray<Summon> = {}
|
||||
|
||||
party.characters.forEach((gridCharacter: GridCharacter) => {
|
||||
if (gridCharacter.position != null)
|
||||
characters[gridCharacter.position] = gridCharacter.character
|
||||
})
|
||||
|
||||
party.weapons.forEach((gridWeapon: GridWeapon) => {
|
||||
if (gridWeapon.mainhand)
|
||||
setMainWeapon(gridWeapon.weapon)
|
||||
else if (!gridWeapon.mainhand && gridWeapon.position != null)
|
||||
weapons[gridWeapon.position] = gridWeapon.weapon
|
||||
})
|
||||
|
||||
party.summons.forEach((gridSummon: GridSummon) => {
|
||||
if (gridSummon.main)
|
||||
setMainSummon(gridSummon.summon)
|
||||
else if (gridSummon.friend)
|
||||
setFriendSummon(gridSummon.summon)
|
||||
else if (!gridSummon.main && !gridSummon.friend && gridSummon.position != null)
|
||||
summons[gridSummon.position] = gridSummon.summon
|
||||
})
|
||||
|
||||
setExtra(response.data.party.is_extra)
|
||||
setFound(true)
|
||||
setLoading(false)
|
||||
setCharacters(characters)
|
||||
setWeapons(weapons)
|
||||
setSummons(summons)
|
||||
setPartyId(party.id)
|
||||
})
|
||||
.catch(error => {
|
||||
if (error.response != null) {
|
||||
if (error.response.status == 404) {
|
||||
setFound(false)
|
||||
setLoading(false)
|
||||
}
|
||||
} else {
|
||||
console.error(error)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
function render() {
|
||||
return (
|
||||
<div id="Content">
|
||||
<Party
|
||||
partyId={partyId}
|
||||
mainWeapon={mainWeapon}
|
||||
mainSummon={mainSummon}
|
||||
friendSummon={friendSummon}
|
||||
characters={characters}
|
||||
weapons={weapons}
|
||||
summons={summons}
|
||||
editable={editable}
|
||||
exists={found}
|
||||
extra={extra}
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
function renderNotFound() {
|
||||
return (
|
||||
<div id="NotFound">
|
||||
<h2>There's no grid here.</h2>
|
||||
<Button type="new">New grid</Button>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
if (!found && !loading) {
|
||||
return renderNotFound()
|
||||
} else if (found && !loading) {
|
||||
return render()
|
||||
} else {
|
||||
return (<div />)
|
||||
}
|
||||
}
|
||||
|
||||
export default
|
||||
withCookies(
|
||||
PartyRoute
|
||||
)
|
||||
Loading…
Reference in a new issue