Skip to content

Commit ab612d9

Browse files
committed
Update layout item my data
1 parent db444bb commit ab612d9

5 files changed

Lines changed: 226 additions & 95 deletions

File tree

app/marketplace/my-data/page.tsx

Lines changed: 128 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,25 @@
11
'use client';
22

3-
import React, { useState, useRef, useCallback, useEffect } from 'react';
3+
import React, { useState, useRef, useCallback } from 'react';
44
import Link from 'next/link';
55
import { useCurrentAccount, useSignAndExecuteTransaction } from '@mysten/dapp-kit';
6-
import { useAllListings, useAccountBalance } from '@/hooks/useMarketplace';
6+
import { useOwnedListings, useAccountBalance } from '@/hooks/useMarketplace';
77
import { formatSize, bytesToHex, formatPrice } from '@/lib/marketplace';
88
import { getFullnodeUrl } from '@mysten/sui/client';
99
import { SuiJsonRpcClient } from '@mysten/sui/jsonRpc';
1010
import { Transaction } from '@mysten/sui/transactions';
1111
import { marketplaceConfig, MIST_PER_SUI } from '@/config/marketplace';
1212
import { getMarketplaceTarget } from '@/lib/marketplace';
1313

14+
// Type for Walrus write files flow
15+
interface WalrusWriteFlow {
16+
encode: () => Promise<void>;
17+
register: (opts: { epochs: number; owner: string; deletable: boolean }) => Transaction;
18+
upload: (opts: { digest: string }) => Promise<void>;
19+
certify: () => Transaction;
20+
listFiles: () => Promise<Array<{ blobId?: string; id?: string }>>;
21+
}
22+
1423
const walrusModule = {
1524
walrus: null as null | typeof import('@mysten/walrus').walrus,
1625
};
@@ -46,7 +55,7 @@ const STEPS: { key: Step; label: string; icon: string }[] = [
4655
export default function MyDataPage() {
4756
const account = useCurrentAccount();
4857
const { mutate: signAndExecute, isPending: isSigning } = useSignAndExecuteTransaction();
49-
const { data: listings, isLoading, refetch } = useAllListings();
58+
const { data: listings, isLoading, refetch } = useOwnedListings(account?.address);
5059
const { data: balance } = useAccountBalance();
5160

5261
const [activeTab, setActiveTab] = useState<Tab>('uploads');
@@ -98,7 +107,7 @@ export default function MyDataPage() {
98107
sendTip: { max: 1_000_000 },
99108
},
100109
})
101-
);
110+
) as unknown as { walrus: { writeFilesFlow: (opts: { files: unknown[] }) => WalrusWriteFlow } };
102111

103112
const walrusFile = WalrusFile.from({
104113
contents: data,
@@ -427,28 +436,128 @@ export default function MyDataPage() {
427436
{isLoading && (
428437
<>
429438
{[1, 2, 3].map(i => (
430-
<div key={i} className="rounded-xl border-2 border-ink bg-white p-6 min-h-[340px] animate-pulse">
431-
<div className="h-6 bg-gray-200 rounded w-3/4 mb-4"></div>
432-
<div className="h-4 bg-gray-200 rounded w-full mb-2"></div>
433-
<div className="h-4 bg-gray-200 rounded w-2/3"></div>
434-
</div>
439+
<article key={i} className="flex flex-col rounded-xl border-2 border-ink bg-white overflow-hidden animate-pulse">
440+
<div className="h-36 bg-gray-200" />
441+
<div className="p-4 flex flex-col flex-1">
442+
<div className="h-5 bg-gray-200 rounded w-3/4 mb-2" />
443+
<div className="h-3 bg-gray-100 rounded w-1/2 mb-3" />
444+
<div className="grid grid-cols-2 gap-4 py-3 border-t border-gray-200">
445+
<div>
446+
<div className="h-2 bg-gray-100 rounded w-12 mb-1" />
447+
<div className="h-4 bg-gray-200 rounded w-16" />
448+
</div>
449+
<div>
450+
<div className="h-2 bg-gray-100 rounded w-12 mb-1" />
451+
<div className="h-4 bg-gray-200 rounded w-16" />
452+
</div>
453+
</div>
454+
<div className="flex gap-2 mt-auto pt-3 border-t border-gray-200">
455+
<div className="flex-1 h-9 bg-gray-200 rounded-lg" />
456+
<div className="flex-1 h-9 bg-gray-200 rounded-lg" />
457+
</div>
458+
</div>
459+
</article>
435460
))}
436461
</>
437462
)}
438463

439464
{listings && listings.map(listing => (
440-
<article key={listing.id} className="flex flex-col rounded-xl border-2 border-ink bg-white p-4 shadow-hard-sm">
441-
<div className="flex items-start justify-between mb-4">
442-
<div className="h-12 w-12 rounded-lg border-2 border-ink bg-accent-blue flex items-center justify-center">
443-
<span className="material-symbols-outlined text-white">dataset</span>
465+
<article key={listing.id} className="flex flex-col rounded-xl border-2 border-ink bg-white overflow-hidden">
466+
{/* Image/Preview Area */}
467+
<div className="relative h-36 bg-linear-to-br from-gray-800 to-gray-900 flex items-center justify-center">
468+
<div className="absolute inset-0 opacity-20">
469+
<svg className="w-full h-full" viewBox="0 0 100 100" preserveAspectRatio="none">
470+
<path d="M0,50 Q25,30 50,50 T100,50" stroke="currentColor" strokeWidth="0.5" fill="none" className="text-accent-lime" />
471+
<path d="M0,60 Q25,40 50,60 T100,60" stroke="currentColor" strokeWidth="0.5" fill="none" className="text-accent-lime" />
472+
</svg>
473+
</div>
474+
<span className="material-symbols-outlined text-5xl text-gray-600">dataset</span>
475+
<span className="absolute top-3 left-3 rounded bg-accent-lime text-ink px-2 py-0.5 text-[10px] font-bold border border-ink">ACTIVE</span>
476+
477+
{/* Explorer Links */}
478+
<div className="absolute top-3 right-3 flex gap-1">
479+
<a
480+
href={`https://suiscan.xyz/testnet/object/${listing.id}`}
481+
target="_blank"
482+
rel="noopener noreferrer"
483+
className="h-7 w-7 rounded bg-white/90 hover:bg-white flex items-center justify-center transition-colors"
484+
title="View on SuiScan"
485+
>
486+
<svg className="w-4 h-4" viewBox="0 0 234 234" fill="none">
487+
<path d="M0 100C0 65 0 47.5 6.8 33C12.7 21.3 22.3 11.8 34 5.8C47.3 0 64.7 0 99.5 0H133.8C168.6 0 186 0 199.3 6.8C211 12.8 220.6 22.3 226.5 34C233.3 47.4 233.3 64.9 233.3 99.8V134.2C233.3 169.1 233.3 186.6 226.5 199.9C220.6 211.6 211 221.2 199.3 227.2C186 234 168.6 234 133.8 234H99.5C64.7 234 47.3 234 34 227.2C22.3 221.2 12.7 211.7 6.8 200C0 186.6 0 169.1 0 134.2V100Z" fill="#4C72FF"/>
488+
<path d="M177 87C178.7 85.9 180.8 85.6 182.4 86.3C183.2 86.6 183.9 87.1 184.3 87.8C184.7 88.5 185 89.4 184.9 90.2L181.4 148.2C181 155.7 178.2 163.4 173.6 170.4C160.4 190.4 133.2 200 112.8 191.8C107.1 189.5 102.5 186 99.2 181.7C100 181.8 100.8 181.7 101.5 181.7C122.4 181.7 143.5 170.3 155.1 152.7C160.7 144.1 164 134.7 164.6 125.6L166.5 93.3L177 87Z" fill="white"/>
489+
<path d="M150 63.6C151.7 62.5 153.8 62.3 155.5 62.9C156.3 63.3 156.9 63.8 157.4 64.5C157.9 65.2 158.1 66.1 158 66.9L154.5 125C154 132.5 151.3 140.1 146.7 147.1C133.5 167.2 106.3 176.7 85.9 168.5C80.1 166.2 75.6 162.7 72.3 158.4C73.1 158.4 73.9 158.4 74.6 158.4C95.6 158.4 116.6 147.1 128.2 129.4C133.9 120.8 137.1 111.4 137.7 102.3L139.6 70L150 63.6Z" fill="white"/>
490+
<path d="M123 40.3C124.7 39.2 126.8 39 128.5 39.6C129.2 39.9 129.9 40.5 130.3 41.2C130.8 41.9 131 42.7 130.9 43.5L127.4 101.6C127 109.1 124.2 116.7 119.6 123.7C106.4 143.8 79.2 153.3 58.8 145.1C38.5 136.9 32.7 114 45.9 93.9C50.5 86.9 57.1 80.7 64.6 76.1L123 40.3Z" fill="white"/>
491+
</svg>
492+
</a>
493+
<a
494+
href={`https://testnet.suivision.xyz/object/${listing.id}`}
495+
target="_blank"
496+
rel="noopener noreferrer"
497+
className="h-7 w-7 rounded bg-white/90 hover:bg-white flex items-center justify-center transition-colors"
498+
title="View on SuiVision"
499+
>
500+
<svg className="w-4 h-4" viewBox="0 0 24 24" fill="none">
501+
<path d="M0 6C0 2.68629 2.68629 0 6 0H18C21.3137 0 24 2.68629 24 6V18C24 21.3137 21.3137 24 18 24H6C2.68629 24 0 21.3137 0 18V6Z" fill="#4DA2FF"/>
502+
<path d="M6.99748 5.28362L6.99748 11.0148L8.71768 12.0008L6.99731 12.987L6.99731 18.7182L11.9972 21.584L16.9971 18.7182L16.9971 12.9866L15.2769 12.0007L16.9973 11.0147L16.9973 5.28308L11.997 2.41732L6.99748 5.28362ZM11.6464 3.42366L11.6464 7.94789L7.69961 10.2105L7.69961 5.68623L11.6464 3.42366ZM12.3482 20.5781L12.3482 16.0535L16.2954 13.7912L16.2954 18.3159L12.3482 20.5781ZM15.9441 13.1879L11.9973 15.4501L8.05048 13.1879L9.41994 12.4031L11.9973 13.8803L14.575 12.4031L15.9441 13.1879ZM11.9973 10.1208L9.41964 11.5982L8.05048 10.8134L11.9973 8.55113L15.9445 10.8134L14.575 11.5982L11.9973 10.1208Z" fill="white"/>
503+
</svg>
504+
</a>
444505
</div>
445-
<span className="rounded bg-green-100 text-green-800 px-2 py-1 text-[10px] font-bold border border-green-200">ACTIVE</span>
446506
</div>
447-
<h3 className="text-lg font-bold text-ink mb-1">{listing.name}</h3>
448-
<p className="text-sm text-gray-500 mb-4 line-clamp-2">{listing.description}</p>
449-
<div className="mt-auto flex items-center justify-between">
450-
<span className="text-lg font-bold text-primary">{formatPrice(listing.price)}</span>
451-
<span className="text-xs text-gray-400">{formatSize(Number(listing.totalSize))}</span>
507+
508+
{/* Content */}
509+
<div className="p-4 flex flex-col flex-1">
510+
<h3 className="text-base font-bold text-ink mb-1 line-clamp-2">{listing.name}</h3>
511+
512+
{/* Object ID */}
513+
<p className="text-[10px] text-gray-400 font-mono mb-1 truncate" title={listing.id}>
514+
ID: {listing.id.slice(0, 8)}...{listing.id.slice(-6)}
515+
</p>
516+
517+
{/* Blob ID with Walrus link */}
518+
<div className="flex items-center gap-1 mb-3">
519+
<p className="text-[10px] text-gray-400 font-mono truncate flex-1" title={listing.blobId}>
520+
Blob: {listing.blobId.slice(0, 8)}...{listing.blobId.slice(-6)}
521+
</p>
522+
<a
523+
href={`https://walruscan.com/testnet/blob/${listing.blobId}`}
524+
target="_blank"
525+
rel="noopener noreferrer"
526+
className="h-5 w-5 rounded bg-gray-100 hover:bg-gray-200 flex items-center justify-center transition-colors shrink-0"
527+
title="View on WalrusScan"
528+
>
529+
<svg className="w-3 h-3" viewBox="0 0 24 24" fill="none">
530+
<circle cx="12" cy="10" r="8" fill="#36B5A8"/>
531+
<ellipse cx="12" cy="22" rx="6" ry="2" fill="#36B5A8" opacity="0.5"/>
532+
<circle cx="9" cy="8" r="1.5" fill="white"/>
533+
<circle cx="15" cy="8" r="1.5" fill="white"/>
534+
<path d="M9 13C9 13 10.5 15 12 15C13.5 15 15 13 15 13" stroke="white" strokeWidth="1.5" strokeLinecap="round"/>
535+
</svg>
536+
</a>
537+
</div>
538+
539+
{/* Stats */}
540+
<div className="grid grid-cols-2 gap-4 py-3 border-t border-gray-200">
541+
<div>
542+
<p className="text-[10px] text-gray-400 uppercase tracking-wide">Price</p>
543+
<p className="text-sm font-bold text-ink">{formatPrice(listing.price)}</p>
544+
</div>
545+
<div>
546+
<p className="text-[10px] text-gray-400 uppercase tracking-wide">Size</p>
547+
<p className="text-sm font-bold text-accent-lime">{formatSize(Number(listing.totalSize))}</p>
548+
</div>
549+
</div>
550+
551+
{/* Actions */}
552+
<div className="flex gap-2 mt-auto pt-3 border-t border-gray-200">
553+
<button className="flex-1 h-9 rounded-lg border-2 border-ink bg-white text-ink text-sm font-bold hover:bg-gray-50 transition-colors">
554+
Edit
555+
</button>
556+
<button className="flex-1 h-9 rounded-lg border-2 border-ink bg-gray-100 text-ink text-sm font-bold hover:bg-gray-200 transition-colors flex items-center justify-center gap-1">
557+
<span className="material-symbols-outlined text-sm">settings</span>
558+
Manage
559+
</button>
560+
</div>
452561
</div>
453562
</article>
454563
))}

bun.lock

Lines changed: 7 additions & 8 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

components/marketplace/MarketplaceSidebar.tsx

Lines changed: 48 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,9 @@ export default function MarketplaceSidebar() {
1717
const account = useCurrentAccount();
1818
const { mutate: disconnect } = useDisconnectWallet();
1919
const suiClient = useSuiClient();
20+
21+
// Copy address state
22+
const [copied, setCopied] = useState(false);
2023

2124
// Get filter state from context
2225
const {
@@ -83,6 +86,24 @@ export default function MarketplaceSidebar() {
8386
disconnect();
8487
};
8588

89+
// Copy address to clipboard
90+
const handleCopyAddress = async () => {
91+
if (!account?.address) return;
92+
try {
93+
await navigator.clipboard.writeText(account.address);
94+
setCopied(true);
95+
setTimeout(() => setCopied(false), 2000);
96+
} catch (err) {
97+
console.error("Failed to copy address:", err);
98+
}
99+
};
100+
101+
// Open SuiVision explorer
102+
const openSuiVision = () => {
103+
if (!account?.address) return;
104+
window.open(`https://suivision.xyz/account/${account.address}`, "_blank");
105+
};
106+
86107
// Price slider handlers
87108
const handleSliderMouseDown = (e: React.MouseEvent) => {
88109
setIsDragging(true);
@@ -347,19 +368,39 @@ export default function MarketplaceSidebar() {
347368
{account ? (
348369
<div className="flex flex-col gap-3">
349370
<div className="flex items-center gap-3">
350-
<div className="h-10 w-10 rounded-full border-2 border-ink bg-gradient-to-br from-primary to-accent-lime flex items-center justify-center">
371+
<div className="h-10 w-10 rounded-full border-2 border-ink bg-linear-to-br from-primary to-accent-lime flex items-center justify-center">
351372
<span className="material-symbols-outlined text-white" style={{ fontSize: "20px" }}>
352373
account_balance_wallet
353374
</span>
354375
</div>
355-
<div className="flex flex-col flex-1 min-w-0">
356-
<span className="text-sm font-bold text-ink truncate">
357-
{suinsName ? `@${suinsName}` : formatAddress(account.address)}
358-
</span>
376+
<div
377+
className="flex flex-col flex-1 min-w-0 cursor-pointer group"
378+
onClick={handleCopyAddress}
379+
title="Click to copy address"
380+
>
381+
<div className="flex items-center gap-1">
382+
<span className="text-sm font-bold text-ink truncate group-hover:text-primary transition-colors">
383+
{suinsName ? `@${suinsName}` : formatAddress(account.address)}
384+
</span>
385+
<span className="material-symbols-outlined text-gray-400 group-hover:text-primary transition-colors" style={{ fontSize: "14px" }}>
386+
{copied ? "check" : "content_copy"}
387+
</span>
388+
</div>
359389
{suinsName && (
360-
<span className="text-xs text-gray-500 truncate">{formatAddress(account.address)}</span>
390+
<span className="text-xs text-gray-500 truncate group-hover:text-primary transition-colors">
391+
{formatAddress(account.address)}
392+
</span>
361393
)}
362394
</div>
395+
<button
396+
onClick={openSuiVision}
397+
className="h-8 w-8 rounded-lg border-2 border-ink bg-white flex items-center justify-center hover:bg-accent-lime transition-colors shrink-0"
398+
title="View on SuiVision"
399+
>
400+
<span className="material-symbols-outlined text-ink" style={{ fontSize: "18px" }}>
401+
open_in_new
402+
</span>
403+
</button>
363404
</div>
364405

365406
{/* Balances */}
@@ -387,7 +428,7 @@ export default function MarketplaceSidebar() {
387428
<p className="text-sm font-bold text-gray-600">Connect your wallet to get started</p>
388429
<ConnectButton
389430
connectText="Connect Wallet"
390-
className="!w-full !rounded-lg !border-2 !border-ink !bg-primary !px-4 !py-3 !font-bold !text-white !shadow-hard-sm hover:!-translate-y-1 !transition-transform"
431+
className="w-full! rounded-lg! border-2! border-ink! bg-primary! px-4! py-3! font-bold! text-white! shadow-hard-sm! hover:-translate-y-1! transition-transform!"
391432
/>
392433
</div>
393434
)}

0 commit comments

Comments
 (0)