Ui fixings

This commit is contained in:
2026-09-24 12:30:21 +05:30
parent f5e8e0e5b9
commit 049c98298a
34 changed files with 1021 additions and 1247 deletions
@@ -22,7 +22,11 @@ import { Badge } from "@/components/ui/badge"
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuGroup,
DropdownMenuItem,
DropdownMenuLabel,
DropdownMenuRadioGroup,
DropdownMenuRadioItem,
DropdownMenuSeparator,
DropdownMenuTrigger,
} from "@/components/ui/dropdown-menu"
@@ -86,6 +90,14 @@ const STOCK_TITLES: Record<string, string> = {
"/dashboard/stock/wastage/new": "Record Wastage",
}
const PRODUCTION_TITLES: Record<string, string> = {
"/dashboard/production": "Production",
"/dashboard/production/templates": "Production Templates",
"/dashboard/production/templates/new": "New Template",
"/dashboard/production/runs": "Production Runs",
"/dashboard/production/produced": "Produced Items",
}
function titleFromPath(pathname: string) {
if (pathname === "/dashboard/sales/invoices") return "Sales"
if (pathname === "/dashboard/sales/invoices/new") return "New Sale"
@@ -103,6 +115,10 @@ function titleFromPath(pathname: string) {
if (/^\/dashboard\/stock\/transfers\/[^/]+$/.test(pathname)) return "Stock Transfer"
if (/^\/dashboard\/stock\/counts\/[^/]+$/.test(pathname)) return "Stock Count"
if (PRODUCTION_TITLES[pathname]) return PRODUCTION_TITLES[pathname]
if (/^\/dashboard\/production\/templates\/[^/]+$/.test(pathname)) return "Template Builder"
if (/^\/dashboard\/production\/runs\/[^/]+$/.test(pathname)) return "Production Run"
if (PROCUREMENT_TITLES[pathname]) return PROCUREMENT_TITLES[pathname]
if (/^\/dashboard\/procurement\/requisitions\/[^/]+$/.test(pathname)) return "Requisition"
if (/^\/dashboard\/procurement\/rfqs\/[^/]+$/.test(pathname)) return "RFQ"
@@ -277,12 +293,16 @@ export function Header() {
type="button"
onClick={() => router.back()}
aria-label="Go back"
className="flex size-9 shrink-0 items-center justify-center rounded-full text-muted-foreground hover:bg-muted hover:text-foreground"
className="flex size-8 shrink-0 items-center justify-center rounded-full text-muted-foreground hover:bg-muted hover:text-foreground sm:size-9"
>
<ArrowLeft className="size-5" />
</button>
)}
<h1 className="min-w-0 truncate text-base font-bold tracking-tight text-foreground sm:text-xl">{title}</h1>
{/* Phones wrap to two lines rather than truncating — at this width a one-line title
is cut to a few letters ("Prod…"). One truncated line from sm, where it fits. */}
<h1 className="line-clamp-2 min-w-0 text-base leading-tight font-bold tracking-tight wrap-break-word text-foreground sm:truncate sm:text-xl sm:leading-normal">
{title}
</h1>
</div>
<div className="flex shrink-0 items-center gap-1.5 sm:gap-3">
@@ -377,7 +397,8 @@ export function Header() {
)}
</div>
<ThemeToggle />
{/* 108px wide — on phones it moves into the account menu so the title has room. */}
<ThemeToggle className="hidden sm:flex" />
<Popover onOpenChange={(open) => open && loadNotifications()}>
<PopoverTrigger
@@ -443,7 +464,7 @@ export function Header() {
</Popover>
<DropdownMenu>
<DropdownMenuTrigger className="flex items-center gap-2 rounded-full py-1 pr-2 pl-1 outline-none hover:bg-muted">
<DropdownMenuTrigger className="flex items-center gap-2 rounded-full p-1 outline-none hover:bg-muted sm:pr-2">
<Avatar>
<AvatarFallback className="bg-primary/10 font-semibold text-primary">
{user ? initials(displayName(user)) : "?"}
@@ -466,6 +487,39 @@ export function Header() {
</p>
)}
</div>
<div className="flex items-center justify-between gap-3 px-2 pb-2.5 sm:hidden">
<span className="text-sm text-muted-foreground">Theme</span>
<ThemeToggle />
</div>
{/* The header's branch picker is hidden on phones, so admins switch here. Radio
items rather than a nested Select: a Select's portaled popup would read as an
outside press and close this menu. */}
{branchingEnabled && isAdmin && (
<div className="sm:hidden">
<DropdownMenuSeparator />
<DropdownMenuGroup>
<DropdownMenuLabel className="flex items-center gap-1.5 px-2 text-sm">
<Building2 className="size-3.5" />
Branch
</DropdownMenuLabel>
<div className="max-h-48 overflow-y-auto">
<DropdownMenuRadioGroup
value={activeBranchId ? String(activeBranchId) : ALL_BRANCHES}
onValueChange={(value: string) => handleBranchChange(value)}
>
<DropdownMenuRadioItem value={ALL_BRANCHES} closeOnClick className="py-2 text-base">
All Branches
</DropdownMenuRadioItem>
{branches.map((b) => (
<DropdownMenuRadioItem key={b.branchId} value={String(b.branchId)} closeOnClick className="py-2 text-base">
{b.name}
</DropdownMenuRadioItem>
))}
</DropdownMenuRadioGroup>
</div>
</DropdownMenuGroup>
</div>
)}
<DropdownMenuSeparator />
<DropdownMenuItem
render={<Link href="/dashboard/profile" />}