Add catalog search on timeline header and fix Back to Timeline navigation.

Public GET /api/search over artists, movements, and paintings with a debounced header bar on the timeline; Back to Timeline resets zoom and gallery session.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Danila Khodjaef
2026-07-15 10:34:29 +03:00
co-authored by Cursor
parent 50fc253ab2
commit acc4a91a08
17 changed files with 827 additions and 12 deletions
+43 -6
View File
@@ -12,6 +12,8 @@ The app is organised as a **drill-down hierarchy**:
4. **Painting detail** — full work in the centre, *Influenced By* on the left, *Influenced* on the right (paintings, artists, or movements), optional **art-history notes** with image markers, prev/next catalog browsing, optional fullscreen, link to artist biography.
5. **Artist biography** — portrait, lifespan, movement, and Wikipedia-sourced intro text (`bio_short` / `bio_full`). With debug mode on, the same image-audit panel as painting detail (portrait search, **Checked** / **Fix it** / **More** / **Clear** / **Upload**).
**Catalog search** — on the timeline home page, the header search bar (`CatalogSearchBar.tsx`) finds artists, paintings, and movements by name and metadata (year, movement, Wikipedia title). Type at least **2 characters** (300 ms debounce); results group into **Artists**, **Movements**, and **Paintings** with thumbnails. Keyboard: `↑`/`↓` to move, `Enter` to open, `Escape` to close. Choosing a result opens the artist gallery, movement gallery, or painting detail. Paintings opened from search show **← Back to Timeline** and return to the home timeline (full year range), not the previous view.
All artwork images are stored locally under `data/images/` — the UI never hot-links to Wikipedia or Commons at runtime (except optional on-demand fetch when a file is missing).
## Stack
@@ -45,6 +47,7 @@ Gallery/
│ │ ├── components/Timeline.tsx # Era bar, year ticks, event markers
│ │ ├── components/TimelineEventGuides.tsx # Event vertical guides into movement flow
│ │ ├── components/MovementBands.tsx # Movement flow (SVG streams + branches)
│ │ ├── components/CatalogSearchBar.tsx # Timeline header catalog search
│ │ ├── components/PaintingAnnotations.tsx # Art-history notes on painting detail
│ │ ├── pages/CheckupPage.tsx # Image audit table
│ │ ├── data/historical-events.ts # Timeline event markers (UI)
@@ -117,9 +120,13 @@ Use for fast frontend iteration without Keenetic. Legacy nginx config in [`deplo
```mermaid
flowchart TD
A[Home — timeline + movement flow] -->|scroll / drag / zoom| A
A -->|catalog search| S[Search results dropdown]
S -->|artist| C
S -->|movement| G
S -->|painting| D
A -->|click movement name| G[Movement gallery — 3D wings]
G -->|click painting| D
D -->|Back| G
D -->|Back to Gallery| G
G -->|back door / Wings / Exit| H[Wing navigator]
H -->|pick wing| G
H -->|Exit to Timeline| A
@@ -131,16 +138,28 @@ flowchart TD
D -->|prev / next| D
D -->|click centre image| F[Fullscreen lightbox]
F -->|close| D
D -->|Back| C
D -->|Back to Gallery| C
C -->|exit doorway / E key| E[Path picker]
E -->|predecessors| C
E -->|successors| C
D -->|influence thumbnail| D
D -->|artist link| B
B -->|Back| A
C -->|Back| A
B -->|Back| C
C -->|Back to Timeline| A
D -->|Back to Timeline when opened from search| A
```
### Back navigation
| Control | Behaviour |
|---------|-----------|
| **← Back to Timeline** (3D gallery header, movement **Exit to Timeline**) | Always returns to the **home timeline**: unmounts the hall, clears the gallery session, resets timeline zoom to the full catalog year range |
| **← Back to Gallery** (painting detail from a hall) | Returns to the **same hall session** — camera position and wing are preserved |
| **← Back to Timeline** (painting detail opened from catalog search) | Returns to the home timeline (same as gallery **Back to Timeline**) |
| **← Back** (artist bio) | Returns to wherever you opened bio from (usually the artist hall) |
Implementation: `goToTimelineHome()` in `HomePage.tsx` — do not use the browser **Back** button; it is not wired to app navigation.
## Timeline and movement flow
The home page shows two linked views over the **same year window** (`viewStart` / `viewEnd` in `HomePage.tsx`):
@@ -152,6 +171,22 @@ The home page shows two linked views over the **same year window** (`viewStart`
Both views share zoom/pan behaviour via `client/src/utils/timelineView.ts` (`zoomTimelineView`, `panTimelineView`, `chooseTimelineTickInterval`, `createViewChangeScheduler`). The home page uses a **fixed viewport** (`100vh`): timeline + movement flow sit in a shared `home-timeline-stack` so event guide lines can extend from the era bar down through the movement canvas. The movement flow compresses vertically so all movements in the visible year range fit without page scrolling.
### Catalog search (timeline header)
`CatalogSearchBar.tsx` calls `GET /api/search?q=…` (public, no login). The dropdown is stacked above the timeline (`z-index` on `.site-header`) so results are not hidden by movement bands.
| UX | Detail |
|----|--------|
| Minimum query | 2 characters after trim |
| Debounce | 300 ms |
| Result groups | Artists, Movements, Paintings (with thumb or movement colour swatch) |
| Open artist | Preload images → artist 3D hall |
| Open movement | Movement gallery (wing 1) |
| Open painting | Painting detail with `returnTo: timeline`**Back to Timeline** |
| Keyboard | `↑`/`↓` highlight, `Enter` open, `Escape` close |
Run `npm run dev:migrate:search` once on existing databases before first use, or rely on `npm run dev:migrate` (includes `migrate-search.sql`). See [API.md — GET /api/search](API.md#get-apsearch).
### Timeline data loading
On first visit, `HomePage.tsx` fetches the full catalog once:
@@ -299,7 +334,7 @@ Enter from the home page by clicking a **movement name** on the movement flow (`
| Front wall | Open **“Next wing →”** archway when a later wing exists; walk through or press `E` when near |
| Influence lamps | Same golden lamps as artist halls when `has_influence_links` is true |
| Missing images | Draped canvas cover in frame |
| Detail return | Hall stays mounted; camera preserved on **Back to Timeline** / **Back to Gallery** |
| Detail return | **Back to Gallery** from painting detail returns to the same wing with camera preserved; **Back to Timeline** exits the hall entirely |
**Controls (movement gallery):**
@@ -337,7 +372,8 @@ Opened from the 3D hall (artist or movement wing — click a frame) or from infl
| Click centre image | Open fullscreen lightbox |
| Click influence thumbnail | Open that works detail (different artist allowed) |
| Click influence artist portrait | Open that artists 3D gallery hall |
| **← Back to Gallery** / **← Back to Timeline** | Return to the hall or movement wing you entered from — **3D camera position is preserved** |
| **← Back to Gallery** | Return to the hall or movement wing you entered from — **3D camera position is preserved** |
| **← Back to Timeline** | Return to the home timeline (from search result, or from the 3D gallery header / movement **Exit to Timeline**) — hall unmounts, timeline zoom resets |
| **About {artist}** | Open artist biography |
**Navigation rules:**
@@ -388,6 +424,7 @@ Curator-only workflow for reviewing and fixing local image files — not part of
| Feature | Where | Purpose |
|---------|--------|---------|
| **Catalog search** | Timeline header (all visitors) | Find artists, paintings, movements; `GET /api/search`; navigate to gallery or detail |
| **Curator login** | Home header (guests) | Username + password modal; unlocks debug tools |
| **Debug mode** | Home header toggle (curators only) | Persists in `localStorage`; enables debug panel on painting detail and artist bio |
| **Show more** | Home header checkbox (curators, when debug on) | Auto-opens the **More** modal on each painting / bio page load |