feat: add PageMeta to 16 pages for SEO and proper browser tab titles

Public pages (Login, Register, Forgot/Reset Password, Verify Email,
Survey Thank You) get descriptions for SEO. Authenticated pages
(Dashboard, Flow Library, My Flows, Session History, AI Assistant,
Account Settings, Step Library, My Shares, Feedback, Guides) get
proper tab titles.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Michael Chihlas
2026-03-08 01:49:52 -05:00
parent f3fbc5142c
commit 337d933fe2
16 changed files with 64 additions and 0 deletions

View File

@@ -1,6 +1,7 @@
import { useEffect, useState } from 'react'
import { Link } from 'react-router-dom'
import { Building2, Users, Mail, Crown, Loader2, AlertCircle, Check, X, Settings, FolderTree, Server, RefreshCw, MessageSquareText, UserCog, AlertTriangle, Clock } from 'lucide-react'
import { PageMeta } from '@/components/common/PageMeta'
import { accountsApi } from '@/api/accounts'
import type { Account, AccountMember, AccountInvite } from '@/types'
import { TransferOwnershipModal } from '@/components/account/TransferOwnershipModal'
@@ -159,6 +160,8 @@ export function AccountSettingsPage() {
const sub = subscription?.subscription
return (
<>
<PageMeta title="Account Settings" />
<div>
<div className="mb-8">
<div className="flex items-center gap-3">
@@ -678,6 +681,7 @@ export function AccountSettingsPage() {
<DeleteAccountModal onClose={() => setShowDeleteModal(false)} />
)}
</div>
</>
)
}

View File

@@ -1,5 +1,6 @@
import { useState, useEffect, useRef, useCallback } from 'react'
import { Sparkles, Send, Loader2, Flag } from 'lucide-react'
import { PageMeta } from '@/components/common/PageMeta'
import { assistantChatApi } from '@/api/assistantChat'
import { toast } from '@/lib/toast'
import { ChatSidebar } from '@/components/assistant/ChatSidebar'
@@ -179,6 +180,8 @@ export default function AssistantChatPage() {
}
return (
<>
<PageMeta title="AI Assistant" />
<div className="flex h-[calc(100vh-3.5rem)]">
{/* Sidebar */}
<ChatSidebar
@@ -303,5 +306,6 @@ export default function AssistantChatPage() {
chatTitle={chats.find(c => c.id === activeChatId)?.title ?? 'Chat'}
/>
</div>
</>
)
}

View File

@@ -1,5 +1,6 @@
import { useState, useRef, useEffect } from 'react'
import { MessageSquareText, Send, CheckCircle2, ChevronDown } from 'lucide-react'
import { PageMeta } from '@/components/common/PageMeta'
import { useAuthStore } from '@/store/authStore'
import { feedbackApi } from '@/api'
import { cn } from '@/lib/utils'
@@ -130,6 +131,8 @@ export function FeedbackPage() {
}
return (
<>
<PageMeta title="Feedback" />
<div className="container mx-auto px-4 py-6 sm:px-6 sm:py-8">
{/* Page header */}
<div className="mb-8">
@@ -273,6 +276,7 @@ export function FeedbackPage() {
)}
</div>
</div>
</>
)
}

View File

@@ -2,6 +2,7 @@ import { useState } from 'react'
import { Link } from 'react-router-dom'
import { authApi } from '@/api/auth'
import { BrandLogo } from '@/components/common/BrandLogo'
import { PageMeta } from '@/components/common/PageMeta'
import { cn } from '@/lib/utils'
export function ForgotPasswordPage() {
@@ -25,6 +26,8 @@ export function ForgotPasswordPage() {
}
return (
<>
<PageMeta title="Forgot Password" description="Reset your ResolutionFlow password" />
<div className="flex min-h-screen items-center justify-center bg-card px-4">
<div className="pointer-events-none fixed inset-0 bg-[radial-gradient(circle_at_50%_0%,rgba(100,100,120,0.03),transparent_50%)]" />
@@ -109,6 +112,7 @@ export function ForgotPasswordPage() {
)}
</div>
</div>
</>
)
}

View File

@@ -1,9 +1,12 @@
import { BookOpen } from 'lucide-react'
import { PageMeta } from '@/components/common/PageMeta'
import { guides } from '@/data/guides'
import { GuideCard } from '@/components/guides/GuideCard'
export default function GuidesHubPage() {
return (
<>
<PageMeta title="Guides" />
<div className="p-6 max-w-5xl mx-auto">
{/* Header */}
<div className="mb-8">
@@ -25,5 +28,6 @@ export default function GuidesHubPage() {
))}
</div>
</div>
</>
)
}

View File

@@ -3,6 +3,7 @@ import { Link, useNavigate, useLocation } from 'react-router-dom'
import { useAuthStore } from '@/store/authStore'
import { BrandLogo } from '@/components/common/BrandLogo'
import { PasswordInput } from '@/components/common/PasswordInput'
import { PageMeta } from '@/components/common/PageMeta'
import { cn } from '@/lib/utils'
export function LoginPage() {
@@ -40,6 +41,8 @@ export function LoginPage() {
}
return (
<>
<PageMeta title="Sign In" description="Sign in to your ResolutionFlow account" />
<div className="flex min-h-screen items-center justify-center bg-background px-4">
{/* Atmosphere orbs */}
<div
@@ -164,6 +167,7 @@ export function LoginPage() {
</form>
</div>
</div>
</>
)
}

View File

@@ -1,6 +1,7 @@
import { useState, useEffect, useCallback } from 'react'
import { Link, useNavigate } from 'react-router-dom'
import { Globe, Users, Copy, Check, Link2, ExternalLink, Trash2, ArrowLeft } from 'lucide-react'
import { PageMeta } from '@/components/common/PageMeta'
import { Button } from '@/components/ui/Button'
import { Spinner } from '@/components/common/Spinner'
import { EmptyState } from '@/components/common/EmptyState'
@@ -121,6 +122,8 @@ export default function MySharesPage() {
}
return (
<>
<PageMeta title="My Shares" />
<div className="container mx-auto px-4 py-6 sm:px-6 sm:py-8">
{/* Back link */}
<Link
@@ -241,5 +244,6 @@ export default function MySharesPage() {
confirmLabel="Revoke"
/>
</div>
</>
)
}

View File

@@ -1,6 +1,7 @@
import { useEffect, useState } from 'react'
import { useNavigate, Link } from 'react-router-dom'
import { Play, Pencil, Share2, Trash2, GitBranch, Clock, TrendingUp, FolderTree, Plus, ListOrdered, ChevronDown, Wrench } from 'lucide-react'
import { PageMeta } from '@/components/common/PageMeta'
import { Button } from '@/components/ui/Button'
import { treesApi } from '@/api/trees'
import { sessionsApi } from '@/api/sessions'
@@ -116,6 +117,8 @@ export function MyTreesPage() {
}
return (
<>
<PageMeta title="My Flows" />
<div className="container mx-auto px-4 py-6 sm:px-6 sm:py-8">
<div className="mb-6 flex items-center justify-between sm:mb-8">
<div>
@@ -389,6 +392,7 @@ export function MyTreesPage() {
)}
</div>
</>
)
}

View File

@@ -1,6 +1,7 @@
import { useState, useEffect, useRef, useMemo, useCallback } from 'react'
import { useNavigate } from 'react-router-dom'
import { Search, Loader2, Star, ChevronLeft, ChevronRight, GitBranch } from 'lucide-react'
import { PageMeta } from '@/components/common/PageMeta'
import { treesApi } from '@/api/trees'
import { sessionsApi } from '@/api/sessions'
import type { TreeListItem, TreeFilters } from '@/types'
@@ -277,6 +278,8 @@ export function QuickStartPage() {
]
return (
<>
<PageMeta title="Dashboard" />
<div className="p-6 space-y-6">
{/* Greeting */}
<div className="fade-in" style={{ animationDelay: '100ms' }}>
@@ -646,6 +649,7 @@ export function QuickStartPage() {
)}
</div>
</>
)
}

View File

@@ -4,6 +4,7 @@ import { useAuthStore } from '@/store/authStore'
import { inviteApi } from '@/api/invite'
import { BrandLogo } from '@/components/common/BrandLogo'
import { PasswordInput } from '@/components/common/PasswordInput'
import { PageMeta } from '@/components/common/PageMeta'
import { cn } from '@/lib/utils'
export function RegisterPage() {
@@ -76,6 +77,8 @@ export function RegisterPage() {
}
return (
<>
<PageMeta title="Create Account" description="Create your ResolutionFlow account to start building guided troubleshooting flows" />
<div className="flex min-h-screen items-center justify-center bg-black px-4">
{/* Subtle radial overlay */}
<div className="pointer-events-none fixed inset-0 bg-[radial-gradient(circle_at_50%_0%,rgba(100,100,120,0.03),transparent_50%)]" />
@@ -251,6 +254,7 @@ export function RegisterPage() {
</form>
</div>
</div>
</>
)
}

View File

@@ -4,6 +4,7 @@ import { authApi } from '@/api/auth'
import { toast } from '@/lib/toast'
import { BrandLogo } from '@/components/common/BrandLogo'
import { PasswordInput } from '@/components/common/PasswordInput'
import { PageMeta } from '@/components/common/PageMeta'
import { cn } from '@/lib/utils'
export function ResetPasswordPage() {
@@ -72,6 +73,8 @@ export function ResetPasswordPage() {
}
return (
<>
<PageMeta title="Reset Password" description="Set a new password for your ResolutionFlow account" />
<div className="flex min-h-screen items-center justify-center bg-black px-4">
<div className="pointer-events-none fixed inset-0 bg-[radial-gradient(circle_at_50%_0%,rgba(100,100,120,0.03),transparent_50%)]" />
@@ -180,6 +183,7 @@ export function ResetPasswordPage() {
)}
</div>
</div>
</>
)
}

View File

@@ -1,5 +1,6 @@
import { useEffect, useState } from 'react'
import { useNavigate, useSearchParams } from 'react-router-dom'
import { PageMeta } from '@/components/common/PageMeta'
import { sessionsApi } from '@/api/sessions'
import { treesApi } from '@/api/trees'
import type { Session, TreeListItem } from '@/types'
@@ -154,6 +155,8 @@ export function SessionHistoryPage() {
}
return (
<>
<PageMeta title="Session History" />
<div className="container mx-auto px-4 py-6 sm:px-6 sm:py-8">
<div className="mb-8">
<h1 className="text-2xl font-heading font-bold text-foreground sm:text-3xl">Session History</h1>
@@ -310,6 +313,7 @@ export function SessionHistoryPage() {
</div>
)}
</div>
</>
)
}

View File

@@ -1,5 +1,6 @@
import { useState } from 'react'
import { Bookmark, Trash2 } from 'lucide-react'
import { PageMeta } from '@/components/common/PageMeta'
import { Button } from '@/components/ui/Button'
import { useAuthStore } from '@/store/authStore'
import { usePermissions } from '@/hooks/usePermissions'
@@ -87,6 +88,8 @@ export default function StepLibraryPage() {
}
return (
<>
<PageMeta title="Step Library" />
<div className="flex h-full flex-col">
{/* Page Header */}
<div className="flex items-center justify-between border-b border-border px-6 py-4">
@@ -167,5 +170,6 @@ export default function StepLibraryPage() {
)}
</div>
</>
)
}

View File

@@ -1,7 +1,10 @@
import { BrandLogo } from '@/components/common/BrandLogo'
import { PageMeta } from '@/components/common/PageMeta'
export default function SurveyThankYouPage() {
return (
<>
<PageMeta title="Thank You" description="Thank you for your feedback on ResolutionFlow" />
<div className="min-h-screen bg-background text-foreground">
{/* Atmosphere orbs */}
<div className="pointer-events-none fixed inset-0 z-0 overflow-hidden" aria-hidden="true">
@@ -72,5 +75,6 @@ export default function SurveyThankYouPage() {
</div>
</div>
</div>
</>
)
}

View File

@@ -1,6 +1,7 @@
import { useEffect, useState, useCallback, useMemo } from 'react'
import { useNavigate, useSearchParams } from 'react-router-dom'
import { X, RotateCcw, Play, FileUp } from 'lucide-react'
import { PageMeta } from '@/components/common/PageMeta'
import { Button } from '@/components/ui/Button'
import { treesApi } from '@/api/trees'
import { categoriesApi } from '@/api/categories'
@@ -265,6 +266,8 @@ export function TreeLibraryPage() {
selectedCategoryId || selectedTags.length > 0 || searchQuery || selectedFolderId
return (
<>
<PageMeta title="Flow Library" />
<div className="min-h-full">
<div className="container mx-auto px-4 py-6 sm:px-6 sm:py-8">
<div className="mb-6 flex flex-col gap-4 sm:mb-8 sm:flex-row sm:items-start sm:justify-between">
@@ -596,6 +599,7 @@ export function TreeLibraryPage() {
/>
)}
</div>
</>
)
}

View File

@@ -2,6 +2,7 @@ import { useEffect, useState } from 'react'
import { useSearchParams, Link } from 'react-router-dom'
import { CheckCircle2, XCircle, Loader2 } from 'lucide-react'
import { authApi } from '@/api/auth'
import { PageMeta } from '@/components/common/PageMeta'
import { cn } from '@/lib/utils'
export function VerifyEmailPage() {
@@ -23,6 +24,8 @@ export function VerifyEmailPage() {
}, [token])
return (
<>
<PageMeta title="Verify Email" description="Verify your ResolutionFlow email address" />
<div className="flex min-h-screen items-center justify-center bg-background p-4">
<div className="glass-card-static w-full max-w-md p-8 text-center">
{status === 'loading' && (
@@ -65,6 +68,7 @@ export function VerifyEmailPage() {
)}
</div>
</div>
</>
)
}