@eintrek/erp-shell 0.1.53 → 0.1.55

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.esm.js CHANGED
@@ -5,7 +5,7 @@ import { useSession, signOut } from 'next-auth/react';
5
5
  import { useQueryClient, useQuery, QueryClientContext, QueryClient, MutationCache, QueryCache, QueryClientProvider } from '@tanstack/react-query';
6
6
  import { jsx, jsxs, Fragment as Fragment$1 } from 'react/jsx-runtime';
7
7
  import { cn, Button, Breadcrumb, BreadcrumbList, BreadcrumbItem, BreadcrumbLink, BreadcrumbSeparator, BreadcrumbPage, Avatar, AvatarImage, AvatarFallback, Collapsible, CollapsibleTrigger, CollapsibleContent, Badge, DropdownMenu, DropdownMenuTrigger, DropdownMenuContent, DropdownMenuLabel, DropdownMenuItem, DropdownMenuSeparator, Skeleton, Dialog, DialogContent, DialogHeader, DialogTitle, Label, Textarea, DialogFooter, Card, CardHeader, CardContent } from '@eintrek/erp-theme';
8
- import { PanelLeftClose, Menu, ChevronRight, Building2, Palette, ChevronUp, Sun, Moon, Monitor, Globe, User, LayoutGrid, ExternalLink, CircleHelp, Loader2, LogOut, ChevronsUpDown, Calculator, Warehouse, FolderKanban, Users, ChevronDown, Plus, ImagePlus, X, CircleCheck, ArrowLeft, ArrowRight, Compass, ArrowUpRight, Ban, Home, Headset, ContactRound, UserPlus } from 'lucide-react';
8
+ import { PanelLeftClose, Menu, ChevronRight, Building2, Palette, ChevronUp, Sun, Moon, Monitor, Globe, User, LayoutGrid, ExternalLink, CircleHelp, Loader2, LogOut, Calculator, Warehouse, FolderKanban, Users, ChevronDown, Plus, ChevronsUpDown, ImagePlus, X, CircleCheck, ArrowLeft, ArrowRight, Compass, ArrowUpRight, Ban, Home, Headset, ContactRound, UserPlus } from 'lucide-react';
9
9
  import { create } from 'zustand';
10
10
  import { persist, createJSONStorage } from 'zustand/middleware';
11
11
  import { useRouter, usePathname, useParams } from 'next/navigation';
@@ -576,13 +576,13 @@ const TapMenu = ({ tabDatas, starterTab, currentTabIndex, variant = "main", }) =
576
576
  tabDatas.map((tab, index) => {
577
577
  if (isMainTab) {
578
578
  // Main tab style: text with border-bottom indicator
579
- return (jsx("button", { type: "button", onClick: () => handleTabClick(index, tab.route), className: `w-fit lg:!w-41 h-10 p-2 text-[10px] lg:text-base text-white ${currentTab === index
579
+ return (jsx("button", { type: "button", onClick: () => handleTabClick(index, tab.route), className: `w-fit lg:!w-41 h-10 p-2 text-xs lg:text-base text-white ${currentTab === index
580
580
  ? "border-b-4 border-white text-white"
581
581
  : ""}`, children: tab.label }, index));
582
582
  }
583
583
  else {
584
584
  // Sub-tab style: rounded button style
585
- return (jsx(Button, { type: "button", variant: currentTab === index ? "default" : "outline", onClick: () => handleTabClick(index, tab.route), className: "h-7 lg:!h-10 text-[10px] lg:text-base p-1 lg:p-2 min-w-[20px] lg:min-w-41 w-fit rounded-[12px] lg:rounded-[40px]", children: tab.label }, index));
585
+ return (jsx(Button, { type: "button", variant: currentTab === index ? "default" : "outline", onClick: () => handleTabClick(index, tab.route), className: "h-7 lg:!h-10 text-xs lg:text-base p-1 lg:p-2 min-w-[20px] lg:min-w-41 w-fit rounded-[12px] lg:rounded-[40px]", children: tab.label }, index));
586
586
  }
587
587
  }) }), tabDatas[currentTab]?.page] }));
588
588
  };
@@ -781,14 +781,14 @@ function AppBreadcrumb({ labels = {}, homeLabel = "แดชบอร์ด", ro
781
781
  if (segments.length === 0) {
782
782
  return jsx("h1", { className: "text-xl font-semibold", children: homeLabel });
783
783
  }
784
- return (jsx(Breadcrumb, { children: jsxs(BreadcrumbList, { children: [jsx(BreadcrumbItem, { children: jsx(BreadcrumbLink, { asChild: true, children: jsx(Link, { href: "/", className: "font-thai text-[14px] font-normal text-[var(--header-fg-muted,rgb(255_255_255/0.8))] hover:text-[var(--header-fg,white)] transition-colors", children: rootLabel }) }) }), segments.map((segment, index) => {
784
+ return (jsx(Breadcrumb, { children: jsxs(BreadcrumbList, { children: [jsx(BreadcrumbItem, { children: jsx(BreadcrumbLink, { asChild: true, children: jsx(Link, { href: "/", className: "font-thai text-xs font-normal text-[var(--header-fg-muted,rgb(255_255_255/0.8))] hover:text-[var(--header-fg,white)] transition-colors", children: rootLabel }) }) }), segments.map((segment, index) => {
785
785
  const href = "/" + segments.slice(0, index + 1).join("/");
786
786
  const isLast = index === segments.length - 1;
787
787
  // A record id is not a place. Falling back to the raw segment put a
788
788
  // 36-character uuid in the trail, which pushed everything before it
789
789
  // off a phone and told the reader nothing they could use.
790
790
  const label = labels[segment] ?? (isRecordID(segment) ? "รายละเอียด" : segment);
791
- return (jsxs(Fragment, { children: [jsx(BreadcrumbSeparator, { className: "text-[var(--header-fg-muted,rgb(255_255_255/0.8))]", children: jsx(ChevronRight, { strokeWidth: 2, className: "h-4 w-4" }) }), jsx(BreadcrumbItem, { children: isLast ? (jsx(BreadcrumbPage, { className: "font-thai text-[14px] font-normal text-[var(--header-fg,rgb(255_255_255/0.95))] leading-none", children: decodeURIComponent(label) })) : (jsx(BreadcrumbLink, { asChild: true, children: jsx(Link, { href: href, className: "font-thai text-[14px] font-normal text-[var(--header-fg-muted,rgb(255_255_255/0.8))] hover:text-[var(--header-fg,white)] transition-colors leading-none", children: decodeURIComponent(label) }) })) })] }, `${segment}-${index}`));
791
+ return (jsxs(Fragment, { children: [jsx(BreadcrumbSeparator, { className: "text-[var(--header-fg-muted,rgb(255_255_255/0.8))]", children: jsx(ChevronRight, { strokeWidth: 2, className: "h-4 w-4" }) }), jsx(BreadcrumbItem, { children: isLast ? (jsx(BreadcrumbPage, { className: "font-thai text-xs font-normal text-[var(--header-fg,rgb(255_255_255/0.95))] leading-none", children: decodeURIComponent(label) })) : (jsx(BreadcrumbLink, { asChild: true, children: jsx(Link, { href: href, className: "font-thai text-xs font-normal text-[var(--header-fg-muted,rgb(255_255_255/0.8))] hover:text-[var(--header-fg,white)] transition-colors leading-none", children: decodeURIComponent(label) }) })) })] }, `${segment}-${index}`));
792
792
  })] }) }));
793
793
  }
794
794
  /**
@@ -936,6 +936,13 @@ function cardRoleLine(roles, limit = CARD_ROLE_LIMIT) {
936
936
  const names = roles.map(r => r.name_th);
937
937
  return { shown: names.slice(0, limit), more: Math.max(0, names.length - limit) };
938
938
  }
939
+ /**
940
+ * Workspace profile card: owner chip + "อีก N บทบาท", without listing role
941
+ * names on the trigger (full names stay in the account menu).
942
+ */
943
+ function workspaceRoleExtra(my) {
944
+ return my.roles.length;
945
+ }
939
946
  /** Everything, for the tooltip: "เจ้าของ · ผู้ดูแลสูงสุด · พนักงานทั่วไป". */
940
947
  function roleSummary(my) {
941
948
  return [...(my.isOwner ? [OWNER_CHIP] : []), ...my.roles.map(r => r.name_th)].join(" · ");
@@ -1472,14 +1479,19 @@ function useMyRoles(organizationId, enabled = true) {
1472
1479
  function OwnerChip({ size = "card" }) {
1473
1480
  return (jsx("span", { className: size === "menu"
1474
1481
  ? "inline-flex shrink-0 items-center rounded-md bg-primary/10 px-2 py-0.5 text-xs font-semibold text-primary"
1475
- : "inline-flex shrink-0 items-center rounded-full bg-primary/10 px-1.5 text-[11px] font-semibold leading-[17px] text-primary", children: OWNER_CHIP }));
1482
+ : "inline-flex shrink-0 items-center rounded-full bg-primary/10 px-1.5 text-xs font-semibold leading-[17px] text-primary", children: OWNER_CHIP }));
1476
1483
  }
1477
1484
  /**
1478
- * The card's role line: the owner's chip, then two role names and a count of
1479
- * the rest. Wraps between names rather than inside one, and truncates a name
1480
- * that is wider than the card on its own; the tooltip has everything.
1485
+ * Brand card: owner chip, then two role names and a count of the rest.
1486
+ * Workspace card: owner chip + "อีก N บทบาท" (names live in the menu).
1481
1487
  */
1482
- function CardRoles({ my, className }) {
1488
+ function CardRoles({ my, className, variant = "brand", }) {
1489
+ if (variant === "workspace") {
1490
+ const extra = workspaceRoleExtra(my);
1491
+ return (jsxs("span", { className: `flex min-w-0 flex-wrap items-center gap-1.5 ${className}`, title: roleSummary(my), children: [my.isOwner ? jsx(OwnerChip, {}) : null, !my.isOwner && my.roles[0] ? (jsx("span", { className: "truncate", children: my.roles[0].name_th })) : null, extra > 0 && (my.isOwner || my.roles.length > 1) ? (jsx("span", { className: "shrink-0 text-muted-foreground", children: my.isOwner
1492
+ ? `อีก ${extra} บทบาท`
1493
+ : `อีก ${extra - 1} บทบาท` })) : null] }));
1494
+ }
1483
1495
  const { shown, more } = cardRoleLine(my.roles);
1484
1496
  return (jsxs("span", { className: `flex min-w-0 flex-wrap items-center gap-x-1 gap-y-0.5 ${className}`, title: roleSummary(my), children: [my.isOwner ? jsx(OwnerChip, {}) : null, shown.map((name, i) => {
1485
1497
  const last = i === shown.length - 1;
@@ -1637,8 +1649,8 @@ function NavUser({ organization, avatarSrc, profileHref, selectOrganizationHref
1637
1649
  openHelp();
1638
1650
  }, className: "flex w-full items-center gap-3 px-3 py-2.5 text-sm text-sidebar-foreground hover:bg-sidebar-accent rounded-md transition-colors", children: [jsx(CircleHelp, { className: "h-4 w-4" }), jsx("span", { className: "flex-1 text-left", children: "\u0E0A\u0E48\u0E27\u0E22\u0E40\u0E2B\u0E25\u0E37\u0E2D" })] })), jsx("button", { onClick: handleSignOut, disabled: isSigningOut, className: "flex w-full items-center gap-3 px-3 py-2.5 text-sm text-sidebar-foreground hover:bg-sidebar-accent rounded-md transition-colors disabled:opacity-50 disabled:cursor-not-allowed mt-1", children: isSigningOut ? (jsxs(Fragment$1, { children: [jsx(Loader2, { className: "h-4 w-4 animate-spin" }), jsx("span", { className: "flex-1 text-left", children: "\u0E01\u0E33\u0E25\u0E31\u0E07\u0E2D\u0E2D\u0E01\u0E08\u0E32\u0E01\u0E23\u0E30\u0E1A\u0E1A..." })] })) : (jsxs(Fragment$1, { children: [jsx(LogOut, { className: "h-4 w-4" }), jsx("span", { className: "flex-1 text-left", children: "\u0E2D\u0E2D\u0E01\u0E08\u0E32\u0E01\u0E23\u0E30\u0E1A\u0E1A" })] })) })] })] })) : null;
1639
1651
  if (variant === "workspace") {
1640
- return (jsx("div", { className: "mt-3.5 border-t border-sidebar-border pt-3", children: jsxs("div", { className: "relative", children: [jsxs("button", { ref: buttonRef, onClick: () => setIsOpen(!isOpen), "aria-expanded": isOpen, className: `relative flex w-full gap-[11px] rounded-lg px-3 py-1.5 text-left transition-colors hover:bg-sidebar-accent/60 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-sidebar-ring ${cardTall ? "items-start" : "items-center"}`, children: [jsxs(Avatar, { className: "size-[34px] shrink-0 rounded-full border-[3px] border-sidebar-accent", children: [user.avatar ? (jsx(AvatarImage, { src: user.avatar, alt: user.name })) : null, jsx(AvatarFallback, { className: "rounded-full bg-sidebar-accent text-sm font-medium text-sidebar-accent-foreground", children: getInitials(user.name) })] }), jsxs("span", { className: `grid min-w-0 flex-1 leading-tight ${cardTall ? "gap-0.5" : ""}`, children: [jsx("strong", { className: `truncate text-[13px] font-semibold ${cardTall ? "pr-5" : ""}`, title: user.name, children: user.name }), myRoles ? (jsx(CardRoles, { my: myRoles, className: "text-[12px] font-medium leading-[17px] text-sidebar-foreground/80" })) : rolesLoading ? (jsx("span", { className: "my-[3px] block h-[11px] w-20 animate-pulse rounded bg-sidebar-accent" })) : null, jsx("small", { className: "truncate text-[11px] text-muted-foreground", title: user.email, children: user.email })] }), jsx(ChevronsUpDown, { className: cardTall
1641
- ? "absolute right-3 top-[9px] size-3.5 text-muted-foreground"
1652
+ return (jsx("div", { className: "mt-2.5 border-t border-sidebar-border pt-3.5", children: jsxs("div", { className: "relative", children: [jsxs("button", { ref: buttonRef, onClick: () => setIsOpen(!isOpen), "aria-expanded": isOpen, className: `relative flex w-full gap-2.5 rounded-[14px] border border-transparent bg-sidebar-accent/50 px-2.5 py-2.5 text-left transition-colors hover:border-sidebar-border hover:bg-sidebar-accent/70 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-sidebar-ring ${cardTall ? "items-start" : "items-center"}`, children: [jsxs(Avatar, { className: "size-[38px] shrink-0 rounded-full border border-sidebar-border", children: [user.avatar ? (jsx(AvatarImage, { src: user.avatar, alt: user.name })) : null, jsx(AvatarFallback, { className: "rounded-full bg-primary/10 text-[17px] font-medium text-primary", children: getInitials(user.name) })] }), jsxs("span", { className: "grid min-w-0 flex-1 gap-0.5 leading-tight", children: [jsx("strong", { className: `truncate text-[13px] font-semibold ${cardTall ? "pr-5" : ""}`, title: user.name, children: user.name }), jsx("small", { className: "truncate text-[11px] text-muted-foreground", title: user.email, children: user.email }), myRoles ? (jsx(CardRoles, { my: myRoles, variant: "workspace", className: "mt-0.5 text-[11px] font-medium leading-[17px] text-sidebar-foreground/80" })) : rolesLoading ? (jsx("span", { className: "my-[3px] block h-[11px] w-20 animate-pulse rounded bg-sidebar-accent" })) : null] }), jsx(ChevronUp, { className: cardTall
1653
+ ? "absolute right-2.5 top-3 size-3.5 text-muted-foreground"
1642
1654
  : "size-3.5 shrink-0 text-muted-foreground" })] }), typeof window !== "undefined" &&
1643
1655
  createPortal(dropdownContent, document.body)] }) }));
1644
1656
  }
@@ -1877,17 +1889,17 @@ function NavMain({ items, orgCode, closeOnNavigation = false, approvalCounts, ch
1877
1889
  const { itemUrl, activeSubItemUrl, isItemActive } = states[index];
1878
1890
  const IconComp = item.icon;
1879
1891
  const workspaceButton = workspace
1880
- ? "h-auto gap-3 rounded-[10px] px-3 py-2.5 text-[13px] " +
1892
+ ? "h-auto gap-3 rounded-[10px] px-3 py-2.5 text-xs " +
1881
1893
  (isItemActive
1882
1894
  ? "bg-sidebar-accent font-bold text-sidebar-accent-foreground"
1883
1895
  : "font-medium text-sidebar-foreground/70")
1884
1896
  : "";
1885
1897
  const icon = workspace && IconComp ? (jsx(IconComp, { className: "size-[18px] shrink-0" })) : null;
1886
- const badge = workspace && item.badge !== undefined && item.badge !== "" ? (jsx("span", { className: "ml-auto min-w-5 rounded-[5px] bg-primary/15 px-1 text-center text-[10px] leading-5 font-bold tabular-nums text-primary", children: item.badge })) : null;
1898
+ const badge = workspace && item.badge !== undefined && item.badge !== "" ? (jsx("span", { className: "ml-auto min-w-5 rounded-[5px] bg-primary/15 px-1 text-center text-xs leading-5 font-bold tabular-nums text-primary", children: item.badge })) : null;
1887
1899
  return (jsxs(React.Fragment, { children: [groupHeading, jsx(Collapsible, { asChild: true, open: openIds.has(item.id), onOpenChange: open => setItemOpen(item.id, open), className: "group/collapsible", children: jsxs(SidebarMenuItem, { children: [jsx(CollapsibleTrigger, { asChild: true, children: jsx(SidebarMenuButton, { asChild: !item.subModules || item.subModules.length === 0, isActive: isItemActive, className: "data-[state=open]:text-sidebar-accent-foreground " +
1888
1900
  workspaceButton, children: item.subModules && item.subModules.length > 0 ? (jsxs(Fragment$1, { children: [icon, jsx("span", { id: item.id, children: item.titleTh }), jsx(ChevronRight, { className: "ml-auto transition-transform duration-200 group-data-[state=open]/collapsible:rotate-90" })] })) : (jsxs(Link, { href: itemUrl, prefetch: false, className: "flex items-center w-full min-w-0 flex-1 " +
1889
1901
  (workspace ? "gap-3" : "gap-2"), onClick: handleNavLinkClick, "aria-current": isItemActive ? "page" : undefined, children: [icon, jsx("span", { id: item.id, className: "flex-1 truncate", title: item.titleTh, children: item.titleTh }), badge] })) }) }), item.subModules && item.subModules.length > 0 && (jsx(CollapsibleContent, { children: jsx(SidebarMenuSub, { className: workspace
1890
- ? "mx-0 mt-1 mb-3 ml-[21px] gap-0.5 border-l border-sidebar-border pl-2.5 [&_a]:h-auto [&_a]:gap-[11px] [&_a]:px-3 [&_a]:py-2 [&_a]:text-[13px] [&_svg]:!size-[17px]"
1902
+ ? "mx-0 mt-1 mb-3 ml-[21px] gap-0.5 border-l border-sidebar-border pl-2.5 [&_a]:h-auto [&_a]:gap-[11px] [&_a]:px-3 [&_a]:py-2 [&_a]:text-xs [&_svg]:!size-[17px]"
1891
1903
  : undefined, children: item.subModules.map(subItem => {
1892
1904
  const subItemUrl = buildUrlWithCode(code, subItem.url);
1893
1905
  const isSubItemActive = subItemUrl === activeSubItemUrl;
@@ -1973,7 +1985,7 @@ function OrganizationSwitcher({ activeOrganization, isContextLoading = false, or
1973
1985
  };
1974
1986
  const isLoading = isLoadingOrgs || isContextLoading;
1975
1987
  if (placement === "header") {
1976
- const face = (interactive) => (jsxs(Fragment$1, { children: [jsx(OrgMark, { logoUrl: activeOrganization?.logoUrl, size: "header" }), jsxs("span", { className: "min-w-0 text-left", children: [jsx("small", { className: "block text-[10px] leading-tight text-[var(--header-fg-muted,currentColor)] max-sm:text-[9px]", children: "\u0E2D\u0E07\u0E04\u0E4C\u0E01\u0E23\u0E17\u0E35\u0E48\u0E01\u0E33\u0E25\u0E31\u0E07\u0E43\u0E0A\u0E49\u0E07\u0E32\u0E19" }), isLoading ? (jsx(Skeleton, { className: "mt-1 h-3.5 w-28" })) : (jsx("strong", { className: "block max-w-[220px] truncate text-xs font-semibold text-[var(--header-fg,currentColor)] max-sm:max-w-[140px] max-sm:text-[11px]", children: activeOrganization?.name || "เลือกองค์กร" }))] }), interactive ? (isPending ? (jsx(Loader2, { className: "ml-1 size-3.5 shrink-0 animate-spin text-[var(--header-fg-muted,currentColor)]" })) : (jsx(ChevronsUpDown, { className: "ml-1 size-3.5 shrink-0 text-[var(--header-fg-muted,currentColor)]" }))) : null] }));
1988
+ const face = (interactive) => (jsxs(Fragment$1, { children: [jsx(OrgMark, { logoUrl: activeOrganization?.logoUrl, size: "header" }), jsxs("span", { className: "min-w-0 text-left", children: [jsx("small", { className: "block text-xs leading-tight text-[var(--header-fg-muted,currentColor)] max-sm:text-xs", children: "\u0E2D\u0E07\u0E04\u0E4C\u0E01\u0E23\u0E17\u0E35\u0E48\u0E01\u0E33\u0E25\u0E31\u0E07\u0E43\u0E0A\u0E49\u0E07\u0E32\u0E19" }), isLoading ? (jsx(Skeleton, { className: "mt-1 h-3.5 w-28" })) : (jsx("strong", { className: "block max-w-[220px] truncate text-xs font-semibold text-[var(--header-fg,currentColor)] max-sm:max-w-[140px] max-sm:text-xs", children: activeOrganization?.name || "เลือกองค์กร" }))] }), interactive ? (isPending ? (jsx(Loader2, { className: "ml-1 size-3.5 shrink-0 animate-spin text-[var(--header-fg-muted,currentColor)]" })) : (jsx(ChevronsUpDown, { className: "ml-1 size-3.5 shrink-0 text-[var(--header-fg-muted,currentColor)]" }))) : null] }));
1977
1989
  const faceClass = cn("flex items-center gap-2.5 rounded-lg py-1.5 max-sm:gap-2", className);
1978
1990
  if (isLoading || organizations.length <= 1) {
1979
1991
  return jsx("div", { className: faceClass, children: face(false) });
@@ -2003,7 +2015,7 @@ function AppSidebar({ modules, tools, activeModule, orgCode, approvalCounts, clo
2003
2015
  if (!open)
2004
2016
  return null;
2005
2017
  if (chrome === "workspace") {
2006
- return (jsxs("div", { className: cn("flex h-screen w-[244px] shrink-0 flex-col overflow-hidden border-r border-sidebar-border bg-sidebar text-sidebar-foreground",
2018
+ return (jsxs("div", { className: cn("flex h-screen w-[264px] shrink-0 flex-col overflow-hidden border-r border-sidebar-border bg-sidebar text-sidebar-foreground",
2007
2019
  // As a drawer (≤1024px) it floats over the page and needs the lift.
2008
2020
  "max-[1024px]:shadow-2xl", className), children: [header ? jsx("div", { className: "shrink-0 px-[18px] pt-8 pb-6", children: header }) : null, jsxs(SidebarContent, { className: "flex-1 overflow-y-auto px-[18px]", children: [jsx(NavMain, { items: modulesWithActiveState, orgCode: orgCode, approvalCounts: approvalCounts, closeOnNavigation: closeOnNavigation, chrome: "workspace", highlightActiveModule: highlightActiveModule }), jsx(NavTools, { tools: tools, closeOnNavigation: closeOnNavigation })] }), bottom ? jsx("div", { className: "shrink-0 px-[18px] pt-6", children: bottom }) : null, jsx("div", { className: "shrink-0 px-[18px] pb-3", children: footer })] }));
2009
2021
  }
@@ -2624,7 +2636,7 @@ function HelpAttachField({ state, disabled, id }) {
2624
2636
  return (jsxs("div", { className: "grid gap-2", children: [jsxs("div", { className: "flex flex-wrap items-start gap-2", children: [items.map(it => (jsx(AttachThumb, { item: it, onRemove: () => attach.remove(it.key), disabled: disabled }, it.key))), jsxs(Button, { type: "button", variant: "outline", size: "sm", disabled: disabled || full, onClick: () => {
2625
2637
  attach.dismissRejections();
2626
2638
  input.current?.click();
2627
- }, "aria-controls": id, className: items.length > 0 ? "h-16 w-16 flex-col gap-1 p-1 text-[11px]" : "gap-1.5", children: [jsx(ImagePlus, { className: "h-4 w-4" }), "\u0E41\u0E19\u0E1A\u0E23\u0E39\u0E1B"] }), jsx("input", { ref: input, id: id, type: "file", accept: HELP_IMAGE_ACCEPT, multiple: true, tabIndex: -1, "aria-hidden": "true", className: "sr-only", onChange: e => {
2639
+ }, "aria-controls": id, className: items.length > 0 ? "h-16 w-16 flex-col gap-1 p-1 text-xs" : "gap-1.5", children: [jsx(ImagePlus, { className: "h-4 w-4" }), "\u0E41\u0E19\u0E1A\u0E23\u0E39\u0E1B"] }), jsx("input", { ref: input, id: id, type: "file", accept: HELP_IMAGE_ACCEPT, multiple: true, tabIndex: -1, "aria-hidden": "true", className: "sr-only", onChange: e => {
2628
2640
  const files = e.currentTarget.files;
2629
2641
  if (files && files.length > 0)
2630
2642
  attach.add(Array.from(files));
@@ -2636,7 +2648,7 @@ function AttachThumb({ item, onRemove, disabled }) {
2636
2648
  return (jsxs("figure", { className: "relative m-0 w-16", children: [jsxs("div", { className: "relative h-16 w-16 overflow-hidden rounded-md border bg-muted " +
2637
2649
  (failed ? "border-destructive" : "border-border"), children: [item.preview ? (
2638
2650
  // eslint-disable-next-line @next/next/no-img-element
2639
- jsx("img", { src: item.preview, alt: item.name, className: "h-full w-full object-cover" })) : null, item.status === "uploading" ? (jsx("div", { role: "progressbar", "aria-label": `กำลังอัปโหลด ${item.name}`, "aria-valuemin": 0, "aria-valuemax": 100, "aria-valuenow": Math.round(item.progress * 100), className: "absolute inset-x-1 bottom-1 h-1.5 overflow-hidden rounded-full bg-background/80", children: jsx("div", { className: "h-full bg-primary transition-[width]", style: { width: `${Math.round(item.progress * 100)}%` } }) })) : null] }), jsx("button", { type: "button", onClick: onRemove, disabled: disabled, "aria-label": `ลบรูป ${item.name}`, title: "\u0E25\u0E1A\u0E23\u0E39\u0E1B", className: "absolute -right-1.5 -top-1.5 grid size-5 place-items-center rounded-full border border-border bg-background text-muted-foreground shadow-sm hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring disabled:opacity-50", children: jsx(X, { className: "h-3 w-3" }) }), jsx("figcaption", { className: "mt-0.5 truncate text-[10px] leading-tight text-muted-foreground", title: item.name, children: failed ? jsx("span", { className: "text-destructive", children: "\u0E44\u0E21\u0E48\u0E2A\u0E33\u0E40\u0E23\u0E47\u0E08" }) : kb(item.size) })] }));
2651
+ jsx("img", { src: item.preview, alt: item.name, className: "h-full w-full object-cover" })) : null, item.status === "uploading" ? (jsx("div", { role: "progressbar", "aria-label": `กำลังอัปโหลด ${item.name}`, "aria-valuemin": 0, "aria-valuemax": 100, "aria-valuenow": Math.round(item.progress * 100), className: "absolute inset-x-1 bottom-1 h-1.5 overflow-hidden rounded-full bg-background/80", children: jsx("div", { className: "h-full bg-primary transition-[width]", style: { width: `${Math.round(item.progress * 100)}%` } }) })) : null] }), jsx("button", { type: "button", onClick: onRemove, disabled: disabled, "aria-label": `ลบรูป ${item.name}`, title: "\u0E25\u0E1A\u0E23\u0E39\u0E1B", className: "absolute -right-1.5 -top-1.5 grid size-5 place-items-center rounded-full border border-border bg-background text-muted-foreground shadow-sm hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring disabled:opacity-50", children: jsx(X, { className: "h-3 w-3" }) }), jsx("figcaption", { className: "mt-0.5 truncate text-xs leading-tight text-muted-foreground", title: item.name, children: failed ? jsx("span", { className: "text-destructive", children: "\u0E44\u0E21\u0E48\u0E2A\u0E33\u0E40\u0E23\u0E47\u0E08" }) : kb(item.size) })] }));
2640
2652
  }
2641
2653
  /** Images already sent: thumbnails that open the full image. */
2642
2654
  function HelpImageStrip({ images, size = "md" }) {
@@ -3053,7 +3065,7 @@ function cx(...parts) {
3053
3065
  * name, and a spaced caption beneath it.
3054
3066
  */
3055
3067
  function WorkspaceBrand({ name, caption, mark, href, compact = false, className, }) {
3056
- const body = (jsxs(Fragment$1, { children: [jsx("span", { className: cn("grid shrink-0 place-items-center overflow-hidden rounded-[14px] [&>img]:size-full [&>img]:object-cover", compact ? "size-9 rounded-[11px]" : "size-11"), children: mark }), compact ? (jsx("span", { className: "sr-only", children: name })) : (jsxs("span", { className: "min-w-0", children: [jsx("span", { className: "block truncate text-[25px] leading-tight font-extrabold tracking-[-0.05em]", children: name }), caption ? (jsx("small", { className: "-mt-0.5 block truncate text-[9px] font-semibold tracking-[0.29em] text-muted-foreground", children: caption })) : null] }))] }));
3068
+ const body = (jsxs(Fragment$1, { children: [jsx("span", { className: cn("grid shrink-0 place-items-center overflow-hidden rounded-[12px] bg-transparent [&>img]:size-full [&>img]:object-contain", compact ? "size-9 rounded-[11px]" : "size-11"), children: mark }), compact ? (jsx("span", { className: "sr-only", children: name })) : (jsxs("span", { className: "min-w-0", children: [jsx("span", { className: "block truncate text-2xl leading-tight font-medium tracking-[-0.05em]", children: name }), caption ? (jsx("small", { className: "mt-0.5 block truncate text-[9px] font-semibold tracking-[0.3em] text-muted-foreground", children: caption })) : null] }))] }));
3057
3069
  const cls = cn("flex items-center gap-[11px] rounded-lg focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring", !compact && "px-4", className);
3058
3070
  return href ? (jsx(Link, { href: href, className: cls, "aria-label": compact ? name : undefined, children: body })) : (jsx("div", { className: cls, children: body }));
3059
3071
  }