From c63d76b55c37ef8a7532b0aef57cc4c577c4bb3c Mon Sep 17 00:00:00 2001 From: Saransh Kumar Date: Tue, 14 Apr 2026 23:43:33 -0400 Subject: [PATCH 1/4] Remove sample chat prompts --- ui/src/components/app/ChatInput.test.tsx | 23 +++++++++++++++++++++++ ui/src/components/app/ChatInput.tsx | 4 ---- ui/src/components/app/PromptChips.tsx | 22 ---------------------- ui/src/lib/constants.ts | 7 ------- ui/src/pages/AppPage.tsx | 4 ---- 5 files changed, 23 insertions(+), 37 deletions(-) create mode 100644 ui/src/components/app/ChatInput.test.tsx delete mode 100644 ui/src/components/app/PromptChips.tsx diff --git a/ui/src/components/app/ChatInput.test.tsx b/ui/src/components/app/ChatInput.test.tsx new file mode 100644 index 0000000..af0d399 --- /dev/null +++ b/ui/src/components/app/ChatInput.test.tsx @@ -0,0 +1,23 @@ +import { render, screen } from "@testing-library/react"; +import { describe, expect, it, vi } from "vitest"; +import { ChatInput } from "@/components/app/ChatInput"; + +describe("ChatInput", () => { + it("does not render the removed sample question chips", () => { + render( + , + ); + + expect(screen.queryByText("Why is pipeline conversion dropping?")).not.toBeInTheDocument(); + expect(screen.queryByText("Generate SQL for this question")).not.toBeInTheDocument(); + }); +}); diff --git a/ui/src/components/app/ChatInput.tsx b/ui/src/components/app/ChatInput.tsx index 86cb9d2..a687c32 100644 --- a/ui/src/components/app/ChatInput.tsx +++ b/ui/src/components/app/ChatInput.tsx @@ -1,7 +1,6 @@ import { useEffect, useLayoutEffect, useRef } from "react"; import { Button } from "@/components/shared/Button"; import { Textarea } from "@/components/shared/Textarea"; -import { PromptChips } from "@/components/app/PromptChips"; import { Spinner } from "@/components/shared/Spinner"; import { UPLOAD_ACCEPT } from "@/lib/uploads"; import type { UploadedAsset } from "@/types/upload"; @@ -10,7 +9,6 @@ interface ChatInputProps { value: string; onChange: (value: string) => void; onSubmit: () => void; - onPickPrompt: (prompt: string) => void; onUpload: (file: File) => void; onRemoveAttachment: (assetId: string) => void; attachments: UploadedAsset[]; @@ -22,7 +20,6 @@ export function ChatInput({ value, onChange, onSubmit, - onPickPrompt, onUpload, onRemoveAttachment, attachments, @@ -77,7 +74,6 @@ export function ChatInput({ return (
- {attachments.length > 0 ? (
{attachments.map((asset) => ( diff --git a/ui/src/components/app/PromptChips.tsx b/ui/src/components/app/PromptChips.tsx deleted file mode 100644 index c34ae37..0000000 --- a/ui/src/components/app/PromptChips.tsx +++ /dev/null @@ -1,22 +0,0 @@ -import { promptSuggestions } from "@/lib/constants"; - -interface PromptChipsProps { - onPick: (prompt: string) => void; -} - -export function PromptChips({ onPick }: PromptChipsProps) { - return ( -
- {promptSuggestions.map((prompt) => ( - - ))} -
- ); -} diff --git a/ui/src/lib/constants.ts b/ui/src/lib/constants.ts index 3796ff6..80e3e25 100644 --- a/ui/src/lib/constants.ts +++ b/ui/src/lib/constants.ts @@ -6,13 +6,6 @@ export const homeNavLinks = [ { label: "Sign In", href: "/sign-in" }, ] as const; -export const promptSuggestions = [ - "Why is pipeline conversion dropping?", - "Show churn by segment", - "Summarize top anomalies", - "Generate SQL for this question", -]; - export const sidebarNavItems = [ { id: "chats", label: "Chats" }, { id: "uploads", label: "Uploads" }, diff --git a/ui/src/pages/AppPage.tsx b/ui/src/pages/AppPage.tsx index 8887d65..ccce521 100644 --- a/ui/src/pages/AppPage.tsx +++ b/ui/src/pages/AppPage.tsx @@ -161,10 +161,6 @@ export function AppPage() { value={draft} onChange={setDraft} onSubmit={() => void handleSubmit()} - onPickPrompt={(prompt) => { - setDraft(prompt); - handleSectionChange("chats"); - }} onUpload={(file) => void handleChatUpload(file)} onRemoveAttachment={removeActiveUpload} attachments={activeUploads} From b387ecd50b17e23a95139d6b707df90eadb0e73a Mon Sep 17 00:00:00 2001 From: Saransh Kumar Date: Tue, 14 Apr 2026 23:44:57 -0400 Subject: [PATCH 2/4] Always expand inspection panel --- .../components/app/InspectionPanel.test.tsx | 67 +++++++++++++++++++ ui/src/components/app/InspectionPanel.tsx | 12 +--- ui/src/components/shared/Drawer.tsx | 9 ++- ui/src/hooks/useInspectionPanel.ts | 3 - ui/src/pages/AppPage.tsx | 2 - 5 files changed, 74 insertions(+), 19 deletions(-) create mode 100644 ui/src/components/app/InspectionPanel.test.tsx diff --git a/ui/src/components/app/InspectionPanel.test.tsx b/ui/src/components/app/InspectionPanel.test.tsx new file mode 100644 index 0000000..2afec47 --- /dev/null +++ b/ui/src/components/app/InspectionPanel.test.tsx @@ -0,0 +1,67 @@ +import { render, screen } from "@testing-library/react"; +import { describe, expect, it, vi } from "vitest"; +import { InspectionPanel } from "@/components/app/InspectionPanel"; +import type { InspectionData } from "@/types/inspection"; + +const inspection: InspectionData = { + id: "inspection_1", + title: "Enterprise conversion review", + status: "valid", + verified: true, + queryType: "SQL", + engine: "DuckDB", + dataSource: "Revenue warehouse", + rowsReturned: 3, + lastUpdated: "2026-04-14T12:00:00.000Z", + filters: ["segment = enterprise"], + query: "select * from revenue_pipeline", + runtimeMs: 814, + confidence: 0.92, + metadata: [ + { label: "Warehouse", value: "Revenue warehouse" }, + { label: "Model", value: "revenue_pipeline" }, + ], + results: { + columns: ["segment", "conversion_rate"], + rows: [{ segment: "Enterprise", conversion_rate: "34.1%" }], + }, + trace: [ + { + id: "trace_1", + label: "Compiled SQL", + description: "The query writer produced the final SQL for execution.", + detail: "1 statement compiled.", + durationLabel: "142 ms", + status: "complete", + }, + ], + validation: [ + { + id: "validation_1", + label: "Query valid", + detail: "SQL parsed and executed without syntax errors.", + status: "pass", + }, + ], +}; + +describe("InspectionPanel", () => { + it("renders without an expand control and uses the wide drawer layout", () => { + render( + , + ); + + expect(screen.queryByRole("button", { name: /expand|collapse/i })).not.toBeInTheDocument(); + + const dialog = screen.getByRole("dialog", { name: "Enterprise conversion review" }); + expect(dialog.className).toContain("lg:w-[min(88vw,980px)]"); + }); +}); diff --git a/ui/src/components/app/InspectionPanel.tsx b/ui/src/components/app/InspectionPanel.tsx index 393ff40..9cc96e7 100644 --- a/ui/src/components/app/InspectionPanel.tsx +++ b/ui/src/components/app/InspectionPanel.tsx @@ -1,7 +1,6 @@ import { Drawer } from "@/components/shared/Drawer"; import { ErrorState } from "@/components/shared/ErrorState"; import { Spinner } from "@/components/shared/Spinner"; -import { Button } from "@/components/shared/Button"; import { SqlPreview } from "@/components/app/SqlPreview"; import { ResultTable } from "@/components/app/ResultTable"; import { ValidationSummary } from "@/components/app/ValidationSummary"; @@ -17,9 +16,7 @@ interface InspectionPanelProps { error: string | null; inspection: InspectionData | null; activeTab: InspectionTabId; - maximized: boolean; onClose: () => void; - onToggleMaximized: () => void; onTabChange: (tab: InspectionTabId) => void; } @@ -58,9 +55,7 @@ export function InspectionPanel({ error, inspection, activeTab, - maximized, onClose, - onToggleMaximized, onTabChange, }: InspectionPanelProps) { return ( @@ -69,12 +64,7 @@ export function InspectionPanel({ onClose={onClose} title={inspection?.title ?? "Inspection"} subtitle="LeetCode-style execution feedback adapted for analytics workflows." - maximized={maximized} - actions={ - - } + size="wide" > {loading ? (
diff --git a/ui/src/components/shared/Drawer.tsx b/ui/src/components/shared/Drawer.tsx index 84419a6..320057b 100644 --- a/ui/src/components/shared/Drawer.tsx +++ b/ui/src/components/shared/Drawer.tsx @@ -7,7 +7,7 @@ interface DrawerProps { title?: string; subtitle?: string; side?: "left" | "right"; - maximized?: boolean; + size?: "default" | "wide"; actions?: ReactNode; children: ReactNode; } @@ -18,7 +18,7 @@ export function Drawer({ title, subtitle, side = "right", - maximized = false, + size = "default", actions, children, }: DrawerProps) { @@ -61,7 +61,7 @@ export function Drawer({ side === "right" ? "right-0 border-l" : "left-0 border-r", - maximized + size === "wide" ? "w-full lg:w-[min(88vw,980px)]" : "w-full sm:w-[min(92vw,560px)] lg:w-[520px]", open @@ -70,6 +70,9 @@ export function Drawer({ ? "translate-x-full" : "-translate-x-full", )} + role="dialog" + aria-modal="true" + aria-label={title} >
diff --git a/ui/src/hooks/useInspectionPanel.ts b/ui/src/hooks/useInspectionPanel.ts index 0e46d74..8a8fc45 100644 --- a/ui/src/hooks/useInspectionPanel.ts +++ b/ui/src/hooks/useInspectionPanel.ts @@ -6,7 +6,6 @@ import type { InspectionData, InspectionTabId } from "@/types/inspection"; export function useInspectionPanel() { const { token } = useAuth(); const [open, setOpen] = useState(false); - const [maximized, setMaximized] = useState(false); const [activeTab, setActiveTab] = useState("sql"); const [inspection, setInspection] = useState(null); const [loading, setLoading] = useState(false); @@ -31,7 +30,6 @@ export function useInspectionPanel() { return { open, - maximized, activeTab, inspection, loading, @@ -39,6 +37,5 @@ export function useInspectionPanel() { setActiveTab, openInspection, closeInspection: () => setOpen(false), - toggleMaximized: () => setMaximized((value) => !value), }; } diff --git a/ui/src/pages/AppPage.tsx b/ui/src/pages/AppPage.tsx index ccce521..2590727 100644 --- a/ui/src/pages/AppPage.tsx +++ b/ui/src/pages/AppPage.tsx @@ -287,9 +287,7 @@ export function AppPage() { error={inspection.error} inspection={inspection.inspection} activeTab={inspection.activeTab} - maximized={inspection.maximized} onClose={inspection.closeInspection} - onToggleMaximized={inspection.toggleMaximized} onTabChange={inspection.setActiveTab} /> } From a4ce7a4c2a35bddd0e3eb259ce988cb5b4bebf13 Mon Sep 17 00:00:00 2001 From: Saransh Kumar Date: Tue, 14 Apr 2026 23:53:27 -0400 Subject: [PATCH 3/4] Add global dark mode toggle --- ui/src/components/app/ChatInput.tsx | 2 +- ui/src/components/app/ChatMessage.tsx | 4 +- ui/src/components/app/InsightCard.tsx | 4 +- ui/src/components/app/ResultTable.tsx | 2 +- ui/src/components/app/Sidebar.test.tsx | 114 +++++++++++++----- ui/src/components/app/Sidebar.tsx | 14 ++- ui/src/components/app/SqlPreview.tsx | 2 +- ui/src/components/app/StatusBadge.tsx | 6 +- ui/src/components/marketing/HeroSection.tsx | 6 +- ui/src/components/marketing/Navbar.test.tsx | 19 +++ ui/src/components/marketing/Navbar.tsx | 5 +- .../components/marketing/PricingSection.tsx | 32 ++--- ui/src/components/shared/Button.tsx | 6 +- ui/src/components/shared/ErrorState.tsx | 4 +- ui/src/components/shared/Input.tsx | 2 +- ui/src/components/shared/Tabs.tsx | 4 +- ui/src/components/shared/Textarea.tsx | 2 +- ui/src/components/shared/ThemeToggle.tsx | 71 +++++++++++ ui/src/context/ThemeProvider.test.tsx | 72 +++++++++++ ui/src/context/ThemeProvider.tsx | 44 +++++++ ui/src/context/theme-context.ts | 11 ++ ui/src/hooks/useTheme.ts | 12 ++ ui/src/pages/SignInPage.tsx | 2 +- ui/src/router/RootLayout.tsx | 9 +- ui/src/store/uiStore.ts | 10 ++ ui/src/styles/globals.css | 16 ++- ui/src/styles/theme.css | 67 +++++++--- ui/src/test/setup.ts | 25 ++++ ui/tailwind.config.ts | 51 +++++--- 29 files changed, 504 insertions(+), 114 deletions(-) create mode 100644 ui/src/components/marketing/Navbar.test.tsx create mode 100644 ui/src/components/shared/ThemeToggle.tsx create mode 100644 ui/src/context/ThemeProvider.test.tsx create mode 100644 ui/src/context/ThemeProvider.tsx create mode 100644 ui/src/context/theme-context.ts create mode 100644 ui/src/hooks/useTheme.ts diff --git a/ui/src/components/app/ChatInput.tsx b/ui/src/components/app/ChatInput.tsx index a687c32..3c881c1 100644 --- a/ui/src/components/app/ChatInput.tsx +++ b/ui/src/components/app/ChatInput.tsx @@ -123,7 +123,7 @@ export function ChatInput({ CSV or JSON only
diff --git a/ui/src/components/app/ChatMessage.tsx b/ui/src/components/app/ChatMessage.tsx index 424f264..893b23a 100644 --- a/ui/src/components/app/ChatMessage.tsx +++ b/ui/src/components/app/ChatMessage.tsx @@ -21,9 +21,9 @@ export function ChatMessage({ message, onInspect }: ChatMessageProps) { if (!isAssistant) { return (
-
+

{message.content}

-

{formatTimestamp(message.createdAt)}

+

{formatTimestamp(message.createdAt)}

); diff --git a/ui/src/components/app/InsightCard.tsx b/ui/src/components/app/InsightCard.tsx index a3c1383..cfdd9fa 100644 --- a/ui/src/components/app/InsightCard.tsx +++ b/ui/src/components/app/InsightCard.tsx @@ -9,8 +9,8 @@ interface InsightCardProps { const toneStyles = { neutral: "bg-panel", - positive: "bg-green-50/70", - caution: "bg-amber-50/80", + positive: "bg-success-soft/70", + caution: "bg-warning-soft/80", }; export function InsightCard({ title, body, tone = "neutral" }: InsightCardProps) { diff --git a/ui/src/components/app/ResultTable.tsx b/ui/src/components/app/ResultTable.tsx index f9d92ca..3f97877 100644 --- a/ui/src/components/app/ResultTable.tsx +++ b/ui/src/components/app/ResultTable.tsx @@ -21,7 +21,7 @@ export function ResultTable({ title, table }: ResultTableProps) { ))} - + {table.rows.map((row, rowIndex) => ( {table.columns.map((column) => ( diff --git a/ui/src/components/app/Sidebar.test.tsx b/ui/src/components/app/Sidebar.test.tsx index 19363e5..c0773fa 100644 --- a/ui/src/components/app/Sidebar.test.tsx +++ b/ui/src/components/app/Sidebar.test.tsx @@ -2,45 +2,97 @@ import { render, screen } from "@testing-library/react"; import { MemoryRouter } from "react-router-dom"; import { describe, expect, it, vi } from "vitest"; import { Sidebar } from "@/components/app/Sidebar"; +import { ThemeProvider } from "@/context/ThemeProvider"; import { AuthContext } from "@/context/auth-context"; describe("Sidebar", () => { - it("does not render a recent uploads section", () => { + const renderSidebar = (props?: Partial>) => render( - - - + + + + + , ); + it("does not render a recent uploads section", () => { + renderSidebar(); + expect(screen.queryByText("Recent uploads")).not.toBeInTheDocument(); }); + + it("renders the theme toggle in collapsed and mobile sidebar states", () => { + const { rerender } = renderSidebar({ collapsed: true }); + + expect(screen.getAllByRole("button", { name: "Switch to dark mode" }).length).toBeGreaterThan(0); + + rerender( + + + + + + + , + ); + + expect(screen.getAllByRole("button", { name: "Switch to dark mode" }).length).toBeGreaterThan(0); + }); }); diff --git a/ui/src/components/app/Sidebar.tsx b/ui/src/components/app/Sidebar.tsx index 943e6f5..832dfc2 100644 --- a/ui/src/components/app/Sidebar.tsx +++ b/ui/src/components/app/Sidebar.tsx @@ -1,6 +1,7 @@ import { Link } from "react-router-dom"; import { Button } from "@/components/shared/Button"; import { Drawer } from "@/components/shared/Drawer"; +import { ThemeToggle } from "@/components/shared/ThemeToggle"; import { useAuth } from "@/hooks/useAuth"; import { sidebarNavItems } from "@/lib/constants"; import { classNames } from "@/lib/classNames"; @@ -40,17 +41,17 @@ function BrandMark({ showExpandCue = false }: { showExpandCue?: boolean }) { return (
P {showExpandCue ? ( <> -
- +
@@ -50,7 +50,7 @@ export function HeroSection() {
-
+
Why is enterprise conversion softening this month?
@@ -90,7 +90,7 @@ export function HeroSection() {
-
+
SELECT segment, AVG(conversion_rate)
FROM revenue_pipeline diff --git a/ui/src/components/marketing/Navbar.test.tsx b/ui/src/components/marketing/Navbar.test.tsx new file mode 100644 index 0000000..d77e3f4 --- /dev/null +++ b/ui/src/components/marketing/Navbar.test.tsx @@ -0,0 +1,19 @@ +import { render, screen } from "@testing-library/react"; +import { MemoryRouter } from "react-router-dom"; +import { describe, expect, it } from "vitest"; +import { Navbar } from "@/components/marketing/Navbar"; +import { ThemeProvider } from "@/context/ThemeProvider"; + +describe("Navbar", () => { + it("renders the theme toggle in the marketing navigation", () => { + render( + + + + + , + ); + + expect(screen.getAllByRole("button", { name: "Switch to dark mode" })).toHaveLength(2); + }); +}); diff --git a/ui/src/components/marketing/Navbar.tsx b/ui/src/components/marketing/Navbar.tsx index 8cc5027..60b426f 100644 --- a/ui/src/components/marketing/Navbar.tsx +++ b/ui/src/components/marketing/Navbar.tsx @@ -2,6 +2,7 @@ import { useEffect, useState } from "react"; import { Link, useLocation } from "react-router-dom"; import { Button } from "@/components/shared/Button"; import { PageContainer } from "@/components/shared/PageContainer"; +import { ThemeToggle } from "@/components/shared/ThemeToggle"; import { homeNavLinks } from "@/lib/constants"; import { classNames } from "@/lib/classNames"; @@ -26,7 +27,7 @@ export function Navbar() { )} > -
P
+
P
Planera
+ Sign In diff --git a/ui/src/components/marketing/PricingSection.tsx b/ui/src/components/marketing/PricingSection.tsx index 9333136..481ce56 100644 --- a/ui/src/components/marketing/PricingSection.tsx +++ b/ui/src/components/marketing/PricingSection.tsx @@ -69,7 +69,7 @@ export function PricingSection() { className="overflow-hidden rounded-[36px] border border-line bg-panel px-6 py-8 shadow-soft sm:px-8 sm:py-10 lg:px-10" style={{ backgroundImage: - "radial-gradient(circle at top right, rgba(35, 88, 82, 0.14), transparent 30%), linear-gradient(180deg, rgba(255, 253, 249, 0.96), rgba(247, 242, 234, 0.92))", + "radial-gradient(circle at top right, rgb(var(--color-accent) / 0.16), transparent 30%), linear-gradient(180deg, rgb(var(--color-panel) / 0.96), rgb(var(--color-elevated) / 0.92))", }} >
@@ -82,7 +82,7 @@ export function PricingSection() {

- +

All paid plans include

{[ @@ -106,7 +106,7 @@ export function PricingSection() { elevated className={classNames( "flex h-full flex-col rounded-[30px] p-7 sm:p-8", - plan.featured ? "border-ink bg-ink text-white" : "bg-panel/85 backdrop-blur", + plan.featured ? "border-contrast bg-contrast text-contrast-foreground" : "bg-panel/85 backdrop-blur", )} >
@@ -114,42 +114,44 @@ export function PricingSection() {

{plan.label}

-

{plan.name}

+

{plan.name}

{plan.featured ? ( - + Popular ) : null}
-

{plan.description}

+

{plan.description}

- {plan.price} - {plan.cadence} + {plan.price} + {plan.cadence}
-

{plan.note}

+

{plan.note}

-
-

+

+

What's included

    @@ -158,10 +160,10 @@ export function PricingSection() { - {feature} + {feature} ))}
diff --git a/ui/src/components/shared/Button.tsx b/ui/src/components/shared/Button.tsx index 91ceec1..cc34a83 100644 --- a/ui/src/components/shared/Button.tsx +++ b/ui/src/components/shared/Button.tsx @@ -12,11 +12,11 @@ interface ButtonProps extends ButtonHTMLAttributes, PropsWith const variantStyles: Record = { primary: - "bg-ink text-white shadow-card hover:bg-black/90 focus-visible:ring-ink/20", + "bg-contrast text-contrast-foreground shadow-card hover:bg-contrast/90 focus-visible:ring-accent/30", secondary: - "border border-line bg-panel text-ink hover:border-ink/20 hover:bg-white", + "border border-line bg-panel text-ink hover:border-line/90 hover:bg-surface", ghost: - "bg-transparent text-muted hover:bg-black/[0.03] hover:text-ink", + "bg-transparent text-muted hover:bg-surface hover:text-ink", subtle: "bg-accent-soft text-accent-strong hover:bg-accent-soft/80", }; diff --git a/ui/src/components/shared/ErrorState.tsx b/ui/src/components/shared/ErrorState.tsx index 07f99f8..57b280a 100644 --- a/ui/src/components/shared/ErrorState.tsx +++ b/ui/src/components/shared/ErrorState.tsx @@ -9,9 +9,9 @@ interface ErrorStateProps { export function ErrorState({ title, description, onRetry }: ErrorStateProps) { return ( - +
-
+
diff --git a/ui/src/components/shared/Input.tsx b/ui/src/components/shared/Input.tsx index 9eb3ada..46f78a6 100644 --- a/ui/src/components/shared/Input.tsx +++ b/ui/src/components/shared/Input.tsx @@ -5,7 +5,7 @@ export function Input({ className, ...props }: InputHTMLAttributes({ tabs, activeTab, onChange }: TabsProps< className={classNames( "rounded-full px-4 py-2 text-sm font-medium transition", activeTab === tab.id - ? "bg-ink text-white shadow-card" - : "text-muted hover:bg-white hover:text-ink", + ? "bg-contrast text-contrast-foreground shadow-card" + : "text-muted hover:bg-panel hover:text-ink", )} > {tab.label} diff --git a/ui/src/components/shared/Textarea.tsx b/ui/src/components/shared/Textarea.tsx index 5c307b1..7a2b56e 100644 --- a/ui/src/components/shared/Textarea.tsx +++ b/ui/src/components/shared/Textarea.tsx @@ -9,7 +9,7 @@ export const Textarea = forwardRef
{error ? ( -
+
{error}
) : null} diff --git a/ui/src/router/RootLayout.tsx b/ui/src/router/RootLayout.tsx index 32be3ef..6526c59 100644 --- a/ui/src/router/RootLayout.tsx +++ b/ui/src/router/RootLayout.tsx @@ -1,10 +1,13 @@ import { Outlet } from "react-router-dom"; import { AuthProvider } from "@/context/AuthProvider"; +import { ThemeProvider } from "@/context/ThemeProvider"; export function RootLayout() { return ( - - - + + + + + ); } diff --git a/ui/src/store/uiStore.ts b/ui/src/store/uiStore.ts index bcc4ce4..a158179 100644 --- a/ui/src/store/uiStore.ts +++ b/ui/src/store/uiStore.ts @@ -2,8 +2,11 @@ const keys = { sidebarCollapsed: "planera.sidebar.collapsed", activeSection: "planera.active.section", activeConversation: "planera.active.conversation", + theme: "planera.theme", }; +type ThemePreference = "light" | "dark"; + export const uiStore = { getSidebarCollapsed() { return window.localStorage.getItem(keys.sidebarCollapsed) === "true"; @@ -23,4 +26,11 @@ export const uiStore = { setActiveConversation(value: string) { window.localStorage.setItem(keys.activeConversation, value); }, + getTheme(): ThemePreference | null { + const value = window.localStorage.getItem(keys.theme); + return value === "light" || value === "dark" ? value : null; + }, + setTheme(value: ThemePreference) { + window.localStorage.setItem(keys.theme, value); + }, }; diff --git a/ui/src/styles/globals.css b/ui/src/styles/globals.css index a56ab53..067ba92 100644 --- a/ui/src/styles/globals.css +++ b/ui/src/styles/globals.css @@ -11,9 +11,13 @@ body { @apply bg-canvas font-sans text-ink antialiased; background-image: - radial-gradient(circle at top left, rgba(35, 88, 82, 0.06), transparent 30%), - radial-gradient(circle at top right, rgba(199, 179, 148, 0.1), transparent 26%); + radial-gradient(circle at top left, rgb(var(--color-accent) / 0.12), transparent 32%), + radial-gradient(circle at top right, rgb(var(--color-contrast) / 0.08), transparent 30%); min-height: 100vh; + transition: + background-color 220ms ease, + color 220ms ease, + background-image 220ms ease; } * { @@ -21,7 +25,7 @@ } ::selection { - background: rgba(35, 88, 82, 0.16); + background: rgb(var(--color-accent) / 0.16); } h1, @@ -49,12 +53,12 @@ } .surface-ring { - box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.65); + box-shadow: inset 0 1px 0 var(--surface-ring); } .scroll-fade { scrollbar-width: thin; - scrollbar-color: rgba(99, 108, 114, 0.5) transparent; + scrollbar-color: rgb(var(--color-muted) / 0.5) transparent; } .scroll-fade::-webkit-scrollbar { @@ -63,7 +67,7 @@ } .scroll-fade::-webkit-scrollbar-thumb { - background: rgba(99, 108, 114, 0.35); + background: rgb(var(--color-muted) / 0.35); border-radius: 999px; } } diff --git a/ui/src/styles/theme.css b/ui/src/styles/theme.css index 944bd04..70b9649 100644 --- a/ui/src/styles/theme.css +++ b/ui/src/styles/theme.css @@ -1,19 +1,58 @@ -:root { - --color-canvas: #f4efe8; - --color-surface: #faf7f2; - --color-panel: #fffdf9; - --color-elevated: #f7f2ea; - --color-line: #d9d0c4; - --color-ink: #161819; - --color-muted: #636c72; - --color-accent: #235852; - --color-accent-soft: #d9ebe7; - --color-accent-strong: #193f3b; - --color-success: #2f6d5a; - --color-warning: #8a6227; - --color-danger: #8c4141; +:root, +[data-theme="light"] { + color-scheme: light; + --color-canvas: 244 239 232; + --color-surface: 250 247 242; + --color-panel: 255 253 249; + --color-elevated: 247 242 234; + --color-line: 217 208 196; + --color-ink: 22 24 25; + --color-muted: 99 108 114; + --color-contrast: 22 24 25; + --color-contrast-foreground: 255 255 255; + --color-accent: 35 88 82; + --color-accent-soft: 217 235 231; + --color-accent-strong: 25 63 59; + --color-success: 47 109 90; + --color-success-soft: 227 241 234; + --color-warning: 138 98 39; + --color-warning-soft: 247 236 215; + --color-danger: 140 65 65; + --color-danger-soft: 250 232 232; + --color-code: 17 20 23; + --color-code-ink: 230 239 233; --shadow-soft: 0 16px 48px rgba(24, 32, 34, 0.07); --shadow-card: 0 12px 28px rgba(24, 32, 34, 0.06); + --shadow-field: inset 0 1px 0 rgba(255, 255, 255, 0.62); + --surface-ring: rgba(255, 255, 255, 0.65); --radius-panel: 28px; --radius-card: 22px; } + +[data-theme="dark"] { + color-scheme: dark; + --color-canvas: 10 14 18; + --color-surface: 17 23 29; + --color-panel: 24 30 37; + --color-elevated: 31 39 47; + --color-line: 66 78 89; + --color-ink: 231 237 240; + --color-muted: 159 170 178; + --color-contrast: 235 241 243; + --color-contrast-foreground: 12 16 20; + --color-accent: 55 131 120; + --color-accent-soft: 27 56 52; + --color-accent-strong: 195 231 224; + --color-success: 118 200 172; + --color-success-soft: 25 52 46; + --color-warning: 229 183 93; + --color-warning-soft: 71 50 21; + --color-danger: 243 156 156; + --color-danger-soft: 76 37 37; + --color-code: 12 17 22; + --color-code-ink: 226 236 232; + --shadow-soft: 0 22px 56px rgba(1, 5, 9, 0.42); + --shadow-card: 0 14px 34px rgba(1, 5, 9, 0.34); + --shadow-field: inset 0 1px 0 rgba(255, 255, 255, 0.05); + --surface-ring: rgba(255, 255, 255, 0.04); +} diff --git a/ui/src/test/setup.ts b/ui/src/test/setup.ts index f149f27..4bdc87b 100644 --- a/ui/src/test/setup.ts +++ b/ui/src/test/setup.ts @@ -1 +1,26 @@ import "@testing-library/jest-dom/vitest"; +import { cleanup } from "@testing-library/react"; +import { afterEach, beforeEach, vi } from "vitest"; + +beforeEach(() => { + Object.defineProperty(window, "matchMedia", { + writable: true, + configurable: true, + value: vi.fn().mockImplementation((query: string) => ({ + matches: false, + media: query, + onchange: null, + addListener: vi.fn(), + removeListener: vi.fn(), + addEventListener: vi.fn(), + removeEventListener: vi.fn(), + dispatchEvent: vi.fn(), + })), + }); +}); + +afterEach(() => { + cleanup(); + localStorage.clear(); + delete document.documentElement.dataset.theme; +}); diff --git a/ui/tailwind.config.ts b/ui/tailwind.config.ts index 9bf3272..b79a649 100644 --- a/ui/tailwind.config.ts +++ b/ui/tailwind.config.ts @@ -5,22 +5,38 @@ const config: Config = { theme: { extend: { colors: { - canvas: "#f4efe8", - surface: "#faf7f2", - panel: "#fffdf9", - elevated: "#f7f2ea", - line: "#d9d0c4", - ink: "#161819", - muted: "#636c72", + canvas: "rgb(var(--color-canvas) / )", + surface: "rgb(var(--color-surface) / )", + panel: "rgb(var(--color-panel) / )", + elevated: "rgb(var(--color-elevated) / )", + line: "rgb(var(--color-line) / )", + ink: "rgb(var(--color-ink) / )", + muted: "rgb(var(--color-muted) / )", + contrast: { + DEFAULT: "rgb(var(--color-contrast) / )", + foreground: "rgb(var(--color-contrast-foreground) / )", + }, accent: { - DEFAULT: "#235852", - soft: "#d9ebe7", - strong: "#193f3b", + DEFAULT: "rgb(var(--color-accent) / )", + soft: "rgb(var(--color-accent-soft) / )", + strong: "rgb(var(--color-accent-strong) / )", + }, + success: { + DEFAULT: "rgb(var(--color-success) / )", + soft: "rgb(var(--color-success-soft) / )", + }, + warning: { + DEFAULT: "rgb(var(--color-warning) / )", + soft: "rgb(var(--color-warning-soft) / )", + }, + danger: { + DEFAULT: "rgb(var(--color-danger) / )", + soft: "rgb(var(--color-danger-soft) / )", + }, + code: { + DEFAULT: "rgb(var(--color-code) / )", + ink: "rgb(var(--color-code-ink) / )", }, - sand: "#ece3d5", - success: "#2f6d5a", - warning: "#8a6227", - danger: "#8c4141", }, fontFamily: { sans: ['"Inter"', '"Avenir Next"', '"Segoe UI"', "system-ui", "sans-serif"], @@ -28,9 +44,10 @@ const config: Config = { mono: ['"SFMono-Regular"', '"SF Mono"', "ui-monospace", "monospace"], }, boxShadow: { - soft: "0 16px 48px rgba(24, 32, 34, 0.07)", - card: "0 12px 28px rgba(24, 32, 34, 0.06)", - focus: "0 0 0 3px rgba(35, 88, 82, 0.16)", + soft: "var(--shadow-soft)", + card: "var(--shadow-card)", + field: "var(--shadow-field)", + focus: "0 0 0 3px rgb(var(--color-accent) / 0.16)", }, borderRadius: { xl2: "1.4rem", From e9c0a12dfa02278bfd448f25a5666b067abd977f Mon Sep 17 00:00:00 2001 From: Saransh Kumar Date: Wed, 15 Apr 2026 15:12:54 -0400 Subject: [PATCH 4/4] Polish sidebar icons and query preview layout --- ui/src/assets/icons/chat-bubbles.png | Bin 0 -> 6124 bytes ui/src/assets/icons/dashboard.png | Bin 0 -> 10792 bytes ui/src/assets/icons/logout.png | Bin 0 -> 10318 bytes ui/src/assets/icons/moon.png | Bin 0 -> 13765 bytes ui/src/assets/icons/save.png | Bin 0 -> 6196 bytes ui/src/assets/icons/setting.png | Bin 0 -> 19182 bytes ui/src/assets/icons/sun.png | Bin 0 -> 15126 bytes ui/src/assets/icons/upload.png | Bin 0 -> 6192 bytes ui/src/components/app/Sidebar.tsx | 81 +++++++++++------------ ui/src/components/app/SqlPreview.tsx | 4 +- ui/src/components/shared/MaskedIcon.tsx | 22 ++++++ ui/src/components/shared/ThemeToggle.tsx | 47 ++++++------- 12 files changed, 82 insertions(+), 72 deletions(-) create mode 100644 ui/src/assets/icons/chat-bubbles.png create mode 100644 ui/src/assets/icons/dashboard.png create mode 100644 ui/src/assets/icons/logout.png create mode 100644 ui/src/assets/icons/moon.png create mode 100644 ui/src/assets/icons/save.png create mode 100644 ui/src/assets/icons/setting.png create mode 100644 ui/src/assets/icons/sun.png create mode 100644 ui/src/assets/icons/upload.png create mode 100644 ui/src/components/shared/MaskedIcon.tsx diff --git a/ui/src/assets/icons/chat-bubbles.png b/ui/src/assets/icons/chat-bubbles.png new file mode 100644 index 0000000000000000000000000000000000000000..118e4d91c15d8799c1d8728bc5fdca1d8a9592aa GIT binary patch literal 6124 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 O@X^Cwhq&KS&i@xfDMy6> literal 0 HcmV?d00001 diff --git a/ui/src/assets/icons/dashboard.png b/ui/src/assets/icons/dashboard.png new file mode 100644 index 0000000000000000000000000000000000000000..ea2f7e06cc9bebbbd1b07994e2d67b888b370c52 GIT binary patch literal 10792 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 au>H^#H9F90z=B`F0uY9l*Xpl$-ur*Rr&|;N literal 0 HcmV?d00001 diff --git a/ui/src/assets/icons/save.png b/ui/src/assets/icons/save.png new file mode 100644 index 0000000000000000000000000000000000000000..059ad8be65f46b1a4c70ae78412864063c488ca4 GIT binary patch literal 6196 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 F{2!jFwtN5p literal 0 HcmV?d00001 diff --git a/ui/src/assets/icons/setting.png b/ui/src/assets/icons/setting.png new file mode 100644 index 0000000000000000000000000000000000000000..7f21dcb10f1c84e0c685b84e0d6c7cd24f6731b0 GIT binary patch literal 19182 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 literal 0 HcmV?d00001 diff --git a/ui/src/assets/icons/sun.png b/ui/src/assets/icons/sun.png new file mode 100644 index 0000000000000000000000000000000000000000..64e9653fe30d5e38221c3f24d5cec3a4fd6ae58b GIT binary patch literal 15126 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 Hd-?wWx`^xa literal 0 HcmV?d00001 diff --git a/ui/src/assets/icons/upload.png b/ui/src/assets/icons/upload.png new file mode 100644 index 0000000000000000000000000000000000000000..ba0d9592d9e36a57715a1e0ce185877d95e82497 GIT binary patch literal 6192 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 literal 0 HcmV?d00001 diff --git a/ui/src/components/app/Sidebar.tsx b/ui/src/components/app/Sidebar.tsx index 832dfc2..586fbb1 100644 --- a/ui/src/components/app/Sidebar.tsx +++ b/ui/src/components/app/Sidebar.tsx @@ -1,6 +1,13 @@ +import chatBubblesIcon from "@/assets/icons/chat-bubbles.png"; +import dashboardIcon from "@/assets/icons/dashboard.png"; +import logoutIcon from "@/assets/icons/logout.png"; +import saveIcon from "@/assets/icons/save.png"; +import settingIcon from "@/assets/icons/setting.png"; +import uploadIcon from "@/assets/icons/upload.png"; import { Link } from "react-router-dom"; import { Button } from "@/components/shared/Button"; import { Drawer } from "@/components/shared/Drawer"; +import { MaskedIcon } from "@/components/shared/MaskedIcon"; import { ThemeToggle } from "@/components/shared/ThemeToggle"; import { useAuth } from "@/hooks/useAuth"; import { sidebarNavItems } from "@/lib/constants"; @@ -25,16 +32,10 @@ interface SidebarProps { } const navIcons = { - chats: ( - - ), - uploads: ( - - ), - saved: ( - - ), - dashboards: , + chats: chatBubblesIcon, + uploads: uploadIcon, + saved: saveIcon, + dashboards: dashboardIcon, }; function BrandMark({ showExpandCue = false }: { showExpandCue?: boolean }) { @@ -154,9 +155,7 @@ function SidebarContent({ active ? "bg-contrast text-contrast-foreground shadow-card" : "text-muted hover:bg-panel hover:text-ink", )} > - - {navIcons[item.id]} - + {!collapsed ? {item.label} : null} ); @@ -204,35 +203,33 @@ function SidebarContent({ {!collapsed && user ?

{user.email}

: null} - - - - - - - {!collapsed ? "Settings" : null} - +
+ + + {!collapsed ? "Settings" : null} + + + +
); } diff --git a/ui/src/components/app/SqlPreview.tsx b/ui/src/components/app/SqlPreview.tsx index 2904740..09d102f 100644 --- a/ui/src/components/app/SqlPreview.tsx +++ b/ui/src/components/app/SqlPreview.tsx @@ -27,8 +27,8 @@ export function SqlPreview({ code, compact = false }: SqlPreviewProps) { {copied ? "Copied" : "Copy SQL"}
-
-        {code}
+      
+        {code}
       
); diff --git a/ui/src/components/shared/MaskedIcon.tsx b/ui/src/components/shared/MaskedIcon.tsx new file mode 100644 index 0000000..3ea13bc --- /dev/null +++ b/ui/src/components/shared/MaskedIcon.tsx @@ -0,0 +1,22 @@ +import type { CSSProperties } from "react"; +import { classNames } from "@/lib/classNames"; + +interface MaskedIconProps { + src: string; + className?: string; +} + +export function MaskedIcon({ src, className }: MaskedIconProps) { + const style = { + WebkitMaskImage: `url(${src})`, + maskImage: `url(${src})`, + WebkitMaskRepeat: "no-repeat", + maskRepeat: "no-repeat", + WebkitMaskPosition: "center", + maskPosition: "center", + WebkitMaskSize: "contain", + maskSize: "contain", + } satisfies CSSProperties; + + return