Fix page navigation when filtering collections
There was a bug that kept page navigation from working properly when filtering. Things would load multiple times, or load the wrong thing, or not navigate properly. That should all be fixed now.
This commit is contained in:
parent
acbb10d458
commit
a064cfa67c
8 changed files with 91 additions and 93 deletions
|
|
@ -21,9 +21,10 @@ interface Props {
|
|||
children: React.ReactNode
|
||||
scrolled: boolean
|
||||
element?: number
|
||||
raidSlug?: string
|
||||
raid?: string
|
||||
recency?: number
|
||||
onFilter: (filters: FilterSet) => void
|
||||
onAdvancedFilter: (filters: FilterSet) => void
|
||||
}
|
||||
|
||||
const FilterBar = (props: Props) => {
|
||||
|
|
@ -55,10 +56,10 @@ const FilterBar = (props: Props) => {
|
|||
const raid = appState.raidGroups
|
||||
.filter((group) => group.section > 0)
|
||||
.flatMap((group) => group.raids)
|
||||
.find((raid) => raid.slug === props.raidSlug)
|
||||
.find((raid) => raid.id === props.raid)
|
||||
|
||||
setCurrentRaid(raid)
|
||||
}, [props.raidSlug])
|
||||
}, [props.raid])
|
||||
|
||||
useEffect(() => {
|
||||
// Fetch user's advanced filters
|
||||
|
|
@ -91,12 +92,12 @@ const FilterBar = (props: Props) => {
|
|||
}
|
||||
|
||||
function raidSelectChanged(raid?: Raid) {
|
||||
props.onFilter({ raidSlug: raid?.slug, ...advancedFilters })
|
||||
props.onFilter({ raid: raid?.slug, ...advancedFilters })
|
||||
}
|
||||
|
||||
function handleAdvancedFiltersChanged(filters: FilterSet) {
|
||||
setAdvancedFilters(filters)
|
||||
props.onFilter(filters)
|
||||
props.onAdvancedFilter(filters)
|
||||
}
|
||||
|
||||
function onSelectChange(name: 'element' | 'recency') {
|
||||
|
|
|
|||
|
|
@ -112,7 +112,7 @@ const RaidCombobox = (props: Props) => {
|
|||
|
||||
// Fetch all raids on mount
|
||||
useEffect(() => {
|
||||
api.raidGroups().then((response) => sortGroups(response.data))
|
||||
sortGroups(appState.raidGroups)
|
||||
}, [])
|
||||
|
||||
// Set current raid and section when the component mounts
|
||||
|
|
@ -136,6 +136,8 @@ const RaidCombobox = (props: Props) => {
|
|||
if (appState.party.raid && appState.party.raid.group.section > 0)
|
||||
setCurrentSection(props.currentRaid.group.section)
|
||||
else setCurrentSection(1)
|
||||
} else {
|
||||
setCurrentRaid(undefined)
|
||||
}
|
||||
}, [props.currentRaid])
|
||||
|
||||
|
|
@ -224,7 +226,9 @@ const RaidCombobox = (props: Props) => {
|
|||
if (group.section > 0) sections[group.section - 1].push(group)
|
||||
})
|
||||
|
||||
setFarmingRaid(groups[0].raids[0])
|
||||
if (groups[0]) {
|
||||
setFarmingRaid(groups[0].raids[0])
|
||||
}
|
||||
|
||||
setSections(sections)
|
||||
},
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
import React, { useCallback, useEffect, useState } from 'react'
|
||||
import InfiniteScroll from 'react-infinite-scroll-component'
|
||||
import { getCookie } from 'cookies-next'
|
||||
import { queryTypes, useQueryState } from 'next-usequerystate'
|
||||
import { useRouter } from 'next/router'
|
||||
import { useTranslation } from 'next-i18next'
|
||||
|
|
@ -53,13 +52,12 @@ const ProfileRoute: React.FC<Props> = ({
|
|||
const { t } = useTranslation('common')
|
||||
|
||||
// Set up app-specific states
|
||||
const [raidsLoading, setRaidsLoading] = useState(true)
|
||||
const [mounted, setMounted] = useState(false)
|
||||
const [scrolled, setScrolled] = useState(false)
|
||||
|
||||
// Set up page-specific states
|
||||
const [parties, setParties] = useState<Party[]>([])
|
||||
const [raids, setRaids] = useState<Raid[]>()
|
||||
const [raid, setRaid] = useState<Raid>()
|
||||
|
||||
// Set up infinite scrolling-related states
|
||||
const [recordCount, setRecordCount] = useState(0)
|
||||
|
|
@ -74,9 +72,15 @@ const ProfileRoute: React.FC<Props> = ({
|
|||
parse: (query: string) => parseElement(query),
|
||||
serialize: (value) => serializeElement(value),
|
||||
})
|
||||
const [raidSlug, setRaidSlug] = useQueryState('raid', {
|
||||
const [raid, setRaid] = useQueryState('raid', {
|
||||
defaultValue: 'all',
|
||||
history: 'push',
|
||||
parse: (query: string) => {
|
||||
const raids = context?.raidGroups.flatMap((group) => group.raids)
|
||||
const raid = raids?.find((r: Raid) => r.slug === query)
|
||||
return raid ? raid.id : 'all'
|
||||
},
|
||||
serialize: (value) => value,
|
||||
})
|
||||
const [recency, setRecency] = useQueryState('recency', {
|
||||
defaultValue: -1,
|
||||
|
|
@ -113,6 +117,7 @@ const ProfileRoute: React.FC<Props> = ({
|
|||
setTotalPages(context.pagination.totalPages)
|
||||
setRecordCount(context.pagination.count)
|
||||
replaceResults(context.pagination.count, context.teams)
|
||||
appState.raidGroups = context.raidGroups
|
||||
appState.version = version
|
||||
}
|
||||
setCurrentPage(1)
|
||||
|
|
@ -139,7 +144,7 @@ const ProfileRoute: React.FC<Props> = ({
|
|||
const filters = {
|
||||
params: {
|
||||
element: element != -1 ? element : undefined,
|
||||
raid: raid ? raid.id : undefined,
|
||||
raid: raid === 'all' ? undefined : raid,
|
||||
recency: recency != -1 ? recency : undefined,
|
||||
page: currentPage,
|
||||
...advancedFilters,
|
||||
|
|
@ -183,14 +188,8 @@ const ProfileRoute: React.FC<Props> = ({
|
|||
// Fetch all raids on mount, then find the raid in the URL if present
|
||||
useEffect(() => {
|
||||
api.endpoints.raids.getAll().then((response) => {
|
||||
setRaids(response.data)
|
||||
|
||||
setRaidsLoading(false)
|
||||
|
||||
const raid = response.data.find((r: Raid) => r.slug === raidSlug)
|
||||
setRaid(raid)
|
||||
|
||||
return raid
|
||||
const raids = appState.raidGroups.flatMap((group) => group.raids)
|
||||
setRaids(raids)
|
||||
})
|
||||
}, [setRaids])
|
||||
|
||||
|
|
@ -198,7 +197,12 @@ const ProfileRoute: React.FC<Props> = ({
|
|||
// fetch all teams again.
|
||||
useDidMountEffect(() => {
|
||||
setCurrentPage(1)
|
||||
fetchProfile({ replace: true })
|
||||
|
||||
if (mounted) {
|
||||
fetchProfile({ replace: true })
|
||||
}
|
||||
|
||||
setMounted(true)
|
||||
}, [username, element, raid, recency, advancedFilters])
|
||||
|
||||
// When the page changes, fetch all teams again.
|
||||
|
|
@ -206,25 +210,18 @@ const ProfileRoute: React.FC<Props> = ({
|
|||
// Current page changed
|
||||
if (currentPage > 1) fetchProfile({ replace: false })
|
||||
else if (currentPage == 1) fetchProfile({ replace: true })
|
||||
setMounted(true)
|
||||
}, [currentPage])
|
||||
|
||||
// Receive filters from the filter bar
|
||||
function receiveFilters(filters: FilterSet) {
|
||||
if (filters.element == 0) setElement(0, { shallow: true })
|
||||
else if (filters.element) setElement(filters.element, { shallow: true })
|
||||
|
||||
if (raids && filters.raidSlug) {
|
||||
const raid = raids.find((raid) => raid.slug === filters.raidSlug)
|
||||
setRaid(raid)
|
||||
setRaidSlug(filters.raidSlug, { shallow: true })
|
||||
}
|
||||
|
||||
if (filters.recency) setRecency(filters.recency, { shallow: true })
|
||||
if (filters.raid) setRaid(filters.raid, { shallow: true })
|
||||
}
|
||||
|
||||
delete filters.element
|
||||
delete filters.raidSlug
|
||||
delete filters.recency
|
||||
|
||||
function receiveAdvancedFilters(filters: FilterSet) {
|
||||
setAdvancedFilters(filters)
|
||||
}
|
||||
|
||||
|
|
@ -273,15 +270,16 @@ const ProfileRoute: React.FC<Props> = ({
|
|||
|
||||
if (context) {
|
||||
return (
|
||||
<div id="Profile">
|
||||
<div className="profile">
|
||||
{pageHead()}
|
||||
<FilterBar
|
||||
defaultFilterset={permissiveFilterset}
|
||||
onAdvancedFilter={receiveAdvancedFilters}
|
||||
onFilter={receiveFilters}
|
||||
persistFilters={false}
|
||||
scrolled={scrolled}
|
||||
element={element}
|
||||
raidSlug={raidSlug ? raidSlug : undefined}
|
||||
raid={raid}
|
||||
recency={recency}
|
||||
>
|
||||
<UserInfo user={context.user!} />
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@ import '../styles/globals.scss'
|
|||
|
||||
function MyApp({ Component, pageProps }: AppProps) {
|
||||
const { t } = useTranslation('common')
|
||||
const [mounted, setMounted] = useState(false)
|
||||
const [refresh, setRefresh] = useState(false)
|
||||
|
||||
// Subscribe to app state to listen for account changes and
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
import React, { useCallback, useEffect, useState } from 'react'
|
||||
import InfiniteScroll from 'react-infinite-scroll-component'
|
||||
import { getCookie } from 'cookies-next'
|
||||
import { queryTypes, useQueryState } from 'next-usequerystate'
|
||||
import { useRouter } from 'next/router'
|
||||
import { useTranslation } from 'next-i18next'
|
||||
|
|
@ -52,13 +51,12 @@ const SavedRoute: React.FC<Props> = ({
|
|||
const { t } = useTranslation('common')
|
||||
|
||||
// Set up app-specific states
|
||||
const [raidsLoading, setRaidsLoading] = useState(true)
|
||||
const [mounted, setMounted] = useState(false)
|
||||
const [scrolled, setScrolled] = useState(false)
|
||||
|
||||
// Set up page-specific states
|
||||
const [parties, setParties] = useState<Party[]>([])
|
||||
const [raids, setRaids] = useState<Raid[]>()
|
||||
const [raid, setRaid] = useState<Raid>()
|
||||
|
||||
// Set up infinite scrolling-related states
|
||||
const [recordCount, setRecordCount] = useState(0)
|
||||
|
|
@ -73,9 +71,15 @@ const SavedRoute: React.FC<Props> = ({
|
|||
parse: (query: string) => parseElement(query),
|
||||
serialize: (value) => serializeElement(value),
|
||||
})
|
||||
const [raidSlug, setRaidSlug] = useQueryState('raid', {
|
||||
const [raid, setRaid] = useQueryState('raid', {
|
||||
defaultValue: 'all',
|
||||
history: 'push',
|
||||
parse: (query: string) => {
|
||||
const raids = context?.raidGroups.flatMap((group) => group.raids)
|
||||
const raid = raids?.find((r: Raid) => r.slug === query)
|
||||
return raid ? raid.id : 'all'
|
||||
},
|
||||
serialize: (value) => value,
|
||||
})
|
||||
const [recency, setRecency] = useQueryState('recency', {
|
||||
defaultValue: -1,
|
||||
|
|
@ -112,6 +116,7 @@ const SavedRoute: React.FC<Props> = ({
|
|||
setTotalPages(context.pagination.totalPages)
|
||||
setRecordCount(context.pagination.count)
|
||||
replaceResults(context.pagination.count, context.teams)
|
||||
appState.raidGroups = context.raidGroups
|
||||
appState.version = version
|
||||
}
|
||||
setCurrentPage(1)
|
||||
|
|
@ -138,7 +143,7 @@ const SavedRoute: React.FC<Props> = ({
|
|||
[key: string]: any
|
||||
} = {
|
||||
element: element !== -1 ? element : undefined,
|
||||
raid: raid ? raid.id : undefined,
|
||||
raid: raid === 'all' ? undefined : raid,
|
||||
recency: recency !== -1 ? recency : undefined,
|
||||
page: currentPage,
|
||||
...advancedFilters,
|
||||
|
|
@ -186,14 +191,8 @@ const SavedRoute: React.FC<Props> = ({
|
|||
// Fetch all raids on mount, then find the raid in the URL if present
|
||||
useEffect(() => {
|
||||
api.endpoints.raids.getAll().then((response) => {
|
||||
setRaids(response.data)
|
||||
|
||||
setRaidsLoading(false)
|
||||
|
||||
const raid = response.data.find((r: Raid) => r.slug === raidSlug)
|
||||
setRaid(raid)
|
||||
|
||||
return raid
|
||||
const raids = appState.raidGroups.flatMap((group) => group.raids)
|
||||
setRaids(raids)
|
||||
})
|
||||
}, [setRaids])
|
||||
|
||||
|
|
@ -201,7 +200,12 @@ const SavedRoute: React.FC<Props> = ({
|
|||
// fetch all teams again.
|
||||
useDidMountEffect(() => {
|
||||
setCurrentPage(1)
|
||||
fetchTeams({ replace: true })
|
||||
|
||||
if (mounted) {
|
||||
fetchTeams({ replace: true })
|
||||
}
|
||||
|
||||
setMounted(true)
|
||||
}, [element, raid, recency, advancedFilters])
|
||||
|
||||
// When the page changes, fetch all teams again.
|
||||
|
|
@ -209,25 +213,18 @@ const SavedRoute: React.FC<Props> = ({
|
|||
// Current page changed
|
||||
if (currentPage > 1) fetchTeams({ replace: false })
|
||||
else if (currentPage == 1) fetchTeams({ replace: true })
|
||||
setMounted(true)
|
||||
}, [currentPage])
|
||||
|
||||
// Receive filters from the filter bar
|
||||
function receiveFilters(filters: FilterSet) {
|
||||
if (filters.element == 0) setElement(0, { shallow: true })
|
||||
else if (filters.element) setElement(filters.element, { shallow: true })
|
||||
|
||||
if (raids && filters.raidSlug) {
|
||||
const raid = raids.find((raid) => raid.slug === filters.raidSlug)
|
||||
setRaid(raid)
|
||||
setRaidSlug(filters.raidSlug, { shallow: true })
|
||||
}
|
||||
|
||||
if (filters.recency) setRecency(filters.recency, { shallow: true })
|
||||
if (filters.raid) setRaid(filters.raid, { shallow: true })
|
||||
}
|
||||
|
||||
delete filters.element
|
||||
delete filters.raidSlug
|
||||
delete filters.recency
|
||||
|
||||
function receiveAdvancedFilters(filters: FilterSet) {
|
||||
setAdvancedFilters(filters)
|
||||
}
|
||||
|
||||
|
|
@ -313,15 +310,16 @@ const SavedRoute: React.FC<Props> = ({
|
|||
|
||||
if (context) {
|
||||
return (
|
||||
<div id="Teams">
|
||||
<div className="teams">
|
||||
{pageHead()}
|
||||
<FilterBar
|
||||
defaultFilterset={permissiveFilterset}
|
||||
onFilter={receiveFilters}
|
||||
onAdvancedFilter={receiveAdvancedFilters}
|
||||
persistFilters={false}
|
||||
scrolled={scrolled}
|
||||
element={element}
|
||||
raidSlug={raidSlug ? raidSlug : undefined}
|
||||
raid={raid}
|
||||
recency={recency}
|
||||
>
|
||||
<h1>{t('saved.title')}</h1>
|
||||
|
|
|
|||
|
|
@ -52,13 +52,12 @@ const TeamsRoute: React.FC<Props> = ({
|
|||
const { t } = useTranslation('common')
|
||||
|
||||
// Set up app-specific states
|
||||
const [raidsLoading, setRaidsLoading] = useState(true)
|
||||
const [mounted, setMounted] = useState(false)
|
||||
const [scrolled, setScrolled] = useState(false)
|
||||
|
||||
// Set up page-specific states
|
||||
const [parties, setParties] = useState<Party[]>([])
|
||||
const [raids, setRaids] = useState<Raid[]>()
|
||||
const [raid, setRaid] = useState<Raid>()
|
||||
|
||||
// Set up infinite scrolling-related states
|
||||
const [recordCount, setRecordCount] = useState(0)
|
||||
|
|
@ -73,9 +72,15 @@ const TeamsRoute: React.FC<Props> = ({
|
|||
parse: (query: string) => parseElement(query),
|
||||
serialize: (value) => serializeElement(value),
|
||||
})
|
||||
const [raidSlug, setRaidSlug] = useQueryState('raid', {
|
||||
const [raid, setRaid] = useQueryState('raid', {
|
||||
defaultValue: 'all',
|
||||
history: 'push',
|
||||
parse: (query: string) => {
|
||||
const raids = context?.raidGroups.flatMap((group) => group.raids)
|
||||
const raid = raids?.find((r: Raid) => r.slug === query)
|
||||
return raid ? raid.id : 'all'
|
||||
},
|
||||
serialize: (value) => value,
|
||||
})
|
||||
const [recency, setRecency] = useQueryState('recency', {
|
||||
defaultValue: -1,
|
||||
|
|
@ -149,7 +154,7 @@ const TeamsRoute: React.FC<Props> = ({
|
|||
[key: string]: any
|
||||
} = {
|
||||
element: element !== -1 ? element : undefined,
|
||||
raid: raid ? raid.id : undefined,
|
||||
raid: raid === 'all' ? undefined : raid,
|
||||
recency: recency !== -1 ? recency : undefined,
|
||||
page: currentPage,
|
||||
...advancedFilters,
|
||||
|
|
@ -196,49 +201,39 @@ const TeamsRoute: React.FC<Props> = ({
|
|||
|
||||
// Fetch all raids on mount, then find the raid in the URL if present
|
||||
useEffect(() => {
|
||||
api.endpoints.raids.getAll().then((response) => {
|
||||
setRaids(response.data)
|
||||
|
||||
setRaidsLoading(false)
|
||||
|
||||
const raid = response.data.find((r: Raid) => r.slug === raidSlug)
|
||||
setRaid(raid)
|
||||
|
||||
return raid
|
||||
})
|
||||
const raids = appState.raidGroups.flatMap((group) => group.raids)
|
||||
setRaids(raids)
|
||||
}, [setRaids])
|
||||
|
||||
// When the element, raid or recency filter changes,
|
||||
// fetch all teams again.
|
||||
useDidMountEffect(() => {
|
||||
setCurrentPage(1)
|
||||
fetchTeams({ replace: true })
|
||||
|
||||
if (mounted) {
|
||||
fetchTeams({ replace: true })
|
||||
}
|
||||
|
||||
setMounted(true)
|
||||
}, [element, raid, recency, advancedFilters])
|
||||
|
||||
// When the page changes, fetch all teams again.
|
||||
useDidMountEffect(() => {
|
||||
// Current page changed
|
||||
if (currentPage > 1) fetchTeams({ replace: false })
|
||||
else if (currentPage == 1) fetchTeams({ replace: true })
|
||||
else if (currentPage == 1 && mounted) fetchTeams({ replace: true })
|
||||
setMounted(true)
|
||||
}, [currentPage])
|
||||
|
||||
// Receive filters from the filter bar
|
||||
function receiveFilters(filters: FilterSet) {
|
||||
if (filters.element == 0) setElement(0, { shallow: true })
|
||||
else if (filters.element) setElement(filters.element, { shallow: true })
|
||||
|
||||
if (raids && filters.raidSlug) {
|
||||
const raid = raids.find((raid) => raid.slug === filters.raidSlug)
|
||||
setRaid(raid)
|
||||
setRaidSlug(filters.raidSlug, { shallow: true })
|
||||
}
|
||||
|
||||
if (filters.recency) setRecency(filters.recency, { shallow: true })
|
||||
if (filters.raid) setRaid(filters.raid, { shallow: true })
|
||||
}
|
||||
|
||||
delete filters.element
|
||||
delete filters.raidSlug
|
||||
delete filters.recency
|
||||
|
||||
function receiveAdvancedFilters(filters: FilterSet) {
|
||||
setAdvancedFilters(filters)
|
||||
}
|
||||
|
||||
|
|
@ -324,15 +319,16 @@ const TeamsRoute: React.FC<Props> = ({
|
|||
|
||||
if (context) {
|
||||
return (
|
||||
<div id="Teams">
|
||||
<div className="teams">
|
||||
{pageHead()}
|
||||
<FilterBar
|
||||
defaultFilterset={defaultFilterset}
|
||||
onFilter={receiveFilters}
|
||||
onAdvancedFilter={receiveAdvancedFilters}
|
||||
persistFilters={true}
|
||||
scrolled={scrolled}
|
||||
element={element}
|
||||
raidSlug={raidSlug ? raidSlug : undefined}
|
||||
raid={raid}
|
||||
recency={recency}
|
||||
>
|
||||
<h1>{t('teams.title')}</h1>
|
||||
|
|
|
|||
|
|
@ -121,8 +121,8 @@ h5 {
|
|||
}
|
||||
|
||||
// Used for collection pages
|
||||
#Teams,
|
||||
#Profile {
|
||||
.teams,
|
||||
.profile {
|
||||
display: flex;
|
||||
height: 100%;
|
||||
flex-direction: column;
|
||||
|
|
|
|||
2
types/FilterSet.d.ts
vendored
2
types/FilterSet.d.ts
vendored
|
|
@ -1,6 +1,6 @@
|
|||
interface FilterSet {
|
||||
element?: number
|
||||
raidSlug?: string
|
||||
raid?: string
|
||||
recency?: number
|
||||
full_auto?: number
|
||||
auto_guard?: number
|
||||
|
|
|
|||
Loading…
Reference in a new issue