diff --git a/src/components/App/index.css b/src/components/App/index.css index c9ba1cea..c2fba2fc 100644 --- a/src/components/App/index.css +++ b/src/components/App/index.css @@ -26,7 +26,7 @@ h1 { display: flex; flex-direction: column; gap: 24px; - margin-top: 96px; + margin-top: 24px; } #NotFound { diff --git a/src/components/CharacterGrid/index.tsx b/src/components/CharacterGrid/index.tsx index 2817ad48..665df305 100644 --- a/src/components/CharacterGrid/index.tsx +++ b/src/components/CharacterGrid/index.tsx @@ -3,14 +3,23 @@ import CharacterUnit from '~components/CharacterUnit' import './index.css' +export enum GridType { + Class, + Character, + Weapon, + Summon +} + interface Props { editable: boolean + exists: boolean + onSelect: (type: GridType, character: Character, position: number) => void } const CharacterGrid = (props: Props) => { const numCharacters: number = 5 - const [characters, setCharacters] = useState({}) + const [characters, setCharacters] = useState>({}) const [partyId, setPartyId] = useState('') return ( diff --git a/src/components/GridRep/index.tsx b/src/components/GridRep/index.tsx index addf31bb..7386e627 100644 --- a/src/components/GridRep/index.tsx +++ b/src/components/GridRep/index.tsx @@ -15,7 +15,7 @@ const GridRep = (props: Props) => { const numWeapons: number = 9 const [mainhand, setMainhand] = useState() - const [weapons, setWeapons] = useState({}) + const [weapons, setWeapons] = useState>({}) useEffect(() => { configure() diff --git a/src/components/Party/index.css b/src/components/Party/index.css new file mode 100644 index 00000000..e69de29b diff --git a/src/components/Party/index.tsx b/src/components/Party/index.tsx new file mode 100644 index 00000000..d8b4db41 --- /dev/null +++ b/src/components/Party/index.tsx @@ -0,0 +1,227 @@ +import React, { useEffect, useState } from 'react' +import { useCookies } from 'react-cookie' +import api from '~utils/api' + +// UI Elements +import PartySegmentedControl from '~components/PartySegmentedControl' + +// Grids +import WeaponGrid from '~components/WeaponGrid' +import SummonGrid from '~components/SummonGrid' +import CharacterGrid from '~components/CharacterGrid' + +// GridType +export enum GridType { + Class, + Character, + Weapon, + Summon +} + +import './index.css' + +interface Props { + editable: boolean + exists: boolean + pushHistory: (path: string) => void +} + +const Party = (props: Props) => { + const [cookies, setCookie] = useCookies(['user']) + + const headers = (cookies.user) ? { + headers: { + 'Authorization': `Bearer ${cookies.user.access_token}` + } + } : {} + + // Grid data + const [weapons, setWeapons] = useState>({}) + const [summons, setSummons] = useState>({}) + + const [mainWeapon, setMainWeapon] = useState() + const [mainSummon, setMainSummon] = useState() + const [friendSummon, setFriendSummon] = useState() + + const weaponGrid = ( + + ) + + const summonGrid = ( + + ) + + const characterGrid = ( + + ) + + const [currentGrid, setCurrentGrid] = useState(weaponGrid) + const [currentTab, setCurrentTab] = useState(GridType.Weapon) + + const [partyId, setPartyId] = useState('') + + function segmentClicked(event: React.ChangeEvent) { + switch(event.target.value) { + case 'characters': + setCurrentTab(GridType.Character) + setCurrentGrid(characterGrid) + break + case 'weapons': + setCurrentTab(GridType.Weapon) + setCurrentGrid(weaponGrid) + break + case 'summons': + setCurrentTab(GridType.Summon) + setCurrentGrid(summonGrid) + break + default: + break + } + } + + function itemSelected(type: GridType, item: Character | Weapon | Summon, position: number) { + if (!partyId) { + createParty() + .then(response => { + return response.data.party + }) + .then(party => { + if (props.pushHistory) { + props.pushHistory(`/p/${party.shortcode}`) + } + + return party.id + }) + .then(partyId => { + setPartyId(partyId) + save(partyId, type, item, position) + }) + } else { + save(partyId, type, item, position) + } + } + + async function createParty() { + const body = (cookies.user.userId === undefined) ? {} : { + party: { + user_id: cookies.user.userId + } + } + + return await api.endpoints.parties.create(body, headers) + } + + function save(partyId: string, type: GridType, item: Character | Weapon | Summon, position: number) { + switch(type) { + case GridType.Class: + saveClass() + break + case GridType.Character: + saveCharacter(item as Character, position, partyId) + break + case GridType.Weapon: + const weapon = item as Weapon + saveWeapon(weapon, position, partyId) + .then(() => { + storeWeapon(weapon, position) + }) + break + case GridType.Summon: + const summon = item as Summon + saveSummon(summon, position, partyId) + .then(() => { + storeSummon(summon, position) + }) + break + } + } + + function storeWeapon(weapon: Weapon, position: number) { + if (position == -1) { + setMainWeapon(weapon) + } else { + // Store the grid unit weapon at the correct position + let newWeapons = Object.assign({}, weapons) + newWeapons[position] = weapon + setWeapons(newWeapons) + } + } + + async function saveWeapon(weapon: Weapon, position: number, party: string) { + await api.endpoints.weapons.create({ + 'weapon': { + 'party_id': party, + 'weapon_id': weapon.id, + 'position': position, + 'mainhand': (position == -1) + } + }, headers) + } + + function storeSummon(summon: Summon, position: number) { + if (position == -1) { + setMainSummon(summon) + } else if (position == 4) { + setFriendSummon(summon) + } else { + // Store the grid unit summon at the correct position + let newSummons = Object.assign({}, summons) + newSummons[position] = summon + setSummons(newSummons) + } + } + + async function saveSummon(summon: Summon, position: number, party: string) { + await api.endpoints.summons.create({ + 'summon': { + 'party_id': party, + 'summon_id': summon.id, + 'position': position, + 'main': (position == -1), + 'friend': (position == 4) + } + }, headers) + } + + function saveCharacter(character: Character, position: number, party: string) { + // TODO: Implement this + } + + function saveClass() { + // TODO: Implement this + } + + return ( +
+ + + {currentGrid} +
+ ) +} + +export default Party \ No newline at end of file diff --git a/src/components/PartySegmentedControl/index.tsx b/src/components/PartySegmentedControl/index.tsx index 2eebfe0d..880776fd 100644 --- a/src/components/PartySegmentedControl/index.tsx +++ b/src/components/PartySegmentedControl/index.tsx @@ -2,8 +2,16 @@ import React from 'react' import SegmentedControl from '~components/SegmentedControl' import Segment from '~components/Segment' +// GridType +export enum GridType { + Class, + Character, + Weapon, + Summon +} + interface Props { - selectedTab: string + selectedTab: GridType onClick: (event: React.ChangeEvent) => void } @@ -11,30 +19,31 @@ const PartySegmentedControl = (props: Props) => { return (
- Class + >Class */} + Characters Weapons Summons diff --git a/src/components/SearchModal/index.tsx b/src/components/SearchModal/index.tsx index 0c53dfc9..cc7efe5e 100644 --- a/src/components/SearchModal/index.tsx +++ b/src/components/SearchModal/index.tsx @@ -5,14 +5,16 @@ import api from '~utils/api' import Modal from '~components/Modal' import Overlay from '~components/Overlay' import WeaponResult from '~components/WeaponResult' +import SummonResult from '~components/SummonResult' import './index.css' interface Props { close: () => void - send: (weapon: Weapon, position: number) => any + send: (object: Weapon | Summon, position: number) => any placeholderText: string fromPosition: number + object: 'weapons' | 'characters' | 'summons' } interface State { @@ -45,7 +47,7 @@ class SearchModal extends React.Component { } fetchResults = (query: string) => { - api.search(query) + api.search(this.props.object, query) .then((response) => { const data = response.data const totalResults = data.length @@ -73,13 +75,27 @@ class SearchModal extends React.Component { } } - sendData = (result: Weapon) => { + sendData = (result: Weapon | Summon) => { this.props.send(result, this.props.fromPosition) this.props.close() } renderSearchResults = () => { - const { results } = this.state + const { results } = this.state + + switch(this.props.object) { + case 'weapons': + return this.renderWeaponSearchResults(results) + + case 'summons': + return this.renderSummonSearchResults(results) + + case 'characters': + return (
) + } + } + + renderWeaponSearchResults = (results: { [key: string]: any }) => { return (
    { results.map( (result: Weapon) => { @@ -89,11 +105,21 @@ class SearchModal extends React.Component { ) } + renderSummonSearchResults = (results: { [key: string]: any }) => { + return ( +
      + { results.map( (result: Summon) => { + return { this.sendData(result) }} /> + })} +
    + ) + } + renderEmptyState = () => { let string = '' if (this.state.query === '') { - string = 'No weapons' + string = `No ${this.props.object}` } else { string = `No results found for '${this.state.query}'` } diff --git a/src/components/SegmentedControl/index.css b/src/components/SegmentedControl/index.css index e5544066..45ff96dd 100644 --- a/src/components/SegmentedControl/index.css +++ b/src/components/SegmentedControl/index.css @@ -1,6 +1,7 @@ .SegmentedControlWrapper { display: flex; justify-content: center; + margin-bottom: 24px; } .SegmentedControl { diff --git a/src/components/SummonGrid/index.tsx b/src/components/SummonGrid/index.tsx index 3d85b633..269007f7 100644 --- a/src/components/SummonGrid/index.tsx +++ b/src/components/SummonGrid/index.tsx @@ -1,29 +1,49 @@ -import React, { useState } from 'react' +import React, { useEffect, useState } from 'react' +import { useCookies } from 'react-cookie' +import api from '~utils/api' + import SummonUnit from '~components/SummonUnit' import './index.css' +// GridType +export enum GridType { + Class, + Character, + Weapon, + Summon +} + +// Props interface Props { + userId?: string + partyId?: string + main?: Summon | undefined + friend?: Summon | undefined + grid: GridArray editable: boolean + exists: boolean + found?: boolean + onSelect: (type: GridType, summon: Summon, position: number) => void + pushHistory?: (path: string) => void } const SummonGrid = (props: Props) => { const numSummons: number = 4 - const [mainSummon, setMainSummon] = useState() - const [friendSummon, setFriendSummon] = useState() - const [summons, setSummons] = useState({}) - const [partyId, setPartyId] = useState('') + function receiveSummon(summon: Summon, position: number) { + props.onSelect(GridType.Summon, summon, position) + } return (
    {}} + onReceiveData={receiveSummon} position={-1} unitType={0} - summon={mainSummon} + summon={props.main} />
      @@ -33,10 +53,10 @@ const SummonGrid = (props: Props) => {
    • {}} + onReceiveData={receiveSummon} position={i} unitType={1} - summon={summons[i]} + summon={props.grid[i]} />
    • ) @@ -47,10 +67,10 @@ const SummonGrid = (props: Props) => { {}} - position={-1} + onReceiveData={receiveSummon} + position={4} unitType={2} - summon={friendSummon} + summon={props.friend} />
    ) diff --git a/src/components/SummonResult/index.css b/src/components/SummonResult/index.css new file mode 100644 index 00000000..584ffec6 --- /dev/null +++ b/src/components/SummonResult/index.css @@ -0,0 +1,48 @@ +.SummonResult { + -webkit-font-smoothing: antialiased; + + border-radius: 6px; + display: flex; + font-family: -apple-system, "Helvetica Neue", "Lucida Grande"; + gap: 8px; + padding: 12px; +} + +.SummonResult img { + background: #e9e9e9; + border-radius: 6px; + display: inline-block; + height: 72px; + width: 120px; +} + +.SummonResult h5 { + color: #555; + display: inline-block; + font-size: 18px; + font-weight: 500; + margin: 2px 4px 4px 0; +} + +.SummonResult .WeaponLabelIcon { + margin-right: 4px; +} + +.SummonResult .stars { + display: inline-block; + color: #FFA15E; + font-size: 21px; +} + +.SummonResult .stars > span { + color: #65DAFF; +} + +.SummonResult:hover { + background: #e9e9e9; + cursor: pointer; +} + +.SummonResult:hover .image_placeholder { + background: #dadada; +} \ No newline at end of file diff --git a/src/components/SummonResult/index.tsx b/src/components/SummonResult/index.tsx new file mode 100644 index 00000000..e62a4731 --- /dev/null +++ b/src/components/SummonResult/index.tsx @@ -0,0 +1,41 @@ +import React from 'react' +import WeaponLabelIcon from '~components/WeaponLabelIcon' + +import gridImages from '../../images/summon-grid/*.jpg' + +import './index.css' + +interface Props { + data: Summon + onClick: () => void +} + +const Element = ['null', 'wind', 'fire', 'water', 'earth', 'dark', 'light'] + +class SummonResult extends React.Component { + render() { + let imgSrc + + const summon = this.props.data + if (process.env.NODE_ENV === 'development') { + imgSrc = gridImages[summon.granblue_id] + } else if (process.env.NODE_ENV === 'production') { + imgSrc = `${process.env.SIERO_IMG_URL}/summon-grid/${summon.granblue_id}.jpg` + } + + return ( +
  • + {summon.name.en} +
    +
    +
    {summon.name.en}
    +
    ⭑⭑⭑{(summon.uncap.flb) ? : ''}{(summon.uncap.ulb) ? : ''}
    +
    + +
    +
  • + ) + } +} + +export default SummonResult \ No newline at end of file diff --git a/src/components/SummonUnit/index.tsx b/src/components/SummonUnit/index.tsx index 9c1e5c9b..bcae2b01 100644 --- a/src/components/SummonUnit/index.tsx +++ b/src/components/SummonUnit/index.tsx @@ -1,11 +1,16 @@ -import React, { useState } from 'react' +import React, { useEffect, useState } from 'react' import classnames from 'classnames' +import { useModal as useModal } from '~utils/useModal' + +import SearchModal from '~components/SearchModal' import UncapIndicator from '~components/UncapIndicator' -import './index.css' - +import mainImages from '../../images/summon-main/*.jpg' +import gridImages from '../../images/summon-grid/*.jpg' import Plus from '../../../assets/plus.svg' +import './index.css' + interface Props { onReceiveData: (summon: Summon, position: number) => void summon: Summon | undefined @@ -15,8 +20,9 @@ interface Props { } const SummonUnit = (props: Props) => { - const numSummons: number = 4 - const openModal = () => {} + const [imageUrl, setImageUrl] = useState('') + + const { open, openModal, closeModal } = useModal() const openModalIfEditable = (props.editable) ? openModal : () => {} @@ -31,10 +37,53 @@ const SummonUnit = (props: Props) => { const summon = props.summon + useEffect(() => { + generateImageUrl() + }) + + function generateImageUrl() { + let imgSrc + if (props.summon) { + const summon = props.summon! + + // Generate the correct source for the weapon + if (process.env.NODE_ENV === 'development') { + if (props.unitType == 0 || props.unitType == 2) + imgSrc = mainImages[summon.granblue_id] + else + imgSrc = gridImages[summon.granblue_id] + } else if (process.env.NODE_ENV === 'production') { + if (props.unitType == 0 || props.unitType == 2) + imgSrc = `${process.env.SIERO_IMG_URL}/summon-main/${summon.granblue_id}.jpg` + else + imgSrc = `${process.env.SIERO_IMG_URL}/summon-grid/${summon.granblue_id}.jpg` + } + } + + setImageUrl(imgSrc) + } + + function sendData(object: Weapon | Summon, position: number) { + if (isSummon(object)) { + props.onReceiveData(object, position) + } + } + + function isSummon(object: Weapon | Summon): object is Summon { + // There aren't really any unique fields here + return (object as Summon).granblue_id !== undefined + } + return (
    + { + (imageUrl != '') + ? + : + + } { (props.editable) ? : '' }
    { />

    {summon?.name.en}

    + {open ? ( + + ) : null}
    ) } diff --git a/src/components/WeaponGrid/index.tsx b/src/components/WeaponGrid/index.tsx index 3f9f9cb0..f972a1c9 100644 --- a/src/components/WeaponGrid/index.tsx +++ b/src/components/WeaponGrid/index.tsx @@ -3,109 +3,35 @@ import { useCookies } from 'react-cookie' import api from '~utils/api' import WeaponUnit from '~components/WeaponUnit' -import Button from '~components/Button' import './index.css' +// GridType +export enum GridType { + Class, + Character, + Weapon, + Summon +} + +// Props interface Props { userId?: string partyId?: string mainhand?: Weapon | undefined - grid?: GridArray + grid: GridArray editable: boolean exists: boolean found?: boolean + onSelect: (type: GridType, weapon: Weapon, position: number) => void pushHistory?: (path: string) => void } -type GridArray = { [key: number]: Weapon } - const WeaponGrid = (props: Props) => { const numWeapons: number = 9 - const [mainhand, setMainhand] = useState() - const [weapons, setWeapons] = useState({}) - const [partyId, setPartyId] = useState('') - - const [cookies, setCookie] = useCookies(['user']) - - useEffect(() => { - if (props.exists && props.found) - configure() - }, [props.mainhand, props.grid, props.partyId]) - - function configure() { - setMainhand(props.mainhand) - setWeapons(props.grid || {}) - setPartyId(props.partyId || '') - } - - function createParty() { - const headers = (cookies.user != null) ? { - headers: { - 'Authorization': `Bearer ${cookies.user.access_token}` - } - } : {} - - const body = (props.userId === undefined) ? {} : { - party: { - user_id: props.userId - } - } - - return api.endpoints.parties.create(body, headers) - } - function receiveWeapon(weapon: Weapon, position: number) { - const isMainhand = position == -1 - - if (isMainhand) { - setMainhand(weapon) - } else { - // Store the grid unit weapon at the correct position - let newWeapons = Object.assign({}, weapons) - newWeapons[position] = weapon - setWeapons(newWeapons) - } - - if (partyId) { - saveWeapon(partyId, weapon, position) - } else { - createParty() - .then(response => { - return response.data.party - }) - .then(party => { - if (props.pushHistory) { - props.pushHistory(`/p/${party.shortcode}`) - } - - return party.id - }) - .then(partyId => { - saveWeapon(partyId, weapon, position) - setPartyId(partyId) - }) - } - } - - function saveWeapon(pid: string, weapon: Weapon, position: number) { - const headers = (cookies.user != null) ? { - headers: { - 'Authorization': `Bearer ${cookies.user.access_token}` - } - } : {} - - const body = { - 'weapon': { - 'party_id': pid, - 'weapon_id': weapon.id, - 'position': position, - 'mainhand': (position == -1) - } - } - - api.endpoints.weapons.create(body, headers) + props.onSelect(GridType.Weapon, weapon, position) } return ( @@ -116,7 +42,7 @@ const WeaponGrid = (props: Props) => { onReceiveData={receiveWeapon} position={-1} unitType={0} - weapon={mainhand} + weapon={props.mainhand} />
      @@ -129,7 +55,7 @@ const WeaponGrid = (props: Props) => { onReceiveData={receiveWeapon} position={i} unitType={1} - weapon={weapons[i]} + weapon={props.grid[i]} /> ) diff --git a/src/components/WeaponResult/index.tsx b/src/components/WeaponResult/index.tsx index c66130de..268e20a7 100644 --- a/src/components/WeaponResult/index.tsx +++ b/src/components/WeaponResult/index.tsx @@ -1,7 +1,7 @@ import React from 'react' import WeaponLabelIcon from '~components/WeaponLabelIcon' -import gridImages from '../../images/grid/*.jpg' +import gridImages from '../../images/weapon-grid/*.jpg' import './index.css' diff --git a/src/components/WeaponUnit/index.tsx b/src/components/WeaponUnit/index.tsx index 45267961..b0b98bd7 100644 --- a/src/components/WeaponUnit/index.tsx +++ b/src/components/WeaponUnit/index.tsx @@ -5,8 +5,8 @@ import { useModal as useModal } from '~utils/useModal' import SearchModal from '~components/SearchModal' import UncapIndicator from '~components/UncapIndicator' -import mainhandImages from '../../images/mainhand/*.jpg' -import gridImages from '../../images/grid/*.jpg' +import mainImages from '../../images/weapon-main/*.jpg' +import gridImages from '../../images/weapon-grid/*.jpg' import Plus from '../../../assets/plus.svg' import './index.css' @@ -19,7 +19,7 @@ interface Props { unitType: 0 | 1 } -function WeaponUnit(props: Props) { +const WeaponUnit = (props: Props) => { const [imageUrl, setImageUrl] = useState('') const { open, openModal, closeModal } = useModal() @@ -48,7 +48,7 @@ function WeaponUnit(props: Props) { // Generate the correct source for the weapon if (process.env.NODE_ENV === 'development') { if (props.unitType == 0) - imgSrc = mainhandImages[weapon.granblue_id] + imgSrc = mainImages[weapon.granblue_id] else imgSrc = gridImages[weapon.granblue_id] } else if (process.env.NODE_ENV === 'production') { @@ -62,6 +62,16 @@ function WeaponUnit(props: Props) { setImageUrl(imgSrc) } + function sendData(object: Weapon | Summon, position: number) { + if (isWeapon(object)) { + props.onReceiveData(object, position) + } + } + + function isWeapon(object: Weapon | Summon): object is Weapon { + return (object as Weapon).proficiency !== undefined + } + return (
      @@ -84,8 +94,9 @@ function WeaponUnit(props: Props) { {open ? ( ) : null} diff --git a/src/routes/New/index.tsx b/src/routes/New/index.tsx index a36b3299..d619999c 100644 --- a/src/routes/New/index.tsx +++ b/src/routes/New/index.tsx @@ -1,74 +1,24 @@ -import React, { useState } from 'react' +import React 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' + +import Party from '~components/Party' interface Props {} interface NewProps extends RouteComponentProps {} -const New: React.FC = (props: NewProps) => { - const [cookies, setCookie] = useCookies(['user']) - const [selectedTab, setSelectedTab] = useState('weapons') - const [grid, setGrid] = useState( - - ) - +const New: React.FC = () => { function callback(path: string) { // This is scuffed, how do we do this natively? window.history.replaceState(null, `Grid Tool`, `${path}`) } - function segmentClicked(event: React.ChangeEvent) { - setSelectedTab(event.target.value) - - switch(event.target.value) { - case 'weapons': - setGrid(( - - )) - break - case 'summons': - setGrid(( - - )) - break - case 'characters': - setGrid(( - - )) - break - default: - break - } - } - return (
      - - - {grid}
      ) } diff --git a/src/routes/Party/index.tsx b/src/routes/Party/index.tsx index ddcd1446..48e4470a 100644 --- a/src/routes/Party/index.tsx +++ b/src/routes/Party/index.tsx @@ -3,40 +3,34 @@ import { withCookies, useCookies } from 'react-cookie' import { RouteComponentProps, withRouter } from 'react-router-dom' import api from '~utils/api' +import PartySegmentedControl from '~components/PartySegmentedControl' import WeaponGrid from '~components/WeaponGrid' +import SummonGrid from '~components/SummonGrid' +import CharacterGrid from '~components/CharacterGrid' import Button from '~components/Button' interface Props { hash: string } -interface State { - found: boolean - editable: boolean - mainhand: Weapon, - grid: GridArray, - partyId: string -} - interface PartyProps extends RouteComponentProps {} -type GridArray = { [key: number]: Weapon } -interface GridWeapon { - id: string - mainhand: boolean - position: number | null - weapon: Weapon -} - -const Party: React.FC = ({ match }, state: State) => { +const Party: React.FC = ({ match }) => { const [found, setFound] = useState(false) const [loading, setLoading] = useState(true) const [editable, setEditable] = useState(false) - const [grid, setGrid] = useState({}) - const [mainhand, setMainhand] = useState() + + const [weapons, setWeapons] = useState>({}) + const [summons, setSummons] = useState>({}) + + const [mainWeapon, setMainWeapon] = useState() + const [mainSummon, setMainSummon] = useState() + const [friendSummon, setFriendSummon] = useState() + const [partyId, setPartyId] = useState('') const [cookies, setCookie] = useCookies(['userId']) - + const [selectedTab, setSelectedTab] = useState('weapons') + const [tab, setTab] = useState() const shortcode = match.params.hash || '' useEffect(() => { @@ -54,17 +48,28 @@ const Party: React.FC = ({ match }, state: State) => { if (partyUser != undefined && loggedInUser != undefined && partyUser === loggedInUser) setEditable(true) - let weapons: GridArray = {} - party.grid.forEach((gridWeapon: GridWeapon) => { + let weapons: GridArray = {} + let summons: GridArray = {} + party.weapons.forEach((gridWeapon: GridWeapon) => { if (gridWeapon.mainhand) - setMainhand(gridWeapon.weapon) + setMainWeapon(gridWeapon.weapon) else if (!gridWeapon.mainhand && gridWeapon.position != null) weapons[gridWeapon.position] = gridWeapon.weapon }) + party.summons.forEach((gridSummon: GridSummon) => { + if (gridSummon.main) + setMainSummon(gridSummon.summon) + else if (gridSummon.friend) + setFriendSummon(gridSummon.summon) + else if (!gridSummon.main && !gridSummon.friend && gridSummon.position != null) + summons[gridSummon.position] = gridSummon.summon + }) + setFound(true) setLoading(false) - setGrid(weapons) + setWeapons(weapons) + setSummons(summons) setPartyId(party.id) }) .catch(error => { @@ -79,18 +84,68 @@ const Party: React.FC = ({ match }, state: State) => { }) } + function segmentClicked(event: React.ChangeEvent) { + setSelectedTab(event.target.value) + + switch(event.target.value) { + case 'weapons': + setTab(( + + )) + break + case 'summons': + setTab(( + + )) + break + case 'characters': + setTab(( + + )) + break + default: + break + } + } + function render() { return ( -
      - + + + {tab || ( + + )}
      ) } diff --git a/src/types/GridArray.d.ts b/src/types/GridArray.d.ts index c469f749..ae10bdd7 100644 --- a/src/types/GridArray.d.ts +++ b/src/types/GridArray.d.ts @@ -1 +1 @@ -type GridArray = { [key: number]: Weapon } \ No newline at end of file +type GridArray = { [key: number]: T } \ No newline at end of file diff --git a/src/types/GridSummon.d.ts b/src/types/GridSummon.d.ts new file mode 100644 index 00000000..2f366574 --- /dev/null +++ b/src/types/GridSummon.d.ts @@ -0,0 +1,7 @@ +interface GridSummon { + id: string + main: boolean + friend: boolean + position: number | null + summon: Summon +} \ No newline at end of file diff --git a/src/utils/api.tsx b/src/utils/api.tsx index 9f63b81b..672d7a94 100644 --- a/src/utils/api.tsx +++ b/src/utils/api.tsx @@ -49,9 +49,9 @@ class Api { return axios.post(`${process.env.SIERO_OAUTH_URL}/token` || 'http://127.0.0.1:3000/oauth/token', object) } - search(query: string) { + search(object: string, query: string) { const resourceUrl = `${this.url}/${name}` - return axios.get(`${resourceUrl}/search?query=${query}`) + return axios.get(`${resourceUrl}/search/${object}?query=${query}`) } check(resource: string, value: string) { @@ -66,5 +66,6 @@ const api: Api = new Api({ url: process.env.SIERO_API_URL || 'http://127.0.0.1:3 api.createEntity( { name: 'users' }) api.createEntity( { name: 'parties' }) api.createEntity( { name: 'weapons' }) +api.createEntity( { name: 'summons' }) export default api \ No newline at end of file