diff --git a/package-lock.json b/package-lock.json index 2e56df3e..67cc839d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,7 +9,7 @@ "version": "0.3.9", "dependencies": { "@babylonlabs-io/babylon-proto-ts": "0.0.3-canary.5", - "@babylonlabs-io/bbn-core-ui": "^0.6.1", + "@babylonlabs-io/bbn-core-ui": "^0.6.3", "@babylonlabs-io/bbn-wallet-connect": "^0.1.22", "@babylonlabs-io/btc-staking-ts": "0.4.0-canary.5", "@bitcoin-js/tiny-secp256k1-asmjs": "2.2.3", @@ -14151,7 +14151,6 @@ "version": "1.13.3", "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.3.tgz", "integrity": "sha512-kDCGIbxkDSXE3euJZZXzc6to7fCrKHNI/hSRQnRuQ+BWjFNzZwiFF8fj/6o2t2G9/jTj8PSIYTfCLelLZEeRpA==", - "dev": true, "license": "MIT", "engines": { "node": ">= 0.4" @@ -16284,7 +16283,6 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz", "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==", - "dev": true, "license": "MIT", "dependencies": { "es-errors": "^1.3.0", @@ -16304,7 +16302,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz", "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==", - "dev": true, "license": "MIT", "dependencies": { "es-errors": "^1.3.0", @@ -16321,7 +16318,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz", "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==", - "dev": true, "license": "MIT", "dependencies": { "call-bound": "^1.0.2", @@ -16340,7 +16336,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz", "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==", - "dev": true, "license": "MIT", "dependencies": { "call-bound": "^1.0.2", diff --git a/package.json b/package.json index 97603e70..cf433680 100644 --- a/package.json +++ b/package.json @@ -26,7 +26,7 @@ }, "dependencies": { "@babylonlabs-io/babylon-proto-ts": "0.0.3-canary.5", - "@babylonlabs-io/bbn-core-ui": "^0.6.1", + "@babylonlabs-io/bbn-core-ui": "^0.6.3", "@babylonlabs-io/bbn-wallet-connect": "^0.1.22", "@babylonlabs-io/btc-staking-ts": "0.4.0-canary.5", "@bitcoin-js/tiny-secp256k1-asmjs": "2.2.3", diff --git a/src/app/components/Staking/FinalityProviders/FinalityProviderTable.tsx b/src/app/components/Staking/FinalityProviders/FinalityProviderTable.tsx index 37de376e..4f0099ee 100644 --- a/src/app/components/Staking/FinalityProviders/FinalityProviderTable.tsx +++ b/src/app/components/Staking/FinalityProviders/FinalityProviderTable.tsx @@ -19,6 +19,7 @@ export const FinalityProviderTable = () => { filterValue, hasError, handleRowSelect, + isRowSelectable, } = useFinalityProviderState(); const tableData = useMemo(() => { @@ -70,6 +71,7 @@ export const FinalityProviderTable = () => { hasMore={hasNextPage} onLoadMore={fetchNextPage} onRowSelect={handleRowSelect} + isRowSelectable={isRowSelectable} /> ); diff --git a/src/app/state/FinalityProviderState.tsx b/src/app/state/FinalityProviderState.tsx index 63a03f65..25089860 100644 --- a/src/app/state/FinalityProviderState.tsx +++ b/src/app/state/FinalityProviderState.tsx @@ -1,5 +1,7 @@ import { useDebounce } from "@uidotdev/usehooks"; +import { useSearchParams } from "next/navigation"; import { + Suspense, useCallback, useEffect, useMemo, @@ -45,30 +47,39 @@ interface FinalityProviderState { handleSort: (sortField: string) => void; handleFilter: (value: string | number) => void; handleRowSelect: (row: FinalityProvider | null) => void; + isRowSelectable: (row: FinalityProvider) => boolean; getFinalityProviderMoniker: (btcPkHex: string) => string; fetchNextPage: () => void; } +const defaultState: FinalityProviderState = { + searchValue: "", + filterValue: "", + finalityProviders: [], + selectedFinalityProvider: null, + hasNextPage: false, + isFetching: false, + hasError: false, + isRowSelectable: () => false, + handleSearch: () => {}, + handleSort: () => {}, + handleFilter: () => {}, + handleRowSelect: () => {}, + getFinalityProviderMoniker: () => "-", + fetchNextPage: () => {}, +}; + const { StateProvider, useState: useFpState } = - createStateUtils({ - searchValue: "", - filterValue: "active", - finalityProviders: [], - selectedFinalityProvider: null, - hasNextPage: false, - isFetching: false, - hasError: false, - handleSearch: () => {}, - handleSort: () => {}, - handleFilter: () => {}, - handleRowSelect: () => {}, - getFinalityProviderMoniker: () => "-", - fetchNextPage: () => {}, - }); + createStateUtils(defaultState); + +function FinalityProviderStateInner({ children }: PropsWithChildren) { + const searchParams = useSearchParams(); + const fpParam = searchParams.get("fp"); -export function FinalityProviderState({ children }: PropsWithChildren) { const [searchValue, setSearchValue] = useState(""); - const [filterValue, setFilterValue] = useState("active"); + const [filterValue, setFilterValue] = useState( + fpParam ? "" : "active", + ); const [sortState, setSortState] = useState({}); const [selectedFinalityProvider, setSelectedFinalityProvider] = useState(null); @@ -83,19 +94,6 @@ export function FinalityProviderState({ children }: PropsWithChildren) { name: debouncedSearch, }); - useEffect(() => { - if (isError && error) { - showError({ - error: { - message: error.message, - errorState: ErrorState.SERVER_ERROR, - }, - retryAction: fetchNextPage, - }); - captureError(error); - } - }, [isError, error, showError, captureError, fetchNextPage]); - const handleSearch = useCallback((searchTerm: string) => { setSearchValue(searchTerm); }, []); @@ -122,6 +120,10 @@ export function FinalityProviderState({ children }: PropsWithChildren) { setSelectedFinalityProvider(row); }, []); + const isRowSelectable = useCallback((row: FinalityProvider) => { + return row.state === FinalityProviderStateEnum.ACTIVE; + }, []); + const filteredFinalityProviders = useMemo(() => { if (!data?.finalityProviders) return []; @@ -167,6 +169,25 @@ export function FinalityProviderState({ children }: PropsWithChildren) { [filteredFinalityProviders], ); + useEffect(() => { + if (fpParam && data?.finalityProviders) { + handleSearch(fpParam); + } + }, [fpParam, data?.finalityProviders, handleSearch]); + + useEffect(() => { + if (isError && error) { + showError({ + error: { + message: error.message, + errorState: ErrorState.SERVER_ERROR, + }, + retryAction: fetchNextPage, + }); + captureError(error); + } + }, [isError, error, showError, captureError, fetchNextPage]); + const state = { searchValue, filterValue, @@ -179,6 +200,7 @@ export function FinalityProviderState({ children }: PropsWithChildren) { handleSort, handleFilter, handleRowSelect, + isRowSelectable, getFinalityProviderMoniker, fetchNextPage, }; @@ -186,4 +208,14 @@ export function FinalityProviderState({ children }: PropsWithChildren) { return {children}; } +export function FinalityProviderState({ children }: PropsWithChildren) { + return ( + {children}} + > + {children} + + ); +} + export { useFpState as useFinalityProviderState };