Fix navigation

This commit is contained in:
Andras Schmelczer 2026-03-08 21:12:08 +00:00
parent 72653a4ddf
commit 5f30928c64
3 changed files with 65 additions and 61 deletions

View file

@ -11,10 +11,15 @@ import { ClipboardIcon } from '../ui/icons/ClipboardIcon';
import { BookmarkIcon } from '../ui/icons/BookmarkIcon';
import { TrashIcon } from '../ui/icons/TrashIcon';
import { CloseIcon } from '../ui/icons/CloseIcon';
import { TabButton } from '../ui/TabButton';
import { SubNav } from '../ui/SubNav';
type AccountTab = 'saved' | 'settings';
const ACCOUNT_TABS = [
{ key: 'saved', label: 'Saved Searches' },
{ key: 'settings', label: 'Settings' },
];
const SUBSCRIPTION_OPTIONS = ['free', 'licensed'] as const;
const SUBSCRIPTION_LABELS: Record<string, string> = {
@ -493,7 +498,8 @@ export default function AccountPage({
return () => window.removeEventListener('hashchange', handleHashChange);
}, []);
const switchTab = (tab: AccountTab) => {
const switchTab = (key: string) => {
const tab = key as AccountTab;
setActiveTab(tab);
window.history.replaceState(
window.history.state,
@ -503,39 +509,25 @@ export default function AccountPage({
};
return (
<div className="flex-1 overflow-y-auto bg-warm-50 dark:bg-warm-900">
<div className="max-w-5xl mx-auto px-6 py-8">
<h1 className="text-2xl font-bold text-navy-950 dark:text-warm-100 mb-6">Account</h1>
{/* Tabs */}
<div className="flex border-b border-warm-200 dark:border-warm-700 mb-6">
<TabButton
label="Saved Searches"
isActive={activeTab === 'saved'}
onClick={() => switchTab('saved')}
/>
<TabButton
label="Settings"
isActive={activeTab === 'settings'}
onClick={() => switchTab('settings')}
/>
<div className="flex-1 overflow-hidden bg-warm-50 dark:bg-warm-900 flex flex-col">
<SubNav tabs={ACCOUNT_TABS} activeTab={activeTab} onTabChange={switchTab} />
<div className="flex-1 overflow-y-auto">
<div className="max-w-5xl mx-auto px-6 py-6">
{activeTab === 'saved' ? (
<SavedSearchesContent
searches={searches}
loading={searchesLoading}
onDelete={onDeleteSearch}
onOpen={onOpenSearch}
/>
) : (
<SettingsContent
user={user}
onRefreshAuth={onRefreshAuth}
onRequestVerification={onRequestVerification}
/>
)}
</div>
{/* Tab content */}
{activeTab === 'saved' ? (
<SavedSearchesContent
searches={searches}
loading={searchesLoading}
onDelete={onDeleteSearch}
onOpen={onOpenSearch}
/>
) : (
<SettingsContent
user={user}
onRefreshAuth={onRefreshAuth}
onRequestVerification={onRequestVerification}
/>
)}
</div>
</div>
);

View file

@ -1,8 +1,15 @@
import { useEffect, useState, useRef } from 'react';
import { ChevronIcon } from '../ui/icons/ChevronIcon';
import { SubNav } from '../ui/SubNav';
type LearnTab = 'data-sources' | 'faq' | 'support';
const LEARN_TABS = [
{ key: 'faq', label: 'FAQ' },
{ key: 'data-sources', label: 'Data Sources' },
{ key: 'support', label: 'Support' },
];
const DATA_SOURCES = [
{
id: 'price-paid',
@ -288,36 +295,20 @@ export default function LearnPage() {
scrollContainerRef.current?.scrollTo(0, 0);
}, [tab]);
const tabClass = (t: LearnTab) =>
`px-4 py-2 text-sm font-medium rounded-t border-b-2 ${tab === t
? 'border-teal-500 text-teal-700 dark:text-teal-400'
: 'border-transparent text-warm-500 dark:text-warm-400 hover:text-warm-700 dark:hover:text-warm-300'
}`;
const switchTab = (key: string) => {
setTab(key as LearnTab);
setHighlightedId(null);
};
return (
<div className="flex-1 overflow-hidden bg-warm-50 dark:bg-navy-950 flex flex-col">
<div className="max-w-5xl mx-auto w-full px-6 pt-6">
<div className="flex gap-2 border-b border-warm-200 dark:border-warm-700">
<button className={tabClass('faq')} onClick={() => setTab('faq')}>
FAQ
</button>
<button className={tabClass('data-sources')} onClick={() => setTab('data-sources')}>
Data Sources
</button>
<button className={tabClass('support')} onClick={() => setTab('support')}>
Support
</button>
</div>
</div>
<SubNav tabs={LEARN_TABS} activeTab={tab} onTabChange={switchTab} />
<div className="flex-1 overflow-y-auto flex flex-col" ref={scrollContainerRef}>
{tab === 'data-sources' ? (
<>
<div className="flex-1">
<div className="max-w-5xl mx-auto px-6 py-6">
<h1 className="text-2xl font-bold text-warm-900 dark:text-warm-100 mb-2">
Data Sources
</h1>
<p className="text-warm-600 dark:text-warm-400 mb-6">
This application combines {DATA_SOURCES.length} open datasets covering property
prices, energy performance, transport, demographics, crime, environment, and more.
@ -423,9 +414,6 @@ export default function LearnPage() {
</>
) : tab === 'faq' ? (
<div className="max-w-3xl mx-auto px-6 py-6 w-full">
<h1 className="text-2xl font-bold text-warm-900 dark:text-warm-100 mb-2">
Frequently Asked Questions
</h1>
<p className="text-warm-600 dark:text-warm-400 mb-6">
Common questions about how Perfect Postcode works, where the data comes from, and how
to use the map.
@ -438,9 +426,6 @@ export default function LearnPage() {
</div>
) : (
<div className="max-w-2xl mx-auto px-6 py-6 w-full">
<h1 className="text-2xl font-bold text-warm-900 dark:text-warm-100 mb-2">
Support
</h1>
<p className="text-warm-600 dark:text-warm-400 mb-6">
Have a question? Check our FAQ or reach out to us directly.
</p>

View file

@ -0,0 +1,27 @@
interface SubNavProps {
tabs: { key: string; label: string }[];
activeTab: string;
onTabChange: (key: string) => void;
}
export function SubNav({ tabs, activeTab, onTabChange }: SubNavProps) {
return (
<div className="max-w-5xl mx-auto w-full px-6 pt-4">
<div className="flex gap-2 border-b border-warm-200 dark:border-warm-700">
{tabs.map((tab) => (
<button
key={tab.key}
className={`px-4 py-2 text-sm font-medium border-b-2 ${
activeTab === tab.key
? 'border-teal-500 text-teal-700 dark:text-teal-400'
: 'border-transparent text-warm-500 dark:text-warm-400 hover:text-warm-700 dark:hover:text-warm-300'
}`}
onClick={() => onTabChange(tab.key)}
>
{tab.label}
</button>
))}
</div>
</div>
);
}