fix(layout): mobile UX cleanup + interest-stage legend popover

Mobile UX:
- Hide ColumnPicker on `< sm` viewports (cards, no columns to toggle).
- Hide kanban toggle in interest list on mobile and snap viewMode back
  to 'table' if the persisted choice was 'board'.
- Drop dead "Inbox" link from the More-sheet (email/IMAP feature is
  deferred per sidebar.tsx note).
- Repoint Notifications nav from `/notifications` (no page.tsx — 404)
  to `/notifications/preferences` and re-label as "Notification
  preferences" (the bell stays the surface for actual notifications).
- Hide Website Analytics on both desktop sidebar and mobile More-sheet
  when Umami isn't configured for the port (`useUmamiActive()`).

Interests:
- New `<StageLegend>` popover button in the filter row decodes the
  card stripe colours to pipeline stage names, kept in sync with
  `STAGE_DOT` automatically.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-05-09 04:11:01 +02:00
parent 82fd75081a
commit 19622985b5
5 changed files with 99 additions and 9 deletions

View File

@@ -11,7 +11,6 @@ import {
Building2,
Globe,
Home,
Mail,
Receipt,
Settings,
Shield,
@@ -26,6 +25,7 @@ import {
DrawerTitle,
DrawerClose,
} from '@/components/shared/drawer';
import { useUmamiActive } from '@/components/website-analytics/use-website-analytics';
type MoreItem = {
label: string;
@@ -38,14 +38,21 @@ type MoreItem = {
// reps reach the active deals via the Interests tab on a client detail
// (or via the new bottom-sheet drawer). Yachts is asset-record traffic
// best reached contextually from inside an interest or client.
//
// Inbox is intentionally absent — the email/threading inbox feature was
// deferred (see sidebar.tsx). Re-add this entry once IMAP/SMTP wiring
// + Google OAuth review are done. Website analytics is filtered below
// when Umami isn't configured for this port.
const MORE_ITEMS: MoreItem[] = [
{ label: 'Interests', icon: Bookmark, segment: 'interests' },
{ label: 'Yachts', icon: Ship, segment: 'yachts' },
{ label: 'Companies', icon: Building2, segment: 'companies' },
{ label: 'Expenses', icon: Receipt, segment: 'expenses' },
{ label: 'Inbox', icon: Mail, segment: 'email' },
{ label: 'Reservations', icon: Anchor, segment: 'berth-reservations' },
{ label: 'Notifications', icon: BellRing, segment: 'notifications' },
// Notifications themselves live on the topbar bell — this entry deep-links
// to the per-channel preferences page. Pointing at the bare `/notifications`
// segment 404s today (no page.tsx, only `/preferences`).
{ label: 'Notification preferences', icon: BellRing, segment: 'notifications/preferences' },
{ label: 'Residential', icon: Home, segment: 'residential/clients' },
{ label: 'Website analytics', icon: Globe, segment: 'website-analytics' },
{ label: 'Alerts', icon: ShieldAlert, segment: 'alerts' },
@@ -65,6 +72,14 @@ export function MoreSheet({
const pathname = usePathname();
const portSlug = pathname.split('/').filter(Boolean)[0] ?? 'port-nimara';
// Hide "Website analytics" if Umami isn't wired up for this port — the
// dedicated tile on the dashboard already does the same.
const umami = useUmamiActive('today');
const umamiConfigured = umami.data?.error !== 'umami_not_configured';
const items = MORE_ITEMS.filter(
(item) => item.segment !== 'website-analytics' || umamiConfigured,
);
return (
<Drawer open={open} onOpenChange={onOpenChange}>
<DrawerContent>
@@ -72,7 +87,7 @@ export function MoreSheet({
<DrawerTitle>More</DrawerTitle>
</DrawerHeader>
<ul className="grid grid-cols-3 gap-2 px-3 pb-4">
{MORE_ITEMS.map((item) => {
{items.map((item) => {
const Icon = item.icon;
return (
<li key={item.segment}>