From 931d0e06f4dee78edb1937d4b49d675764afad9f Mon Sep 17 00:00:00 2001 From: Froidefond Julien Date: Thu, 19 Mar 2026 11:12:00 +0100 Subject: [PATCH] feat: redesign search bars with prominent search input and compact filters Restructure LiveSearchForm: full-width search input with magnifying glass icon, filters in a compact row below with contextual icons per field (library, status, sort, etc.) and inline labels. Remove per-field className overrides from series and books pages. Co-Authored-By: Claude Opus 4.6 --- apps/backoffice/app/books/page.tsx | 8 +- .../app/components/LiveSearchForm.tsx | 148 +++++++++++------- apps/backoffice/app/series/page.tsx | 14 +- 3 files changed, 105 insertions(+), 65 deletions(-) diff --git a/apps/backoffice/app/books/page.tsx b/apps/backoffice/app/books/page.tsx index ab0945a..5cb0cbc 100644 --- a/apps/backoffice/app/books/page.tsx +++ b/apps/backoffice/app/books/page.tsx @@ -114,10 +114,10 @@ export default async function BooksPage({ diff --git a/apps/backoffice/app/components/LiveSearchForm.tsx b/apps/backoffice/app/components/LiveSearchForm.tsx index cb78356..477bb68 100644 --- a/apps/backoffice/app/components/LiveSearchForm.tsx +++ b/apps/backoffice/app/components/LiveSearchForm.tsx @@ -4,6 +4,22 @@ import { useRef, useCallback, useEffect } from "react"; import { useRouter, useSearchParams } from "next/navigation"; import { useTranslation } from "../../lib/i18n/context"; +// SVG path data for filter icons, keyed by field name +const FILTER_ICONS: Record = { + // Library - building/collection + library: "M8 14v3m4-3v3m4-3v3M3 21h18M3 10h18M3 7l9-4 9 4M4 10h16v11H4V10z", + // Reading status - open book + status: "M12 6.253v13m0-13C10.832 5.477 9.246 5 7.5 5S4.168 5.477 3 6.253v13C4.168 18.477 5.754 18 7.5 18s3.332.477 4.5 1.253m0-13C13.168 5.477 14.754 5 16.5 5c1.747 0 3.332.477 4.5 1.253v13C19.832 18.477 18.247 18 16.5 18c-1.746 0-3.332.477-4.5 1.253", + // Series status - signal/activity + series_status: "M9 19v-6a2 2 0 00-2-2H5a2 2 0 00-2 2v6a2 2 0 002 2h2a2 2 0 002-2zm0 0V9a2 2 0 012-2h2a2 2 0 012 2v10m-6 0a2 2 0 002 2h2a2 2 0 002-2m0 0V5a2 2 0 012-2h2a2 2 0 012 2v14a2 2 0 01-2 2h-2a2 2 0 01-2-2z", + // Missing books - warning triangle + has_missing: "M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z", + // Metadata provider - tag + metadata_provider: "M7 7h.01M7 3h5c.512 0 1.024.195 1.414.586l7 7a2 2 0 010 2.828l-7 7a2 2 0 01-2.828 0l-7-7A1.994 1.994 0 013 12V7a4 4 0 014-4z", + // Sort - arrows up/down + sort: "M3 4h13M3 8h9m-9 4h6m4 0l4-4m0 0l4 4m-4-4v12", +}; + interface FieldDef { name: string; type: "text" | "select"; @@ -60,6 +76,9 @@ export function LiveSearchForm({ fields, basePath, debounceMs = 300 }: LiveSearc return val && val.trim() !== ""; }); + const textFields = fields.filter((f) => f.type === "text"); + const selectFields = fields.filter((f) => f.type === "select"); + return (
- {fields.map((field) => - field.type === "text" ? ( -
- - navigate(false)} - className="flex h-10 w-full rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2" - /> + {/* Search input with icon */} + {textFields.map((field) => ( +
+ + + + navigate(false)} + className="flex h-11 w-full rounded-lg border border-input bg-background pl-10 pr-3 py-2 text-sm ring-offset-background placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2" + /> +
+ ))} + + {/* Filters row */} + {selectFields.length > 0 && ( + <> + {textFields.length > 0 && ( +
+ )} +
+ {selectFields.map((field) => ( +
+ {FILTER_ICONS[field.name] && ( + + + + )} + + +
+ ))} + {hasFilters && ( + + )}
- ) : ( -
- - -
- ) - )} - {hasFilters && ( - + )} ); diff --git a/apps/backoffice/app/series/page.tsx b/apps/backoffice/app/series/page.tsx index a9dbfac..509bd7a 100644 --- a/apps/backoffice/app/series/page.tsx +++ b/apps/backoffice/app/series/page.tsx @@ -99,13 +99,13 @@ export default async function SeriesPage({