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) => { // Cookies const cookie = getCookie("account"); const accountData: AccountCookie = cookie ? JSON.parse(cookie as string) : null; const headers = useMemo(() => { return accountData ? { headers: { Authorization: `Bearer ${accountData.token}` } } : {}; }, [accountData]); // 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: { ...(accountData && { user_id: accountData.userId }), extra: extra, }, }; return await api.endpoints.parties.create(body, headers); } // 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 }, }, headers ); } } 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, }, }, headers ) .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, params: headers }) .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 (party: Party) { // Store the important party and state-keeping values appState.party.name = party.name; appState.party.description = party.description; appState.party.raid = party.raid; appState.party.updated_at = party.updated_at; appState.party.job = party.job; appState.party.jobSkills = party.job_skills; appState.party.id = party.id; appState.party.extra = party.extra; appState.party.user = party.user; appState.party.favorited = party.favorited; appState.party.created_at = party.created_at; appState.party.updated_at = party.updated_at; // Populate state storeCharacters(party.characters); storeWeapons(party.weapons); storeSummons(party.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;