diff --git a/components/FilterBar/index.tsx b/components/FilterBar/index.tsx index cf3f93ca..f3446142 100644 --- a/components/FilterBar/index.tsx +++ b/components/FilterBar/index.tsx @@ -1,14 +1,10 @@ import React from 'react' -import { useSnapshot } from 'valtio' import { useTranslation } from 'next-i18next' import classNames from 'classnames' import RaidDropdown from '~components/RaidDropdown' -import { appState } from '~utils/appState' - import './index.scss' -import { raidGroups } from '~utils/raidGroups' interface Props { children: React.ReactNode @@ -16,16 +12,13 @@ interface Props { element?: number raidSlug?: string recency?: number - onFilter: ({element, raid, recency} : { element?: number, raid?: Raid, recency?: number}) => void + onFilter: ({element, raidSlug, recency} : { element?: number, raidSlug?: string, recency?: number}) => void } const FilterBar = (props: Props) => { // Set up translation const { t } = useTranslation('common') - // Set up state object - const app = useSnapshot(appState) - // Set up refs for filter dropdowns const elementSelect = React.createRef() const raidSelect = React.createRef() @@ -47,8 +40,8 @@ const FilterBar = (props: Props) => { props.onFilter({ recency: recencyValue }) } - function raidSelectChanged(raid?: Raid) { - props.onFilter({ raid: raid }) + function raidSelectChanged(slug?: string) { + props.onFilter({ raidSlug: slug }) } return ( @@ -65,6 +58,7 @@ const FilterBar = (props: Props) => { void + onChange?: (slug?: string) => void onBlur?: (event: React.ChangeEvent) => void } @@ -73,9 +73,10 @@ const RaidDropdown = React.forwardRef(function useFiel // Enable changing select value function handleChange(event: React.ChangeEvent) { + if (props.onChange) props.onChange(event.target.value) + if (raids) { const raid = raids.find(raid => raid.slug === event.target.value) - if (props.onChange) props.onChange(raid) setCurrentRaid(raid) } } diff --git a/pages/teams.tsx b/pages/teams.tsx index c745ba50..8fbd8b01 100644 --- a/pages/teams.tsx +++ b/pages/teams.tsx @@ -1,9 +1,9 @@ import React, { useCallback, useEffect, useState } from 'react' import Head from 'next/head' -import { useRouter } from 'next/router' import { useCookies } from 'react-cookie' -import { queryTypes, useQueryState } from 'next-usequerystate' +import { useQueryState, queryTypes } from 'next-usequerystate' +import { useRouter } from 'next/router' import { useTranslation } from 'next-i18next' import { serverSideTranslations } from 'next-i18next/serverSideTranslations' @@ -19,13 +19,13 @@ import FilterBar from '~components/FilterBar' const TeamsRoute: React.FC = () => { // Set up cookies const [cookies] = useCookies(['account']) - const headers = (cookies.account != null) ? { - 'Authorization': `Bearer ${cookies.account.access_token}` + const headers = (cookies.account) ? { + headers: { + 'Authorization': `Bearer ${cookies.account.access_token}` + } } : {} - // const { raids } = useSnapshot(appState) - - // Get the information we need from the router + // Set up router const router = useRouter() // Import translations @@ -33,10 +33,12 @@ const TeamsRoute: React.FC = () => { // Set up app-specific states const [loading, setLoading] = useState(true) + const [raidsLoading, setRaidsLoading] = useState(true) const [scrolled, setScrolled] = useState(false) // Set up page-specific states const [parties, setParties] = useState([]) + const [raids, setRaids] = useState() const [raid, setRaid] = useState() // Set up filter-specific query states @@ -49,8 +51,7 @@ const TeamsRoute: React.FC = () => { const [raidSlug, setRaidSlug] = useQueryState("raid", { defaultValue: "all" }) const [recency, setRecency] = useQueryState("recency", queryTypes.integer.withDefault(-1)) - - // Define transformers for element and raid + // Define transformers for element function parseElement(query: string) { let element: TeamElement | undefined = (query === 'all') ? @@ -62,23 +63,22 @@ const TeamsRoute: React.FC = () => { let name = '' if (value != undefined) { - if (value == -1) { + if (value == -1) name = allElement.name.en.toLowerCase() - } else { - console.log(value) + else name = elements[value].name.en.toLowerCase() - } } return name } - // Add scroll event listener for shadow on FilterBar + // Add scroll event listener for shadow on FilterBar on mount useEffect(() => { window.addEventListener("scroll", handleScroll) return () => window.removeEventListener("scroll", handleScroll); }, []) + // Handle errors const handleError = useCallback((error: any) => { if (error.response != null) { console.error(error) @@ -91,52 +91,70 @@ const TeamsRoute: React.FC = () => { const filters = { params: { element: (element != -1) ? element : undefined, - raid: (raidSlug !== "all") ? raid?.id : undefined, + raid: (raid) ? raid.id : undefined, recency: (recency != -1) ? recency : undefined } } - console.log(filters) - - const headers = (cookies.account) ? { - headers: { - 'Authorization': `Bearer ${cookies.account.access_token}` - } - } : {} - - const params = {...filters, ...headers} - - setLoading(true) - - api.endpoints.parties.getAll(params) + api.endpoints.parties.getAll({...filters, ...headers}) .then(response => { const parties: Party[] = response.data - setParties(parties.map((p: any) => p.party).sort((a, b) => (a.created_at > b.created_at) ? -1 : 1)) + setParties(parties.map((p: any) => p.party) + .sort((a, b) => (a.created_at > b.created_at) ? -1 : 1)) }) .then(() => { setLoading(false) }) .catch(error => handleError(error)) - }, [element, raid, recency, cookies.account, handleError]) + }, [element, raid, recency]) + // Fetch all raids on mount, then find the raid in the URL if present useEffect(() => { - fetchTeams() - }, [fetchTeams]) + api.endpoints.raids.getAll() + .then(response => { + const cleanRaids: Raid[] = response.data.map((r: any) => r.raid) + setRaids(cleanRaids) - function receiveFilters({ element, raid, recency }: {element?: number, raid?: Raid, recency?: number}) { + setRaidsLoading(false) + + const raid = cleanRaids.find(r => r.slug === raidSlug) + setRaid(raid) + + return raid + }) + }, [setRaids]) + + // When the element, raid or recency filter changes, + // fetch all teams again. + useEffect(() => { + if (!raidsLoading) fetchTeams() + }, [element, raid, recency]) + + // On first mount only, disable loading if we are fetching all teams + useEffect(() => { + if (raidSlug === 'all') { + setRaidsLoading(false) + fetchTeams() + } + }, []) + + // Receive filters from the filter bar + function receiveFilters({ element, raidSlug, recency }: {element?: number, raidSlug?: string, recency?: number}) { if (element == 0) setElement(0) else if (element) setElement(element) - if (raid) { + if (raids && raidSlug) { + const raid = raids.find(raid => raid.slug === raidSlug) setRaid(raid) - setRaidSlug(raid.slug) + setRaidSlug(raidSlug) } if (recency) setRecency(recency) } + // Methods: Favorites function toggleFavorite(teamId: string, favorited: boolean) { if (favorited) unsaveFavorite(teamId) @@ -178,6 +196,7 @@ const TeamsRoute: React.FC = () => { }) } + // Methods: Navigation function handleScroll() { if (window.pageYOffset > 90) setScrolled(true) @@ -209,7 +228,7 @@ const TeamsRoute: React.FC = () => { onFilter={receiveFilters} scrolled={scrolled} element={element} - raidSlug={raidSlug} + raidSlug={ (raidSlug) ? raidSlug : undefined } recency={recency}>

{t('teams.title')}

@@ -230,8 +249,7 @@ const TeamsRoute: React.FC = () => { key={`party-${i}`} displayUser={true} onClick={goTo} - onSave={toggleFavorite} - /> + onSave={toggleFavorite} /> }) } diff --git a/types/Raid.d.ts b/types/Raid.d.ts index 8283d9cf..dbccbf71 100644 --- a/types/Raid.d.ts +++ b/types/Raid.d.ts @@ -5,7 +5,8 @@ interface Raid { en: string ja: string } + slug: string level: number group: number - element: TeamElement + element: number } \ No newline at end of file