learning_ai_notes/web/src/app/(app)/search/page.tsx

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>
);
}