diff --git a/src/pages/StashPage.tsx b/src/pages/StashPage.tsx index f64b121..231029c 100644 --- a/src/pages/StashPage.tsx +++ b/src/pages/StashPage.tsx @@ -54,10 +54,7 @@ import { MapPin, LayoutGrid, List, - RefreshCw, ChevronRight, - Smartphone, - Monitor, } from 'lucide-react'; import { cn } from '@/lib/utils'; @@ -934,6 +931,12 @@ export default function StashPage() { const hasForSale = stashItems.filter(i => i.willingToSell || i.willingToTrade).length; + // Category chips — only show categories that have items + const activeCategoryChips = Object.entries(STASH_CATEGORIES).filter( + ([key]) => displayItems.some(i => i.category === key) + ); + const showCategoryChips = activeCategoryChips.length > 1; + return ( - {/* ── Sticky page header ── */} -
-
-
- {/* Title + counts */} + {/* ── Page header — sticky, compact, everything you need ── */} +
+
+ {/* Top row */} +
-
- -
-
- {stats.total} +
+
+ {stats.total > 0 && ( +
+ {stats.total} +
+ )}
-
-

My Stash

-

- - Encrypted · Synced across devices -

+
+

My Stash

+
+ + Encrypted + + · + Syncs everywhere + {stats.totalValue > 0 && ( + <> + · + + + {stats.totalValue > 999 ? Math.floor(stats.totalValue / 1000) + 'k' : stats.totalValue} sats + + + )} +
- {/* Actions */} -
- {/* View toggle — desktop only */} -
+
+ {/* View toggle */} +
- addItem.mutate(item)} mode="wtb" /> - addItem.mutate(item)} mode="stash" /> + {/* Desktop add buttons */} +
+ addItem.mutate(item)} mode="wtb" /> + addItem.mutate(item)} mode="stash" /> +
+ + {/* Tab row — sits flush below title row */} +
+ + +
-
- {/* ── Cross-device sync banner (shown first time) ── */} -
-
- - - -
-
-

Synced across all devices

-

Add items on desktop, see them instantly on your phone — and vice versa. Your Nostr key = your account everywhere.

-
-
- +
- {/* ── Main content ── */} -
- {/* Profile stats bar */} - + {/* ── Main content column ── */} +
- {/* Tab switcher */} -
- - -
- - {/* Search bar */} -
+ {/* Search + filter in one tight row */} +
- - setSearchQuery(e.target.value)} - className="pl-9 bg-black/40 border-white/20" /> + + setSearchQuery(e.target.value)} + className="pl-9 h-9 bg-white/5 border-white/10 text-sm" + />
- {/* Category quick-chips */} -
- {Object.entries(STASH_CATEGORIES).map(([key, cat]) => { - const count = displayItems.filter(i => i.category === key).length; - if (count === 0) return null; - return ( - - ); - })} -
+ {/* Category chips — only when >1 category present */} + {showCategoryChips && ( +
+ {activeCategoryChips.map(([key, cat]) => { + const count = displayItems.filter(i => i.category === key).length; + return ( + + ); + })} +
+ )} - {/* Location filter — stash only */} - {activeTab === 'stash' && stashItems.some(i => i.storageLocation) && ( -
- 📍 + {/* Location filter chips — only when stash items have locations */} + {activeTab === 'stash' && stashItems.some(i => i.storageLocation && i.storageLocation !== 'other') && ( +
+ Where: {([ { value: 'all', label: 'All' }, - { value: 'home', label: '🏠' }, { value: 'car', label: '🚗' }, - { value: 'backpack', label: '🎒' }, { value: 'skatepark', label: '🛹' }, - { value: 'van', label: '🚐' }, { value: 'friends', label: '👫' }, + { value: 'home', label: '🏠 Home' }, + { value: 'car', label: '🚗 Car' }, + { value: 'backpack', label: '🎒 Backpack' }, + { value: 'skatepark', label: '🛹 Skatepark' }, + { value: 'van', label: '🚐 Van' }, + { value: 'friends', label: "👫 Friend's" }, ] as const).map(({ value, label }) => { - const count = value === 'all' ? stashItems.length : stashItems.filter(i => i.storageLocation === value).length; + const count = value === 'all' + ? stashItems.length + : stashItems.filter(i => i.storageLocation === value).length; if (value !== 'all' && count === 0) return null; return ( ); @@ -1081,48 +1118,50 @@ export default function StashPage() {
)} - {/* Items */} + {/* Items list */} {isLoading ? ( -
+
{Array.from({ length: 4 }).map((_, i) => ( -
+
- - + +
))}
) : filteredItems.length === 0 ? ( - - - {activeTab === 'wishlist' ? ( - <> - -

Wishlist is Empty

-

Add items you're hunting for to get notified when friends have matching gear.

- addItem.mutate(item)} mode="wtb" /> - - ) : ( - <> - -

- {stashItems.length === 0 ? 'Your Stash is Empty' : 'No Items Match'} -

-

- {stashItems.length === 0 - ? 'Add your gear to track what you own. Add on any device — it syncs everywhere via Nostr.' - : 'Try adjusting your search or filters.'} -

- {stashItems.length === 0 && addItem.mutate(item)} />} - - )} -
-
+
+ {activeTab === 'wishlist' ? ( + <> + +

Wishlist is empty

+

Add gear you're hunting for — we'll match you with friends' stashes.

+ addItem.mutate(item)} mode="wtb" /> + + ) : stashItems.length === 0 ? ( + <> +
+ +
+

Your stash is empty

+

+ Start tracking your gear. Add here or on desktop — it syncs everywhere. +

+ addItem.mutate(item)} /> + + ) : ( + <> + +

No items match your filters.

+ + + )} +
) : viewMode === 'list' ? ( - /* List view — default on mobile, toggleable on desktop */ -
+
{filteredItems.map((item) => ( setEditingItem(item)} @@ -1131,8 +1170,7 @@ export default function StashPage() { ))}
) : ( - /* Grid view */ -
+
{filteredItems.map((item) => ( setEditingItem(item)} @@ -1143,89 +1181,101 @@ export default function StashPage() { )}
- {/* ── Sidebar ── */} -
- {/* Marketplace card — shows "Ready to Sell" CTA when items are for sale, - otherwise a quieter info card. Never duplicated. */} - 0 - ? 'bg-gradient-to-br from-[#ff6600]/15 to-[#ff0040]/10 border-[#ff6600]/40' - : 'bg-black/40 border-white/10' - )}> + {/* ── Sidebar — desktop only, hidden on mobile ── */} +
+ + {/* Marketplace card */} + 0 + ? 'bg-gradient-to-br from-[#ff6600]/15 to-[#ff0040]/10 border-[#ff6600]/40' + : 'bg-white/3 border-white/8')}>
- 0 ? 'text-[#ff6600]' : 'text-white')}> - {hasForSale > 0 ? 'Ready to Sell' : 'Marketplace'} + 0 ? 'text-[#ff6600]' : 'text-gray-300')}> + {hasForSale > 0 ? `${hasForSale} ready to sell` : 'Marketplace'}
-

+

{hasForSale > 0 - ? <>{hasForSale} item{hasForSale > 1 ? 's' : ''} marked for sale or trade — list on the marketplace in one tap. - : 'Mark items as "Willing to Sell" or "Willing to Trade" to list them publicly.'} + ? `${hasForSale} item${hasForSale > 1 ? 's' : ''} marked for sale or trade.` + : 'Mark items as "Willing to Sell" or "Willing to Trade" to list them.'}

-
- Sell - Trade +
+ + Sell + + + Trade +
- - {/* Wishlist match teaser */} + {/* Wishlist */} {wishlistItems.length > 0 && ( - +
- - Wishlist - {wishlistItems.length} + + Wishlist + {wishlistItems.length}
-

- We'll match your wishlist with friends' stashes and alert you when something fits. -

+

We'll match your wishlist with friends' stashes.

)} - {/* Pro tips — compact */} - + {/* Tips */} + -
- - Tips -
-
    -
  • →Tap the ✏️ icon to edit any item
  • -
  • →Tap 🏪 to list an item on the marketplace
  • -
  • →Add photos to attract better trade offers
  • -
  • →Items added on desktop sync to your phone automatically
  • +

    Tips

    +
      +
    • ✏️ Tap to edit any item
    • +
    • 🏪 Tap to list on marketplace
    • +
    • 📸 Add photos for better trades
    • +
    • 🔄 Syncs across all devices
+ + {/* ── Mobile bottom info bar — marketplace CTA, only if items for sale ── */} + {hasForSale > 0 && ( +
+ +
+
+ +
+
+

{hasForSale} item{hasForSale > 1 ? 's' : ''} ready to sell

+

Browse Marketplace →

+
+
+ +
+ )}
- {/* ── Floating Add FAB (mobile only) ── */} + {/* ── Mobile FAB — single + button, tapping reveals stash/wishlist choice ── */}
addItem.mutate(item)} mode="wtb" trigger={ - } /> @@ -1233,8 +1283,9 @@ export default function StashPage() { onAdd={(item) => addItem.mutate(item)} mode="stash" trigger={ - } />