mirror of
https://github.com/temetro/temetro.git
synced 2026-08-10 18:49:29 +00:00
97bf9ed8cc
- Linear-inspired dark theme (app/globals.css), forced dark in layout
- Clinical sidebar (components/sidebar-02) with temetro brand
- AI chat UI (components/chat): Cursor-style input, UI-only mock replies
- Settings page (components/settings): Polar-style tabs/sections, UI only
- Route-group app shell: app/(app)/{layout,page,settings}
- shadcn (Base UI) + ai-elements component libraries
- CLAUDE.md: architecture notes + per-folder commit policy
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
82 lines
2.9 KiB
TypeScript
82 lines
2.9 KiB
TypeScript
"use client";
|
|
|
|
import {
|
|
DropdownMenu,
|
|
DropdownMenuContent,
|
|
DropdownMenuItem,
|
|
DropdownMenuLabel,
|
|
DropdownMenuSeparator,
|
|
DropdownMenuShortcut,
|
|
DropdownMenuTrigger,
|
|
} from "@/components/ui/dropdown-menu";
|
|
import {
|
|
SidebarMenu,
|
|
SidebarMenuButton,
|
|
SidebarMenuItem,
|
|
useSidebar,
|
|
} from "@/components/ui/sidebar";
|
|
import { ChevronsUpDown, Plus } from "lucide-react";
|
|
import * as React from "react";
|
|
|
|
type Team = {
|
|
name: string;
|
|
logo: React.ElementType;
|
|
plan: string;
|
|
};
|
|
|
|
export function TeamSwitcher({ teams }: { teams: Team[] }) {
|
|
const { isMobile } = useSidebar();
|
|
const [activeTeam, setActiveTeam] = React.useState(teams[0]);
|
|
|
|
if (!activeTeam) return null;
|
|
|
|
const Logo = activeTeam.logo;
|
|
|
|
return (
|
|
<SidebarMenu>
|
|
<SidebarMenuItem>
|
|
<DropdownMenu>
|
|
<DropdownMenuTrigger render={<SidebarMenuButton size="lg" className="data-[state=open]:bg-sidebar-accent data-[state=open]:text-sidebar-accent-foreground" />}><div className="flex aspect-square size-8 items-center justify-center rounded-lg bg-background text-foreground">
|
|
<Logo className="size-4" />
|
|
</div><div className="grid flex-1 text-left text-sm leading-tight">
|
|
<span className="truncate font-semibold">
|
|
{activeTeam.name}
|
|
</span>
|
|
<span className="truncate text-xs">{activeTeam.plan}</span>
|
|
</div><ChevronsUpDown className="ml-auto" /></DropdownMenuTrigger>
|
|
<DropdownMenuContent
|
|
className="w-(--radix-dropdown-menu-trigger-width) min-w-56 rounded-lg mb-4"
|
|
align="start"
|
|
side={isMobile ? "bottom" : "right"}
|
|
sideOffset={4}
|
|
>
|
|
<DropdownMenuLabel className="text-xs text-muted-foreground">
|
|
Teams
|
|
</DropdownMenuLabel>
|
|
{teams.map((team, index) => (
|
|
<DropdownMenuItem
|
|
key={team.name}
|
|
onClick={() => setActiveTeam(team)}
|
|
className="gap-2 p-2"
|
|
>
|
|
<div className="flex size-6 items-center justify-center rounded-sm border">
|
|
<team.logo className="size-4 shrink-0" />
|
|
</div>
|
|
{team.name}
|
|
<DropdownMenuShortcut>⌘{index + 1}</DropdownMenuShortcut>
|
|
</DropdownMenuItem>
|
|
))}
|
|
<DropdownMenuSeparator />
|
|
<DropdownMenuItem className="gap-2 p-2">
|
|
<div className="flex size-6 items-center justify-center rounded-md border bg-background">
|
|
<Plus className="size-4" />
|
|
</div>
|
|
<div className="font-medium text-muted-foreground">Add team</div>
|
|
</DropdownMenuItem>
|
|
</DropdownMenuContent>
|
|
</DropdownMenu>
|
|
</SidebarMenuItem>
|
|
</SidebarMenu>
|
|
);
|
|
}
|