diff --git a/src/components/NotificationBell.tsx b/src/components/NotificationBell.tsx
index 45bf115..3fb435a 100644
--- a/src/components/NotificationBell.tsx
+++ b/src/components/NotificationBell.tsx
@@ -12,6 +12,7 @@ import { JoinRequestCard } from '@/components/JoinRequestCard';
import { CollectiveJoinRequestCard } from '@/components/CollectiveJoinRequestCard';
import { ActivityNotificationCard } from '@/components/ActivityNotificationCard';
import { ImageWithFallback } from '@/components/ImageWithFallback';
+import { EmptyState as SharedEmptyState } from '@/components/EmptyState';
import { useCrewNotifications, useIsPendingMember } from '@/hooks/useCrewNotifications';
import { useActivityNotifications } from '@/hooks/useActivityNotifications';
import { useNotificationsRead } from '@/hooks/useNotificationsRead';
@@ -180,13 +181,12 @@ function NewsletterItem({
function EmptyState({ label }: { label: string }) {
return (
-
-
-
-
-
You're all caught up
-
{label}
-
+
);
}
diff --git a/src/pages/AmberCallbackPage.tsx b/src/pages/AmberCallbackPage.tsx
index 6c2fa9f..a41b488 100644
--- a/src/pages/AmberCallbackPage.tsx
+++ b/src/pages/AmberCallbackPage.tsx
@@ -11,6 +11,7 @@
import { useEffect, useRef, useState } from 'react';
import { useNavigate, Link } from 'react-router-dom';
+import { useSeoMeta } from '@unhead/react';
import { useLoginActions } from '@/hooks/useLoginActions';
import { useToast } from '@/hooks/useToast';
import {
@@ -34,6 +35,11 @@ export default function AmberCallbackPage() {
const [status, setStatus] = useState('processing');
const [message, setMessage] = useState('Completing login with Amber...');
+ useSeoMeta({
+ title: 'Signing in with Amber - SkateSpots',
+ description: 'Completing your Amber (NIP-55) login.',
+ });
+
useEffect(() => {
if (hasProcessed.current) return;
hasProcessed.current = true;
diff --git a/src/pages/EditTourPage.tsx b/src/pages/EditTourPage.tsx
index 29fba52..0978b70 100644
--- a/src/pages/EditTourPage.tsx
+++ b/src/pages/EditTourPage.tsx
@@ -1,4 +1,5 @@
import { useParams } from 'react-router-dom';
+import { useSeoMeta } from '@unhead/react';
import { Layout } from '@/components/Layout';
import { Card, CardContent } from '@/components/ui/card';
import { Skeleton } from '@/components/ui/skeleton';
@@ -20,6 +21,11 @@ export default function EditTourPage() {
const { user } = useCurrentUser();
const { data: tour, isLoading, error } = useTour(identifier || '', pubkey);
+ useSeoMeta({
+ title: tour?.title ? `Edit ${tour.title} - SkateSpots` : 'Edit Tour - SkateSpots',
+ description: 'Edit your skate tour — update stops, dates and details.',
+ });
+
if (isLoading) {
return (
diff --git a/src/pages/LabPage.tsx b/src/pages/LabPage.tsx
index e19740e..2bfb28e 100644
--- a/src/pages/LabPage.tsx
+++ b/src/pages/LabPage.tsx
@@ -71,7 +71,7 @@ import {
PersonStanding,
ArrowRight,
} from 'lucide-react';
-import { cn } from '@/lib/utils';
+import { EmptyState as SharedEmptyState } from '@/components/EmptyState';
import { Avatar, AvatarImage, AvatarFallback } from '@/components/ui/avatar';
import { ProBadge } from '@/components/ProBadge';
import { LabCrewsStrip } from '@/components/LabCrewsStrip';
@@ -1096,28 +1096,29 @@ function EmptyState({ serviceType, user }: { serviceType: ServiceType; user: boo
const Icon = c.icon;
return (
-
-
-
-
-
{c.title}
-
{c.body}
- {user ? (
-
-
-
- ) : (
-
- Log in to create a profile
-
- )}
-
- Have questions? Check the FAQ →
-
-
+
+ {c.body}{' '}
+
+ Log in
+ {' '}
+ to create a profile.
+ >
+ )
+ }
+ actions={
+ user
+ ? [{ label: c.cta, to: c.to, icon: Plus, className: c.color }]
+ : []
+ }
+ footer={{ label: 'Have questions? Check the FAQ →', to: '/faq' }}
+ />
);
}
diff --git a/src/pages/NIP19Page.tsx b/src/pages/NIP19Page.tsx
index 2c064c0..62defdd 100644
--- a/src/pages/NIP19Page.tsx
+++ b/src/pages/NIP19Page.tsx
@@ -1,5 +1,6 @@
import { nip19 } from 'nostr-tools';
import { useParams, Link } from 'react-router-dom';
+import { useSeoMeta } from '@unhead/react';
import { Layout } from '@/components/Layout';
import { ImageWithFallback } from '@/components/ImageWithFallback';
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
@@ -164,6 +165,11 @@ function ProfilePage({ pubkey }: { pubkey: string }) {
const npub = nip19.npubEncode(pubkey);
const isOwnProfile = user?.pubkey === pubkey;
+ useSeoMeta({
+ title: `${displayName} - SkateSpots`,
+ description: about ? about.slice(0, 160) : `${displayName}'s profile on SkateSpots.`,
+ });
+
// At-a-glance skater stats for the summary strip.
const { data: riderStats } = useRiderStats(pubkey);
const memberSince = profileEventCreatedAt(author.data?.event?.created_at);