73 lines
3.8 KiB
TypeScript
73 lines
3.8 KiB
TypeScript
import Link from "next/link";
|
|
import { AppShell } from "@/components/AppShell";
|
|
import { mockNotes, mockSavedViews } from "@/lib/mock-data";
|
|
|
|
export default function SearchPage() {
|
|
return (
|
|
<AppShell
|
|
title="Search"
|
|
description="Lexical search, tag filtering, and retrieval entry points. Semantic ranking and explainability remain follow-up work."
|
|
actions={<div className="badge">Dense retrieval shell</div>}
|
|
>
|
|
<section style={{ display: "grid", gridTemplateColumns: "minmax(260px, 320px) minmax(0, 1fr)", gap: "var(--ml-space-4)" }}>
|
|
<aside className="surface-card" style={{ padding: "var(--ml-space-5)", display: "grid", gap: "var(--ml-space-4)" }}>
|
|
<div style={{ fontWeight: 700 }}>Saved searches</div>
|
|
<div style={{ display: "grid", gap: "var(--ml-space-3)" }}>
|
|
{mockSavedViews
|
|
.filter((view) => view.scope === "search")
|
|
.map((view) => (
|
|
<div key={view.id} className="surface-muted" style={{ padding: "var(--ml-space-4)", display: "grid", gap: "var(--ml-space-2)" }}>
|
|
<strong>{view.name}</strong>
|
|
<span style={{ color: "var(--ml-text-secondary)" }}>{view.query}</span>
|
|
<span className="badge">{view.resultCount} results</span>
|
|
</div>
|
|
))}
|
|
</div>
|
|
|
|
<div style={{ display: "grid", gap: "var(--ml-space-2)" }}>
|
|
<strong>Retrieval filters</strong>
|
|
<span style={{ color: "var(--ml-text-secondary)" }}>workspace:any</span>
|
|
<span style={{ color: "var(--ml-text-secondary)" }}>status:active + draft</span>
|
|
<span style={{ color: "var(--ml-text-secondary)" }}>relationship scope: linked + cited</span>
|
|
<span style={{ color: "var(--ml-text-secondary)" }}>explainability: matched fields</span>
|
|
</div>
|
|
</aside>
|
|
|
|
<section className="surface-card" style={{ padding: "var(--ml-space-6)", display: "grid", gap: "var(--ml-space-4)" }}>
|
|
<input
|
|
aria-label="Search notes"
|
|
className="input-shell"
|
|
placeholder="Search notes, tags, tasks, and linked context"
|
|
/>
|
|
<div style={{ display: "flex", gap: "var(--ml-space-2)", flexWrap: "wrap" }}>
|
|
<span className="badge">workspace:all</span>
|
|
<span className="badge">status:active</span>
|
|
<span className="badge">source:manual+agent</span>
|
|
<span className="badge">matched:title+tags</span>
|
|
</div>
|
|
<div style={{ display: "grid", gap: "var(--ml-space-3)" }}>
|
|
{mockNotes.map((note) => (
|
|
<Link key={note.id} href={`/notes/${note.id}`} className="surface-muted" style={{ padding: "var(--ml-space-4)", display: "grid", gap: "var(--ml-space-2)" }}>
|
|
<div style={{ display: "grid", gridTemplateColumns: "minmax(0, 1.5fr) repeat(3, minmax(100px, auto))", gap: "var(--ml-space-3)", alignItems: "start" }}>
|
|
<div style={{ display: "grid", gap: "var(--ml-space-2)" }}>
|
|
<strong>{note.title}</strong>
|
|
<span style={{ color: "var(--ml-text-secondary)" }}>{note.excerpt}</span>
|
|
</div>
|
|
<span style={{ color: "var(--ml-text-secondary)" }}>{note.status}</span>
|
|
<span style={{ color: "var(--ml-text-secondary)" }}>{note.updatedBy}</span>
|
|
<span style={{ color: "var(--ml-text-secondary)" }}>{note.workspaceId.replace("workspace-", "")}</span>
|
|
</div>
|
|
<div style={{ display: "flex", gap: "var(--ml-space-2)", flexWrap: "wrap" }}>
|
|
{note.tags.map((tag) => (
|
|
<span key={tag} className="badge">#{tag}</span>
|
|
))}
|
|
</div>
|
|
</Link>
|
|
))}
|
|
</div>
|
|
</section>
|
|
</section>
|
|
</AppShell>
|
|
);
|
|
}
|