diff --git a/app/globals.css b/app/globals.css index 900673d..5faa7a0 100644 --- a/app/globals.css +++ b/app/globals.css @@ -17,11 +17,11 @@ --color-primary: #00bfff; --color-background-light: #f6f7f9; --color-background-dark: #19202e; - --color-slush-yellow: #ffd600; - --color-slush-orange: #ff5c00; - --color-slush-purple: #9747ff; - --color-slush-green: #00d68f; - --color-slush-dark: #1a1a1a; + --color-slush-yellow: #FFD600; + --color-slush-orange: #FF5C00; + --color-slush-purple: #9747FF; + --color-slush-green: #00D68F; + --color-slush-dark: #1A1A1A; /* Marketplace Colors */ --color-ink: #101618; @@ -104,6 +104,7 @@ } @keyframes float { + 0%, 100% { transform: translateY(0); @@ -118,6 +119,22 @@ body { font-family: var(--font-inter), Arial, Helvetica, sans-serif; } +/* Global cursor pointer for clickable elements */ +button, +a, +[role="button"], +[role="link"], +[role="menuitem"], +input[type="submit"], +input[type="button"], +input[type="checkbox"], +input[type="radio"], +label[for], +select, +.cursor-pointer { + cursor: pointer; +} + .text-outline-light { -webkit-text-stroke: 2px black; color: transparent; @@ -269,6 +286,7 @@ body { white-space: nowrap; direction: ltr; } + /* Cursor Hover Animation */ .cursor-animation { animation: cursorMove 3s ease-in-out infinite; @@ -426,7 +444,8 @@ body { * { @apply border-border outline-ring/50; } + body { @apply bg-background text-foreground; } -} +} \ No newline at end of file diff --git a/app/marketplace/layout.tsx b/app/marketplace/layout.tsx index f56b30e..64760ca 100644 --- a/app/marketplace/layout.tsx +++ b/app/marketplace/layout.tsx @@ -1,4 +1,7 @@ +'use client'; + import MarketplaceSidebar from '@/components/marketplace/MarketplaceSidebar'; +import { MarketplaceFilterProvider } from '@/contexts/MarketplaceFilterContext'; export default function MarketplaceLayout({ children, @@ -6,11 +9,13 @@ export default function MarketplaceLayout({ children: React.ReactNode; }) { return ( -
- -
- {children} -
-
+ +
+ +
+ {children} +
+
+
); } diff --git a/app/marketplace/my-data/page.tsx b/app/marketplace/my-data/page.tsx index 237de11..1df7c92 100644 --- a/app/marketplace/my-data/page.tsx +++ b/app/marketplace/my-data/page.tsx @@ -56,7 +56,7 @@ export default function MyDataPage() { const createFlow = useCallback(async (data: Uint8Array, identifier: string) => { const walrus = await getWalrus(); const { WalrusFile } = await import('@mysten/walrus'); - + const client = new SuiJsonRpcClient({ url: getFullnodeUrl('testnet'), network: 'testnet', @@ -97,7 +97,7 @@ export default function MyDataPage() { const handleStartUpload = async () => { if (!file || !account) return; - + setIsProcessing(true); setUploadError(''); @@ -110,7 +110,7 @@ export default function MyDataPage() { flowRef.current = flow; await flow.encode(); - + setEncryptedObject('0x' + bytesToHex(uint8Array).slice(0, 128)); setUploadStep('upload'); } catch (err) { @@ -243,9 +243,9 @@ export default function MyDataPage() { }); tl.to('#anim-overlay', { opacity: 1, duration: 0.2 }) - .to('#anim-text', { - duration: 0.5, - onStart: () => { + .to('#anim-text', { + duration: 0.5, + onStart: () => { document.getElementById('anim-text')!.innerText = 'ENCRYPTING METADATA'; document.getElementById('anim-subtext')!.innerText = 'Preparing asset for encryption'; } @@ -254,14 +254,14 @@ export default function MyDataPage() { .to('#anim-seal', { scale: 1, opacity: 1, rotation: 0, duration: 0.4, ease: 'elastic.out(1, 0.5)' }) .to('#anim-overlay', { backgroundColor: '#101618', duration: 0.1, yoyo: true, repeat: 1 }, '-=0.2') .to('#anim-icon', { scale: 1, opacity: 1, duration: 0.3, ease: 'back.out(1.7)' }) - .add(() => { + .add(() => { document.getElementById('anim-text')!.innerText = 'VERIFYING ZK-PROOFS'; document.getElementById('anim-subtext')!.innerText = 'Generating SNARKs on Sui Network...'; }) .to('#anim-progress', { width: '90%', duration: 1 }) .to('#anim-seal', { borderColor: '#ccff00', boxShadow: '0 0 30px #ccff00', duration: 0.3 }) .to('#anim-icon', { color: '#ccff00', duration: 0.3 }, '<') - .add(() => { + .add(() => { document.getElementById('anim-text')!.innerText = 'ASSET SECURED'; document.getElementById('anim-text')!.classList.add('text-accent-lime'); document.getElementById('anim-subtext')!.innerText = 'Listing created successfully.'; @@ -283,7 +283,7 @@ export default function MyDataPage() {

My Data Dashboard

- +
@@ -309,23 +309,21 @@ export default function MyDataPage() {
- - @@ -343,9 +341,9 @@ export default function MyDataPage() { View Analytics arrow_outward
- +
-
setIsCreateModalOpen(true)} className="flex flex-col items-center justify-center rounded-xl border-2 border-dashed border-ink bg-gray-50 p-6 min-h-[340px] hover:bg-blue-50 hover:border-primary transition-all duration-200 cursor-pointer group" > @@ -398,7 +396,7 @@ export default function MyDataPage() { Recent Purchases (0 items)
- +
@@ -409,7 +407,7 @@ export default function MyDataPage() {

No purchases yet

Start exploring the marketplace to find datasets.

- @@ -421,15 +419,6 @@ export default function MyDataPage() { )}
-
-

Powered by Sui Network

-
- dataset - security - hub -
-
- {isCreateModalOpen && (
@@ -606,15 +595,14 @@ export default function MyDataPage() {

Upload Wizard

- +
check_circle Step 1: Encode file
-
+
{isProcessing ? 'pending' : 'radio_button_unchecked'} @@ -670,7 +658,7 @@ export default function MyDataPage() {

Your data is stored on Walrus

- +

Status

Successfully uploaded to Walrus!

@@ -729,19 +717,19 @@ export default function MyDataPage() { )} {processingType && ( -
-
- + lock - + @@ -752,8 +740,8 @@ export default function MyDataPage() {
-

INITIALIZING @@ -763,19 +751,20 @@ export default function MyDataPage() {

-
-
+

BLOCK: #{listings?.[0]?.id?.slice(0, 8) || '000000'} HASH: 0x{blobId?.slice(0, 4) || '0000'}...{blobId?.slice(-4) || '0000'} NODE: SUI-TESTNET-01
-
- )} +
+ ) + } ); } diff --git a/app/marketplace/page.tsx b/app/marketplace/page.tsx index 1327857..e561d67 100644 --- a/app/marketplace/page.tsx +++ b/app/marketplace/page.tsx @@ -1,63 +1,144 @@ 'use client'; -import React from 'react'; +import React, { useState } from 'react'; import { useRouter } from 'next/navigation'; import MarketplaceHeader from '@/components/marketplace/MarketplaceHeader'; import FeaturedCollections from '@/components/marketplace/FeaturedCollections'; import AssetCard from '@/components/marketplace/AssetCard'; import { DATA_ASSETS } from '@/constants/marketplace'; +import { DataAsset, SortOption } from '@/types/marketplace'; +import { useMarketplaceFilterContext } from '@/contexts/MarketplaceFilterContext'; +import DataDetail from '@/components/marketplace/DataDetail'; + +const SORT_OPTIONS: { value: SortOption; label: string }[] = [ + { value: 'newest', label: 'Newest' }, + { value: 'oldest', label: 'Oldest' }, + { value: 'price_asc', label: 'Price: Low → High' }, + { value: 'price_desc', label: 'Price: High → Low' }, +]; export default function MarketplacePage() { const router = useRouter(); + const [selectedAsset, setSelectedAsset] = useState(null); + const [showSortDropdown, setShowSortDropdown] = useState(false); + + const { + filters, + setSearch, + setSortBy, + resetFilters, + filterAssets, + } = useMarketplaceFilterContext(); + + const filteredAssets = filterAssets(DATA_ASSETS); + + if (selectedAsset) { + return setSelectedAsset(null)} />; + } + + const currentSortLabel = SORT_OPTIONS.find((o) => o.value === filters.sortBy)?.label || 'Newest'; return (
- + { }} // Search happens automatically on change + />
- +

- All Data Assets ({DATA_ASSETS.length + 137} items) + All Data Assets{' '} + + ({filteredAssets.length} items) +

-
+
Sort by: - Newest + + + {/* Sort Dropdown */} + {showSortDropdown && ( +
+ {SORT_OPTIONS.map((option) => ( + + ))} +
+ )}
- -
- {DATA_ASSETS.map(asset => ( - router.push(`/marketplace/dataset/${asset.id}`)} - /> - ))} -
- -
- -
+ + {filteredAssets.length > 0 ? ( +
+ {filteredAssets.map((asset) => ( + setSelectedAsset(asset)} + /> + ))} +
+ ) : ( +
+ + search_off + +

No assets found

+

+ Try adjusting your filters or search query +

+ +
+ )} + + {filteredAssets.length > 0 && ( +
+ +
+ )}
- -
-

Powered by Sui Network

-
- dataset - security - hub -
-
{/* Floating Decorative Element */}
blur_on
+ + {/* Click outside to close dropdown */} + {showSortDropdown && ( +
setShowSortDropdown(false)} + /> + )}
); } diff --git a/components/Footer.tsx b/components/Footer.tsx index 59be106..92732cf 100644 --- a/components/Footer.tsx +++ b/components/Footer.tsx @@ -1,8 +1,8 @@ export default function Footer() { return ( -