From 9e3f15c28616a7eadd11ebb89c30f504312d5710 Mon Sep 17 00:00:00 2001 From: Justin Edmund Date: Sat, 28 Jan 2023 17:58:12 -0800 Subject: [PATCH] Refactor [username] and extract ProfileHead --- components/ProfileHead/index.tsx | 59 ++++++++ pages/[username].tsx | 240 +++++++++++++++---------------- 2 files changed, 177 insertions(+), 122 deletions(-) create mode 100644 components/ProfileHead/index.tsx diff --git a/components/ProfileHead/index.tsx b/components/ProfileHead/index.tsx new file mode 100644 index 00000000..f196c09e --- /dev/null +++ b/components/ProfileHead/index.tsx @@ -0,0 +1,59 @@ +import React from 'react' +import Head from 'next/head' +import { useTranslation } from 'next-i18next' + +interface Props { + user: User +} + +const ProfileHead = ({ user }: Props) => { + // Import translations + const { t } = useTranslation('common') + + return ( + + {/* HTML */} + {t('page.titles.profile', { username: user.username })} + + + + {/* OpenGraph */} + + + + + + {/* Twitter */} + + + + + + ) +} + +export default ProfileHead diff --git a/pages/[username].tsx b/pages/[username].tsx index fc75944a..0b13f655 100644 --- a/pages/[username].tsx +++ b/pages/[username].tsx @@ -1,42 +1,48 @@ import React, { useCallback, useEffect, useState } from 'react' -import Head from 'next/head' - +import InfiniteScroll from 'react-infinite-scroll-component' import { queryTypes, useQueryState } from 'next-usequerystate' import { useRouter } from 'next/router' import { useTranslation } from 'next-i18next' -import InfiniteScroll from 'react-infinite-scroll-component' - import { serverSideTranslations } from 'next-i18next/serverSideTranslations' import api from '~utils/api' - -import setUserToken from '~utils/setUserToken' import extractFilters from '~utils/extractFilters' import fetchLatestVersion from '~utils/fetchLatestVersion' import organizeRaids from '~utils/organizeRaids' +import setUserToken from '~utils/setUserToken' import useDidMountEffect from '~utils/useDidMountEffect' import { appState } from '~utils/appState' import { elements, allElement } from '~data/elements' import { emptyPaginationObject } from '~utils/emptyStates' -import { printError } from '~utils/reportError' import GridRep from '~components/GridRep' import GridRepCollection from '~components/GridRepCollection' +import ErrorSection from '~components/ErrorSection' import FilterBar from '~components/FilterBar' +import ProfileHead from '~components/ProfileHead' import type { NextApiRequest, NextApiResponse } from 'next' -import type { FilterObject, PaginationObject } from '~types' +import type { + FilterObject, + PageContextObj, + PaginationObject, + ResponseStatus, +} from '~types' +import { AxiosError } from 'axios' interface Props { - user?: User - teams?: Party[] - meta: PaginationObject - raids: Raid[] - sortedRaids: Raid[][] + context?: PageContextObj version: AppUpdate + error: boolean + status?: ResponseStatus } -const ProfileRoute: React.FC = (props: Props) => { +const ProfileRoute: React.FC = ({ + context, + version, + error, + status, +}: Props) => { // Set up router const router = useRouter() const { username } = router.query @@ -99,11 +105,11 @@ const ProfileRoute: React.FC = (props: Props) => { // Set the initial parties from props useEffect(() => { - if (props.teams) { - setTotalPages(props.meta.totalPages) - setRecordCount(props.meta.count) - replaceResults(props.meta.count, props.teams) - appState.version = props.version + if (context && context.teams && context.pagination) { + setTotalPages(context.pagination.totalPages) + setRecordCount(context.pagination.count) + replaceResults(context.pagination.count, context.teams) + appState.version = version } setCurrentPage(1) }, []) @@ -229,6 +235,16 @@ const ProfileRoute: React.FC = (props: Props) => { router.push(`/p/${shortcode}`) } + // Methods: Page component rendering + function pageHead() { + if (context && context.user) return + } + + function pageError() { + if (status) return + else return
+ } + // TODO: Add save functions function renderParties() { @@ -250,95 +266,54 @@ const ProfileRoute: React.FC = (props: Props) => { }) } - return ( -
- - {/* HTML */} - - {t('page.titles.profile', { username: props.user?.username })} - - - - - {/* OpenGraph */} - - - - - - {/* Twitter */} - - - - - - -
- {props.user?.avatar.picture} -

{props.user?.username}

-
-
- -
- 0 ? parties.length : 0} - next={() => setCurrentPage(currentPage + 1)} - hasMore={totalPages > currentPage} - loader={ -
-

Loading...

-
- } + if (context) { + return ( +
+ {pageHead()} + - {renderParties()} - - - {parties.length == 0 ? ( -
-

{t('teams.not_found')}

+
+ {context.user?.avatar.picture} +

{context.user?.username}

- ) : ( - '' - )} -
-
- ) + + +
+ 0 ? parties.length : 0} + next={() => setCurrentPage(currentPage + 1)} + hasMore={totalPages > currentPage} + loader={ +
+

Loading...

+
+ } + > + {renderParties()} +
+ + {parties.length == 0 ? ( +
+

{t('teams.not_found')}

+
+ ) : ( + '' + )} +
+
+ ) + } else return pageError() } export const getServerSidePaths = async () => { @@ -356,10 +331,10 @@ export const getServerSideProps = async ({ req, res, locale, query }: { req: Nex // Set headers for server-side requests setUserToken(req, res) - try { - // Fetch latest version - const version = await fetchLatestVersion() + // Fetch latest version + const version = await fetchLatestVersion() + try { // Fetch and organize raids let { raids, sortedRaids } = await api.endpoints.raids .getAll() @@ -372,9 +347,9 @@ export const getServerSideProps = async ({ req, res, locale, query }: { req: Nex } // Set up empty variables - let user: User | null = null - let teams: Party[] | null = null - let meta: PaginationObject = emptyPaginationObject + let user: User | undefined = undefined + let teams: Party[] | undefined = undefined + let pagination: PaginationObject = emptyPaginationObject // Perform a request only if we received a username if (query.username) { @@ -389,25 +364,46 @@ export const getServerSideProps = async ({ req, res, locale, query }: { req: Nex if (response.data.profile.parties) teams = response.data.profile.parties else teams = [] - meta.count = response.data.meta.count - meta.totalPages = response.data.meta.total_pages - meta.perPage = response.data.meta.per_page + pagination.count = response.data.meta.count + pagination.totalPages = response.data.meta.total_pages + pagination.perPage = response.data.meta.per_page } + // Consolidate data into context object + const context: PageContextObj = { + user: user, + teams: teams, + raids: raids, + sortedRaids: sortedRaids, + pagination: pagination, + } + + // Pass to the page component as props return { props: { - user: user, - teams: teams, - meta: meta, - raids: raids, - sortedRaids: sortedRaids, + context: context, version: version, + error: false, ...(await serverSideTranslations(locale, ['common', 'roadmap'])), - // Will be passed to the page component as props }, } } catch (error) { - printError(error, 'axios') + // Extract the underlying Axios error + const axiosError = error as AxiosError + const response = axiosError.response + + // Pass to the page component as props + return { + props: { + context: null, + error: true, + status: { + code: response?.status, + text: response?.statusText, + }, + ...(await serverSideTranslations(locale, ['common', 'roadmap'])), + }, + } } }