feat(ui): adopt the shared PageHeader on Wallet, CreateListing, GearSwap, Messages

PageHeader now carries the app's neon glow (accent-tinted text-shadow), so the
unified header keeps the brand look rather than flattening it. Four more plain
headers migrate (title + accent + optional subtitle/actions).
This commit is contained in:
SkateSpots 2026-09-26 19:23:01 +07:00
parent 4d2c29edb0
commit 2edf7a797e
5 changed files with 52 additions and 71 deletions

View file

@ -30,7 +30,7 @@ export function PageHeader({
<div className="min-w-0"> <div className="min-w-0">
<h1 <h1
className="flex items-center gap-2 text-3xl font-black uppercase leading-none sm:text-4xl" className="flex items-center gap-2 text-3xl font-black uppercase leading-none sm:text-4xl"
style={{ color: accent, fontFamily: 'Impact, "Arial Black", sans-serif' }} style={{ color: accent, fontFamily: 'Impact, "Arial Black", sans-serif', textShadow: `0 0 24px ${accent}66` }}
> >
{Icon && <Icon className="h-7 w-7 shrink-0 sm:h-8 sm:w-8" />} {Icon && <Icon className="h-7 w-7 shrink-0 sm:h-8 sm:w-8" />}
<span className="truncate">{title}</span> <span className="truncate">{title}</span>

View file

@ -2,6 +2,7 @@ import { useState, useEffect, useMemo } from 'react';
import { useSeoMeta } from '@unhead/react'; import { useSeoMeta } from '@unhead/react';
import { useNavigate, Link, useSearchParams } from 'react-router-dom'; import { useNavigate, Link, useSearchParams } from 'react-router-dom';
import { Layout } from '@/components/Layout'; import { Layout } from '@/components/Layout';
import { PageHeader } from '@/components/PageHeader';
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card'; import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card';
import { Button } from '@/components/ui/button'; import { Button } from '@/components/ui/button';
import { Input } from '@/components/ui/input'; import { Input } from '@/components/ui/input';
@ -394,19 +395,15 @@ export default function CreateListingPage() {
<ArrowLeft className="h-4 w-4 mr-2" /> <ArrowLeft className="h-4 w-4 mr-2" />
{fromStash ? 'Back to Stash' : (selectedSpot ? `Back to ${selectedSpot.title}` : (returnTo === '/marketplace' ? 'Back to Marketplace' : 'Back to Map'))} {fromStash ? 'Back to Stash' : (selectedSpot ? `Back to ${selectedSpot.title}` : (returnTo === '/marketplace' ? 'Back to Marketplace' : 'Back to Map'))}
</Link> </Link>
<h1 <PageHeader
className="text-3xl font-black uppercase neon-orange" title={listingType === 'wtb' ? 'Want to Buy' : 'List Your Gear'}
style={{ accent="#ff6600"
fontFamily: 'Impact, "Arial Black", sans-serif', subtitle={
}} listingType === 'wtb'
> ? "Tell the community what gear you're looking for"
{listingType === 'wtb' ? 'WANT TO BUY' : 'LIST YOUR GEAR'} : 'Sell skateboarding gear to the community'
</h1> }
<p className="text-gray-400 mt-1"> />
{listingType === 'wtb'
? 'Tell the community what gear you\'re looking for'
: 'Sell skateboarding gear to the community'}
</p>
</div> </div>
{/* Coming from Stash indicator */} {/* Coming from Stash indicator */}

View file

@ -3,6 +3,7 @@ import { Link } from 'react-router-dom';
import { useSeoMeta } from '@unhead/react'; import { useSeoMeta } from '@unhead/react';
import { nip19 } from 'nostr-tools'; import { nip19 } from 'nostr-tools';
import { Layout } from '@/components/Layout'; import { Layout } from '@/components/Layout';
import { PageHeader } from '@/components/PageHeader';
import { LoginArea } from '@/components/auth/LoginArea'; import { LoginArea } from '@/components/auth/LoginArea';
import { Card, CardContent } from '@/components/ui/card'; import { Card, CardContent } from '@/components/ui/card';
import { Button } from '@/components/ui/button'; import { Button } from '@/components/ui/button';
@ -249,27 +250,28 @@ export default function DirectMessagesPage() {
{/* Phishing warning — shown once, dismissible */} {/* Phishing warning — shown once, dismissible */}
<PhishingWarningBanner /> <PhishingWarningBanner />
{/* Header */} <PageHeader
<div className="flex items-center justify-between gap-3 mb-4 sm:mb-6"> title="Messages"
<div className="min-w-0 flex-1"> icon={MessageCircle}
<h1 className="text-xl sm:text-2xl font-black uppercase tracking-wider flex items-center gap-2 sm:gap-3"> accent="#ff0040"
<MessageCircle className="h-5 w-5 sm:h-7 sm:w-7 text-[#ff0040] flex-shrink-0" /> className="mb-4 sm:mb-6"
<span className="truncate">MESSAGES</span> subtitle={
</h1> <span className="flex items-center gap-1">
<p className="text-gray-400 text-xs sm:text-sm mt-1 flex items-center gap-1"> <Lock className="h-3 w-3" />
<Lock className="h-2.5 w-2.5 sm:h-3 sm:w-3" />
<span className="hidden xs:inline">End-to-end encrypted with NIP-17</span> <span className="hidden xs:inline">End-to-end encrypted with NIP-17</span>
<span className="xs:hidden">Encrypted</span> <span className="xs:hidden">Encrypted</span>
</p> </span>
</div> }
actions={
<Button <Button
onClick={() => setShowNewMessage(true)} onClick={() => setShowNewMessage(true)}
className="bg-[#ff0040] hover:bg-[#ff0040]/90 text-white font-bold flex-shrink-0 h-10 sm:h-auto px-3 sm:px-4" className="bg-[#ff0040] hover:bg-[#ff0040]/90 text-white font-bold h-10 sm:h-auto px-3 sm:px-4"
> >
<Plus className="h-4 w-4 sm:mr-2" /> <Plus className="h-4 w-4 sm:mr-2" />
<span className="hidden sm:inline">New Message</span> <span className="hidden sm:inline">New Message</span>
</Button> </Button>
</div> }
/>
{/* Conversations List */} {/* Conversations List */}
<div className="space-y-3"> <div className="space-y-3">

View file

@ -2,6 +2,7 @@ import { useState, useMemo } from 'react';
import { useSeoMeta } from '@unhead/react'; import { useSeoMeta } from '@unhead/react';
import { Link } from 'react-router-dom'; import { Link } from 'react-router-dom';
import { Layout } from '@/components/Layout'; import { Layout } from '@/components/Layout';
import { PageHeader } from '@/components/PageHeader';
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'; import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
import { Button } from '@/components/ui/button'; import { Button } from '@/components/ui/button';
import { Badge } from '@/components/ui/badge'; import { Badge } from '@/components/ui/badge';
@ -185,28 +186,13 @@ export default function GearSwapPage() {
return ( return (
<Layout> <Layout>
<div className="container px-4 py-8 max-w-7xl"> <div className="container px-4 py-8 max-w-7xl">
{/* Header */} <PageHeader
<div className="flex flex-col md:flex-row md:items-center md:justify-between gap-4 mb-8"> title="Gear Swap"
<div> icon={ShoppingCart}
<div className="flex items-center gap-3 mb-2"> accent="#ff6600"
<div className="w-12 h-12 rounded-xl bg-gradient-to-br from-orange-500 to-orange-600 flex items-center justify-center"> subtitle="Buy & sell used skate gear with other skaters"
<ShoppingCart className="h-6 w-6 text-white" /> className="mb-8"
</div> actions={
<h1
className="text-3xl md:text-4xl font-black uppercase neon-orange"
style={{
fontFamily: 'Impact, "Arial Black", sans-serif',
letterSpacing: '0.05em',
}}
>
GEAR SWAP
</h1>
</div>
<p className="text-gray-400">
Buy & sell used skate gear with other skaters
</p>
</div>
<Link to="/create-listing?returnTo=/marketplace"> <Link to="/create-listing?returnTo=/marketplace">
<Button <Button
size="lg" size="lg"
@ -216,7 +202,8 @@ export default function GearSwapPage() {
List Gear List Gear
</Button> </Button>
</Link> </Link>
</div> }
/>
{/* Search & Filters */} {/* Search & Filters */}
<Card className="bg-black/90 border-2 border-orange-500/20 mb-6"> <Card className="bg-black/90 border-2 border-orange-500/20 mb-6">

View file

@ -1,6 +1,7 @@
import { useState } from 'react'; import { useState } from 'react';
import { useSeoMeta } from '@unhead/react'; import { useSeoMeta } from '@unhead/react';
import { Layout } from '@/components/Layout'; import { Layout } from '@/components/Layout';
import { PageHeader } from '@/components/PageHeader';
import { WalletModal } from '@/components/WalletModal'; import { WalletModal } from '@/components/WalletModal';
import { Badge } from '@/components/ui/badge'; import { Badge } from '@/components/ui/badge';
import { useWallet } from '@/hooks/useWallet'; import { useWallet } from '@/hooks/useWallet';
@ -240,13 +241,7 @@ export default function WalletPage() {
<Layout> <Layout>
<div className="container px-4 py-5 max-w-lg mx-auto"> <div className="container px-4 py-5 max-w-lg mx-auto">
{/* Header */} <PageHeader title="Wallet" accent="#ff6600" subtitle="Bitcoin Lightning + Cashu" />
<div className="mb-4">
<h1 className="text-4xl md:text-5xl font-black uppercase leading-none mb-1">
<span className="neon-orange">WALLET</span>
</h1>
<p className="text-muted-foreground text-sm">Bitcoin Lightning + Cashu</p>
</div>
{user ? ( {user ? (
<div className="space-y-4"> <div className="space-y-4">