VayuChat-v2 / src /Sidebar.tsx
Nipun's picture
Add typed SQL analysis functions and rigorous testing (#4)
916f8e7
Raw
History Blame Contribute Delete
3.01 kB
import { promptGroups } from "./prompts";
import type { DataInfo } from "./types";
import {
ChevronIcon,
CloseIcon,
DatabaseIcon,
ExitIcon,
PlusIcon,
WindIcon,
} from "./icons";
type SidebarProps = {
open: boolean;
dataInfo: DataInfo | null;
onClose: () => void;
onPrompt: (prompt: string) => void;
onNewChat: () => void;
onLogout: () => void;
};
function compactNumber(value?: number) {
if (!value) return "—";
return new Intl.NumberFormat("en-US", {
notation: "compact",
maximumFractionDigits: 1,
}).format(value);
}
export function Sidebar({
open,
dataInfo,
onClose,
onPrompt,
onNewChat,
onLogout,
}: SidebarProps) {
return (
<>
<button
className={`sidebar-scrim ${open ? "is-visible" : ""}`}
onClick={onClose}
aria-label="Close question library"
tabIndex={open ? 0 : -1}
/>
<aside className={`sidebar ${open ? "is-open" : ""}`} aria-label="Question library">
<div className="sidebar__top">
<div className="brand-lockup">
<span className="brand-mark">
<WindIcon />
</span>
<span>
<strong>VayuChat</strong>
<small>Sustainability Lab</small>
</span>
</div>
<button className="icon-button sidebar__close" onClick={onClose} aria-label="Close">
<CloseIcon />
</button>
</div>
<button className="new-chat-button" onClick={onNewChat}>
<PlusIcon />
New analysis
</button>
<nav className="prompt-library" aria-label="Suggested questions">
<p className="sidebar-label">Question library</p>
{promptGroups.map((group, groupIndex) => (
<details key={group.name} open={groupIndex === 0}>
<summary>
<span>{group.label}</span>
<small>{group.prompts.length}</small>
<ChevronIcon />
</summary>
<div className="prompt-list">
{group.prompts.map((prompt) => (
<button
key={prompt}
onClick={() => {
onPrompt(prompt);
onClose();
}}
>
{prompt}
</button>
))}
</div>
</details>
))}
</nav>
<div className="sidebar__footer">
<div className="data-card">
<DatabaseIcon />
<div>
<span>Air-quality dataset</span>
<strong>
{compactNumber(dataInfo?.records)} records ·{" "}
{dataInfo?.cities ?? "—"} cities
</strong>
</div>
</div>
<button className="logout-button" onClick={onLogout}>
<ExitIcon />
Sign out
</button>
</div>
</aside>
</>
);
}