Profiles and GridReps

This commit is contained in:
Justin Edmund 2020-09-25 17:57:46 -07:00
parent e17be1211f
commit c90f35fff6
11 changed files with 311 additions and 76 deletions

View file

@ -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;
}

View 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%;
}

View 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

View file

@ -0,0 +1,6 @@
.GridRepCollection {
display: flex;
flex-wrap: wrap;
justify-content: center;
padding: 0;
}

View 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

View file

@ -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>
)

View file

@ -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;
}

View file

@ -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

View file

@ -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

View file

@ -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
View file

@ -0,0 +1,6 @@
interface GridWeapon {
id: string
mainhand: boolean
position: number | null
weapon: Weapon
}