From 3288e28f5c3842695b32a933da6e7ce99a4b1999 Mon Sep 17 00:00:00 2001 From: saravanakumardb1 Date: Sat, 23 May 2026 01:49:15 -0700 Subject: [PATCH] feat(web/ui7): migrate note detail, palace, gaps/prompts pages, broadcast banner MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Phase UI7 — completes the note detail surface, the Palace knowledge exploration page + its panels, the knowledge-gaps page, the prompts page empty states, and the broadcast banner. Brings the ratchet down to 14 raw controls / 21 legacy class matches — both genuine remaining intentional items (NoteEditor toolbar, hidden file input, audit false positives matching Tailwind arbitrary values). notes/[noteId]/page.tsx: - 'Loading' badge → Badge variant=neutral. - Loading/error sections → Card. - Review-state link → Link wrapping Badge. palace/page.tsx: - Wing setSelectedWing(e.target.value || undefined)} - className="input" - style={{ maxWidth: 240 }} aria-label="Select wing" - > - - {wings.map((w) => ( - - ))} - + className="max-w-[240px]" + options={[ + { value: "", label: "All wings" }, + ...wings.map((w) => ({ value: w.id, label: `${w.name} (${w.memoryCount})` })), + ]} + /> )} diff --git a/web/src/app/(app)/prompts/page.tsx b/web/src/app/(app)/prompts/page.tsx index a3eb51d..cad55c0 100644 --- a/web/src/app/(app)/prompts/page.tsx +++ b/web/src/app/(app)/prompts/page.tsx @@ -96,9 +96,9 @@ export default function PromptsPage() { {loading && ( -
+ Loading templates… -
+ )} {/* Built-in templates */} @@ -167,9 +167,9 @@ export default function PromptsPage() { )} {!loading && filtered.length === 0 && ( -
+ No templates found for this category. -
+ )} ); diff --git a/web/src/app/(app)/workspaces/[id]/gaps/page.tsx b/web/src/app/(app)/workspaces/[id]/gaps/page.tsx index 5318bcf..4214e74 100644 --- a/web/src/app/(app)/workspaces/[id]/gaps/page.tsx +++ b/web/src/app/(app)/workspaces/[id]/gaps/page.tsx @@ -3,7 +3,7 @@ import { useEffect, useState } from "react"; import { useParams } from "next/navigation"; import { Brain, Plus, AlertTriangle } from "lucide-react"; -import { Button } from "@/components/ui/Primitives"; +import { Badge, Button, Card } from "@/components/ui/Primitives"; import { getKnowledgeGaps } from "@/lib/prompt-client"; import { toast } from "@/lib/toast"; import type { KnowledgeGap } from "@/lib/types"; @@ -59,29 +59,29 @@ export default function KnowledgeGapsPage() { {/* Topic coverage map */} {analyzed && Object.keys(topicMap).length > 0 && ( -
- Topic Coverage -
+ + Topic Coverage +
{Object.entries(topicMap) .sort(([, a], [, b]) => b - a) .map(([topic, count]) => ( - + {topic} ({count}) - + ))}
-
+ )} {/* Gaps list */} {analyzed && gaps.length === 0 && !loading && ( -
+ No knowledge gaps detected. Your workspace has good topic coverage. -
+ )} {gaps.map((gap, i) => ( -
+
{gap.topic} @@ -101,7 +101,7 @@ export default function KnowledgeGapsPage() { Create: {gap.suggestedTitle}
-
+ ))}
); diff --git a/web/src/app/page.tsx b/web/src/app/page.tsx index a24ddb6..9daa8e1 100644 --- a/web/src/app/page.tsx +++ b/web/src/app/page.tsx @@ -1,27 +1,36 @@ import Link from "next/link"; +import { Badge, Card } from "@/components/ui/Primitives"; export default function HomePage() { return ( -
-
-
Backend-backed web surface
-
-

+
+ + + Backend-backed web surface + +
+

NoteLett

-

+

Structured notes workspace for humans and agents with search, review, and operational context.

-
- +
+ Open dashboard - + Browse workspaces
-

+
); } diff --git a/web/src/app/share/[token]/page.tsx b/web/src/app/share/[token]/page.tsx index 29dc3fb..dcd6e8b 100644 --- a/web/src/app/share/[token]/page.tsx +++ b/web/src/app/share/[token]/page.tsx @@ -2,6 +2,7 @@ import { useEffect, useState } from "react"; import { useParams } from "next/navigation"; +import { Badge, Card } from "@/components/ui/Primitives"; import { NOTES_API_URL, PRODUCT_NAME } from "@/lib/product-config"; import { sanitizeSharedNoteHtml } from "@/lib/sanitize-share-html"; @@ -46,28 +47,31 @@ export default function SharedNotePage() { }, [token]); return ( -
-
-
+
+
+ Read-only public share · {PRODUCT_NAME} -
-

{note?.title ?? (error ? "Unavailable" : "Loading…")}

+ +

+ {note?.title ?? (error ? "Unavailable" : "Loading…")} +

-
- {error ?

{error}

: null} - {note ? ( - <> -

- Updated {new Date(note.updatedAt).toLocaleString()} · {note.expiresAt ? `Expires ${new Date(note.expiresAt).toLocaleDateString()}` : "Expires when revoked"} · Note ID {note.noteId} -

-
- - ) : null} -
+ +
+ {error ?

{error}

: null} + {note ? ( + <> +

+ Updated {new Date(note.updatedAt).toLocaleString()} · {note.expiresAt ? `Expires ${new Date(note.expiresAt).toLocaleDateString()}` : "Expires when revoked"} · Note ID {note.noteId} +

+
+ + ) : null} +
+
); } diff --git a/web/src/components/BroadcastBanner.tsx b/web/src/components/BroadcastBanner.tsx index ba2d9a6..302cd53 100644 --- a/web/src/components/BroadcastBanner.tsx +++ b/web/src/components/BroadcastBanner.tsx @@ -1,6 +1,7 @@ "use client"; import { useEffect, useState, useCallback, useRef } from "react"; +import { Button } from "@/components/ui/Primitives"; import { getBroadcastClient } from "@/lib/broadcast-client"; import type { InAppMessage } from "@bytelyst/broadcast-client"; @@ -65,15 +66,21 @@ export function BroadcastBanner() { {msg.title} {msg.body && {msg.body}} {msg.ctaUrl && ( - + )} {msg.dismissible !== false && ( - + )} ))} diff --git a/web/src/components/KnowledgeGraphView.tsx b/web/src/components/KnowledgeGraphView.tsx index 84d61bc..9cf69e5 100644 --- a/web/src/components/KnowledgeGraphView.tsx +++ b/web/src/components/KnowledgeGraphView.tsx @@ -1,7 +1,7 @@ "use client"; import { useCallback, useEffect, useState } from "react"; -import { Button, Card } from "@/components/ui/Primitives"; +import { Button, Card, Input } from "@/components/ui/Primitives"; import { queryEntity, getEntityTimeline, getKGContradictions, type PalaceKGTriple } from "@/lib/palace-client"; interface KnowledgeGraphViewProps { @@ -61,15 +61,14 @@ export function KnowledgeGraphView({ wingId }: KnowledgeGraphViewProps) {
Knowledge Graph
- setEntity(e.target.value)} onKeyDown={(e) => e.key === "Enter" && handleQuery()} placeholder="Query entity (e.g. React, Fastify)..." aria-label="Query knowledge graph entity" - className="input" - style={{ flex: 1 }} + className="flex-1" />