Skip to content

Commit

Permalink
feat(wallet-dashboard): add assets page (#3724)
Browse files Browse the repository at this point in the history
* feat(wallet-dashboard): add protected layout

* feat: add missing TopNav

* fix: tests

* fix: imports

* feat(wallet-dashboard): add assets page

* fix: add missing themes

* feat: improve connect button size

* revert: "feat: improve connect button size"

* refactor: remove unnecessary useMemo

* fix: remove commented lines

---------

Co-authored-by: evavirseda <[email protected]>
Co-authored-by: Begoña Álvarez de la Cruz <[email protected]>
  • Loading branch information
3 people authored Nov 6, 2024
1 parent 9a79b5c commit 8c1255d
Show file tree
Hide file tree
Showing 11 changed files with 165 additions and 141 deletions.
45 changes: 45 additions & 0 deletions apps/wallet-dashboard/app/(protected)/assets/[objectId]/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
// Copyright (c) 2024 IOTA Stiftung
// SPDX-License-Identifier: Apache-2.0

'use client';

import React, { useCallback } from 'react';
import { useParams } from 'next/navigation';
import { AssetCard, Button, RouteLink, SendAssetPopup } from '@/components';
import { isAssetTransferable, useGetObject } from '@iota/core';
import { usePopups } from '@/hooks';
import { useCurrentAccount } from '@iota/dapp-kit';
import { ASSETS_ROUTE } from '@/lib/constants/routes.constants';

const VisualAssetDetailPage = () => {
const params = useParams();
const objectId = params.objectId as string;
const { data: asset } = useGetObject(objectId);
const activeAccount = useCurrentAccount();

const { openPopup, closePopup } = usePopups();

const showSendAssetPopup = useCallback(() => {
if (asset?.data) {
openPopup(<SendAssetPopup asset={asset?.data} onClose={closePopup} />);
}
}, [asset, openPopup, closePopup]);

const assetIsTransferable = asset?.data ? isAssetTransferable(asset?.data) : false;

return (
<div className="flex h-full w-full flex-col space-y-4 px-40">
<RouteLink path={ASSETS_ROUTE.path} title="Back" />
{asset?.data ? (
<AssetCard key={asset.data.objectId} asset={asset.data} />
) : (
<div className="flex justify-center p-20">Asset not found</div>
)}
{assetIsTransferable && activeAccount ? (
<Button onClick={showSendAssetPopup}>Send Asset</Button>
) : null}
</div>
);
};

export default VisualAssetDetailPage;

This file was deleted.

27 changes: 0 additions & 27 deletions apps/wallet-dashboard/app/(protected)/assets/layout.tsx

This file was deleted.

97 changes: 91 additions & 6 deletions apps/wallet-dashboard/app/(protected)/assets/page.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,97 @@
// Copyright (c) 2024 IOTA Stiftung
// SPDX-License-Identifier: Apache-2.0

function AssetsDashboardPage(): JSX.Element {
'use client';

import { AssetCard, VirtualList } from '@/components';
import { ASSETS_ROUTE } from '@/lib/constants/routes.constants';
import { Panel, Title, Chip } from '@iota/apps-ui-kit';
import { hasDisplayData, useGetOwnedObjects } from '@iota/core';
import { useCurrentAccount } from '@iota/dapp-kit';
import { IotaObjectData } from '@iota/iota-sdk/client';
import { useState } from 'react';
import { AssetCategory } from '@/lib/enums';
import Link from 'next/link';

const ASSET_CATEGORIES: { label: string; value: AssetCategory }[] = [
{
label: 'Visual',
value: AssetCategory.Visual,
},
{
label: 'Other',
value: AssetCategory.Other,
},
];

export default function AssetsDashboardPage(): React.JSX.Element {
const [selectedCategory, setSelectedCategory] = useState<AssetCategory>(AssetCategory.Visual);

const account = useCurrentAccount();
const {
data: ownedObjects,
fetchNextPage,
hasNextPage,
isFetchingNextPage,
} = useGetOwnedObjects(account?.address);

const [visual, nonVisual] = (() => {
const visual: IotaObjectData[] = [];
const nonVisual: IotaObjectData[] = [];

ownedObjects?.pages
.flatMap((page) => page.data)
.filter((asset) => asset.data && asset.data.objectId)
.forEach((asset) => {
if (asset.data) {
if (hasDisplayData(asset)) {
visual.push(asset.data);
} else {
nonVisual.push(asset.data);
}
}
});

return [visual, nonVisual];
})();

const categoryToAsset: Record<AssetCategory, IotaObjectData[]> = {
[AssetCategory.Visual]: visual,
[AssetCategory.Other]: nonVisual,
};

const assetList = categoryToAsset[selectedCategory];

return (
<div className="flex items-center justify-center pt-12">
<h1>ASSETS</h1>
</div>
<Panel>
<Title title="Assets" />
<div className="px-lg">
<div className="flex flex-row items-center justify-start gap-xs py-xs">
{ASSET_CATEGORIES.map((tab) => (
<Chip
key={tab.label}
label={tab.label}
onClick={() => setSelectedCategory(tab.value)}
selected={selectedCategory === tab.value}
/>
))}
</div>

<div className="max-h-[600px] overflow-auto py-sm">
<VirtualList
items={assetList}
hasNextPage={hasNextPage}
isFetchingNextPage={isFetchingNextPage}
fetchNextPage={fetchNextPage}
estimateSize={() => 180}
render={(asset) => (
<Link href={ASSETS_ROUTE.path + `/${asset.objectId}`}>
<AssetCard asset={asset} />
</Link>
)}
/>
</div>
</div>
</Panel>
);
}

export default AssetsDashboardPage;

This file was deleted.

4 changes: 2 additions & 2 deletions apps/wallet-dashboard/app/(protected)/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,11 @@ function DashboardLayout({ children }: PropsWithChildren): JSX.Element {
<Sidebar />
</div>

<div className="container relative min-h-screen">
<div className="container relative flex min-h-screen flex-col">
<div className="sticky top-0">
<TopNav />
</div>
<div>{children}</div>
<div className="flex-1 py-md--rs">{children}</div>
</div>

<div className="fixed bottom-5 right-5">
Expand Down
2 changes: 1 addition & 1 deletion apps/wallet-dashboard/components/VirtualList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ function VirtualList<T>({
]);

return (
<div className="relative h-[50vh] w-full overflow-auto" ref={containerRef}>
<div className="relative h-full w-full" ref={containerRef}>
<div
style={{
height: `${virtualizer.getTotalSize()}px`,
Expand Down
7 changes: 7 additions & 0 deletions apps/wallet-dashboard/lib/enums/assetCategory.enum.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
// Copyright (c) 2024 IOTA Stiftung
// SPDX-License-Identifier: Apache-2.0

export enum AssetCategory {
Visual = 'Visual',
Other = 'Other',
}
1 change: 1 addition & 0 deletions apps/wallet-dashboard/lib/enums/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@
// SPDX-License-Identifier: Apache-2.0

export * from './protectedRouteTitle.enum';
export * from './assetCategory.enum';
17 changes: 17 additions & 0 deletions apps/wallet-dashboard/lib/utils/assets.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// Copyright (c) 2024 IOTA Stiftung
// SPDX-License-Identifier: Apache-2.0

import { hasDisplayData } from '@iota/core';
import { PaginatedObjectsResponse } from '@iota/iota-sdk/client';

export function filterAssetList(pages: PaginatedObjectsResponse[], shouldBeVisual: boolean) {
return (
pages
.flatMap((page) => page.data)
.filter(
(asset) =>
asset.data && asset.data.objectId && hasDisplayData(asset) === shouldBeVisual,
)
.map((response) => response.data!) ?? []
);
}
2 changes: 1 addition & 1 deletion apps/wallet-dashboard/next.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ const nextConfig = {
return [
{
source: '/dashboard',
destination: '/dashboard/home',
destination: '/home',
permanent: true,
},
];
Expand Down

0 comments on commit 8c1255d

Please sign in to comment.