Profiles and GridReps
This commit is contained in:
parent
e17be1211f
commit
c90f35fff6
11 changed files with 311 additions and 76 deletions
|
|
@ -21,3 +21,15 @@ h1 {
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#NotFound {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
margin-top: 40px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#NotFound h2 {
|
||||||
|
color: #444;
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
51
src/components/GridRep/index.css
Normal file
51
src/components/GridRep/index.css
Normal file
|
|
@ -0,0 +1,51 @@
|
||||||
|
.GridRep {
|
||||||
|
border: 2px solid transparent;
|
||||||
|
border-radius: 6px;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
flex-shrink: 0;
|
||||||
|
margin: 0 8px 8px 0;
|
||||||
|
padding: 4px;
|
||||||
|
height: 148px;
|
||||||
|
width: 311px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.GridRep:hover {
|
||||||
|
border: 2px solid #61B3FF;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.GridRep .weapon {
|
||||||
|
background: white;
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.GridRep .grid_mainhand {
|
||||||
|
flex-shrink: 0;
|
||||||
|
height: 136px;
|
||||||
|
width: 65px;
|
||||||
|
margin-right: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.GridRep .grid_weapons {
|
||||||
|
list-style: none;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.GridRep .grid_weapon {
|
||||||
|
float: left;
|
||||||
|
margin: 0 8px 8px 0;
|
||||||
|
height: 40px;
|
||||||
|
width: 70px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.GridRep .grid_weapon:nth-child(3n+3) {
|
||||||
|
margin-right: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.GridRep .weapon img[src*="jpg"] {
|
||||||
|
border-radius: 4px;
|
||||||
|
height: 100%;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
71
src/components/GridRep/index.tsx
Normal file
71
src/components/GridRep/index.tsx
Normal file
|
|
@ -0,0 +1,71 @@
|
||||||
|
import React, { useEffect, useState } from 'react'
|
||||||
|
|
||||||
|
import './index.css'
|
||||||
|
|
||||||
|
import mainhandImages from '../../images/mainhand/*.jpg'
|
||||||
|
import gridImages from '../../images/grid/*.jpg'
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
shortcode: string
|
||||||
|
grid: GridWeapon[]
|
||||||
|
onClick: (shortcode: string) => void
|
||||||
|
}
|
||||||
|
|
||||||
|
const GridRep = (props: Props) => {
|
||||||
|
const numWeapons: number = 9
|
||||||
|
|
||||||
|
const [mainhand, setMainhand] = useState<Weapon>()
|
||||||
|
const [weapons, setWeapons] = useState<GridArray>({})
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
configure()
|
||||||
|
}, [])
|
||||||
|
|
||||||
|
function configure() {
|
||||||
|
const newWeapons = Array(numWeapons)
|
||||||
|
|
||||||
|
for (const [key, value] of Object.entries(props.grid)) {
|
||||||
|
if (value.position == -1)
|
||||||
|
setMainhand(value.weapon)
|
||||||
|
else if (!value.mainhand && value.position != null)
|
||||||
|
newWeapons[value.position] = value.weapon
|
||||||
|
}
|
||||||
|
|
||||||
|
setWeapons(newWeapons)
|
||||||
|
}
|
||||||
|
|
||||||
|
function navigate() {
|
||||||
|
props.onClick(props.shortcode)
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="GridRep" onClick={navigate}>
|
||||||
|
<div className="weapon grid_mainhand">
|
||||||
|
<img src={
|
||||||
|
process.env.NODE_ENV === 'development'
|
||||||
|
? mainhandImages[mainhand?.granblue_id || 0]
|
||||||
|
: `${process.env.SIERO_IMG_URL}/mainhand/${mainhand?.granblue_id}.jpg`
|
||||||
|
} />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<ul className="grid_weapons">
|
||||||
|
{
|
||||||
|
Array.from(Array(numWeapons)).map((x, i) => {
|
||||||
|
console.log()
|
||||||
|
return (
|
||||||
|
<li className="weapon grid_weapon" key={`grid_unit_${i}`}>
|
||||||
|
<img src={
|
||||||
|
process.env.NODE_ENV === 'development'
|
||||||
|
? gridImages[weapons[i]?.granblue_id || 0]
|
||||||
|
: `${process.env.SIERO_IMG_URL}/grid/${weapons[i]?.granblue_id}.jpg`
|
||||||
|
} />
|
||||||
|
</li>
|
||||||
|
)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default GridRep
|
||||||
6
src/components/GridRepCollection/index.css
Normal file
6
src/components/GridRepCollection/index.css
Normal file
|
|
@ -0,0 +1,6 @@
|
||||||
|
.GridRepCollection {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
justify-content: center;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
15
src/components/GridRepCollection/index.tsx
Normal file
15
src/components/GridRepCollection/index.tsx
Normal file
|
|
@ -0,0 +1,15 @@
|
||||||
|
import React from 'react'
|
||||||
|
|
||||||
|
import './index.css'
|
||||||
|
|
||||||
|
interface Props {}
|
||||||
|
|
||||||
|
const GridRepCollection: React.FC<Props> = ({ children }) => {
|
||||||
|
return (
|
||||||
|
<ul className="GridRepCollection">
|
||||||
|
{children}
|
||||||
|
</ul>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default GridRepCollection
|
||||||
|
|
@ -19,7 +19,7 @@ const Main = () => (
|
||||||
<Route exact path='/' component={New} />
|
<Route exact path='/' component={New} />
|
||||||
<Route exact path='/parties/' component={Parties} />
|
<Route exact path='/parties/' component={Parties} />
|
||||||
<Route path='/p/:hash' component={Party} />
|
<Route path='/p/:hash' component={Party} />
|
||||||
<Route path='/:username' component={Profile} />
|
<Route exact path='/:username' component={Profile} />
|
||||||
</Router>
|
</Router>
|
||||||
</main>
|
</main>
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -26,15 +26,3 @@
|
||||||
#grid_weapons > li {
|
#grid_weapons > li {
|
||||||
list-style: none;
|
list-style: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
#NotFound {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
align-items: center;
|
|
||||||
margin-top: 40px;
|
|
||||||
}
|
|
||||||
|
|
||||||
#NotFound h2 {
|
|
||||||
color: #444;
|
|
||||||
font-weight: 500;
|
|
||||||
}
|
|
||||||
|
|
@ -90,49 +90,36 @@ const WeaponGrid = (props: Props) => {
|
||||||
api.endpoints.weapons.create(body)
|
api.endpoints.weapons.create(body)
|
||||||
}
|
}
|
||||||
|
|
||||||
function renderGrid() {
|
return (
|
||||||
return (
|
<div className="WeaponGrid">
|
||||||
<div className="WeaponGrid">
|
<WeaponUnit
|
||||||
<WeaponUnit
|
editable={props.editable}
|
||||||
editable={props.editable}
|
key="grid_mainhand"
|
||||||
key="grid_mainhand"
|
onReceiveData={receiveWeapon}
|
||||||
onReceiveData={receiveWeapon}
|
position={-1}
|
||||||
position={-1}
|
unitType={0}
|
||||||
unitType={0}
|
weapon={mainhand}
|
||||||
weapon={mainhand}
|
/>
|
||||||
/>
|
|
||||||
|
|
||||||
<ul id="grid_weapons">
|
<ul id="grid_weapons">
|
||||||
{
|
{
|
||||||
Array.from(Array(numWeapons)).map((x, i) => {
|
Array.from(Array(numWeapons)).map((x, i) => {
|
||||||
return (
|
return (
|
||||||
<li key={`grid_unit_${i}`} >
|
<li key={`grid_unit_${i}`} >
|
||||||
<WeaponUnit
|
<WeaponUnit
|
||||||
editable={props.editable}
|
editable={props.editable}
|
||||||
onReceiveData={receiveWeapon}
|
onReceiveData={receiveWeapon}
|
||||||
position={i}
|
position={i}
|
||||||
unitType={1}
|
unitType={1}
|
||||||
weapon={weapons[i]}
|
weapon={weapons[i]}
|
||||||
/>
|
/>
|
||||||
</li>
|
</li>
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
|
||||||
|
|
||||||
function renderGridNotFound() {
|
|
||||||
return (
|
|
||||||
<div id="NotFound">
|
|
||||||
<h2>There's no grid here.</h2>
|
|
||||||
<Button type="new">New grid</Button>
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
return (!props.exists || props.found) ? renderGrid() : renderGridNotFound()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export default WeaponGrid
|
export default WeaponGrid
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@ import { RouteComponentProps, withRouter } from 'react-router-dom'
|
||||||
import api from '~utils/api'
|
import api from '~utils/api'
|
||||||
|
|
||||||
import WeaponGrid from '~components/WeaponGrid'
|
import WeaponGrid from '~components/WeaponGrid'
|
||||||
|
import Button from '~components/Button'
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
hash: string
|
hash: string
|
||||||
|
|
@ -29,6 +30,7 @@ interface GridWeapon {
|
||||||
|
|
||||||
const Party: React.FC<PartyProps> = ({ match }, state: State) => {
|
const Party: React.FC<PartyProps> = ({ match }, state: State) => {
|
||||||
const [found, setFound] = useState(false)
|
const [found, setFound] = useState(false)
|
||||||
|
const [loading, setLoading] = useState(true)
|
||||||
const [editable, setEditable] = useState(false)
|
const [editable, setEditable] = useState(false)
|
||||||
const [grid, setGrid] = useState<GridArray>({})
|
const [grid, setGrid] = useState<GridArray>({})
|
||||||
const [mainhand, setMainhand] = useState<Weapon>()
|
const [mainhand, setMainhand] = useState<Weapon>()
|
||||||
|
|
@ -61,6 +63,7 @@ const Party: React.FC<PartyProps> = ({ match }, state: State) => {
|
||||||
})
|
})
|
||||||
|
|
||||||
setFound(true)
|
setFound(true)
|
||||||
|
setLoading(false)
|
||||||
setGrid(weapons)
|
setGrid(weapons)
|
||||||
setPartyId(party.id)
|
setPartyId(party.id)
|
||||||
})
|
})
|
||||||
|
|
@ -68,6 +71,7 @@ const Party: React.FC<PartyProps> = ({ match }, state: State) => {
|
||||||
if (error.response != null) {
|
if (error.response != null) {
|
||||||
if (error.response.status == 404) {
|
if (error.response.status == 404) {
|
||||||
setFound(false)
|
setFound(false)
|
||||||
|
setLoading(false)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
console.error(error)
|
console.error(error)
|
||||||
|
|
@ -75,19 +79,38 @@ const Party: React.FC<PartyProps> = ({ match }, state: State) => {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
function render() {
|
||||||
<div>
|
return (
|
||||||
<WeaponGrid
|
<div>
|
||||||
userId={cookies.user ? cookies.user.user_id : ''}
|
<WeaponGrid
|
||||||
partyId={partyId}
|
userId={cookies.user ? cookies.user.user_id : ''}
|
||||||
mainhand={mainhand}
|
partyId={partyId}
|
||||||
grid={grid}
|
mainhand={mainhand}
|
||||||
editable={editable}
|
grid={grid}
|
||||||
exists={true}
|
editable={editable}
|
||||||
found={found}
|
exists={true}
|
||||||
/>
|
found={found}
|
||||||
</div>
|
/>
|
||||||
)
|
</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
|
export default
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,10 @@ import { withCookies, useCookies } from 'react-cookie'
|
||||||
import { RouteComponentProps, withRouter } from 'react-router-dom'
|
import { RouteComponentProps, withRouter } from 'react-router-dom'
|
||||||
import api from '~utils/api'
|
import api from '~utils/api'
|
||||||
|
|
||||||
|
import GridRep from '~components/GridRep'
|
||||||
|
import GridRepCollection from '~components/GridRepCollection'
|
||||||
|
import { composeInitialProps } from 'react-i18next'
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
username: string
|
username: string
|
||||||
}
|
}
|
||||||
|
|
@ -13,20 +17,30 @@ interface User {
|
||||||
granblueId: number
|
granblueId: number
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface Party {
|
||||||
|
id: string
|
||||||
|
shortcode: string
|
||||||
|
grid: GridWeapon[]
|
||||||
|
}
|
||||||
|
|
||||||
interface ProfileProps extends RouteComponentProps<Props> {}
|
interface ProfileProps extends RouteComponentProps<Props> {}
|
||||||
|
|
||||||
const Profile: React.FC<ProfileProps> = ({ match }) => {
|
const Profile: React.FC<ProfileProps> = ({ history, match }) => {
|
||||||
const [cookies, setCookie] = useCookies(['user'])
|
const [cookies, setCookie] = useCookies(['user'])
|
||||||
|
|
||||||
|
const [found, setFound] = useState(false)
|
||||||
|
const [loading, setLoading] = useState(true)
|
||||||
|
const [parties, setParties] = useState<Party[]>([])
|
||||||
const [user, setUser] = useState<User>({
|
const [user, setUser] = useState<User>({
|
||||||
id: '',
|
id: '',
|
||||||
username: '',
|
username: '',
|
||||||
granblueId: 0
|
granblueId: 0
|
||||||
})
|
})
|
||||||
const [parties, setParties] = useState<GridArray[]>([])
|
|
||||||
|
|
||||||
const username = match.params.username || ''
|
const username = match.params.username || ''
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
console.log(`Fetching profile for ${username}...`)
|
||||||
fetchProfile(username)
|
fetchProfile(username)
|
||||||
}, [])
|
}, [])
|
||||||
|
|
||||||
|
|
@ -40,13 +54,75 @@ const Profile: React.FC<ProfileProps> = ({ match }) => {
|
||||||
})
|
})
|
||||||
setParties(response.data.user.parties)
|
setParties(response.data.user.parties)
|
||||||
})
|
})
|
||||||
|
.then(() => {
|
||||||
|
setFound(true)
|
||||||
|
setLoading(false)
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
if (error.response != null) {
|
||||||
|
if (error.response.status == 404) {
|
||||||
|
setFound(false)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
console.error(error)
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
function render() {
|
||||||
<div>
|
const content = (parties && parties.length > 0) ? renderGrids() : renderNoGrids()
|
||||||
<h1>{user.username}</h1>
|
return (
|
||||||
</div>
|
<div>
|
||||||
)
|
<h1>{user.username}</h1>
|
||||||
|
{content}
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
function navigate(shortcode: string) {
|
||||||
|
history.push(`/p/${shortcode}`)
|
||||||
|
}
|
||||||
|
|
||||||
|
function renderGrids() {
|
||||||
|
return (
|
||||||
|
<GridRepCollection>
|
||||||
|
{
|
||||||
|
parties.map((party, i) => {
|
||||||
|
return <GridRep
|
||||||
|
shortcode={party.shortcode}
|
||||||
|
grid={party.grid}
|
||||||
|
key={`party-${i}`}
|
||||||
|
onClick={navigate}
|
||||||
|
/>
|
||||||
|
})
|
||||||
|
}
|
||||||
|
</GridRepCollection>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
function renderNoGrids() {
|
||||||
|
return (
|
||||||
|
<div id="NotFound">
|
||||||
|
<h2>This user has no grids.</h2>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
function renderNotFound() {
|
||||||
|
return (
|
||||||
|
<div id="NotFound">
|
||||||
|
<h2>That user doesn't exist.</h2>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!found && !loading) {
|
||||||
|
return renderNotFound()
|
||||||
|
} else if (found && !loading) {
|
||||||
|
return render()
|
||||||
|
} else {
|
||||||
|
return (<div />)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default
|
export default
|
||||||
|
|
|
||||||
6
src/types/GridWeapon.d.ts
vendored
Normal file
6
src/types/GridWeapon.d.ts
vendored
Normal file
|
|
@ -0,0 +1,6 @@
|
||||||
|
interface GridWeapon {
|
||||||
|
id: string
|
||||||
|
mainhand: boolean
|
||||||
|
position: number | null
|
||||||
|
weapon: Weapon
|
||||||
|
}
|
||||||
Loading…
Reference in a new issue