diff --git a/explorer/src/constants/columns/portal.tsx b/explorer/src/constants/columns/portal.tsx index 980da05c..7231b875 100644 --- a/explorer/src/constants/columns/portal.tsx +++ b/explorer/src/constants/columns/portal.tsx @@ -55,3 +55,29 @@ export const columns = ({ chain }: { chain: Chain }): ColumnDef[] => [ }, }, ]; + +export const portalColumnsOption = { + name: { + width: "25%", + }, + description: { + width: "50%", + }, + owner: { + width: "25%", + }, +}; + +export const skeletonPortals = (count: number) => + Array(count) + .fill(null) + .map((_, index) => ({ + id: `0x${index.toString(16).padStart(40, "0")}` as `0x${string}`, + name: "", + description: "", + ownerAddress: "0x0000000000000000000000000000000000000000" as `0x${string}`, + ownerName: "", + modules: [] as `0x${string}`[], + isRevocable: false, + attestationCounter: 0, + })); diff --git a/explorer/src/interfaces/swr/enum.ts b/explorer/src/interfaces/swr/enum.ts index f717d253..87afc72c 100644 --- a/explorer/src/interfaces/swr/enum.ts +++ b/explorer/src/interfaces/swr/enum.ts @@ -11,6 +11,7 @@ export enum SWRKeys { GET_RECENT_ATTESTATION_GLOBAL = "getRecentAttestations", GET_MODULE_LIST = "getModuleList", GET_MODULE_COUNT = "getModuleCount", + GET_MODULE_PORTAL_LIST = "getModulePortalList", SEARCH = "search", GET_PORTALS_BY_ISSUER = "getPortalsByIssuer", GET_PORTAL_BY_ID = "getPortalByID", diff --git a/explorer/src/pages/Issuer/components/Portals/index.tsx b/explorer/src/pages/Issuer/components/Portals/index.tsx index a65ffe51..cdc7e549 100644 --- a/explorer/src/pages/Issuer/components/Portals/index.tsx +++ b/explorer/src/pages/Issuer/components/Portals/index.tsx @@ -20,7 +20,12 @@ export const Portals: React.FC = ({ address }) => { const location = useLocation(); const { data: portals } = useSWR(`${SWRKeys.GET_PORTALS_BY_ISSUER}/${address}`, () => - sdk.portal.findBy(undefined, undefined, { ownerAddress: address }), + sdk.portal.findBy(undefined, undefined, { ownerAddress: address }).then((portalList) => + portalList.map((portal) => ({ + ...portal, + id: portal.id as `0x${string}`, + })), + ), ); if (!portals) return null; diff --git a/explorer/src/pages/Module/components/ModulePortals/index.tsx b/explorer/src/pages/Module/components/ModulePortals/index.tsx new file mode 100644 index 00000000..da8cff96 --- /dev/null +++ b/explorer/src/pages/Module/components/ModulePortals/index.tsx @@ -0,0 +1,46 @@ +import { t } from "i18next"; +import { useRef } from "react"; +import useSWR from "swr"; +import { Address } from "viem"; + +import { DataTable } from "@/components/DataTable"; +import { columns, portalColumnsOption, skeletonPortals } from "@/constants/columns/portal"; +import { columnsSkeleton } from "@/constants/columns/skeleton"; +import { SWRKeys } from "@/interfaces/swr/enum"; +import { useNetworkContext } from "@/providers/network-provider/context"; +import { APP_ROUTES } from "@/routes/constants"; +import { isNotNullOrUndefined } from "@/utils"; + +export const ModulePortals: React.FC<{ moduleId: Address }> = ({ moduleId }) => { + const { + sdk, + network: { chain }, + } = useNetworkContext(); + + const { data: portals, isLoading } = useSWR( + `${SWRKeys.GET_MODULE_PORTAL_LIST}/${moduleId}/${chain.id}`, + async () => { + const allPortals = await sdk.portal.findBy(100, 0); + const portalList = allPortals.filter((portal) => portal.modules.includes(moduleId)); + return portalList.slice(0, 5).map((portal) => ({ + ...portal, + id: portal.id as `0x${string}`, + })); + }, + { + shouldRetryOnError: false, + }, + ); + + const columnsSkeletonRef = useRef(columnsSkeleton(columns({ chain }), portalColumnsOption)); + const data = isLoading + ? { columns: columnsSkeletonRef.current, list: skeletonPortals(5) } + : { columns: columns({ chain }), list: portals?.filter(isNotNullOrUndefined) || [] }; + + return ( +
+

{t("portal.title")}

+ +
+ ); +}; diff --git a/explorer/src/pages/Module/index.tsx b/explorer/src/pages/Module/index.tsx index eed87040..19ff0923 100644 --- a/explorer/src/pages/Module/index.tsx +++ b/explorer/src/pages/Module/index.tsx @@ -10,6 +10,7 @@ import { useNetworkContext } from "@/providers/network-provider/context"; import { getBlockExplorerLink } from "@/utils"; import { ModuleLoadingSkeleton } from "./components/ModuleLoadingSkeleton"; +import { ModulePortals } from "./components/ModulePortals"; export const Module = () => { const { id } = useParams(); @@ -60,6 +61,7 @@ export const Module = () => { + ); };