From 39b98d3f398c2445e3d10ddb5d84c6a04140304a Mon Sep 17 00:00:00 2001 From: Justin Edmund Date: Fri, 3 Feb 2023 14:40:47 -0800 Subject: [PATCH 1/5] Fix #225 When logging in, the editable flag was not recalculated, so the team appeared as editable (even though it wasn't thanks to backend validation). This fixes the visual bug. --- components/Party/index.tsx | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/components/Party/index.tsx b/components/Party/index.tsx index 347bc49e..2878f17a 100644 --- a/components/Party/index.tsx +++ b/components/Party/index.tsx @@ -1,7 +1,7 @@ import React, { useEffect, useState } from 'react' import { getCookie } from 'cookies-next' import { useRouter } from 'next/router' -import { useSnapshot } from 'valtio' +import { subscribe, useSnapshot } from 'valtio' import clonedeep from 'lodash.clonedeep' import ls from 'local-storage' @@ -20,6 +20,7 @@ import { accountCookie, setEditKey, unsetEditKey } from '~utils/userToken' import type { DetailsObject } from '~types' import './index.scss' +import { accountState } from '~utils/accountState' // Props interface Props { @@ -42,6 +43,7 @@ const Party = (props: Props) => { const { party } = useSnapshot(appState) const [editable, setEditable] = useState(false) const [currentTab, setCurrentTab] = useState(GridType.Weapon) + const [refresh, setRefresh] = useState(false) // Retrieve cookies const cookies = retrieveCookies() @@ -53,6 +55,14 @@ const Party = (props: Props) => { if (props.team) storeParty(props.team) }, []) + // Subscribe to app state to listen for account changes and + // unsubscribe when component is unmounted + const unsubscribe = subscribe(accountState, () => { + setRefresh(true) + }) + + useEffect(() => () => unsubscribe(), []) + // Set editable on first load useEffect(() => { // Get cookie @@ -86,7 +96,7 @@ const Party = (props: Props) => { appState.party.editable = editable setEditable(editable) - }) + }, [refresh]) // Set selected tab from props useEffect(() => { From cd4f80816615c724f41abd7f78ab5ba3e2634234 Mon Sep 17 00:00:00 2001 From: Justin Edmund Date: Fri, 3 Feb 2023 19:33:56 -0800 Subject: [PATCH 2/5] Update remix API call to send local_id --- utils/api.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/utils/api.tsx b/utils/api.tsx index 862dac3c..391dfeb1 100644 --- a/utils/api.tsx +++ b/utils/api.tsx @@ -120,9 +120,9 @@ class Api { return axios.get(resourceUrl, params) } - remix(shortcode: string, params?: {}) { + remix({ shortcode, body, params}: { shortcode: string, body?: {}, params?: {} }) { const resourceUrl = `${this.url}/parties/${shortcode}/remix` - return axios.post(resourceUrl, params) + return axios.post(resourceUrl, body, params) } savedTeams(params: {}) { From b36fd03c1159a1861a0f350941b56e6374aa32a2 Mon Sep 17 00:00:00 2001 From: Justin Edmund Date: Fri, 3 Feb 2023 19:34:28 -0800 Subject: [PATCH 3/5] Send local_id with remix API call --- components/Header/index.tsx | 17 +++++++++++------ components/Party/index.tsx | 16 ++++------------ utils/localId.tsx | 9 +++++++++ 3 files changed, 24 insertions(+), 18 deletions(-) create mode 100644 utils/localId.tsx diff --git a/components/Header/index.tsx b/components/Header/index.tsx index 57cad9d1..91504b11 100644 --- a/components/Header/index.tsx +++ b/components/Header/index.tsx @@ -10,6 +10,7 @@ import Link from 'next/link' import api from '~utils/api' import { accountState, initialAccountState } from '~utils/accountState' import { appState, initialAppState } from '~utils/appState' +import { getLocalId } from '~utils/localId' import { retrieveLocaleCookies } from '~utils/retrieveCookies' import { @@ -189,12 +190,16 @@ const Header = () => { function remixTeam() { setOriginalName(partySnapshot.name ? partySnapshot.name : t('no_title')) - if (partySnapshot.shortcode) - api.remix(partySnapshot.shortcode).then((response) => { - const remix = response.data.party - router.push(`/p/${remix.shortcode}`) - setRemixToastOpen(true) - }) + if (partySnapshot.shortcode) { + const body = getLocalId() + api + .remix({ shortcode: partySnapshot.shortcode, body: body }) + .then((response) => { + const remix = response.data.party + router.push(`/p/${remix.shortcode}`) + setRemixToastOpen(true) + }) + } } function toggleFavorite() { diff --git a/components/Party/index.tsx b/components/Party/index.tsx index 2878f17a..3bc61ce1 100644 --- a/components/Party/index.tsx +++ b/components/Party/index.tsx @@ -12,15 +12,16 @@ import SummonGrid from '~components/SummonGrid' import CharacterGrid from '~components/CharacterGrid' import api from '~utils/api' +import { accountState } from '~utils/accountState' import { appState, initialAppState } from '~utils/appState' +import { getLocalId } from '~utils/localId' import { GridType } from '~utils/enums' import { retrieveCookies } from '~utils/retrieveCookies' -import { accountCookie, setEditKey, unsetEditKey } from '~utils/userToken' +import { setEditKey, unsetEditKey } from '~utils/userToken' import type { DetailsObject } from '~types' import './index.scss' -import { accountState } from '~utils/accountState' // Props interface Props { @@ -109,7 +110,7 @@ const Party = (props: Props) => { if (details) payload = formatDetailsObject(details) return await api.endpoints.parties - .create({ ...payload, ...localId() }) + .create({ ...payload, ...getLocalId() }) .then((response) => storeParty(response.data.party)) } @@ -300,15 +301,6 @@ const Party = (props: Props) => { } } - // Methods: Unauth validation - function localId() { - const cookie = accountCookie() - const parsed = JSON.parse(cookie as string) - if (parsed && !parsed.token) { - return { local_id: parsed.userId } - } else return {} - } - // Render: JSX components const navigation = ( Date: Fri, 3 Feb 2023 19:35:48 -0800 Subject: [PATCH 4/5] Persist generated localId in localStorage --- pages/new/index.tsx | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/pages/new/index.tsx b/pages/new/index.tsx index 69c8ae7d..a89e554a 100644 --- a/pages/new/index.tsx +++ b/pages/new/index.tsx @@ -1,6 +1,8 @@ import React, { useEffect, useState } from 'react' -import { useRouter } from 'next/router' +import { getCookie, setCookie } from 'cookies-next' +import { get, set } from 'local-storage' import { serverSideTranslations } from 'next-i18next/serverSideTranslations' +import { useRouter } from 'next/router' import { v4 as uuidv4 } from 'uuid' import clonedeep from 'lodash.clonedeep' @@ -19,7 +21,6 @@ import type { AxiosError } from 'axios' import type { NextApiRequest, NextApiResponse } from 'next' import type { PageContextObj, ResponseStatus } from '~types' import { GridType } from '~utils/enums' -import { setCookie } from 'cookies-next' interface Props { context?: PageContextObj @@ -59,6 +60,13 @@ const NewRoute: React.FC = ({ } }, [router.asPath]) + // Persist generated userId in storage + useEffect(() => { + const cookie = getCookie('account') + const data: AccountCookie = JSON.parse(cookie as string) + if (!get('userId') && data && !data.token) set('userId', data.userId) + }, []) + useEffect(() => { if (context && context.jobs && context.jobSkills) { appState.raids = context.raids From bc1f6fa64b3bf1d745147e062dadcbf91587bb38 Mon Sep 17 00:00:00 2001 From: Justin Edmund Date: Fri, 3 Feb 2023 19:38:06 -0800 Subject: [PATCH 5/5] Set cookie from LocalStorage on when app loads --- pages/_app.tsx | 55 ++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 49 insertions(+), 6 deletions(-) diff --git a/pages/_app.tsx b/pages/_app.tsx index d3455586..ab639d9d 100644 --- a/pages/_app.tsx +++ b/pages/_app.tsx @@ -1,19 +1,34 @@ -import { useEffect } from 'react' -import { getCookie } from 'cookies-next' import { appWithTranslation } from 'next-i18next' +import { get } from 'local-storage' +import { getCookie, setCookie } from 'cookies-next' +import { subscribe } from 'valtio' +import { useEffect, useState } from 'react' import { ThemeProvider } from 'next-themes' -import type { AppProps } from 'next/app' -import Layout from '~components/Layout' - import { accountState } from '~utils/accountState' +import { retrieveCookies } from '~utils/retrieveCookies' import { setHeaders } from '~utils/userToken' -import '../styles/globals.scss' import { ToastProvider, Viewport } from '@radix-ui/react-toast' import { TooltipProvider } from '@radix-ui/react-tooltip' +import Layout from '~components/Layout' + +import type { AppProps } from 'next/app' + +import '../styles/globals.scss' + function MyApp({ Component, pageProps }: AppProps) { + const [refresh, setRefresh] = useState(false) + + // Subscribe to app state to listen for account changes and + // unsubscribe when component is unmounted + const unsubscribe = subscribe(accountState, () => { + setRefresh(true) + }) + + useEffect(() => () => unsubscribe(), []) + const accountCookie = getCookie('account') const userCookie = getCookie('user') @@ -42,9 +57,37 @@ function MyApp({ Component, pageProps }: AppProps) { } } else { console.log(`You are not currently logged in.`) + setCookieFromLocalStorage() } }, []) + useEffect(() => { + setCookieFromLocalStorage() + }, [refresh]) + + function setCookieFromLocalStorage() { + const localUserId: string | null = get('userId') + const cookies = retrieveCookies() + if ( + localUserId && + (!cookies || (cookies && cookies.account && !cookies.account.token)) + ) { + const expiresAt = new Date() + expiresAt.setDate(expiresAt.getDate() + 60) + + const cookieObj = { + userId: localUserId, + username: undefined, + token: undefined, + } + + setCookie('account', cookieObj, { + path: '/', + expires: expiresAt, + }) + } + } + return (