-
Notifications
You must be signed in to change notification settings - Fork 3
feat: Implement filter memory functionality #74
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,6 +1,7 @@ | ||
| 'use client'; | ||
| import { useCallback, useEffect, useState } from 'react'; | ||
| import { useCallback, useEffect, useState, useRef } from 'react'; | ||
| import storage from 'local-storage-fallback'; | ||
| import { useRouter, useSearchParams } from 'next/navigation'; | ||
| import Header from '@/components/layout/header/Header'; | ||
| import LoadingScreen from '@/components/Status/LoadingScreen'; | ||
| import useMarkets from '@/hooks/useMarkets'; | ||
|
|
@@ -33,14 +34,24 @@ const defaultStaredMarkets = JSON.parse( | |
| * that you want toLowerCase() render on the page. | ||
| */ | ||
| export default function Markets() { | ||
| const router = useRouter(); | ||
| const searchParams = useSearchParams(); | ||
|
|
||
| const { loading, data: rawMarkets } = useMarkets(); | ||
|
|
||
| // token keys, aggregated with | for each "ERC20Token" object | ||
| // Parse and validate network parameter | ||
| const defaultNetwork = (() => { | ||
| const networkParam = searchParams.get('network'); | ||
| return networkParam && | ||
| Object.values(SupportedNetworks).includes(Number(networkParam) as SupportedNetworks) | ||
| ? (Number(networkParam) as SupportedNetworks) | ||
| : null; | ||
| })(); | ||
|
Comment on lines
+37
to
+49
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Move defaultNetwork calculation into a useEffect hook. The current implementation won't update when URL parameters change. Use a useEffect hook to keep it in sync with searchParams. Example fix: const [defaultNetwork, setDefaultNetwork] = useState<SupportedNetworks | null>(null);
useEffect(() => {
const networkParam = searchParams.get('network');
setDefaultNetwork(
networkParam &&
Object.values(SupportedNetworks).includes(Number(networkParam) as SupportedNetworks)
? (Number(networkParam) as SupportedNetworks)
: null
);
}, [searchParams]); |
||
|
|
||
| // Initialize states | ||
| const [selectedCollaterals, setSelectedCollaterals] = useState<string[]>([]); | ||
| const [selectedLoanAssets, setSelectedLoanAssets] = useState<string[]>([]); | ||
|
|
||
| // single choice: null for all networks | ||
| const [selectedNetwork, setSelectedNetwork] = useState<SupportedNetworks | null>(null); | ||
| const [selectedNetwork, setSelectedNetwork] = useState<SupportedNetworks | null>(defaultNetwork); | ||
|
Comment on lines
+51
to
+54
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Initialize states with URL parameters. Consider initializing selectedCollaterals, selectedLoanAssets, and selectedNetwork with values from URL parameters for immediate sync on load. Example: const [selectedCollaterals, setSelectedCollaterals] = useState<string[]>(() => {
const collaterals = searchParams.get('collaterals');
return collaterals ? collaterals.split(',').filter(Boolean) : [];
});
const [selectedLoanAssets, setSelectedLoanAssets] = useState<string[]>(() => {
const loanAssets = searchParams.get('loanAssets');
return loanAssets ? loanAssets.split(',').filter(Boolean) : [];
});
const [selectedNetwork, setSelectedNetwork] = useState<SupportedNetworks | null>(defaultNetwork); |
||
|
|
||
| const [uniqueCollaterals, setUniqueCollaterals] = useState<ERC20Token[]>([]); | ||
| const [uniqueLoanAssets, setUniqueLoanAssets] = useState<ERC20Token[]>([]); | ||
|
|
@@ -61,6 +72,31 @@ export default function Markets() { | |
|
|
||
| const [filteredMarkets, setFilteredMarkets] = useState(rawMarkets); | ||
|
|
||
| // Use useRef to store the previous URL parameters | ||
| const prevParamsRef = useRef<string>(''); | ||
|
|
||
| // Synchronize state with URL parameters | ||
| useEffect(() => { | ||
| const currentParams = searchParams.toString(); | ||
| if (currentParams !== prevParamsRef.current) { | ||
| const collaterals = searchParams.get('collaterals'); | ||
| setSelectedCollaterals(collaterals ? collaterals.split(',').filter(Boolean) : []); | ||
|
|
||
| const loanAssets = searchParams.get('loanAssets'); | ||
| setSelectedLoanAssets(loanAssets ? loanAssets.split(',').filter(Boolean) : []); | ||
|
|
||
| const networkParam = searchParams.get('network'); | ||
| setSelectedNetwork( | ||
| networkParam && | ||
| Object.values(SupportedNetworks).includes(Number(networkParam) as SupportedNetworks) | ||
| ? (Number(networkParam) as SupportedNetworks) | ||
| : null, | ||
| ); | ||
|
|
||
| prevParamsRef.current = currentParams; | ||
| } | ||
| }, [searchParams]); | ||
|
|
||
| const starMarket = useCallback( | ||
| (id: string) => { | ||
| setStaredIds([...staredIds, id]); | ||
|
|
@@ -92,7 +128,34 @@ export default function Markets() { | |
| } | ||
| }, [rawMarkets]); | ||
|
|
||
| // Update the all markets pass to the table | ||
| const updateUrlParams = useCallback( | ||
| (collaterals: string[], loanAssets: string[], network: SupportedNetworks | null) => { | ||
| const params = new URLSearchParams(searchParams); | ||
| if (collaterals.length > 0) { | ||
| params.set('collaterals', collaterals.join(',')); | ||
| } else { | ||
| params.delete('collaterals'); | ||
| } | ||
| if (loanAssets.length > 0) { | ||
| params.set('loanAssets', loanAssets.join(',')); | ||
| } else { | ||
| params.delete('loanAssets'); | ||
| } | ||
| if (network) { | ||
| params.set('network', network.toString()); | ||
| } else { | ||
| params.delete('network'); | ||
| } | ||
| const newParams = params.toString(); | ||
| if (newParams !== prevParamsRef.current) { | ||
| router.push(`?${newParams}`, { scroll: false }); | ||
| prevParamsRef.current = newParams; | ||
| } | ||
| }, | ||
| [router, searchParams], | ||
| ); | ||
|
|
||
| // Update filtered markets | ||
| useEffect(() => { | ||
| const filtered = applyFilterAndSort( | ||
| rawMarkets, | ||
|
|
@@ -116,6 +179,11 @@ export default function Markets() { | |
| selectedNetwork, | ||
| ]); | ||
|
|
||
| // Update URL params when filters change | ||
| useEffect(() => { | ||
| updateUrlParams(selectedCollaterals, selectedLoanAssets, selectedNetwork); | ||
| }, [selectedCollaterals, selectedLoanAssets, selectedNetwork, updateUrlParams]); | ||
|
|
||
| const titleOnclick = useCallback( | ||
| (column: number) => { | ||
| setSortColumn(column); | ||
|
|
@@ -146,13 +214,22 @@ export default function Markets() { | |
| {/* left section: asset filters */} | ||
| <div className="flex flex-col gap-2 lg:flex-row"> | ||
| {/* network filter */} | ||
| <NetworkFilter setSelectedNetwork={setSelectedNetwork} /> | ||
| <NetworkFilter | ||
| selectedNetwork={selectedNetwork} | ||
| setSelectedNetwork={(network) => { | ||
| setSelectedNetwork(network); | ||
| updateUrlParams(selectedCollaterals, selectedLoanAssets, network); | ||
| }} | ||
| /> | ||
|
|
||
| <AssetFilter | ||
| label="Loan Asset" | ||
| placeholder="All loan asset" | ||
| selectedAssets={selectedLoanAssets} | ||
| setSelectedAssets={setSelectedLoanAssets} | ||
| setSelectedAssets={(assets) => { | ||
| setSelectedLoanAssets(assets); | ||
| updateUrlParams(selectedCollaterals, assets, selectedNetwork); | ||
| }} | ||
| items={uniqueLoanAssets} | ||
| loading={loading} | ||
| /> | ||
|
|
@@ -162,7 +239,10 @@ export default function Markets() { | |
| label="Collateral" | ||
| placeholder="All collateral" | ||
| selectedAssets={selectedCollaterals} | ||
| setSelectedAssets={setSelectedCollaterals} | ||
| setSelectedAssets={(assets) => { | ||
| setSelectedCollaterals(assets); | ||
| updateUrlParams(assets, selectedLoanAssets, selectedNetwork); | ||
| }} | ||
| items={uniqueCollaterals} | ||
| loading={loading} | ||
| /> | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
defaultNetworkmay not reflect URL changesAssigning
defaultNetworkoutside of state hooks won't update it whensearchParamschange. Use state anduseEffectto keep it in sync.Suggested fix:
📝 Committable suggestion