Fix navigation
This commit is contained in:
parent
72653a4ddf
commit
5f30928c64
3 changed files with 65 additions and 61 deletions
|
|
@ -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>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
27
frontend/src/components/ui/SubNav.tsx
Normal file
27
frontend/src/components/ui/SubNav.tsx
Normal 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>
|
||||
);
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue