import React, { useCallback, useEffect, useMemo, useState } from 'react' import { useRouter } from 'next/router' import { useSnapshot } from 'valtio' import { getCookie } from 'cookies-next' import clonedeep from 'lodash.clonedeep' import PartySegmentedControl from '~components/PartySegmentedControl' import PartyDetails from '~components/PartyDetails' import WeaponGrid from '~components/WeaponGrid' import SummonGrid from '~components/SummonGrid' import CharacterGrid from '~components/CharacterGrid' import api from '~utils/api' import { appState, initialAppState } from '~utils/appState' import { GridType, TeamElement } from '~utils/enums' import './index.scss' // Props interface Props { new?: boolean team?: Party raids: Raid[][] pushHistory?: (path: string) => void } const Party = (props: Props) => { // Set up router const router = useRouter() // Set up states const { party } = useSnapshot(appState) const [currentTab, setCurrentTab] = useState(GridType.Weapon) // Reset state on first load useEffect(() => { const resetState = clonedeep(initialAppState) appState.grid = resetState.grid if (props.team) storeParty(props.team) }, []) // Methods: Creating a new party async function createParty(extra: boolean = false) { let body = { party: { extra: extra, }, } return await api.endpoints.parties.create(body) } // Methods: Updating the party's details function checkboxChanged(event: React.ChangeEvent) { appState.party.extra = event.target.checked if (party.id) { api.endpoints.parties.update(party.id, { party: { extra: event.target.checked }, }) } } function updateDetails(name?: string, description?: string, raid?: Raid) { if ( appState.party.name !== name || appState.party.description !== description || appState.party.raid?.id !== raid?.id ) { if (appState.party.id) api.endpoints.parties .update(appState.party.id, { party: { name: name, description: description, raid_id: raid?.id, }, }) .then(() => { appState.party.name = name appState.party.description = description appState.party.raid = raid appState.party.updated_at = party.updated_at }) } } // Deleting the party function deleteTeam(event: React.MouseEvent) { if (appState.party.editable && appState.party.id) { api.endpoints.parties .destroy({ id: appState.party.id }) .then(() => { // Push to route router.push('/') // Clean state const resetState = clonedeep(initialAppState) Object.keys(resetState).forEach((key) => { appState[key] = resetState[key] }) // Set party to be editable appState.party.editable = true }) .catch((error) => { console.error(error) }) } } // Methods: Storing party data const storeParty = function (team: Party) { // Store the important party and state-keeping values appState.party.name = team.name appState.party.description = team.description appState.party.raid = team.raid appState.party.updated_at = team.updated_at appState.party.job = team.job appState.party.jobSkills = team.job_skills appState.party.id = team.id appState.party.extra = team.extra appState.party.user = team.user appState.party.favorited = team.favorited appState.party.created_at = team.created_at appState.party.updated_at = team.updated_at appState.party.detailsVisible = false // Populate state storeCharacters(team.characters) storeWeapons(team.weapons) storeSummons(team.summons) } const storeCharacters = (list: Array) => { list.forEach((object: GridCharacter) => { if (object.position != null) appState.grid.characters[object.position] = object }) } const storeWeapons = (list: Array) => { list.forEach((gridObject: GridWeapon) => { if (gridObject.mainhand) { appState.grid.weapons.mainWeapon = gridObject appState.party.element = gridObject.object.element } else if (!gridObject.mainhand && gridObject.position != null) { appState.grid.weapons.allWeapons[gridObject.position] = gridObject } }) } const storeSummons = (list: Array) => { list.forEach((gridObject: GridSummon) => { if (gridObject.main) appState.grid.summons.mainSummon = gridObject else if (gridObject.friend) appState.grid.summons.friendSummon = gridObject else if ( !gridObject.main && !gridObject.friend && gridObject.position != null ) appState.grid.summons.allSummons[gridObject.position] = gridObject }) } // Methods: Navigating with segmented control function segmentClicked(event: React.ChangeEvent) { switch (event.target.value) { case 'class': setCurrentTab(GridType.Class) break case 'characters': setCurrentTab(GridType.Character) break case 'weapons': setCurrentTab(GridType.Weapon) break case 'summons': setCurrentTab(GridType.Summon) break default: break } } // Render: JSX components const navigation = ( ) const weaponGrid = ( ) const summonGrid = ( ) const characterGrid = ( ) const currentGrid = () => { switch (currentTab) { case GridType.Character: return characterGrid case GridType.Weapon: return weaponGrid case GridType.Summon: return summonGrid } } return ( {navigation}
{currentGrid()}
) } export default Party