Profiles and GridReps
This commit is contained in:
parent
e17be1211f
commit
c90f35fff6
11 changed files with 311 additions and 76 deletions
|
|
@ -20,4 +20,16 @@ h1 {
|
|||
font-size: 18px;
|
||||
font-weight: 500;
|
||||
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='/parties/' component={Parties} />
|
||||
<Route path='/p/:hash' component={Party} />
|
||||
<Route path='/:username' component={Profile} />
|
||||
<Route exact path='/:username' component={Profile} />
|
||||
</Router>
|
||||
</main>
|
||||
)
|
||||
|
|
|
|||
|
|
@ -25,16 +25,4 @@
|
|||
|
||||
#grid_weapons > li {
|
||||
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)
|
||||
}
|
||||
|
||||
function renderGrid() {
|
||||
return (
|
||||
<div className="WeaponGrid">
|
||||
<WeaponUnit
|
||||
editable={props.editable}
|
||||
key="grid_mainhand"
|
||||
onReceiveData={receiveWeapon}
|
||||
position={-1}
|
||||
unitType={0}
|
||||
weapon={mainhand}
|
||||
/>
|
||||
|
||||
<ul id="grid_weapons">
|
||||
{
|
||||
Array.from(Array(numWeapons)).map((x, i) => {
|
||||
return (
|
||||
<li key={`grid_unit_${i}`} >
|
||||
<WeaponUnit
|
||||
editable={props.editable}
|
||||
onReceiveData={receiveWeapon}
|
||||
position={i}
|
||||
unitType={1}
|
||||
weapon={weapons[i]}
|
||||
/>
|
||||
</li>
|
||||
)
|
||||
})
|
||||
}
|
||||
</ul>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
return (
|
||||
<div className="WeaponGrid">
|
||||
<WeaponUnit
|
||||
editable={props.editable}
|
||||
key="grid_mainhand"
|
||||
onReceiveData={receiveWeapon}
|
||||
position={-1}
|
||||
unitType={0}
|
||||
weapon={mainhand}
|
||||
/>
|
||||
|
||||
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()
|
||||
<ul id="grid_weapons">
|
||||
{
|
||||
Array.from(Array(numWeapons)).map((x, i) => {
|
||||
return (
|
||||
<li key={`grid_unit_${i}`} >
|
||||
<WeaponUnit
|
||||
editable={props.editable}
|
||||
onReceiveData={receiveWeapon}
|
||||
position={i}
|
||||
unitType={1}
|
||||
weapon={weapons[i]}
|
||||
/>
|
||||
</li>
|
||||
)
|
||||
})
|
||||
}
|
||||
</ul>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default WeaponGrid
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ import { RouteComponentProps, withRouter } from 'react-router-dom'
|
|||
import api from '~utils/api'
|
||||
|
||||
import WeaponGrid from '~components/WeaponGrid'
|
||||
import Button from '~components/Button'
|
||||
|
||||
interface Props {
|
||||
hash: string
|
||||
|
|
@ -29,6 +30,7 @@ interface GridWeapon {
|
|||
|
||||
const Party: React.FC<PartyProps> = ({ match }, state: State) => {
|
||||
const [found, setFound] = useState(false)
|
||||
const [loading, setLoading] = useState(true)
|
||||
const [editable, setEditable] = useState(false)
|
||||
const [grid, setGrid] = useState<GridArray>({})
|
||||
const [mainhand, setMainhand] = useState<Weapon>()
|
||||
|
|
@ -61,6 +63,7 @@ const Party: React.FC<PartyProps> = ({ match }, state: State) => {
|
|||
})
|
||||
|
||||
setFound(true)
|
||||
setLoading(false)
|
||||
setGrid(weapons)
|
||||
setPartyId(party.id)
|
||||
})
|
||||
|
|
@ -68,6 +71,7 @@ const Party: React.FC<PartyProps> = ({ match }, state: State) => {
|
|||
if (error.response != null) {
|
||||
if (error.response.status == 404) {
|
||||
setFound(false)
|
||||
setLoading(false)
|
||||
}
|
||||
} else {
|
||||
console.error(error)
|
||||
|
|
@ -75,19 +79,38 @@ const Party: React.FC<PartyProps> = ({ match }, state: State) => {
|
|||
})
|
||||
}
|
||||
|
||||
return (
|
||||
<div>
|
||||
<WeaponGrid
|
||||
userId={cookies.user ? cookies.user.user_id : ''}
|
||||
partyId={partyId}
|
||||
mainhand={mainhand}
|
||||
grid={grid}
|
||||
editable={editable}
|
||||
exists={true}
|
||||
found={found}
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
function render() {
|
||||
return (
|
||||
<div>
|
||||
<WeaponGrid
|
||||
userId={cookies.user ? cookies.user.user_id : ''}
|
||||
partyId={partyId}
|
||||
mainhand={mainhand}
|
||||
grid={grid}
|
||||
editable={editable}
|
||||
exists={true}
|
||||
found={found}
|
||||
/>
|
||||
</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
|
||||
|
|
|
|||
|
|
@ -3,6 +3,10 @@ import { withCookies, useCookies } from 'react-cookie'
|
|||
import { RouteComponentProps, withRouter } from 'react-router-dom'
|
||||
import api from '~utils/api'
|
||||
|
||||
import GridRep from '~components/GridRep'
|
||||
import GridRepCollection from '~components/GridRepCollection'
|
||||
import { composeInitialProps } from 'react-i18next'
|
||||
|
||||
interface Props {
|
||||
username: string
|
||||
}
|
||||
|
|
@ -13,21 +17,31 @@ interface User {
|
|||
granblueId: number
|
||||
}
|
||||
|
||||
interface Party {
|
||||
id: string
|
||||
shortcode: string
|
||||
grid: GridWeapon[]
|
||||
}
|
||||
|
||||
interface ProfileProps extends RouteComponentProps<Props> {}
|
||||
|
||||
const Profile: React.FC<ProfileProps> = ({ match }) => {
|
||||
const Profile: React.FC<ProfileProps> = ({ history, match }) => {
|
||||
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>({
|
||||
id: '',
|
||||
username: '',
|
||||
granblueId: 0
|
||||
})
|
||||
const [parties, setParties] = useState<GridArray[]>([])
|
||||
|
||||
const username = match.params.username || ''
|
||||
|
||||
useEffect(() => {
|
||||
fetchProfile(username)
|
||||
console.log(`Fetching profile for ${username}...`)
|
||||
fetchProfile(username)
|
||||
}, [])
|
||||
|
||||
async function fetchProfile(username: string) {
|
||||
|
|
@ -40,13 +54,75 @@ const Profile: React.FC<ProfileProps> = ({ match }) => {
|
|||
})
|
||||
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 (
|
||||
<div>
|
||||
<h1>{user.username}</h1>
|
||||
</div>
|
||||
)
|
||||
function render() {
|
||||
const content = (parties && parties.length > 0) ? renderGrids() : renderNoGrids()
|
||||
return (
|
||||
<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
|
||||
|
|
|
|||
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