Ui fixings
This commit is contained in:
@@ -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" />}
|
||||
|
||||
Reference in New Issue
Block a user