Files
pn-new-crm/13-UI-PAGE-MAP.md
Matt 67d7e6e3d5
Some checks failed
Build & Push Docker Images / build-and-push (push) Has been cancelled
Build & Push Docker Images / deploy (push) Has been cancelled
Build & Push Docker Images / lint (push) Has been cancelled
Initial commit: Port Nimara CRM (Layers 0-4)
Full CRM rebuild with Next.js 15, TypeScript, Tailwind, Drizzle ORM,
PostgreSQL, Redis, BullMQ, MinIO, and Socket.io. Includes 461 source
files covering clients, berths, interests/pipeline, documents/EOI,
expenses/invoices, email, notifications, dashboard, admin, and
client portal. CI/CD via Gitea Actions with Docker builds.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 11:52:51 +01:00

763 lines
54 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Port Nimara CRM — UI Page Map & Navigation Structure
**Compiled:** 2026-03-11
**Framework:** Next.js 15 App Router
**Component Library:** shadcn/ui + Tailwind CSS
**Routing:** File-based via `src/app/` directory
---
## Navigation Architecture
### Global Shell (persistent on all authenticated pages)
```
┌─────────────────────────────────────────────────────────────┐
│ [Logo/Port Name] [Port Switcher ▾] [⌘K Search] [🔔 3] [👤 Matt ▾] │
├──────────┬──────────────────────────────────────────────────┤
│ Sidebar │ │
│ │ Page Content │
│ Dashboard│ │
│ Clients │ │
│ Interests│ │
│ Berths │ │
│ Expenses │ │
│ Invoices │ │
│ Files │ │
│ Email │ │
│ Reminders│ │
│ ──────── │ │
│ Admin ▾ │ │
│ │ │
│ [Collapse│ │
│ Toggle] │ │
└──────────┴──────────────────────────────────────────────────┘
```
**Top bar components:**
- Port name + logo (from port settings branding)
- Port switcher dropdown (hidden entirely in single-port mode; visible only when 2+ active ports exist and user has access to multiple ports)
- Global search trigger (Cmd+K / Ctrl+K → modal)
- Notification bell with unread count badge → dropdown panel
- User avatar + name → dropdown: Profile, Dark Mode toggle, Scratchpad, Logout
**Sidebar:**
- Collapsible (persisted in user prefs via Zustand)
- Collapsed state shows icons only with tooltips
- Active page highlighted
- Admin section expandable submenu (only visible to users with any admin permission)
- Mobile: hamburger icon → slide-out drawer
---
## Route Map
### Auth Pages (unauthenticated — no shell)
| Route | Page | Description |
| ---------------------- | -------------- | ---------------------------------------------------------------------------------------------------- |
| `/login` | Login | Email + password form, "Forgot password?" link, CRM-styled (maritime branding, port logo) |
| `/auth/set-password` | Set Password | Token-validated form: new password + confirm. Used for first-time login after admin creates account. |
| `/auth/reset-password` | Reset Password | Token-validated form: new password + confirm. Used from "forgot password" email link. |
**Layout:** Centered card on full-screen branded background. No sidebar, no top bar.
---
### User Settings (accessible from user avatar menu)
| Route | Page | Description |
| ------------------------- | ------------------------ | --------------------------------------------------- |
| `/settings/profile` | My Profile | Edit own name, avatar, timezone, preferred language |
| `/settings/notifications` | Notification Preferences | Per-notification-type delivery channel toggles |
#### `/settings/notifications` — Notification Preferences
- **Table:** Notification type (rows) × delivery channel (columns: In-App, Email)
- **Notification types:** Reminder due, reminder overdue, new website registration, EOI signature event, new email received, duplicate client alert, invoice overdue, waiting list notification, system alert, follow-up auto-created, tenure expiring
- **Per-type toggles:** In-app (always on, read-only), Email (toggle on/off)
- **Save button** applies changes
---
### Dashboard
| Route | Page | Description |
| ----- | --------- | ---------------------------------- |
| `/` | Dashboard | Home screen — port-scoped overview |
**Page contents:**
- **Pipeline funnel widget** — interest count and weighted value per pipeline stage (bar or funnel chart). Click a stage → navigates to `/interests?stage={stage}`
- **Berth occupancy widget** — available / under offer / sold breakdown (donut chart). Click a status → navigates to `/berths?status={status}`
- **Revenue forecast widget** — weighted pipeline value with best/likely/worst scenarios, trend line over time
- **Expense summary widget** — month-over-month spend by category (bar chart)
- **Recent activity feed** — last 10 actions across all entities (from audit log). Each entry links to the relevant record.
- **Upcoming reminders & events** — unified list of next 5 CRM reminders + upcoming Google Calendar events (next 7 days). CRM reminders show linked entity; Calendar events show a Google Calendar badge. Link to `/reminders` for full view.
- **Overdue items panel** — unsigned EOIs, overdue invoices, overdue reminders, expiring tenures. Each item links to its record.
- **Timeline strip** — upcoming key dates: reminder due dates, tenure expirations, invoice due dates, Google Calendar events (horizontal scrollable timeline at top or bottom)
**Permission:** `reports.view_dashboard` (all roles by default)
---
### Client Management
| Route | Page | Description |
| -------------------- | ------------- | --------------------------------------------------- |
| `/clients` | Client List | Paginated table of all clients |
| `/clients/new` | Create Client | New client form |
| `/clients/[id]` | Client Detail | Full client record with tabbed sections |
| `/clients/[id]/edit` | Edit Client | Edit client fields (could also be inline on detail) |
#### `/clients` — Client List
- **Table columns:** Name, company, nationality, source, tags, # interests, last activity, created date
- **Filters:** Search (name/email/phone), nationality, source, tags, archived (toggle), date range
- **Sort:** Name, created date, last activity
- **Saved views:** Dropdown of saved filter configurations, "Save current view" button, "Manage Views" link → modal: rename, delete, share/unshare saved views
- **Bulk actions toolbar** (appears when rows selected): Bulk tag, bulk export (CSV/PDF), bulk archive
- **Actions per row:** View, Edit, Archive
- **"+ New Client" button** → `/clients/new`
#### `/clients/new` — Create Client
- **Sections:**
- Basic info: Full name, company/entity (optional), nationality
- Contact info: Add multiple contacts (channel + value + label), at least one required
- Vessel details: Yacht name, length, width, draft (dual unit input), berth size desired
- Proxy/representative: Toggle, proxy type, actual owner name, relationship notes
- Communication preferences: Preferred method, language, timezone
- Source: Website / manual / referral / broker (+ referrer link)
- Tags: Tag selector (multi-select from existing tags or create new)
- **On submit:** Duplicate detection runs (same email → auto-merge, fuzzy match → alert modal)
- **Cancel** → back to `/clients`
#### `/clients/[id]` — Client Detail
- **Header area:** Client name, company, tags, status badges, quick actions (Edit, Archive, Export PDF, Merge)
- **Tabs:**
| Tab | Contents |
| ----------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Overview** | Core fields (name, company, nationality, vessel, proxy info, communication prefs, source), contact cards |
| **Relationships** | Visual/list view of related clients. Relationship types: referred by, broker for, family member, same vessel, custom. Add/remove relationships. Shows referral networks and broker portfolios. |
| **Interests** | List of all interests for this client. Single interest → inline expanded. Multiple → accordion or sub-table. Each links to `/interests/[id]`. "+ New Interest" button. |
| **Activity** | Chronological timeline feed (from audit log). Filterable by event type. |
| **Notes** | Timestamped notes thread. New note input with @mention support. Edit (within 15 min) / locked indicator. |
| **Files** | Client-scoped file browser (MinIO). Upload button, folder tree, file cards with preview/download. |
| **Emails** | Email threads linked to this client (from IMAP sync). Compose new button. |
| **Documents** | EOIs, contracts, NDAs linked through interests. Status indicators (pending, signed, completed). |
| **Invoices** | Invoices billed to this client. Status badges. Link to invoice detail. |
| **Audit Trail** | Raw audit log entries for this client and all related entities. Filterable by action type, date range. |
---
### Interest Management
| Route | Page | Description |
| ----------------- | --------------- | ------------------------------------------------- |
| `/interests` | Interest List | Table + pipeline (Kanban) views |
| `/interests/new` | Create Interest | New interest form (often initiated from a client) |
| `/interests/[id]` | Interest Detail | Full interest record |
#### `/interests` — Interest List
- **View toggle:** Table view ↔ Pipeline (Kanban) view
- **Table view:**
- Columns: Client name, berth (if linked), pipeline stage, lead category, EOI status, last activity, date created
- Filters: Stage, berth, client, lead category, source, tags, date range, assigned salesperson
- Sort: Date created, last activity, stage, client name
- **Pipeline (Kanban) view:**
- 8 columns (one per pipeline stage): Open → Details Sent → In Communication → Visited → Signed EOI and NDA → 10% Deposit → Contract → Completed
- Cards show: client name, berth, days in stage, next action indicator
- Drag-and-drop between stages (confirmation dialog for significant changes)
- Filters same as table view (applied to both views)
- **Saved views, bulk actions** same pattern as clients
#### `/interests/new` — Create Interest
- **Fields:**
- Client selector (search/select existing or "+ New Client" inline)
- Berth link (optional — search/select berth)
- Initial pipeline stage (default: Open)
- Lead category
- Source
- Notes (initial note)
- Tags
#### `/interests/[id]` — Interest Detail
- **Header:** Client name → link to client, berth → link to berth (if linked), pipeline stage badge (with manual override dropdown), lead category, EOI status badge
- **Quick actions:** Generate EOI, Link Berth, Change Stage, Export PDF, Archive
- **Sections / Tabs:**
| Tab | Contents |
| ------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| **Overview** | Pipeline stage (with stage history), berth details (inline if linked), vessel info (from client), milestone dates (first contact, EOI sent, signed, deposit, contract, completed), lead category, source |
| **EOI & Documents** | EOI section: generate button (if prerequisites met), signing status per signer, signing URLs, reminder controls. Documents list: all docs on this interest (EOI, contracts, NDAs) with status. Upload manual doc button. |
| **Recommendations** | Berth recommendation panel: vessel dimensions summary, "Run Recommendation" button → ranked berth list with match scores. Assign berth from recommendation. |
| **Waiting List** | If berth is linked and client is on waiting list: position, priority, notification pref. If berth has a waiting list: show queue. |
| **Notes** | Interest-specific notes thread (separate from client notes). Same @mention / edit window behavior. |
| **Activity** | Interest-specific timeline (subset of client timeline filtered to this interest). |
| **Audit Trail** | Audit log for this interest record. |
---
### Berth Management
| Route | Page | Description |
| ---------------------- | ------------------------- | ----------------------------------------------------------------- |
| `/berths` | Berth Explorer | Three-panel layout: map + list + detail |
| `/berths/new` | Create Berth | New berth form (admin/super admin) |
| `/berths/[id]` | Berth Detail | Full berth specs (also shown in right panel of explorer) |
| `/berths/compare` | Berth Comparison | Side-by-side comparison of 2-3 berths |
| ~~`/berths/calendar`~~ | ~~Availability Calendar~~ | **CUT FROM V1** — Gantt-style tenure timeline deferred to post-V1 |
#### `/berths` — Berth Explorer (Three-Panel Layout)
```
┌──────────────────────────────────────────────────────┐
│ [Interactive Berth Map] [Collapse Map ▲]│
│ SVG map color-coded: green=available, orange=under │
│ offer, red=sold. Click berth → selects in list. │
├─────────────────┬────────────────────────────────────┤
│ Smart List │ Detail Panel │
│ ───────────── │ ─────────────── │
│ Grouped by │ Full berth specs │
│ status: │ (collapsible sections): │
│ Under Offer │ - Dimensions │
│ Available │ - Infrastructure │
│ Sold │ - Commercial │
│ │ - Linked interests │
│ Filter: area, │ - Waiting list │
│ size, price │ - Maintenance log │
│ │ - Files / Gallery │
│ [+ New Berth] │ - Tenure info │
│ │ [Edit] [Compare] [Export PDF] │
└─────────────────┴────────────────────────────────────┘
```
- **Map panel:** Toggleable (collapse to maximize list/detail). SVG with berth outlines colored by status. Hover shows tooltip (mooring #, area, status, size). Click selects berth.
- **List panel:** Grouped by status (Under Offer first, then Available, then Sold). Each item: mooring number, area, nominal size, price. Search/filter by area, size range, price range, status.
- **Detail panel:** Full spec sheet. Collapsible sections for each data group. Action buttons: Edit, Compare (adds to comparison), Export PDF, View on map.
- **Waiting List section:** Ordered queue of clients with position, priority (normal/high), date added, notification preference. Actions: reorder, change priority, update notification pref, remove entry. "Add to waiting list" button (client selector).
- **Maintenance Log section:** Chronological log of maintenance/repair/inspection entries. Each entry: date, description, cost, category (routine/repair/inspection/upgrade), photos (thumbnail gallery), responsible party. "+ Add Entry" form with photo upload. Edit/delete existing entries.
#### `/berths/compare` — Berth Comparison
- Select 2-3 berths (from berth list or via URL params)
- Side-by-side table: rows are spec fields, columns are berths
- Highlights differences
- Export as PDF button (branded with port logo/colors)
#### `/berths/calendar` — Availability Calendar — **CUT FROM V1**
> **Deferred to post-V1.** Tenure data and expiry checks remain active (see BR-003 tenure expiry, `tenure-expiry-check` background job). Only the Gantt-style visualization UI is deferred.
~~- Gantt-style horizontal timeline~~
~~- Rows = berths, bars = tenure periods~~
~~- Color: active tenure (blue), expiring soon (amber), expired (red), available (green)~~
~~- Configurable time range (3 months, 6 months, 1 year, 5 years)~~
~~- Click a tenure bar → links to interest or client detail~~
~~- Flags upcoming expirations (configurable warning threshold, set in port settings)~~
~~- Legend: color key for tenure status types~~
~~- Warning threshold control: dropdown to set how far in advance expirations are flagged (1/3/6/12 months)~~
---
### Expenses
| Route | Page | Description |
| ---------------- | --------------------- | ------------------------------------------------------------------------------------------------------ |
| `/expenses` | Expense List | Paginated table of all expenses |
| `/expenses/new` | Create Expense | New expense form with receipt upload |
| `/expenses/[id]` | Expense Detail | Full expense record with receipt images |
| `/scan` | Receipt Scanner (PWA) | Standalone PWA — camera → AI extraction → save expense. Also accessible via `/expenses/scan` redirect. |
#### `/expenses` — Expense List
- **Table columns:** Date, establishment, amount (original currency + USD), category, payer, payment status, receipt indicator
- **Filters:** Date range, payer, category, payment status, currency, amount range
- **Sort:** Date, amount, establishment
- **Export controls:** CSV export, PDF export (with receipts), parent company export (EUR + 5% fee)
- **Bulk actions:** Bulk export, bulk payment status update, create invoice from selected
#### `/expenses/new` — Create Expense
- **Fields:** Establishment name, amount, currency (dropdown), date/time, category, payer, description, payment method, payment status
- **Receipt upload:** Drag-and-drop or camera capture, multiple images allowed
- **"Scan Receipt" button** → redirects to `/scan` (standalone PWA receipt scanner)
#### `/scan` — Receipt Scanner (Standalone PWA)
- **Standalone PWA:** `manifest.json` with `display: "standalone"`, custom icon ("Port Nimara Scanner"). Addable to Apple home screen / Android — opens without browser chrome.
- **Service worker:** Caches UI shell for instant load. Offline: photos queued in IndexedDB, uploaded on reconnect.
- **Easy URL:** `crm.portnimara.dev/scan` — short and bookmarkable. `/expenses/scan` redirects here.
- **Minimal UI:** No sidebar or navigation chrome. Camera viewfinder (or file upload for desktop) → Capture → AI processing spinner → Review extracted data (establishment, amount, currency, date, items) → Edit/correct → Save as expense → "Scan Another" or "Back to CRM"
- **Multi-currency indicator:** Shows detected currency + USD conversion at current rate
- **Auth:** Session-based. If not logged in, shows minimal login form then returns to scanner.
---
### Invoices
| Route | Page | Description |
| ---------------- | -------------- | ---------------------------------------------------- |
| `/invoices` | Invoice List | Paginated table of all invoices |
| `/invoices/new` | Create Invoice | Invoice builder (select expenses, configure billing) |
| `/invoices/[id]` | Invoice Detail | Full invoice with line items, payment tracking |
#### `/invoices` — Invoice List
- **Table columns:** Invoice # (INV-YYYYMM-###), client/company, total, currency, status (draft/sent/paid/overdue/cancelled), due date, created date
- **Filters:** Status, client, date range, amount range, currency
- **Status badges color-coded:** Draft (gray), Sent (blue), Paid (green), Overdue (red), Cancelled (strikethrough)
#### `/invoices/new` — Create Invoice
- **Step 1:** Select billing target (client or company, billing email, billing address)
- **Step 2:** Add line items — inline editable table: description, quantity, unit price, amount (auto-calculated). "Add Row" button for manual items. "Import from Expenses" button → modal showing un-invoiced expenses with checkboxes, select → auto-creates line items.
- **Step 3:** Configure: payment terms (Immediate/Net 10/15/30/45/60), currency, discount (% or fixed), additional fees, notes
- **Preview:** Live invoice preview as you configure
- **Save as draft** or **Save & Send**
#### `/invoices/[id]` — Invoice Detail
- **Header:** Invoice #, status badge, client/company, total, due date
- **Line items table:** Description, quantity, unit price, amount
- **Totals section:** Subtotal, discount, fees, total
- **Payment tracking:** Status, payment date, method, reference, notes. "Record Payment" button.
- **Actions:** Send (email PDF), Download PDF, Edit (if draft), Mark as Paid, Cancel
- **Linked expenses:** List of expenses included in this invoice
---
### File Management
| Route | Page | Description |
| -------- | ------------ | ---------------------------------------------- |
| `/files` | File Browser | MinIO-backed file explorer organized by client |
#### `/files` — File Browser
- **Left panel:** Folder tree (clients as top-level folders, sub-folders: eoi, contracts, images, receipts, correspondence, misc)
- **Right panel:** File grid/list for selected folder
- **File cards:** Thumbnail (images/PDFs), filename, size, uploaded date, uploaded by
- **Actions per file:** Preview (inline modal for images/PDFs), Download, Rename, Delete (confirmation), Move
- **Upload:** Drag-and-drop zone + click upload. Context-aware (if in a client's eoi folder, auto-categorizes)
- **Folder management:** Create folder, rename folder, delete folder (with contents warning)
- **Search:** Search files by name within current context
---
### Email System
| Route | Page | Description |
| ----------------- | -------------- | ----------------------------------------------- |
| `/email` | Email Inbox | Connected email threads (if mailbox configured) |
| `/email/settings` | Email Settings | IMAP/SMTP configuration |
#### `/email` — Email Inbox
- **If no mailbox configured:** Prompt to set up in `/email/settings`. Show system-sent emails log instead.
- **If configured:**
- Left panel: Thread list (newest first), search, filter by linked client
- Right panel: Thread detail (conversation view, newest at bottom)
- Compose button → TipTap rich text editor modal (recipients, subject, body, merge fields, attachments from MinIO)
- Threads auto-linked to clients by email address matching
- Unlinked threads shown in a separate "Unlinked" section
#### `/email/settings` — Email Settings
- Provider presets: Google Workspace, Outlook, Custom
- SMTP configuration: host, port, username, password (encrypted), TLS toggle
- IMAP configuration: host, port, username, password (encrypted), TLS toggle
- Test connection button
- Sync frequency setting
---
### Reminders
| Route | Page | Description |
| ------------ | -------------------- | ------------------------------------------------------ |
| `/reminders` | Reminders & Upcoming | Unified list of CRM reminders + Google Calendar events |
#### `/reminders` — Reminders & Upcoming
- **Unified list view:** CRM reminders and Google Calendar events interleaved chronologically
- Toggle: My Reminders ↔ All Reminders (requires `reminders.view_all`)
- CRM reminders: Title, linked entity (client/interest/berth), priority (color-coded), due date, assigned to, status badge
- Google Calendar events: Title, time, location (if any), calendar badge icon to distinguish from CRM reminders
- Filters: Source (CRM only / Calendar only / Both), status (pending/snoozed/completed/dismissed), priority, assignee, entity type, due date range, overdue toggle
- Sort: Due date (default), priority, created date
- **Quick create:** "+ New Reminder" → inline form or modal (title, note, due date/time, priority, assignee, linked entity, "Add to Google Calendar" toggle)
- **Reminder detail:** Click reminder → slide-out panel with full fields, edit capability, snooze/complete/dismiss buttons
- **Snooze options:** 1 hour, 4 hours, tomorrow morning, next week, custom date/time
- **Calendar connection banner:** If Google Calendar not connected, show a subtle banner: "Connect Google Calendar to see your events alongside reminders" → link to `/settings/calendar`
- **Google Calendar event detail:** Click calendar event → read-only panel showing event details, link to open in Google Calendar
### User Settings — Calendar
| Route | Page | Description |
| -------------------- | ----------------- | -------------------------------------------- |
| `/settings/calendar` | Calendar Settings | Google Calendar connection and configuration |
#### `/settings/calendar` — Calendar Settings
- **Connection status:** Connected / Not connected, with Google account email displayed
- **Connect button:** Initiates Google OAuth flow → redirects to Google consent screen → returns with token
- **Calendar selector:** Dropdown listing all user's Google Calendars (fetched via `calendarList.list`). User picks which calendar to sync with (e.g., "Business", "CRM", "Primary").
- **Sync toggle:** Enable/disable background sync
- **Last synced:** Timestamp of most recent sync
- **Manual sync:** "Sync now" button to trigger immediate pull
- **Disconnect:** Button to revoke connection and clear cached events
---
### Admin Panel
| Route | Page | Description |
| ----------------------- | ---------------------- | --------------------------------------------- |
| `/admin` | Admin Overview | Admin landing with section links |
| `/admin/users` | User Management | User list + create/edit |
| `/admin/users/new` | Create User | New user form |
| `/admin/users/[id]` | User Detail | User profile, assigned ports/roles, activity |
| `/admin/roles` | Role Management | Role list + builder |
| `/admin/roles/new` | Create Role | Role builder with permission toggles |
| `/admin/roles/[id]` | Edit Role | Edit existing role permissions |
| `/admin/ports` | Port Management | Port list + settings |
| `/admin/ports/new` | Create Port | New port setup (or onboarding wizard) |
| `/admin/ports/[id]` | Port Settings | Per-port configuration |
| `/admin/audit` | Audit Log | System-wide audit log viewer |
| `/admin/settings` | System Settings | Global system configuration |
| `/admin/webhooks` | Webhook Management | Webhook CRUD + delivery logs |
| `/admin/webhooks/new` | Create Webhook | New webhook configuration |
| `/admin/webhooks/[id]` | Webhook Detail | Edit webhook + view delivery history |
| `/admin/reports` | Scheduled Reports | Report schedule management |
| `/admin/reports/new` | Create Report Schedule | Configure new scheduled report |
| `/admin/custom-fields` | Custom Fields | Custom field definitions per entity type |
| `/admin/templates` | Document Templates | Template CRUD with TipTap rich text editor |
| `/admin/templates/new` | Create Template | New template with merge field insertion |
| `/admin/templates/[id]` | Edit Template | Edit existing template |
| `/admin/forms` | Form Management | Data collection form builder + submissions |
| `/admin/forms/new` | Create Form | Build a pre-filled data collection form |
| `/admin/forms/[id]` | Form Detail | Edit form + view submissions |
| `/admin/import` | Data Import | CSV/Excel import center + import history |
| `/admin/monitoring` | System Health | Service health dashboard + BullMQ job monitor |
| `/admin/backup` | Backup & Restore | Database backup management |
| `/admin/tags` | Tag Management | Manage tags across entity types |
| `/admin/onboarding` | Port Onboarding Wizard | Step-by-step new port setup |
#### `/admin/users` — User Management
- **Table:** Name, email, status (active/inactive), last login, ports assigned, roles
- **Actions:** Create, edit, deactivate/reactivate, reset password
- **User detail page (`/admin/users/[id]`):**
- Full profile: name, email, status, created date, last login
- Port assignments: table of assigned ports with role per port, add/remove assignments
- Active sessions: list of current sessions (device/browser, IP, last active). "Revoke" button per session, "Revoke All Sessions" button.
- Activity history: last N actions from audit log filterable by date range
#### `/admin/roles` — Role Management
- **Role list:** Name, description, system role flag, # users assigned
- **Role builder:**
- Permission grid: categories on the left (clients, interests, berths, etc.), permission flags as toggles
- Visual grouping by domain
- "Clone from" dropdown to start from an existing role
- Preview: "What can this role do?" summary
#### `/admin/ports` — Port Management
- **Port list:** Name, slug, status (active/inactive), # users, # berths
- **Port settings:**
- Basic: Name, slug, timezone, default currency
- Branding: Logo upload, primary/secondary color pickers → stored in port settings
- Operational: Follow-up reminder schedules, alert thresholds, EOI reminder settings
- Role overrides: Per-port permission tweaks for global roles
#### `/admin/audit` — Audit Log
- **Filterable table:** Timestamp, user, action (create/update/delete/archive/restore/merge), entity type, entity ID, field changed, old value → new value
- **Filters:** User, entity type, action type, date range, entity ID
- **Export:** CSV
- **Revert button** (super admin only) on individual entries
#### `/admin/settings` — System Settings
- **Sections:**
- **Berth Status Rules:** Table of trigger→mode→target status rules. Each row: Trigger description (read-only), Mode dropdown (auto/suggest/off), Target Status dropdown (available/under_offer/sold). "Reset to Defaults" button. Per-port if multi-port.
- Email: Poste.io SMTP config, test send
- Documenso: API URL, API key, test connection
- MinIO: Endpoint, access key, secret key, bucket, test connection
- Currency: Primary currency, exchange rate refresh interval, Frankfurter API status, current rates table (auto-updated + manual override per pair), "Refresh Now" button
- Backup: Schedule (cron), retention days, last backup status
- Security: Session timeout, login rate limits, password requirements
- Expiration alerts: Default warning threshold for tenure expirations (months before)
#### `/admin/webhooks` — Webhook Management
- **Webhook list:** Name, target URL, events subscribed, enabled/disabled toggle, last delivery status
- **Create/edit:** Target URL, secret key (for HMAC signing), event selector (checkboxes), enable/disable
- **"Test Webhook" button:** Sends a test payload to the target URL, shows response status/body inline
- **Delivery log per webhook:** Timestamp, event type, response status, response time, payload preview, retry count
#### `/admin/reports` — Scheduled Reports
- **Report list:** Name, type, frequency, recipients, last sent, next send, enabled toggle
- **Create/edit:** Report type (dropdown), frequency (daily/weekly/monthly/cron), enable/disable
- **Recipient selector:** Multi-select from CRM users + free-text entry for external email addresses. Shows recipient list with remove buttons.
#### `/admin/custom-fields` — Custom Fields
- **Per entity type tabs:** Clients, Interests, Berths, Expenses
- **Field list:** Name, type (text/number/date/boolean/select), required flag, sort order
- **Create field:** Name, type, options (for select type), required, default value
#### `/admin/templates` — Document Templates
- **Template list:** Name, type (welcome letter, handover checklist, etc.), last modified, active toggle
- **Template editor:**
- Rich text editor (**TipTap** — confirmed, with table + merge field extensions)
- Merge field insertion toolbar: dropdown showing available fields organized by entity (client.full_name, berth.mooring_number, etc.), click to insert `{{token}}`
- Preview with sample data
- Save / activate / deactivate
#### `/admin/forms` — Form Management
- **Form list:** Name, linked entity type, status (active/inactive), submissions count, last submitted, created date
- **Create/edit form:**
- Form name, description
- Entity type: client data collection, interest data collection, general intake
- Field selector: choose which CRM fields appear on the form, set which are pre-filled vs. editable
- Branding preview: shows form as client will see it (port logo/colors)
- Generate link: creates per-client secure token URL
- **Submissions view per form:** Table of submissions with date, client, status (pending review / applied / rejected). Click submission → diff view showing what data the client provided vs. current CRM data. "Apply" button to merge submitted data into CRM records.
#### `/admin/tags` — Tag Management
- **Entity type tabs:** Clients, Interests, Berths (each port has its own tag set)
- **Tag list per type:** Tag name, color swatch, usage count (how many records tagged)
- **Create tag:** Name input + color picker
- **Edit tag:** Rename, change color
- **Delete tag:** Confirmation with cascade warning ("This tag is used on X records. Removing it will untag all of them.")
- **Drag to reorder** (sort order for display in tag selectors)
#### `/admin/import` — Data Import
- **Import wizard:**
- Step 1: Select entity type (clients, interests, berths, expenses)
- Step 2: Upload CSV/Excel file
- Step 3: Column mapping (source columns → CRM fields, auto-mapped where names match)
- Step 4: Validation preview (valid rows, error rows, duplicate alerts)
- Step 5: Import + progress bar
- **Import history:** Past imports with record counts, errors, date, user
#### `/admin/monitoring` — System Health
- **Service health cards:** PostgreSQL, Redis, MinIO, Documenso, Poste.io, Socket.io — each with green/yellow/red indicator, last check time, response time
- **BullMQ dashboard:** Queue cards (one per queue: email, documents, reminders, calendar-sync, backups, etc.) showing pending/active/completed/failed counts. Click queue → drill-down job list with: job ID, status, data preview, created/processed timestamps. Actions per job: retry, remove. Dead letter queue section with bulk retry/clear.
- **Alert configuration:** Per-category alert rules (service down, job failure, backup failure, disk space, unusual activity). Each rule: threshold (e.g., >5 failures), time window (e.g., in 10 minutes), notification targets (super admin email + in-app). Enable/disable per rule.
- **System info:** Disk usage, memory, uptime (non-sensitive info only)
#### `/admin/backup` — Backup & Restore
- **Backup list:** Date, size, type (scheduled/manual), status
- **Manual backup trigger button**
- **Download backup** button per entry
- **Restore:** Upload backup → preview (record counts) → confirm → restore (super admin only)
- **Retention settings:** Keep last N days
---
### Global Overlays & Modals
These UI elements appear on top of any page:
| Component | Trigger | Description |
| ------------------------------ | ----------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Global Search Modal** | Cmd+K / Ctrl+K or search icon | Full-screen modal: search input, results grouped by entity type (clients, berths, interests, invoices, expenses, documents), recent searches. Enter or click → navigates to record. |
| **Notification Panel** | Bell icon click | Slide-out right panel or dropdown: notification list ordered by recency. Each: icon, title, description, timestamp, read/unread dot, click → navigates to record. "Mark all as read" button. |
| **Scratchpad** | User menu → Scratchpad | Slide-out panel: personal notes area. Persisted per user. Notes can be dragged to a client record (opens a "move to client" modal). |
| **Confirmation Dialog** | Any destructive action | Modal: "Are you sure?" with context (what's being deleted/archived). Confirm / Cancel. |
| **Quick Note Modal** | "Add Note" button on any entity | Modal: text area with @mention support, entity context pre-filled. Save → adds to entity's notes. |
| **Duplicate Alert Modal** | On client creation (fuzzy match detected) | Modal: shows potential duplicate(s) side-by-side. Options: "Merge with existing", "Create anyway", "Cancel". |
| **Merge Preview Modal** | From client detail → Merge action | Modal: two records side-by-side, field-by-field selection of which values to keep, preview of merged result. Confirm → merge. |
| **EOI Generation Wizard** | "Generate EOI" button on interest | Multi-step modal: Step 1 verify client data → Step 2 verify berth data → Step 3 select signers → Step 4 confirm → generate. |
| **Berth Recommendation Panel** | "Run Recommendation" on interest | Panel/modal: shows vessel dimensions, ranked berth results with match scores and reasons. "Assign" button per result. |
| **Bulk Operation Progress** | After triggering bulk action | Toast/modal: progress bar, record count, success/error count. Stays until dismissed or auto-closes on completion. |
---
### Client Portal (Separate Auth Context)
| Route | Page | Description |
| ----------------------------- | -------------------- | ---------------------------------------------- |
| `/portal/login` | Portal Login | Client authentication (separate from CRM auth) |
| `/portal` | Portal Dashboard | Client's berths, pending documents, invoices |
| `/portal/documents` | My Documents | Documents awaiting signature, signed documents |
| `/portal/documents/[id]/sign` | Sign Document | Embedded Documenso signing view |
| `/portal/invoices` | My Invoices | Invoice history with status |
| `/portal/files` | My Files | Files shared by salesperson, upload area |
| `/portal/forms/[token]` | Data Collection Form | Pre-filled form for client to complete |
**Layout:** Simplified layout — no sidebar, just a top bar with portal logo and client name. Clean, focused UI for non-CRM users.
---
### Public Pages (No Authentication)
| Route | Page | Description |
| -------------------------- | ----------------- | --------------------------------------------------------- |
| `/api/public/berths` | — | JSON API endpoint (no UI) |
| `/api/public/berths/:id` | — | JSON API endpoint (no UI) |
| `/api/public/interests` | — | JSON API endpoint (POST, no UI) |
| `/api/public/forms/:token` | Public Form | Pre-filled data collection form (branded, minimal layout) |
| `/api-docs` | API Documentation | OpenAPI/Swagger UI for the public API |
---
## Page Count Summary
| Section | Page Count |
| ---------------------- | ------------------------------------- |
| Auth pages | 3 |
| User settings | 2 |
| Dashboard | 1 |
| Client management | 4 |
| Interest management | 3 |
| Berth management | 5 |
| Expenses | 4 |
| Invoices | 3 |
| File management | 1 |
| Email | 2 |
| Reminders | 1 |
| Calendar Settings | 1 |
| Admin panel | 27 (includes forms, tags detail) |
| Global overlays/modals | 10 components |
| Client portal | 7 |
| Public pages | 2 (with UI) |
| **TOTAL** | **~66 pages + 10 overlay components** |
---
## Responsive Breakpoints
| Breakpoint | Layout Adaptation |
| ----------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Desktop (≥1280px)** | Full three-panel layouts (berths), sidebar expanded, all columns visible |
| **Tablet (7681279px)** | Sidebar collapsed to icons, detail panels become full-page navigation, berth map toggles to separate tab, table columns reduced |
| **Mobile (< 768px)** | Sidebar → hamburger slide-out drawer, all views single-column, receipt scanner optimized for camera, touch-friendly tap targets (min 44px), swipe gestures for pipeline cards |
---
## Navigation Flow Diagram
```
Login ──→ Dashboard
┌─────────┼──────────┬──────────┬──────────┬──────────┐
▼ ▼ ▼ ▼ ▼ ▼
Clients Interests Berths Expenses Invoices Reminders
│ │ │ │ │ │
▼ ▼ ▼ ▼ ▼ ▼
Detail Detail Explorer Detail Detail Upcoming List
│ │ │ │
│ ┌───┘ │ │
│ ▼ │ │
│ EOI/Signing │ │
│ Recommendations │ │
│ ▼ │
│ Compare/Calendar │
│ │
└──── Files ◄─── linked ───────┘
Email
┌────────┘
Admin Panel ──→ Users / Roles / Ports / Audit / Settings
Webhooks / Reports / Custom Fields / Templates
Import / Monitoring / Backup / Tags / Onboarding
```
**Cross-linking patterns:**
- Client detail → links to interests, files, emails, invoices, documents
- Interest detail → links to client, berth, EOI documents, recommendations
- Berth detail → links to interests, waiting list entries (which link to clients)
- Expense detail → links to invoice (if invoiced), receipt files
- Invoice detail → links to client, linked expenses
- Activity timelines → every entry links to the relevant record
- Notification items → each links to the triggering record
- Dashboard widgets → each links to the relevant list/filter view
---
## State Management Summary
| State Type | Technology | Scope |
| ---------------------------------------------- | ---------------------------------------------- | --------------------------------------------- |
| **Server state** (entities, lists) | TanStack Query | Cache + refetch on focus/stale |
| **UI state** (sidebar, modals, view prefs) | Zustand store | Per-session, persisted subset to localStorage |
| **Form state** | React Hook Form + Zod | Per-form, validated on submit |
| **Real-time updates** | Socket.io events → TanStack Query invalidation | Port-scoped rooms |
| **URL state** (filters, pagination, view mode) | URL search params (nuqs or manual) | Shareable/bookmarkable |
**Real-time update flow:**
1. User A creates a client → API saves → Socket.io emits `client:created` to port room
2. User B's browser receives event → TanStack Query cache invalidated for client list
3. User B's client list auto-refetches → new client appears without page refresh
4. If User B is on the dashboard → activity feed also refreshes
---
## Appendix: Route-to-Feature Spec Cross-Reference
| Feature Spec Section | Primary Routes |
| ----------------------------- | ---------------------------------------------------------------------------------------------- |
| 1. Client Management | `/clients`, `/clients/new`, `/clients/[id]` |
| 2. Interest Management | `/interests`, `/interests/new`, `/interests/[id]` |
| 3. Berth Management | `/berths`, `/berths/compare` (~~`/berths/calendar`~~ cut from V1) |
| 4.14.5 EOI & Signing | `/interests/[id]` (EOI tab), EOI Generation modal |
| 4.5 Data Collection Forms | `/admin/forms`, `/admin/forms/new`, `/admin/forms/[id]`, `/api/public/forms/:token` |
| 4.6 Document Templates | `/admin/templates`, `/admin/templates/new`, `/admin/templates/[id]` |
| 4.7 Record PDF Export | Export buttons on `/clients/[id]`, `/berths/[id]`, `/interests/[id]` |
| 5. Expenses & Invoicing | `/expenses`, `/expenses/new`, `/expenses/scan`, `/invoices`, `/invoices/new`, `/invoices/[id]` |
| 6. File Management | `/files`, file tabs on client detail |
| 7. Email System | `/email`, `/email/settings` |
| 8. Dashboard & Analytics | `/` |
| 9. Reminders & Calendar | `/reminders`, `/settings/calendar` |
| 10. Notification Center | Notification bell overlay |
| 11.1 Global Search | Cmd+K overlay |
| 11.2 Saved Filters | Filter controls on all list pages |
| 11.3 Bulk Operations | Bulk action toolbar on all list pages |
| 12. Admin Panel | `/admin/*` (all sub-routes) |
| 13. Audit System | `/admin/audit`, audit trail tabs on entity detail pages |
| 14. Multi-Port Tenancy | Port switcher in top bar |
| 15. Auth & Authorization | `/login`, `/auth/*`, middleware (invisible) |
| 16. Public API | `/api/public/*`, `/api-docs` |
| 17.1 Berth Spec Import | `/admin/import` (berth-specific flow) |
| 17.2 Receipt Scanner (PWA) | `/scan` (standalone PWA, also `/expenses/scan` redirect) |
| 17.3 Recommendation Engine | `/interests/[id]` (Recommendations tab) |
| 17.4 S3 File Migration | One-time admin script (no permanent UI — progress in `/admin/monitoring`) |
| 18. Data Import/Export | `/admin/import`, export buttons on all list pages |
| 19. Webhooks | `/admin/webhooks`, `/admin/webhooks/new`, `/admin/webhooks/[id]` |
| 20. Scheduled Reports | `/admin/reports`, `/admin/reports/new` |
| 21. System Monitoring | `/admin/monitoring`, `/admin/backup` |
| 22. Client Portal | `/portal/*` |
| 23.1 Mobile Responsive | Responsive breakpoints (all pages) |
| 23.2 Dark Mode | User menu toggle (all pages) |
| 23.3 Quick Notes | Scratchpad overlay |
| 10.2 Notification Preferences | `/settings/notifications` |
| 23.4 Tags | `/admin/tags`, tag components on entity forms/detail |
| 23.5 Archiving | Archive actions on all entity detail/list pages |
| 23.6 Multi-Currency | Currency display on berth detail, expense forms |
| 23.7 Audit Export | Export button in `/admin/audit` or dedicated modal |