Added other grid layouts

This commit is contained in:
Justin Edmund 2020-10-15 23:01:59 -07:00
parent 92f3f2f4eb
commit 962720f86f
16 changed files with 506 additions and 8 deletions

View file

@ -3,7 +3,7 @@
}
html {
background: #f5f5f5;
background: #efefef;
padding: 16px;
}
@ -22,6 +22,13 @@ h1 {
text-align: center;
}
#Content {
display: flex;
flex-direction: column;
gap: 24px;
margin-top: 96px;
}
#NotFound {
display: flex;
flex-direction: column;

View file

@ -0,0 +1,27 @@
.CharacterGrid {
display: flex;
justify-content: center;
}
#grid_characters {
display: flex;
flex-direction: row;
flex-wrap: wrap;
margin: 0;
padding: 0;
width: 752px;
}
#grid_characters > * {
margin-bottom: 24px;
margin-right: 24px;
}
#grid_characters > li {
list-style: none;
}
#grid_characters > li:last-child {
margin: 0;
}

View file

@ -0,0 +1,38 @@
import React, { useState } from 'react'
import CharacterUnit from '~components/CharacterUnit'
import './index.css'
interface Props {
editable: boolean
}
const CharacterGrid = (props: Props) => {
const numCharacters: number = 5
const [characters, setCharacters] = useState<GridArray>({})
const [partyId, setPartyId] = useState('')
return (
<div className="CharacterGrid">
<ul id="grid_characters">
{
Array.from(Array(numCharacters)).map((x, i) => {
return (
<li key={`grid_unit_${i}`} >
<CharacterUnit
editable={props.editable}
onReceiveData={() => {}}
position={i}
character={characters[i]}
/>
</li>
)
})
}
</ul>
</div>
)
}
export default CharacterGrid

View file

@ -0,0 +1,64 @@
.CharacterUnit {
display: flex;
flex-direction: column;
gap: 4px;
max-width: 200px;
}
.CharacterUnit .CharacterImage {
background: white;
border: 1px solid rgba(0, 0, 0, 0);
border-radius: 8px;
display: flex;
align-items: center;
justify-content: center;
overflow: hidden;
transition: all 0.18s ease-in-out;
height: 275px;
width: 131px;
}
.CharacterUnit.editable .CharacterImage:hover {
border: 1px solid rgba(0, 0, 0, 0.1);
box-shadow: rgba(0, 0, 0, 0.14) 0px 0px 14px;
cursor: pointer;
transform: scale(1.1, 1.1);
}
.CharacterUnit.filled h3 {
display: block;
}
.CharacterUnit.filled ul {
display: flex;
}
.CharacterUnit h3,
.CharacterUnit ul {
display: none;
}
.CharacterUnit h3 {
color: #333;
font-weight: 500;
margin: 0;
text-align: center;
}
.CharacterUnit img {
position: relative;
width: 100%;
z-index: 2;
}
.CharacterImage .icon {
position: absolute;
color: #c9c9c9;
height: 20px;
width: 20px;
z-index: 1;
}
.CharacterImage:hover .icon {
color: #555;
}

View file

@ -0,0 +1,46 @@
import React, { useState } from 'react'
import classnames from 'classnames'
import UncapIndicator from '~components/UncapIndicator'
import './index.css'
import Plus from '../../../assets/plus.svg'
interface Props {
onReceiveData: (character: Character, position: number) => void
character: Character | undefined
position: number
editable: boolean
}
const CharacterUnit = (props: Props) => {
const openModal = () => {}
const openModalIfEditable = (props.editable) ? openModal : () => {}
const classes = classnames({
CharacterUnit: true,
'editable': props.editable,
'filled': (props.character !== undefined)
})
const character = props.character
return (
<div>
<div className={classes} onClick={openModalIfEditable}>
<div className="CharacterImage">
{ (props.editable) ? <span className='icon'><Plus /></span> : '' }
</div>
<UncapIndicator
ulb={character?.uncap.ulb || false}
flb={character?.uncap.flb || false}
uncapLevel={3}
/>
<h3 className="CharacterName">{character?.name.en}</h3>
</div>
</div>
)
}
export default CharacterUnit

View file

@ -68,9 +68,9 @@ const GridRep = (props: Props) => {
{
Array.from(Array(numWeapons)).map((x, i) => {
return (
<div className="grid_weapon">
<li key={`${props.shortcode}-${i}`} className="grid_weapon">
{generateGridImage(i)}
</div>
</li>
)
})
}

View file

@ -6,9 +6,9 @@ interface Props {}
const GridRepCollection: React.FC<Props> = ({ children }) => {
return (
<ul className="GridRepCollection">
<div className="GridRepCollection">
{children}
</ul>
</div>
)
}

View file

@ -1,5 +1,5 @@
import React, { useEffect, useState } from 'react'
import { useLocation } from 'react-router-dom'
import { useHistory, useLocation } from 'react-router-dom'
import { useCookies } from 'react-cookie'
import Button from '~components/Button'
@ -14,6 +14,8 @@ interface Props {
const Header = (props: Props) => {
const [username, setUsername] = useState(undefined)
const [cookies, setCookie, removeCookie] = useCookies(['user'])
let history = useHistory()
let location = useLocation()
const route = (pathname: string) => props.navigate(pathname)
@ -42,7 +44,7 @@ const Header = (props: Props) => {
function logout() {
removeCookie('user')
window.history.replaceState(null, `Grid Tool`, `/`)
props.history.go(0)
history.go(0)
}
if (cookies.user != null) {

View file

@ -0,0 +1,27 @@
.SummonGrid {
display: flex;
justify-content: center;
}
#grid_summons {
display: flex;
flex-direction: row;
flex-wrap: wrap;
margin: 0 24px 0 0;
padding: 0;
width: 344px;
}
#grid_summons > * {
margin-bottom: 24px;
margin-right: 24px;
}
#grid_summons > *:nth-child(2n+2) {
margin-right: 0;
}
#grid_summons > li {
list-style: none;
}

View file

@ -0,0 +1,59 @@
import React, { useState } from 'react'
import SummonUnit from '~components/SummonUnit'
import './index.css'
interface Props {
editable: boolean
}
const SummonGrid = (props: Props) => {
const numSummons: number = 4
const [mainSummon, setMainSummon] = useState<Summon>()
const [friendSummon, setFriendSummon] = useState<Summon>()
const [summons, setSummons] = useState<GridArray>({})
const [partyId, setPartyId] = useState('')
return (
<div className="SummonGrid">
<SummonUnit
editable={props.editable}
key="grid_main_summon"
onReceiveData={() => {}}
position={-1}
unitType={0}
summon={mainSummon}
/>
<ul id="grid_summons">
{
Array.from(Array(numSummons)).map((x, i) => {
return (
<li key={`grid_unit_${i}`} >
<SummonUnit
editable={props.editable}
onReceiveData={() => {}}
position={i}
unitType={1}
summon={summons[i]}
/>
</li>
)
})
}
</ul>
<SummonUnit
editable={props.editable}
key="grid_friend_summon"
onReceiveData={() => {}}
position={-1}
unitType={2}
summon={friendSummon}
/>
</div>
)
}
export default SummonGrid

View file

@ -0,0 +1,89 @@
.SummonUnit {
display: flex;
flex-direction: column;
gap: 4px;
}
.SummonUnit .SummonImage {
background: white;
border: 1px solid rgba(0, 0, 0, 0);
border-radius: 8px;
display: flex;
align-items: center;
justify-content: center;
overflow: hidden;
transition: all 0.18s ease-in-out;
}
.SummonUnit.editable .SummonImage:hover {
border: 1px solid rgba(0, 0, 0, 0.1);
box-shadow: rgba(0, 0, 0, 0.14) 0px 0px 14px;
cursor: pointer;
transform: scale(1.1, 1.1);
}
.SummonUnit.filled h3 {
display: block;
}
.SummonUnit.filled ul {
display: flex;
}
.SummonUnit h3,
.SummonUnit ul {
display: none;
}
.SummonUnit h3 {
color: #333;
font-weight: 500;
margin: 0;
text-align: center;
}
.SummonUnit img {
position: relative;
width: 100%;
z-index: 2;
}
.SummonImage .icon {
position: absolute;
color: #c9c9c9;
height: 20px;
width: 20px;
z-index: 1;
}
.SummonImage:hover .icon {
color: #555;
}
/* Mainhand */
.SummonUnit.main,
.SummonUnit.friend {
margin-right: 24px;
max-width: 200px;
}
.SummonUnit.friend {
margin-right: 0;
}
.SummonUnit.main .SummonImage,
.SummonUnit.friend .SummonImage {
height: 378px;
width: 180px;
}
/* Grid */
.SummonUnit.grid {
max-width: 160px;
}
.SummonUnit.grid .SummonImage {
list-style-type: none;
height: 92px;
width: 160px;
}

View file

@ -0,0 +1,51 @@
import React, { useState } from 'react'
import classnames from 'classnames'
import UncapIndicator from '~components/UncapIndicator'
import './index.css'
import Plus from '../../../assets/plus.svg'
interface Props {
onReceiveData: (summon: Summon, position: number) => void
summon: Summon | undefined
position: number
editable: boolean
unitType: 0 | 1 | 2
}
const SummonUnit = (props: Props) => {
const numSummons: number = 4
const openModal = () => {}
const openModalIfEditable = (props.editable) ? openModal : () => {}
const classes = classnames({
SummonUnit: true,
'main': props.unitType == 0,
'grid': props.unitType == 1,
'friend': props.unitType == 2,
'editable': props.editable,
'filled': (props.summon !== undefined)
})
const summon = props.summon
return (
<div>
<div className={classes} onClick={openModalIfEditable}>
<div className="SummonImage">
{ (props.editable) ? <span className='icon'><Plus /></span> : '' }
</div>
<UncapIndicator
ulb={summon?.uncap.ulb || false}
flb={summon?.uncap.flb || false}
uncapLevel={3}
/>
<h3 className="SummonName">{summon?.name.en}</h3>
</div>
</div>
)
}
export default SummonUnit

View file

@ -1,6 +1,5 @@
.WeaponGrid {
display: flex;
margin-top: 96px;
justify-content: center;
}

View file

@ -2,6 +2,11 @@ import React, { useState } from 'react'
import { RouteComponentProps } from 'react-router-dom'
import { useCookies } from 'react-cookie'
import WeaponGrid from '~components/WeaponGrid'
import SegmentedControl from '~components/SegmentedControl'
import Segment from '~components/Segment'
import PartySegmentedControl from '~components/PartySegmentedControl'
import SummonGrid from '~components/SummonGrid'
import CharacterGrid from '~components/CharacterGrid'
interface Props {}
interface NewProps extends RouteComponentProps<Props> {}
@ -24,6 +29,36 @@ const New: React.FC<NewProps> = (props: NewProps) => {
}
function segmentClicked(event: React.ChangeEvent<HTMLInputElement>) {
setSelectedTab(event.target.value)
switch(event.target.value) {
case 'weapons':
setGrid((
<WeaponGrid
userId={cookies.user ? cookies.user.user_id : ''}
editable={true}
exists={false}
pushHistory={callback}
/>
))
break
case 'summons':
setGrid((
<SummonGrid
editable={true}
/>
))
break
case 'characters':
setGrid((
<CharacterGrid
editable={true}
/>
))
break
default:
break
}
}
return (

27
src/types/Character.d.ts vendored Normal file
View file

@ -0,0 +1,27 @@
interface Character {
id: string
granblue_id: number
element: number
max_level: number
name: {
en: string
jp: string
}
hp: {
min_hp: number
max_hp: number
max_hp_flb: number
max_hp_ulb: number
}
atk: {
min_atk: number
max_atk: number
max_atk_flb: number
max_atk_ulb: number
}
uncap: {
flb: boolean
ulb: boolean
}
position?: number
}

27
src/types/Summon.d.ts vendored Normal file
View file

@ -0,0 +1,27 @@
interface Summon {
id: string
granblue_id: number
element: number
max_level: number
name: {
en: string
jp: string
}
hp: {
min_hp: number
max_hp: number
max_hp_flb: number
max_hp_ulb: number
}
atk: {
min_atk: number
max_atk: number
max_atk_flb: number
max_atk_ulb: number
}
uncap: {
flb: boolean
ulb: boolean
}
position?: number
}