mirror of
https://github.com/temetro/temetro.git
synced 2026-08-31 04:47:57 +00:00
Patients page, clinical Settings re-theme, Polar-style user footer
- Patients: new /patients directory table (name, MRN, age·sex, status,
last seen, allergies) with search + Add patient; clicking a row opens
the record in the chat via /?patient=<#>. chat-panel reads that search
param (Suspense-wrapped) and runs the lookup once on arrival. Sidebar
"Patients" now links to /patients; lib/patients gains listPatients().
- Settings: re-themed to clinical tabs (Profile · Records · Signing ·
Care team · Developers) — clinician profile, patient notifications,
patient-owned-storage/signed-records features, and a Signing key panel.
Same layout/components, only content changed.
- Sidebar footer: Polar-style NavUser (avatar + name + chevron) opening a
menu upward — Settings · Docs & GitHub · Theme · Log out. Collapsed
("locked"): avatar only, name on hover (tooltip), menu opens to the
right. Placeholder identity (no auth yet).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -15,6 +15,7 @@ import Image from "next/image";
|
||||
import type { Route } from "./nav-main";
|
||||
import DashboardNavigation from "@/components/sidebar-02/nav-main";
|
||||
import { NotificationsPopover } from "@/components/sidebar-02/nav-notifications";
|
||||
import { NavUser } from "@/components/sidebar-02/nav-user";
|
||||
|
||||
const sampleNotifications = [
|
||||
{
|
||||
@@ -51,7 +52,7 @@ const dashboardRoutes: Route[] = [
|
||||
id: "patients",
|
||||
title: "Patients",
|
||||
icon: <Users className="size-4" />,
|
||||
link: "#",
|
||||
link: "/patients",
|
||||
},
|
||||
{
|
||||
id: "settings",
|
||||
@@ -109,12 +110,7 @@ export function DashboardSidebar() {
|
||||
<DashboardNavigation routes={dashboardRoutes} />
|
||||
</SidebarContent>
|
||||
<SidebarFooter className="px-2">
|
||||
{!isCollapsed && (
|
||||
<div className="flex items-baseline gap-2 px-2 py-1.5">
|
||||
<span className="font-semibold text-foreground">temetro</span>
|
||||
<span className="text-xs text-muted-foreground">open source</span>
|
||||
</div>
|
||||
)}
|
||||
<NavUser />
|
||||
</SidebarFooter>
|
||||
</Sidebar>
|
||||
);
|
||||
|
||||
@@ -0,0 +1,116 @@
|
||||
"use client";
|
||||
|
||||
import { ChevronsUpDown, LogOut, Settings as SettingsIcon, Sun } from "lucide-react";
|
||||
import Link from "next/link";
|
||||
|
||||
import { Avatar, AvatarFallback } from "@/components/ui/avatar";
|
||||
import {
|
||||
DropdownMenu,
|
||||
DropdownMenuContent,
|
||||
DropdownMenuItem,
|
||||
DropdownMenuLabel,
|
||||
DropdownMenuSeparator,
|
||||
DropdownMenuShortcut,
|
||||
DropdownMenuTrigger,
|
||||
} from "@/components/ui/dropdown-menu";
|
||||
import {
|
||||
SidebarMenu,
|
||||
SidebarMenuButton,
|
||||
SidebarMenuItem,
|
||||
useSidebar,
|
||||
} from "@/components/ui/sidebar";
|
||||
|
||||
// Placeholder identity — there is no auth backend yet.
|
||||
const user = { name: "Dr. Khalid", role: "Clinician", initials: "K" };
|
||||
// Open-source repo (placeholder).
|
||||
const REPO_URL = "https://github.com/temetro/temetro";
|
||||
|
||||
function GitHubIcon({ className }: { className?: string }) {
|
||||
return (
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
className={className}
|
||||
fill="currentColor"
|
||||
viewBox="0 0 24 24"
|
||||
>
|
||||
<path d="M12 .5C5.37.5 0 5.78 0 12.29c0 5.2 3.44 9.6 8.21 11.16.6.11.82-.25.82-.55 0-.27-.01-1.16-.02-2.1-3.34.73-4.04-1.42-4.04-1.42-.55-1.39-1.34-1.76-1.34-1.76-1.09-.75.08-.73.08-.73 1.21.09 1.84 1.25 1.84 1.25 1.07 1.84 2.81 1.31 3.5 1 .11-.78.42-1.31.76-1.61-2.67-.31-5.47-1.34-5.47-5.95 0-1.31.47-2.39 1.24-3.23-.12-.31-.54-1.54.12-3.21 0 0 1.01-.32 3.3 1.23a11.5 11.5 0 0 1 6 0c2.29-1.55 3.3-1.23 3.3-1.23.66 1.67.24 2.9.12 3.21.77.84 1.24 1.92 1.24 3.23 0 4.62-2.81 5.64-5.49 5.94.43.37.82 1.1.82 2.22 0 1.6-.02 2.89-.02 3.29 0 .31.21.69.83.57A12.02 12.02 0 0 0 24 12.29C24 5.78 18.63.5 12 .5Z" />
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
|
||||
export function NavUser() {
|
||||
const { isMobile, state } = useSidebar();
|
||||
const isCollapsed = state === "collapsed";
|
||||
|
||||
return (
|
||||
<SidebarMenu>
|
||||
<SidebarMenuItem>
|
||||
<DropdownMenu>
|
||||
<DropdownMenuTrigger
|
||||
render={
|
||||
<SidebarMenuButton
|
||||
className="data-[state=open]:bg-sidebar-accent data-[state=open]:text-sidebar-accent-foreground"
|
||||
size="lg"
|
||||
tooltip={user.name}
|
||||
/>
|
||||
}
|
||||
>
|
||||
<Avatar className="size-8">
|
||||
<AvatarFallback>{user.initials}</AvatarFallback>
|
||||
</Avatar>
|
||||
{!isCollapsed && (
|
||||
<>
|
||||
<div className="grid flex-1 text-left text-sm leading-tight">
|
||||
<span className="truncate font-medium">{user.name}</span>
|
||||
<span className="truncate text-xs text-muted-foreground">
|
||||
{user.role}
|
||||
</span>
|
||||
</div>
|
||||
<ChevronsUpDown className="ml-auto size-4" />
|
||||
</>
|
||||
)}
|
||||
</DropdownMenuTrigger>
|
||||
<DropdownMenuContent
|
||||
align="start"
|
||||
className="min-w-56"
|
||||
side={isMobile ? "bottom" : isCollapsed ? "right" : "top"}
|
||||
sideOffset={8}
|
||||
>
|
||||
<DropdownMenuLabel className="flex items-center gap-2 py-2 text-foreground">
|
||||
<Avatar className="size-8">
|
||||
<AvatarFallback>{user.initials}</AvatarFallback>
|
||||
</Avatar>
|
||||
<div className="grid flex-1 text-left text-sm leading-tight">
|
||||
<span className="truncate font-medium">{user.name}</span>
|
||||
<span className="truncate text-xs text-muted-foreground">
|
||||
{user.role}
|
||||
</span>
|
||||
</div>
|
||||
</DropdownMenuLabel>
|
||||
<DropdownMenuSeparator />
|
||||
<DropdownMenuItem render={<Link href="/settings" />}>
|
||||
<SettingsIcon />
|
||||
Settings
|
||||
</DropdownMenuItem>
|
||||
<DropdownMenuItem
|
||||
render={<a href={REPO_URL} rel="noreferrer" target="_blank" />}
|
||||
>
|
||||
<GitHubIcon className="size-4" />
|
||||
Docs & GitHub
|
||||
</DropdownMenuItem>
|
||||
<DropdownMenuItem>
|
||||
<Sun />
|
||||
Theme
|
||||
<DropdownMenuShortcut>Dark</DropdownMenuShortcut>
|
||||
</DropdownMenuItem>
|
||||
<DropdownMenuSeparator />
|
||||
<DropdownMenuItem variant="destructive">
|
||||
<LogOut />
|
||||
Log out
|
||||
</DropdownMenuItem>
|
||||
</DropdownMenuContent>
|
||||
</DropdownMenu>
|
||||
</SidebarMenuItem>
|
||||
</SidebarMenu>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user