Unify empty state
This commit is contained in:
parent
5f060d2994
commit
4e3fcd7252
4 changed files with 34 additions and 21 deletions
|
|
@ -12,7 +12,7 @@ import ExternalSearchLinks from './ExternalSearchLinks';
|
||||||
import { InfoIcon, CloseIcon } from './ui/Icons';
|
import { InfoIcon, CloseIcon } from './ui/Icons';
|
||||||
import { IconButton } from './ui/IconButton';
|
import { IconButton } from './ui/IconButton';
|
||||||
import { FeatureInfoPopup } from './FeatureInfoPopup';
|
import { FeatureInfoPopup } from './FeatureInfoPopup';
|
||||||
import { PaneEmptyState } from './ui/EmptyState';
|
import { EmptyState } from './ui/EmptyState';
|
||||||
|
|
||||||
interface AreaPaneProps {
|
interface AreaPaneProps {
|
||||||
stats: HexagonStatsResponse | null;
|
stats: HexagonStatsResponse | null;
|
||||||
|
|
@ -62,7 +62,14 @@ export default function AreaPane({
|
||||||
);
|
);
|
||||||
|
|
||||||
if (!hexagonId) {
|
if (!hexagonId) {
|
||||||
return <PaneEmptyState message="Click a hexagon or postcode to view area statistics" />;
|
return (
|
||||||
|
<EmptyState
|
||||||
|
icon={<InfoIcon className="w-8 h-8 text-warm-300 dark:text-warm-600" />}
|
||||||
|
title="No area selected"
|
||||||
|
description="Click a hexagon or postcode to view area statistics"
|
||||||
|
centered
|
||||||
|
/>
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
|
||||||
|
|
@ -113,7 +113,9 @@ function FeatureBrowser({
|
||||||
))}
|
))}
|
||||||
{grouped.length === 0 && (
|
{grouped.length === 0 && (
|
||||||
<EmptyState
|
<EmptyState
|
||||||
|
icon={<FilterIcon className="w-8 h-8 text-warm-300 dark:text-warm-600" />}
|
||||||
title={search ? 'No matching features' : 'All features are active'}
|
title={search ? 'No matching features' : 'All features are active'}
|
||||||
|
description={search ? 'Try a different search term' : 'Remove a filter to see available features'}
|
||||||
className="px-3 py-4"
|
className="px-3 py-4"
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,8 @@ import { getNum } from '../lib/property-fields';
|
||||||
import InfoPopup from './InfoPopup';
|
import InfoPopup from './InfoPopup';
|
||||||
import { SearchInput } from './ui/SearchInput';
|
import { SearchInput } from './ui/SearchInput';
|
||||||
import { PaneHeader } from './ui/PaneHeader';
|
import { PaneHeader } from './ui/PaneHeader';
|
||||||
import { PaneEmptyState } from './ui/EmptyState';
|
import { EmptyState } from './ui/EmptyState';
|
||||||
|
import { InfoIcon } from './ui/Icons';
|
||||||
|
|
||||||
interface PropertiesPaneProps {
|
interface PropertiesPaneProps {
|
||||||
properties: Property[];
|
properties: Property[];
|
||||||
|
|
@ -54,7 +55,14 @@ export function PropertiesPane({
|
||||||
}, [properties, sortBy, search]);
|
}, [properties, sortBy, search]);
|
||||||
|
|
||||||
if (!hexagonId) {
|
if (!hexagonId) {
|
||||||
return <PaneEmptyState message="Click a hexagon to view properties" />;
|
return (
|
||||||
|
<EmptyState
|
||||||
|
icon={<InfoIcon className="w-8 h-8 text-warm-300 dark:text-warm-600" />}
|
||||||
|
title="No area selected"
|
||||||
|
description="Click a hexagon or postcode to view area statistics"
|
||||||
|
centered
|
||||||
|
/>
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
|
||||||
|
|
@ -1,31 +1,27 @@
|
||||||
import type { ReactNode } from 'react';
|
import type { ReactNode } from 'react';
|
||||||
|
|
||||||
interface EmptyStateProps {
|
interface EmptyStateProps {
|
||||||
icon?: ReactNode;
|
icon: ReactNode;
|
||||||
title: string;
|
title: string;
|
||||||
description?: string;
|
description: string;
|
||||||
|
centered?: boolean;
|
||||||
className?: string;
|
className?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function EmptyState({ icon, title, description, className = '' }: EmptyStateProps) {
|
export function EmptyState({
|
||||||
|
icon,
|
||||||
|
title,
|
||||||
|
description,
|
||||||
|
centered = false,
|
||||||
|
className = '',
|
||||||
|
}: EmptyStateProps) {
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className={`flex flex-col items-center justify-center py-8 text-center ${className}`}
|
className={`flex flex-col items-center justify-center text-center ${centered ? 'h-full px-4' : 'py-8'} ${className}`}
|
||||||
>
|
>
|
||||||
{icon && <div className="mb-2">{icon}</div>}
|
<div className="mb-2">{icon}</div>
|
||||||
<span className="text-sm font-medium text-warm-400 dark:text-warm-500">{title}</span>
|
<span className="text-sm font-medium text-warm-400 dark:text-warm-500">{title}</span>
|
||||||
{description && (
|
<span className="text-xs text-warm-400 dark:text-warm-500 mt-1">{description}</span>
|
||||||
<span className="text-xs text-warm-400 dark:text-warm-500 mt-1">{description}</span>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Centered message variant for panes
|
|
||||||
export function PaneEmptyState({ message }: { message: string }) {
|
|
||||||
return (
|
|
||||||
<div className="flex items-center justify-center h-full text-warm-500 dark:text-warm-400 px-4 text-center text-sm">
|
|
||||||
{message}
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue