hensei-web/components/GridRep/index.tsx

154 lines
4.9 KiB
TypeScript

import React, { useEffect, useState } from 'react'
import { useSnapshot } from 'valtio'
import classNames from 'classnames'
import { accountState } from '~utils/accountState'
import { formatTimeAgo } from '~utils/timeAgo'
import Button from '~components/Button'
import { ButtonType } from '~utils/enums'
import './index.scss'
interface Props {
shortcode: string
id: string
name: string
raid: Raid
grid: GridWeapon[]
user?: User
favorited: boolean
createdAt: Date
displayUser?: boolean | false
onClick: (shortcode: string) => void
onSave: (partyId: string, favorited: boolean) => void
}
const GridRep = (props: Props) => {
const numWeapons: number = 9
const { account } = useSnapshot(accountState)
const [mainhand, setMainhand] = useState<Weapon>()
const [weapons, setWeapons] = useState<GridArray<Weapon>>({})
const titleClass = classNames({
'empty': !props.name
})
const raidClass = classNames({
'raid': true,
'empty': !props.raid
})
const userClass = classNames({
'user': true,
'empty': !props.user
})
useEffect(() => {
const newWeapons = Array(numWeapons)
for (const [key, value] of Object.entries(props.grid)) {
if (value.position == -1)
setMainhand(value.object)
else if (!value.mainhand && value.position != null)
newWeapons[value.position] = value.object
}
setWeapons(newWeapons)
}, [props.grid])
function navigate() {
props.onClick(props.shortcode)
}
function generateMainhandImage() {
return (mainhand) ?
<img alt={mainhand?.name.en} src={`${process.env.NEXT_PUBLIC_SIERO_IMG_URL}/weapon-main/${mainhand?.granblue_id}.jpg`} /> : ''
}
function generateGridImage(position: number) {
return (weapons[position]) ?
<img alt={weapons[position]?.name.en} src={`${process.env.NEXT_PUBLIC_SIERO_IMG_URL}/weapon-grid/${weapons[position]?.granblue_id}.jpg`} /> : ''
}
function sendSaveData() {
props.onSave(props.id, props.favorited)
}
const userImage = () => {
if (props.user)
return (
<img
alt="Gran"
className="gran"
srcSet="/profile/gran.png,
/profile/gran@2x.png 2x"
src="/profile/gran.png" />
)
else
return (<div className="no-user" />)
}
const details = (
<div className="Details">
<h2 className={titleClass} onClick={navigate}>{ (props.name) ? props.name : 'Untitled' }</h2>
<div className="bottom">
<div className={raidClass}>{ (props.raid) ? props.raid.name.en : 'No raid set' }</div>
<time className="last-updated" dateTime={props.createdAt.toISOString()}>{formatTimeAgo(props.createdAt, 'en-us')}</time>
</div>
</div>
)
const detailsWithUsername = (
<div className="Details">
<div className="top">
<div className="info">
<h2 className={titleClass} onClick={navigate}>{ (props.name) ? props.name : 'Untitled' }</h2>
<div className={raidClass}>{ (props.raid) ? props.raid.name.en : 'No raid set' }</div>
</div>
{ (!props.user || (account.user && account.user.id !== props.user.id)) ?
<Button
active={props.favorited}
icon="save"
type={ButtonType.IconOnly}
click={sendSaveData}
/> : ''}
</div>
<div className="bottom">
<div className={userClass}>
{ userImage() }
{ (props.user) ? props.user.username : 'Anonymous' }
</div>
<time className="last-updated" dateTime={props.createdAt.toISOString()}>{formatTimeAgo(props.createdAt, 'en-us')}</time>
</div>
</div>
)
return (
<div className="GridRep">
{ (props.displayUser) ? detailsWithUsername : details}
<div className="Grid" onClick={navigate}>
<div className="weapon grid_mainhand">
{generateMainhandImage()}
</div>
<ul className="grid_weapons">
{
Array.from(Array(numWeapons)).map((x, i) => {
return (
<li key={`${props.shortcode}-${i}`} className="weapon grid_weapon">
{generateGridImage(i)}
</li>
)
})
}
</ul>
</div>
</div>
)
}
export default GridRep