Skip to content

Commit 46db0ba

Browse files
committed
Store orderBy and orderDir in URL for operators and sponsorships pages
1 parent f78fd57 commit 46db0ba

File tree

4 files changed

+130
-26
lines changed

4 files changed

+130
-26
lines changed

src/hooks/useUrlParams.ts

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
import { useSearchParams } from 'react-router-dom'
2+
import { useEffect } from 'react'
3+
4+
interface UrlParamConfig<T extends string> {
5+
param: string
6+
value: T | undefined
7+
defaultValue: T
8+
}
9+
10+
export function useUrlParams<T extends string>(params: UrlParamConfig<T>[]) {
11+
const [searchParams, setSearchParams] = useSearchParams()
12+
13+
useEffect(() => {
14+
// Check if current params are different from desired params
15+
let needsUpdate = false
16+
const currentParams = new URLSearchParams(searchParams)
17+
18+
params.forEach(({ param, value, defaultValue }) => {
19+
const currentValue = currentParams.get(param)
20+
const targetValue = value !== defaultValue ? value || defaultValue : null
21+
22+
if (targetValue === null && currentValue !== null) {
23+
needsUpdate = true
24+
} else if (targetValue !== null && targetValue !== currentValue) {
25+
needsUpdate = true
26+
}
27+
})
28+
29+
// Only update if necessary
30+
if (needsUpdate) {
31+
setSearchParams((prevParams) => {
32+
const newParams = new URLSearchParams(prevParams)
33+
34+
params.forEach(({ param, value, defaultValue }) => {
35+
if (value !== defaultValue) {
36+
newParams.set(param, value || defaultValue)
37+
} else {
38+
newParams.delete(param)
39+
}
40+
})
41+
42+
return newParams
43+
})
44+
}
45+
}, [params, searchParams, setSearchParams])
46+
}

src/pages/OperatorsPage.tsx

Lines changed: 34 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ import { useTableOrder } from '~/hooks/useTableOrder'
1919
import { Operator } from '~/parsers/Operator'
2020
import { ScrollTableCore } from '~/shared/components/ScrollTable/ScrollTable'
2121
import Tabs, { Tab } from '~/shared/components/Tabs'
22-
import { useWalletAccount } from '~/shared/stores/wallet'
22+
import { useIsWalletLoading, useWalletAccount } from '~/shared/stores/wallet'
2323
import { OrderDirection } from '~/types'
2424
import { saveOperator } from '~/utils'
2525
import {
@@ -28,34 +28,55 @@ import {
2828
useCurrentChainSymbolicName,
2929
} from '~/utils/chains'
3030
import { Route as R, routeOptions } from '~/utils/routes'
31-
32-
const PAGE_SIZE = 20
31+
import { useUrlParams } from '~/hooks/useUrlParams'
3332

3433
enum TabOption {
3534
AllOperators = 'all',
3635
MyDelegations = 'my',
3736
}
3837

38+
const PAGE_SIZE = 20
39+
const DEFAULT_ORDER_BY = 'totalValue'
40+
const DEFAULT_ORDER_DIRECTION = 'desc'
41+
const DEFAULT_TAB = TabOption.AllOperators
42+
3943
function isTabOption(value: unknown): value is TabOption {
4044
return value === TabOption.AllOperators || value === TabOption.MyDelegations
4145
}
4246

4347
export const OperatorsPage = () => {
44-
const [params] = useSearchParams()
45-
46-
const tab = params.get('tab')
47-
48-
const selectedTab = isTabOption(tab) ? tab : TabOption.AllOperators
49-
5048
const [searchQuery, setSearchQuery] = useState('')
5149

5250
const wallet = useWalletAccount()
51+
const isWalletLoading = useIsWalletLoading()
5352

5453
const { orderBy, orderDirection, setOrder } = useTableOrder<string>({
55-
orderBy: 'totalValue',
56-
orderDirection: 'desc',
54+
orderBy: DEFAULT_ORDER_BY,
55+
orderDirection: DEFAULT_ORDER_DIRECTION,
5756
})
5857

58+
const [params] = useSearchParams()
59+
const tab = params.get('tab')
60+
const selectedTab = isTabOption(tab) ? tab : DEFAULT_TAB
61+
62+
useUrlParams([
63+
{
64+
param: 'tab',
65+
value: selectedTab,
66+
defaultValue: DEFAULT_TAB,
67+
},
68+
{
69+
param: 'orderBy',
70+
value: orderBy,
71+
defaultValue: DEFAULT_ORDER_BY,
72+
},
73+
{
74+
param: 'orderDir',
75+
value: orderDirection,
76+
defaultValue: DEFAULT_ORDER_DIRECTION,
77+
},
78+
])
79+
5980
const allOperatorsQuery = useAllOperatorsQuery({
6081
batchSize: PAGE_SIZE,
6182
searchQuery,
@@ -83,7 +104,7 @@ export const OperatorsPage = () => {
83104
const navigate = useNavigate()
84105

85106
useEffect(() => {
86-
if (!wallet) {
107+
if (!wallet && !isWalletLoading) {
87108
navigate(
88109
R.operators(
89110
routeOptions(chainName, {
@@ -92,7 +113,7 @@ export const OperatorsPage = () => {
92113
),
93114
)
94115
}
95-
}, [wallet, navigate, chainName])
116+
}, [wallet, isWalletLoading, navigate, chainName])
96117

97118
return (
98119
<Layout>

src/pages/SponsorshipsPage.tsx

Lines changed: 34 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -20,43 +20,64 @@ import {
2020
} from '~/hooks/sponsorships'
2121
import { useTableOrder } from '~/hooks/useTableOrder'
2222
import Tabs, { Tab } from '~/shared/components/Tabs'
23-
import { useWalletAccount } from '~/shared/stores/wallet'
23+
import { useWalletAccount, useIsWalletLoading } from '~/shared/stores/wallet'
2424
import {
2525
useCurrentChainFullName,
2626
useCurrentChainId,
2727
useCurrentChainSymbolicName,
2828
} from '~/utils/chains'
2929
import { Route as R, routeOptions } from '~/utils/routes'
30-
31-
const PAGE_SIZE = 20
30+
import { useUrlParams } from '~/hooks/useUrlParams'
3231

3332
enum TabOption {
3433
AllSponsorships = 'all',
3534
MySponsorships = 'my',
3635
}
3736

37+
const PAGE_SIZE = 20
38+
const DEFAULT_ORDER_BY = 'remainingWei'
39+
const DEFAULT_ORDER_DIRECTION = 'desc'
40+
const DEFAULT_TAB = TabOption.AllSponsorships
41+
3842
function isTabOption(value: unknown): value is TabOption {
3943
return value === TabOption.AllSponsorships || value === TabOption.MySponsorships
4044
}
4145

4246
export const SponsorshipsPage = () => {
43-
const [params] = useSearchParams()
44-
45-
const tab = params.get('tab')
46-
47-
const selectedTab = isTabOption(tab) ? tab : TabOption.AllSponsorships
48-
4947
const [searchQuery, setSearchQuery] = useState('')
5048

5149
const [filters, setFilters] = useState<SponsorshipFilters>(defaultFilters)
5250

5351
const wallet = useWalletAccount()
52+
const isWalletLoading = useIsWalletLoading()
5453

5554
const { orderBy, orderDirection, setOrder } = useTableOrder<string>({
56-
orderBy: 'remainingWei',
57-
orderDirection: 'desc',
55+
orderBy: DEFAULT_ORDER_BY,
56+
orderDirection: DEFAULT_ORDER_DIRECTION,
5857
})
5958

59+
const [params] = useSearchParams()
60+
const tab = params.get('tab')
61+
const selectedTab = isTabOption(tab) ? tab : DEFAULT_TAB
62+
63+
useUrlParams([
64+
{
65+
param: 'tab',
66+
value: selectedTab,
67+
defaultValue: DEFAULT_TAB,
68+
},
69+
{
70+
param: 'orderBy',
71+
value: orderBy,
72+
defaultValue: DEFAULT_ORDER_BY,
73+
},
74+
{
75+
param: 'orderDir',
76+
value: orderDirection,
77+
defaultValue: DEFAULT_ORDER_DIRECTION,
78+
},
79+
])
80+
6081
const allSponsorshipsQuery = useAllSponsorshipsQuery({
6182
pageSize: PAGE_SIZE,
6283
searchQuery,
@@ -78,7 +99,7 @@ export const SponsorshipsPage = () => {
7899
const chainName = useCurrentChainSymbolicName()
79100

80101
useEffect(() => {
81-
if (!wallet) {
102+
if (!wallet && !isWalletLoading) {
82103
navigate(
83104
R.sponsorships(
84105
routeOptions(chainName, {
@@ -87,7 +108,7 @@ export const SponsorshipsPage = () => {
87108
),
88109
)
89110
}
90-
}, [wallet, navigate, chainName])
111+
}, [wallet, navigate, chainName, isWalletLoading])
91112

92113
const createSponsorship = useCreateSponsorship()
93114

src/shared/stores/wallet.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,7 @@ export async function getWalletAccount({
161161
interface WalletStore {
162162
account: string | undefined
163163
ens: Record<string, string | undefined>
164+
isLoading: boolean
164165
}
165166

166167
const useWalletStore = create<WalletStore>((set, get) => {
@@ -219,13 +220,20 @@ const useWalletStore = create<WalletStore>((set, get) => {
219220
onAccountsChange(accounts)
220221
} catch (e) {
221222
console.warn('Provider setup failed', e)
223+
} finally {
224+
set((current) =>
225+
produce(current, (next) => {
226+
next.isLoading = false
227+
}),
228+
)
222229
}
223230
})
224231

225232
return {
226233
account: undefined,
227234

228235
ens: {},
236+
isLoading: true,
229237
}
230238
})
231239

@@ -238,6 +246,14 @@ export function useWalletAccount() {
238246
return useWalletStore().account
239247
}
240248

249+
/**
250+
* A hook that gives you the loading state of the wallet.
251+
* @returns a boolean value indicating whether the wallet is loading.
252+
*/
253+
export function useIsWalletLoading() {
254+
return useWalletStore().isLoading
255+
}
256+
241257
/**
242258
* A hook that gives you an ENS domain for an account address.
243259
* @returns either an ENS domain name, or an empty string.

0 commit comments

Comments
 (0)