@spacesync/client 0.1.11 → 0.1.12
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/README.md +105 -13
- package/dist/analog-clock-picker.js +1 -1
- package/dist/booking-schedule-calendars.js +78 -9
- package/dist/booking-schedule-calendars.js.map +1 -1
- package/dist/booking-schedule.js +1 -1
- package/dist/booking-space-layout-picker.d.ts +1 -1
- package/dist/booking-space-layout-picker.js +2 -2
- package/dist/{chunk-OTSA5ROL.js → chunk-5CUJZNUC.js} +16 -5
- package/dist/chunk-5CUJZNUC.js.map +1 -0
- package/dist/{chunk-5NOKULX2.js → chunk-AHFRK6KP.js} +22 -5
- package/dist/chunk-AHFRK6KP.js.map +1 -0
- package/dist/{chunk-OV5ODANJ.js → chunk-EQLKSX4E.js} +22 -5
- package/dist/chunk-EQLKSX4E.js.map +1 -0
- package/dist/{chunk-RC5SWZPB.js → chunk-KXTYPZDK.js} +89 -18
- package/dist/chunk-KXTYPZDK.js.map +1 -0
- package/dist/chunk-ZVWUPYSV.js +170 -0
- package/dist/chunk-ZVWUPYSV.js.map +1 -0
- package/dist/{layout-canvas-view-DOjyUNJH.d.ts → layout-canvas-view-C3u96xu4.d.ts} +5 -1
- package/dist/layout-canvas-view.d.ts +1 -1
- package/dist/layout-canvas-view.js +2 -2
- package/dist/lib/dateDisplay.d.ts +16 -1
- package/dist/lib/dateDisplay.js +1 -1
- package/dist/notification-sidebar-preview.js +1 -1
- package/dist/page-list-chrome.d.ts +3 -1
- package/dist/page-list-chrome.js +1 -1
- package/dist/page-list-loading.js +1 -1
- package/dist/support-presence-status.js +1 -1
- package/dist/ui.d.ts +11 -1
- package/dist/ui.js +59 -15
- package/dist/ui.js.map +1 -1
- package/package.json +11 -5
- package/dist/chunk-5NOKULX2.js.map +0 -1
- package/dist/chunk-OTSA5ROL.js.map +0 -1
- package/dist/chunk-OV5ODANJ.js.map +0 -1
- package/dist/chunk-PBNBLCC2.js +0 -84
- package/dist/chunk-PBNBLCC2.js.map +0 -1
- package/dist/chunk-RC5SWZPB.js.map +0 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@spacesync/client",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.12",
|
|
4
4
|
"description": "Reusable SpaceSync React UI, shell, theme, and API client primitives.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"files": [
|
|
@@ -217,12 +217,18 @@
|
|
|
217
217
|
},
|
|
218
218
|
"repository": {
|
|
219
219
|
"type": "git",
|
|
220
|
-
"url": "https://github.com/
|
|
220
|
+
"url": "git+https://github.com/spacesync-pro/spacesync-client.git"
|
|
221
|
+
},
|
|
222
|
+
"homepage": "https://github.com/spacesync-pro/spacesync-client#readme",
|
|
223
|
+
"bugs": {
|
|
224
|
+
"url": "https://github.com/spacesync-pro/spacesync-client/issues"
|
|
221
225
|
},
|
|
222
|
-
"homepage": "https://github.com/YOUR_ORG/spacesync-client#readme",
|
|
223
|
-
"bugs": "https://github.com/YOUR_ORG/spacesync-client/issues",
|
|
224
226
|
"scripts": {
|
|
225
227
|
"build": "tsup",
|
|
226
|
-
"
|
|
228
|
+
"dev": "tsup --watch --onSuccess \"node scripts/sync-apps.mjs\"",
|
|
229
|
+
"typecheck": "tsc --noEmit -p tsconfig.json",
|
|
230
|
+
"sync:member": "pnpm build && node scripts/sync-apps.mjs member",
|
|
231
|
+
"sync:operator": "pnpm build && node scripts/sync-apps.mjs operator",
|
|
232
|
+
"sync:apps": "pnpm build && node scripts/sync-apps.mjs"
|
|
227
233
|
}
|
|
228
234
|
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/shell/page-list-sticky-columns.ts","../src/shell/page-list-chrome.tsx"],"names":[],"mappings":"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","file":"chunk-5NOKULX2.js","sourcesContent":["import { cn } from \"../ui/utils\";\n\nexport type PageListColumnFixed = \"left\" | \"right\";\n\nexport type PageListStickyColumnOptions = {\n side: PageListColumnFixed;\n layer: \"head\" | \"body\";\n sortActive?: boolean;\n};\n\nconst leftEdgeShadow = cn(\n \"after:pointer-events-none after:absolute after:inset-y-0 after:right-0 after:w-3 after:translate-x-full\",\n \"after:bg-gradient-to-r after:from-black/[0.06] after:to-transparent dark:after:from-black/20\",\n \"after:opacity-0 after:transition-opacity\",\n \"group-data-[scrolled-x=true]/table-scroll:after:opacity-100\",\n);\n\nconst rightEdgeShadow = cn(\n \"before:pointer-events-none before:absolute before:inset-y-0 before:left-0 before:w-3 before:-translate-x-full\",\n \"before:bg-gradient-to-l before:from-black/[0.06] before:to-transparent dark:before:from-black/20\",\n \"before:opacity-0 before:transition-opacity\",\n \"group-data-[scrolled-x-end=false]/table-scroll:before:opacity-100\",\n);\n\n/** Sticky left/right column classes for horizontally scrollable list tables (antd-style). */\nexport function pageListStickyColumnClass({\n side,\n layer,\n sortActive = false,\n}: PageListStickyColumnOptions): string {\n const isHead = layer === \"head\";\n const pin = side === \"left\" ? \"left-0\" : \"right-0\";\n const edgeShadow = side === \"left\" ? leftEdgeShadow : rightEdgeShadow;\n\n return cn(\n \"relative sticky\",\n pin,\n isHead ? \"top-0 z-[3]\" : \"z-[1]\",\n sortActive\n ? \"bg-blue-50/80 dark:bg-blue-950/40\"\n : isHead\n ? \"bg-card\"\n : \"bg-card group-hover:bg-accent\",\n edgeShadow,\n );\n}\n\n/** Use on tables with fixed columns instead of border-collapse. */\nexport const pageListTableWithFixedColumnsClass = \"border-separate border-spacing-0\";\n","import { useEffect, useRef, type ButtonHTMLAttributes, type MouseEvent, type ReactNode } from \"react\";\nimport { ChevronDown, ChevronUp, ChevronsUpDown } from \"lucide-react\";\nimport type { SortDirection } from \"../hooks/use-client-sort\";\nimport {\n pageListStickyColumnClass,\n pageListTableWithFixedColumnsClass,\n type PageListColumnFixed,\n} from \"./page-list-sticky-columns\";\nexport {\n pageListStickyColumnClass,\n pageListTableWithFixedColumnsClass,\n type PageListColumnFixed,\n} from \"./page-list-sticky-columns\";\nimport {\n shellTopBarNeutralActionDataAttr,\n shellTopBarOutlineButtonClass,\n shellTopBarPrimaryButtonClass,\n} from \"./shell-top-bar-chrome\";\nimport { cn } from \"../ui/utils\";\nimport { Button } from \"../ui/button\";\nimport { SearchField } from \"../ui/search-field\";\nimport {\n Pagination,\n PaginationContent,\n PaginationEllipsis,\n PaginationItem,\n PaginationLink,\n PaginationNext,\n PaginationPrevious,\n} from \"../ui/pagination\";\nimport {\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from \"../ui/select\";\nimport type { UseClientPaginationResult } from \"../hooks/use-client-pagination\";\n\n/** Fills the app main pane (white card on grey chrome). */\nexport function PageListRoot({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div className={cn(\"h-full flex flex-col min-h-0 bg-card\", className)} {...props} />\n );\n}\n\n/** White header block under the app chrome. */\nexport function PageListHeader({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n className={cn(\"shrink-0 bg-card border-b border-border px-5 pt-4 pb-4\", className)}\n {...props}\n />\n );\n}\n\nexport function PageListTitleRow({\n title,\n subtitle,\n actions,\n titleAddon,\n}: {\n title: ReactNode;\n subtitle?: string;\n actions?: ReactNode;\n /** Rendered before the title (e.g. live indicator). */\n titleAddon?: ReactNode;\n}) {\n return (\n <div className=\"flex flex-col gap-4 lg:flex-row lg:items-start lg:justify-between\">\n <div>\n {titleAddon ? (\n <div className=\"flex items-center gap-2 mb-1\">\n {titleAddon}\n <h1 className=\"text-base font-semibold text-foreground\">{title}</h1>\n </div>\n ) : (\n <h1 className=\"text-base font-semibold text-foreground\">{title}</h1>\n )}\n {subtitle ? <p className=\"text-xs text-muted-foreground mt-1\">{subtitle}</p> : null}\n </div>\n {actions ? (\n <div className=\"flex flex-wrap items-center gap-2 shrink-0\">{actions}</div>\n ) : null}\n </div>\n );\n}\n\n/** Primary CTA in a page list header (e.g. New announcement). */\nexport function PageListPrimaryActionButton({\n className,\n ...props\n}: ButtonHTMLAttributes<HTMLButtonElement>) {\n return (\n <Button\n type=\"button\"\n className={cn(\n \"h-9 gap-1.5 rounded-xl bg-blue-500 px-4 text-sm font-medium text-white hover:bg-blue-600\",\n className,\n )}\n {...props}\n />\n );\n}\n\n/** Secondary CTA for empty states and alternate actions. */\nexport function PageListSecondaryActionButton({\n className,\n ...props\n}: ButtonHTMLAttributes<HTMLButtonElement>) {\n return (\n <Button\n type=\"button\"\n variant=\"outline\"\n className={cn(\n \"h-9 gap-1.5 rounded-xl border-border bg-card px-4 text-sm font-medium text-foreground hover:bg-accent\",\n className,\n )}\n {...props}\n />\n );\n}\n\n/** Primary CTA rendered in {@link ShellTopBar} actions on the dark shell. */\nexport function ShellTopBarPrimaryActionButton({\n className,\n ...props\n}: ButtonHTMLAttributes<HTMLButtonElement>) {\n return (\n <Button type=\"button\" size=\"sm\" className={cn(shellTopBarPrimaryButtonClass, className)} {...props} />\n );\n}\n\n/** Secondary / outline CTA in {@link ShellTopBar} — same chrome as detail header actions (Edit member, Add adjustment). */\nexport function ShellTopBarSecondaryActionButton({\n className,\n ...props\n}: ButtonHTMLAttributes<HTMLButtonElement>) {\n return (\n <Button\n type=\"button\"\n variant=\"outline\"\n size=\"sm\"\n className={cn(shellTopBarOutlineButtonClass, className)}\n {...props}\n />\n );\n}\n\nexport { shellTopBarNeutralActionDataAttr };\n\n/** Search, filters, or secondary controls (spacing matches Live space). */\nexport function PageListToolbar({ className, ...props }: React.ComponentProps<\"div\">) {\n return <div className={cn(\"mt-4 flex flex-col gap-3 items-start\", className)} {...props} />;\n}\n\n/** Compact KPI tiles (Live space stat row). */\nexport function PageListStatGrid({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n className={cn(\"mt-4 grid grid-cols-2 gap-2 sm:grid-cols-4\", className)}\n {...props}\n />\n );\n}\n\nexport type PageListStatTone = \"default\" | \"danger\" | \"success\";\n\nexport function PageListStatCard({\n label,\n value,\n tone = \"default\",\n}: {\n label: string;\n value: ReactNode;\n tone?: PageListStatTone;\n}) {\n const shell =\n tone === \"danger\"\n ? \"border-red-100 bg-red-50/80\"\n : tone === \"success\"\n ? \"border-emerald-100 bg-emerald-50/80\"\n : \"border-border bg-muted\";\n const labelClass =\n tone === \"danger\"\n ? \"text-red-600/80\"\n : tone === \"success\"\n ? \"text-emerald-700/80\"\n : \"text-muted-foreground\";\n const valueClass =\n tone === \"danger\" ? \"text-red-700\" : tone === \"success\" ? \"text-emerald-800\" : \"text-foreground\";\n\n return (\n <div className={cn(\"rounded-lg border px-3 py-2\", shell)}>\n <p className={cn(\"text-[11px] mb-0.5\", labelClass)}>{label}</p>\n <p className={cn(\"text-sm font-semibold tabular-nums\", valueClass)}>{value}</p>\n </div>\n );\n}\n\n/** Scrollable white region for tables / lists. Stay flush horizontally; table cells provide inset (same as Live space). */\nexport function PageListTableArea({ className, ...props }: React.ComponentProps<\"div\">) {\n const ref = useRef<HTMLDivElement>(null);\n\n useEffect(() => {\n const el = ref.current;\n if (!el) return;\n\n const syncScrollState = () => {\n if (el.scrollLeft > 0) {\n el.dataset.scrolledX = \"true\";\n } else {\n delete el.dataset.scrolledX;\n }\n\n const atRightEnd = el.scrollLeft + el.clientWidth >= el.scrollWidth - 1;\n if (!atRightEnd && el.scrollWidth > el.clientWidth) {\n el.dataset.scrolledXEnd = \"false\";\n } else {\n delete el.dataset.scrolledXEnd;\n }\n };\n\n syncScrollState();\n el.addEventListener(\"scroll\", syncScrollState, { passive: true });\n const resizeObserver = new ResizeObserver(syncScrollState);\n resizeObserver.observe(el);\n if (el.firstElementChild) {\n resizeObserver.observe(el.firstElementChild);\n }\n\n return () => {\n el.removeEventListener(\"scroll\", syncScrollState);\n resizeObserver.disconnect();\n };\n }, []);\n\n return (\n <div\n ref={ref}\n className={cn(\n \"group/table-scroll flex-1 min-h-0 overflow-auto bg-card border-t border-border\",\n className,\n )}\n {...props}\n />\n );\n}\n\n/** Search input styling shared with Live space. */\nexport function PageListSearchField({\n value,\n onChange,\n placeholder,\n className,\n}: {\n value: string;\n onChange: (v: string) => void;\n placeholder: string;\n className?: string;\n}) {\n return (\n <SearchField\n value={value}\n onChange={onChange}\n placeholder={placeholder}\n className={className}\n />\n );\n}\n\n/** Sticky table header row (Live space). */\nexport function PageListStickyThead({ children }: { children: ReactNode }) {\n return (\n <thead className=\"sticky top-0 z-[2] bg-card shadow-[0_1px_0_0_var(--border)]\">\n {children}\n </thead>\n );\n}\n\n/** Non-sticky thead for embedded detail tables. */\nexport function PageListThead({ className, ...props }: React.ComponentProps<\"thead\">) {\n return <thead className={cn(\"border-b border-border\", className)} {...props} />;\n}\n\n/** Standard `<table>` shell for list and detail tables. */\nexport function PageListTable({\n minWidth,\n fixedColumns = false,\n compact = false,\n className,\n style,\n ...props\n}: React.ComponentProps<\"table\"> & {\n minWidth?: number;\n fixedColumns?: boolean;\n compact?: boolean;\n}) {\n return (\n <table\n className={cn(\n \"w-full text-left text-sm\",\n fixedColumns ? pageListTableWithFixedColumnsClass : \"border-collapse\",\n compact && \"border-collapse\",\n className,\n )}\n style={minWidth != null ? { ...style, minWidth: `${minWidth}px` } : style}\n {...props}\n />\n );\n}\n\n/** Standard header row styling for column labels. */\nexport function PageListHeaderRow({ className, ...props }: React.ComponentProps<\"tr\">) {\n return (\n <tr\n className={cn(\"text-[10px] uppercase tracking-wide text-muted-foreground\", className)}\n {...props}\n />\n );\n}\n\nexport type PageListTdTone = \"default\" | \"primary\" | \"muted\" | \"mono\";\nexport type PageListCellSize = \"default\" | \"comfortable\";\n\nconst pageListTdToneClass: Record<PageListTdTone, string> = {\n default: \"text-xs text-foreground\",\n primary: \"text-xs font-medium text-foreground\",\n muted: \"text-xs text-muted-foreground\",\n mono: \"text-xs font-mono text-muted-foreground\",\n};\n\nconst pageListTdSizeClass: Record<PageListCellSize, string> = {\n default: \"px-2 py-2.5 first:pl-5 last:pr-5\",\n comfortable: \"px-5 py-3.5 first:pl-5 last:pr-5\",\n};\n\n/** Standard data row — border, hover, optional click navigation. */\nexport function PageListTr({\n onClick,\n selected = false,\n className,\n onKeyDown,\n ...props\n}: React.ComponentProps<\"tr\"> & {\n onClick?: () => void;\n selected?: boolean;\n}) {\n const clickable = Boolean(onClick);\n\n return (\n <tr\n role={clickable ? \"link\" : undefined}\n tabIndex={clickable ? 0 : undefined}\n onClick={onClick}\n onKeyDown={\n clickable && onClick\n ? (e) => {\n onKeyDown?.(e);\n if (e.defaultPrevented) return;\n if (e.key === \"Enter\" || e.key === \" \") {\n e.preventDefault();\n onClick();\n }\n }\n : onKeyDown\n }\n className={cn(\n \"border-b border-border last:border-0 transition-colors\",\n clickable &&\n \"group cursor-pointer hover:bg-accent outline-none focus-visible:ring-2 focus-visible:ring-blue-400 focus-visible:ring-inset\",\n selected && \"bg-accent/60\",\n className,\n )}\n {...props}\n />\n );\n}\n\nexport const pageListThClass =\n \"font-medium py-2.5 px-2 text-left text-[10px] uppercase tracking-wide text-muted-foreground first:pl-5 last:pr-5\";\n\nexport const pageListTdClass = pageListTdSizeClass.default;\n\nexport function PageListTh({\n children,\n columnFixed,\n align = \"left\",\n className,\n ...props\n}: React.ComponentProps<\"th\"> & {\n columnFixed?: PageListColumnFixed;\n align?: \"left\" | \"right\";\n}) {\n return (\n <th\n className={cn(\n pageListThClass,\n align === \"right\" && \"text-right\",\n columnFixed &&\n pageListStickyColumnClass({ side: columnFixed, layer: \"head\" }),\n className,\n )}\n {...props}\n >\n {children}\n </th>\n );\n}\n\nexport function PageListTd({\n children,\n columnFixed,\n align = \"left\",\n tone = \"default\",\n size = \"default\",\n className,\n ...props\n}: React.ComponentProps<\"td\"> & {\n columnFixed?: PageListColumnFixed;\n align?: \"left\" | \"right\";\n tone?: PageListTdTone;\n size?: PageListCellSize;\n}) {\n return (\n <td\n className={cn(\n pageListTdSizeClass[size],\n pageListTdToneClass[tone],\n tone === \"mono\" && align === \"right\" && \"font-medium text-foreground\",\n align === \"right\" && \"text-right\",\n columnFixed &&\n pageListStickyColumnClass({ side: columnFixed, layer: \"body\" }),\n className,\n )}\n {...props}\n >\n {children}\n </td>\n );\n}\n\nexport function PageListSortableTh<K extends string>({\n label,\n columnKey,\n sortKey,\n direction,\n onSort,\n align = \"left\",\n columnFixed,\n className,\n}: {\n label: ReactNode;\n columnKey: K;\n sortKey: K;\n direction: SortDirection;\n onSort: (key: K) => void;\n align?: \"left\" | \"right\";\n columnFixed?: PageListColumnFixed;\n className?: string;\n}) {\n const active = sortKey === columnKey;\n const ariaSort = active ? (direction === \"asc\" ? \"ascending\" : \"descending\") : undefined;\n const DirectionIcon = direction === \"asc\" ? ChevronUp : ChevronDown;\n\n return (\n <th\n className={cn(\n pageListThClass,\n align === \"right\" && \"text-right\",\n active &&\n \"text-blue-700 shadow-[inset_0_-2px_0_0_rgb(59,130,246)] dark:text-blue-300\",\n columnFixed &&\n pageListStickyColumnClass({\n side: columnFixed,\n layer: \"head\",\n sortActive: active,\n }),\n !columnFixed &&\n active &&\n \"bg-blue-50/80 dark:bg-blue-950/40\",\n className,\n )}\n aria-sort={ariaSort}\n >\n <Button\n type=\"button\"\n variant=\"ghost\"\n onClick={() => onSort(columnKey)}\n className={cn(\n \"group inline-flex h-auto w-full gap-1 rounded-none border-0 p-0 shadow-none\",\n \"text-[10px] font-medium uppercase tracking-wide\",\n \"hover:bg-transparent\",\n active\n ? \"text-blue-700 dark:text-blue-300\"\n : \"text-muted-foreground hover:text-foreground\",\n align === \"right\" ? \"justify-end\" : \"justify-start\",\n )}\n >\n <span>{label}</span>\n {active ? (\n <DirectionIcon\n size={12}\n strokeWidth={2}\n className=\"shrink-0 text-blue-600 dark:text-blue-400\"\n aria-hidden\n />\n ) : (\n <ChevronsUpDown\n size={12}\n strokeWidth={2}\n className=\"shrink-0 opacity-40 transition-opacity group-hover:opacity-70\"\n aria-hidden\n />\n )}\n </Button>\n </th>\n );\n}\n\nfunction getVisiblePages(page: number, totalPages: number): (number | \"ellipsis\")[] {\n if (totalPages <= 5) {\n return Array.from({ length: totalPages }, (_, i) => i + 1);\n }\n\n const pages = new Set<number>([1, totalPages, page - 1, page, page + 1]);\n const sorted = [...pages].filter((p) => p >= 1 && p <= totalPages).sort((a, b) => a - b);\n\n const result: (number | \"ellipsis\")[] = [];\n for (let i = 0; i < sorted.length; i += 1) {\n const current = sorted[i]!;\n const prev = sorted[i - 1];\n if (prev !== undefined && current - prev > 1) {\n result.push(\"ellipsis\");\n }\n result.push(current);\n }\n return result;\n}\n\nfunction paginationLinkClick(page: number, setPage: (page: number) => void) {\n return (event: MouseEvent<HTMLAnchorElement>) => {\n event.preventDefault();\n setPage(page);\n };\n}\n\nexport type PageListPaginationProps = Pick<\n UseClientPaginationResult<unknown>,\n | \"page\"\n | \"setPage\"\n | \"pageSize\"\n | \"setPageSize\"\n | \"pageSizeOptions\"\n | \"totalItems\"\n | \"totalPages\"\n | \"rangeStart\"\n | \"rangeEnd\"\n | \"canPrev\"\n | \"canNext\"\n>;\n\n/** Footer bar for paginated list tables — count, page-size selector, and page controls. */\nexport function PageListPagination({\n page,\n setPage,\n pageSize,\n setPageSize,\n pageSizeOptions,\n totalItems,\n totalPages,\n rangeStart,\n rangeEnd,\n canPrev,\n canNext,\n}: PageListPaginationProps) {\n if (totalItems === 0) return null;\n\n const visiblePages = getVisiblePages(page, totalPages);\n const showPageControls = totalPages > 1;\n\n return (\n <div\n className=\"shrink-0 flex flex-col gap-3 border-t border-border bg-card px-5 py-3 sm:flex-row sm:items-center sm:justify-between\"\n >\n <p className=\"text-sm text-muted-foreground tabular-nums\">\n Showing <span className=\"font-medium text-foreground\">{rangeStart}</span>\n {\"–\"}\n <span className=\"font-medium text-foreground\">{rangeEnd}</span> of{\" \"}\n <span className=\"font-medium text-foreground\">{totalItems}</span>\n </p>\n\n <div className=\"flex flex-col gap-3 sm:flex-row sm:items-center sm:gap-4\">\n <div className=\"flex items-center gap-2\">\n <span className=\"text-sm text-muted-foreground whitespace-nowrap\">Rows per page</span>\n <Select\n value={String(pageSize)}\n onValueChange={(value) => setPageSize(Number(value))}\n >\n <SelectTrigger className=\"h-8 w-[72px] rounded-lg border-border bg-card text-sm\">\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n {pageSizeOptions.map((option) => (\n <SelectItem key={option} value={String(option)}>\n {option}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n\n {showPageControls ? (\n <Pagination className=\"mx-0 w-auto justify-end\">\n <PaginationContent>\n <PaginationItem>\n <PaginationPrevious\n href=\"#\"\n aria-disabled={!canPrev}\n className={cn(!canPrev && \"pointer-events-none opacity-50\")}\n onClick={\n canPrev\n ? paginationLinkClick(page - 1, setPage)\n : (event) => event.preventDefault()\n }\n />\n </PaginationItem>\n {visiblePages.map((pageNum, index) =>\n pageNum === \"ellipsis\" ? (\n <PaginationItem key={`ellipsis-${index}`}>\n <PaginationEllipsis />\n </PaginationItem>\n ) : (\n <PaginationItem key={pageNum}>\n <PaginationLink\n href=\"#\"\n isActive={pageNum === page}\n onClick={paginationLinkClick(pageNum, setPage)}\n >\n {pageNum}\n </PaginationLink>\n </PaginationItem>\n ),\n )}\n <PaginationItem>\n <PaginationNext\n href=\"#\"\n aria-disabled={!canNext}\n className={cn(!canNext && \"pointer-events-none opacity-50\")}\n onClick={\n canNext\n ? paginationLinkClick(page + 1, setPage)\n : (event) => event.preventDefault()\n }\n />\n </PaginationItem>\n </PaginationContent>\n </Pagination>\n ) : null}\n </div>\n </div>\n );\n}\n\n/** Empty state for list pages inside PageListTableArea. */\nexport function PageListEmptyState({\n title,\n description,\n icon,\n action,\n variant = \"minimal\",\n className,\n}: {\n title: string;\n description?: string;\n icon?: ReactNode;\n action?: ReactNode;\n variant?: \"minimal\" | \"illustrated\";\n className?: string;\n}) {\n if (variant === \"minimal\") {\n return (\n <div\n className={cn(\n \"flex flex-col items-center justify-center py-24 gap-2\",\n className,\n )}\n >\n <span className=\"text-sm text-muted-foreground\">{title}</span>\n {description ? (\n <span className=\"text-xs text-muted-foreground\">{description}</span>\n ) : null}\n {action}\n </div>\n );\n }\n\n return (\n <div\n className={cn(\n \"flex flex-col items-center justify-center py-20 gap-3 border-2 border-dashed border-border rounded-2xl bg-muted/50\",\n className,\n )}\n >\n {icon ? (\n <div className=\"w-10 h-10 rounded-2xl bg-muted flex items-center justify-center\">\n {icon}\n </div>\n ) : null}\n <div className=\"flex flex-col items-center gap-1 text-center px-4\">\n <p className=\"text-sm text-muted-foreground font-medium\">{title}</p>\n {description ? (\n <p className=\"text-xs text-muted-foreground max-w-sm\">{description}</p>\n ) : null}\n </div>\n {action}\n </div>\n );\n}\n\n/** Bordered scroll wrapper for embedded detail tables. */\nexport function DetailTableFrame({\n className,\n children,\n ...props\n}: React.ComponentProps<\"div\">) {\n return (\n <div\n className={cn(\"overflow-x-auto rounded-xl border border-border\", className)}\n {...props}\n >\n {children}\n </div>\n );\n}\n\n/** Flat content section for detail pages — title + optional description + optional header action, separated by a thin divider. */\nexport function DetailSection({\n title,\n description,\n headerMeta,\n headerAction,\n children,\n}: {\n title: string;\n description?: string;\n /** Right-aligned non-interactive meta (counts, tax note). */\n headerMeta?: ReactNode;\n headerAction?: ReactNode;\n children: ReactNode;\n}) {\n return (\n <div className=\"border-b border-border px-6 py-6 last:border-0\">\n <div className=\"flex items-start justify-between gap-4 mb-4\">\n <div>\n <h2 className=\"text-sm font-semibold text-foreground\">{title}</h2>\n {description && <p className=\"text-xs text-muted-foreground mt-0.5\">{description}</p>}\n </div>\n {headerAction ? (\n headerAction\n ) : headerMeta ? (\n <div className=\"shrink-0 text-xs text-muted-foreground\">{headerMeta}</div>\n ) : null}\n </div>\n {children}\n </div>\n );\n}\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/lib/booking-schedule.ts"],"names":[],"mappings":"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","file":"chunk-OTSA5ROL.js","sourcesContent":["/**\n * Date / schedule helpers used by booking-schedule calendars.\n */\n\nexport type RepeatType = \"none\" | \"daily\" | \"weekly\" | \"monthly\";\nexport type BookingMode = \"slots\" | \"schedule\";\nexport type ScheduleChargeBy = \"minutes\" | \"hours\" | \"days\" | \"weeks\" | \"months\" | \"quantity\";\n\nexport type PartialElapsedUnit = \"days\" | \"hours\" | \"minutes\";\n\nexport interface PartialElapsed {\n amount: number;\n unit: PartialElapsedUnit;\n}\n\n/** Editor state for slot / schedule / daily / item shaped tiers */\nexport interface BookingState {\n slotCount: number;\n bookingDate: string;\n bookingMode: BookingMode;\n scheduleDate: string;\n scheduleTime: string;\n scheduleEndTime: string;\n repeatType: RepeatType;\n repeatEveryDays: number;\n repeatEveryWeeks: number;\n repeatOnDays: string[];\n repeatEveryMonths: number;\n repeatUntilDate: string;\n startDate: string;\n endDate: string;\n monthFrom: string;\n monthTo: string;\n weekFrom: string;\n weekCount: number;\n itemQuantity: number;\n oneDayBooking?: boolean;\n}\n\nexport interface ScheduleDefaultsConfig {\n chargeBy: ScheduleChargeBy;\n}\n\n/** YYYY-MM-DD in local timezone (never UTC ISO split). */\nexport function localDateYmd(d: Date): string {\n const y = d.getFullYear();\n const m = String(d.getMonth() + 1).padStart(2, \"0\");\n const day = String(d.getDate()).padStart(2, \"0\");\n return `${y}-${m}-${day}`;\n}\n\nexport function todayLocalYmd(now: Date = new Date()): string {\n return localDateYmd(now);\n}\n\n/** @deprecated Prefer `todayLocalYmd()` — kept for existing imports. */\nexport function pricingTodayYmd(now: Date = new Date()): string {\n return todayLocalYmd(now);\n}\n\nexport const PRICING_TODAY = todayLocalYmd();\n\nexport function currentMonthYm(now: Date = new Date()): string {\n return `${now.getFullYear()}-${String(now.getMonth() + 1).padStart(2, \"0\")}`;\n}\n\n/** Monday of the current local week (YYYY-MM-DD). */\nexport function currentWeekStart(now: Date = new Date()): string {\n const d = new Date(now.getFullYear(), now.getMonth(), now.getDate());\n const day = d.getDay();\n const offset = day === 0 ? -6 : 1 - day;\n d.setDate(d.getDate() + offset);\n return localDateYmd(d);\n}\n\n/** First full month default: next month if today is past the 1st, else current month. */\nexport function computeMinMonth(now: Date = new Date()): string {\n if (now.getDate() === 1) {\n return currentMonthYm(now);\n }\n const n = new Date(now.getFullYear(), now.getMonth() + 1, 1);\n return currentMonthYm(n);\n}\n\n/** First full week default: next Monday unless today is already Monday. */\nexport function computeMinWeekStart(now: Date = new Date()): string {\n const day = now.getDay();\n if (day === 1) return todayLocalYmd(now);\n const d = new Date(now.getFullYear(), now.getMonth(), now.getDate());\n const skip = day === 0 ? 1 : 8 - day;\n d.setDate(d.getDate() + skip);\n return localDateYmd(d);\n}\n\nexport const MIN_MONTH = computeMinMonth();\nexport const MIN_WEEK_START = computeMinWeekStart();\n\nexport const IS_PARTIAL_MONTH = new Date().getDate() !== 1;\n\nexport function monthLabel(ym: string): string {\n const [y, m] = ym.split(\"-\").map(Number);\n return new Date(y, m - 1, 1).toLocaleDateString(\"en-US\", { month: \"long\", year: \"numeric\" });\n}\n\nexport function monthCount(from: string, to: string): number {\n if (!from || !to || !from.includes(\"-\") || !to.includes(\"-\")) return 0;\n const [fy, fm] = from.split(\"-\").map(Number);\n const [ty, tm] = to.split(\"-\").map(Number);\n return (ty - fy) * 12 + (tm - fm) + 1;\n}\n\nexport function weekRangeLabel(weekFrom: string, weekCount: number): string {\n if (!weekFrom || isNaN(new Date(weekFrom + \"T00:00:00\").getTime())) return \"—\";\n const end = parseDateOnly(weekFrom);\n end.setDate(end.getDate() + weekCount * 7 - 1);\n const s = parseDateOnly(weekFrom).toLocaleDateString(\"en-US\", { month: \"short\", day: \"numeric\" });\n const e = end.toLocaleDateString(\"en-US\", { month: \"short\", day: \"numeric\", year: \"numeric\" });\n return `${s} – ${e}`;\n}\n\n/** Inclusive number of Mon-anchored weeks from `weekFrom` through `weekToMon`. */\nexport function weekCountBetween(weekFrom: string, weekToMon: string): number {\n if (!weekFrom || !weekToMon) return 0;\n if (weekToMon < weekFrom) return 1;\n return Math.floor(diffDays(weekFrom, weekToMon) / 7) + 1;\n}\n\nexport function addMonthsYm(ym: string, delta: number): string {\n const [y, m] = ym.split(\"-\").map(Number);\n const d = new Date(y, (m ?? 1) - 1 + delta, 1);\n return `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, \"0\")}`;\n}\n\nfunction parseDateOnly(date: string): Date {\n const [y, m, d] = date.split(\"-\").map(Number);\n return new Date(y, m - 1, d);\n}\n\nexport function diffDays(a: string, b: string): number {\n const da = parseDateOnly(a);\n const db = parseDateOnly(b);\n return Math.max(0, Math.round((db.getTime() - da.getTime()) / 86_400_000));\n}\n\nexport function addDays(date: string, days: number): string {\n const d = parseDateOnly(date);\n d.setDate(d.getDate() + days);\n return localDateYmd(d);\n}\n\nfunction hmMinutes(hm: string): number | null {\n const [h, m] = hm.split(\":\").map(Number);\n if (!Number.isFinite(h) || !Number.isFinite(m)) return null;\n return h * 60 + m;\n}\n\nfunction isSlotCharge(chargeBy: ScheduleChargeBy): boolean {\n return chargeBy === \"hours\" || chargeBy === \"minutes\";\n}\n\nfunction isPeriodCharge(chargeBy: ScheduleChargeBy): boolean {\n return chargeBy === \"days\" || chargeBy === \"weeks\" || chargeBy === \"months\";\n}\n\nfunction snapScheduleEndTime(from: string, end: string, chargeBy: ScheduleChargeBy): string {\n if (end && end > from) return end;\n const fromMin = hmMinutes(from);\n if (fromMin == null) return end || \"10:00\";\n const delta = chargeBy === \"minutes\" ? 1 : 60;\n const next = fromMin + delta;\n return `${String(Math.floor(next / 60)).padStart(2, \"0\")}:${String(next % 60).padStart(2, \"0\")}`;\n}\n\nfunction minNeededTimeHm(prepMinutes: number, now: Date = new Date()): string {\n const earliest = new Date(now.getTime() + prepMinutes * 60_000);\n if (earliest.getSeconds() > 0 || earliest.getMilliseconds() > 0) {\n earliest.setMinutes(earliest.getMinutes() + 1);\n }\n earliest.setSeconds(0, 0);\n return `${String(earliest.getHours()).padStart(2, \"0\")}:${String(earliest.getMinutes()).padStart(2, \"0\")}`;\n}\n\n/** Elapsed time in the selected in-progress booking period, if any. */\nexport function partialElapsed(\n config: ScheduleDefaultsConfig,\n booking: BookingState,\n now: Date = new Date(),\n): PartialElapsed | null {\n const today = todayLocalYmd(now);\n\n if (config.chargeBy === \"months\") {\n const cur = currentMonthYm(now);\n const min = computeMinMonth(now);\n if (!booking.monthFrom || booking.monthFrom !== cur || booking.monthFrom >= min) return null;\n const days = diffDays(`${booking.monthFrom}-01`, today);\n return days > 0 ? { amount: days, unit: \"days\" } : null;\n }\n\n if (config.chargeBy === \"weeks\") {\n const cur = currentWeekStart(now);\n const min = computeMinWeekStart(now);\n if (!booking.weekFrom || booking.weekFrom !== cur || booking.weekFrom >= min) return null;\n const days = diffDays(booking.weekFrom, today);\n return days > 0 ? { amount: days, unit: \"days\" } : null;\n }\n\n if (config.chargeBy === \"days\") {\n if (!booking.startDate) return null;\n if (booking.startDate < today) {\n const days = diffDays(booking.startDate, today);\n return days > 0 ? { amount: days, unit: \"days\" } : null;\n }\n if (booking.oneDayBooking !== false && booking.startDate === today) {\n const hours = now.getHours() + now.getMinutes() / 60;\n const rounded = Math.floor(hours);\n return rounded > 0 ? { amount: rounded, unit: \"hours\" } : null;\n }\n return null;\n }\n\n if (isSlotCharge(config.chargeBy)) {\n if (booking.scheduleDate !== today || !booking.scheduleTime) return null;\n const startMin = hmMinutes(booking.scheduleTime);\n const nowMin = now.getHours() * 60 + now.getMinutes();\n if (startMin == null || startMin >= nowMin) return null;\n const elapsed = nowMin - startMin;\n if (config.chargeBy === \"minutes\") {\n return elapsed > 0 ? { amount: elapsed, unit: \"minutes\" } : null;\n }\n const hours = Math.floor(elapsed / 60);\n return hours > 0 ? { amount: hours, unit: \"hours\" } : null;\n }\n\n return null;\n}\n\nexport function formatPartialElapsedLabel(elapsed: PartialElapsed): string {\n const { amount, unit } = elapsed;\n if (unit === \"days\") return `${amount} day${amount !== 1 ? \"s\" : \"\"}`;\n if (unit === \"hours\") return `${amount} hour${amount !== 1 ? \"s\" : \"\"}`;\n return `${amount} minute${amount !== 1 ? \"s\" : \"\"}`;\n}\n\n/** Patch empty schedule fields with tier-appropriate defaults. */\nexport function applyBookingScheduleDefaults(\n config: ScheduleDefaultsConfig,\n booking: BookingState,\n options?: { preparationMinutes?: number; now?: Date },\n): Partial<BookingState> {\n const now = options?.now ?? new Date();\n const today = todayLocalYmd(now);\n const patch: Partial<BookingState> = {};\n\n if (isSlotCharge(config.chargeBy)) {\n if (!booking.scheduleDate) patch.scheduleDate = today;\n if (!booking.scheduleTime) patch.scheduleTime = \"09:00\";\n const from = patch.scheduleTime ?? booking.scheduleTime ?? \"09:00\";\n if (!booking.scheduleEndTime) {\n patch.scheduleEndTime = snapScheduleEndTime(from, \"\", config.chargeBy);\n }\n return patch;\n }\n\n if (config.chargeBy === \"days\") {\n if (!booking.startDate) {\n patch.startDate = today;\n patch.endDate = addDays(today, 1);\n patch.oneDayBooking = true;\n } else if (!booking.endDate) {\n patch.endDate = addDays(booking.startDate, 1);\n }\n if (booking.oneDayBooking === undefined) patch.oneDayBooking = true;\n return patch;\n }\n\n if (config.chargeBy === \"weeks\") {\n if (!booking.weekFrom) patch.weekFrom = computeMinWeekStart(now);\n if (!booking.weekCount) patch.weekCount = 1;\n return patch;\n }\n\n if (config.chargeBy === \"months\") {\n const min = computeMinMonth(now);\n if (!booking.monthFrom) patch.monthFrom = min;\n if (!booking.monthTo) patch.monthTo = patch.monthFrom ?? booking.monthFrom ?? min;\n return patch;\n }\n\n if (config.chargeBy === \"quantity\") {\n if (!booking.scheduleDate) patch.scheduleDate = today;\n let time = booking.scheduleTime || \"09:00\";\n const prep = options?.preparationMinutes ?? 0;\n if (prep > 0 && (patch.scheduleDate ?? booking.scheduleDate ?? today) === today) {\n const floor = minNeededTimeHm(prep, now);\n if (time < floor) time = floor;\n }\n if (!booking.scheduleTime) patch.scheduleTime = time;\n if (!booking.itemQuantity) patch.itemQuantity = 1;\n return patch;\n }\n\n return patch;\n}\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/ui/time-field.tsx"],"names":[],"mappings":"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","file":"chunk-OV5ODANJ.js","sourcesContent":["\"use client\";\n\nimport * as React from \"react\";\nimport { Clock } from \"lucide-react\";\nimport { Popover, PopoverContent, PopoverTrigger } from \"./popover\";\nimport { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from \"./select\";\nimport { cn } from \"./utils\";\n\nconst SELECT_CONTENT_Z = \"z-[200]\";\n\nconst TIME_SELECT_TRIGGER_CLASS =\n \"border-white/20 bg-card/10 text-popover-foreground hover:bg-card/15 hover:border-white/30 focus-visible:border-blue-400/70 focus-visible:ring-blue-400/30 [&_svg:not([class*='text-'])]:text-white/60\";\n\nexport function parseHm(value: string): { h: number; m: number } | undefined {\n const m = /^([01]\\d|2[0-3]):([0-5]\\d)$/.exec(value.trim());\n if (!m) return undefined;\n const h = Number(m[1]);\n const min = Number(m[2]);\n if (h > 23 || min > 59) return undefined;\n return { h, m: min };\n}\n\nexport function toTimeStr(h: number, m: number): string {\n return `${String(h).padStart(2, \"0\")}:${String(m).padStart(2, \"0\")}`;\n}\n\nexport function hmToMinutes(value: string): number | null {\n const p = parseHm(value);\n return p ? p.h * 60 + p.m : null;\n}\n\nexport function minutesToHm(total: number): string | null {\n if (!Number.isFinite(total) || total < 0 || total >= 24 * 60) return null;\n const h = Math.floor(total / 60);\n const m = total % 60;\n return toTimeStr(h, m);\n}\n\nexport function addMinutesToHm(value: string, delta: number): string | null {\n const start = hmToMinutes(value);\n if (start == null) return null;\n return minutesToHm(start + delta);\n}\n\n/** Same-day end times at whole hours after `from` (2:10 → 3:10, 4:10, …). */\nexport function hourlyEndTimes(from: string): string[] {\n const start = hmToMinutes(from);\n if (start == null) return [];\n const out: string[] = [];\n for (let add = 60; start + add < 24 * 60; add += 60) {\n const next = minutesToHm(start + add);\n if (next) out.push(next);\n }\n return out;\n}\n\nexport function snapScheduleEndTime(\n from: string,\n to: string,\n chargeBy: \"hours\" | \"minutes\",\n): string {\n if (chargeBy === \"hours\") {\n const allowed = hourlyEndTimes(from);\n if (allowed.includes(to)) return to;\n return allowed[0] ?? \"\";\n }\n const start = hmToMinutes(from);\n const end = hmToMinutes(to);\n if (start == null) return to;\n if (end != null && end > start) return to;\n return addMinutesToHm(from, 1) ?? \"\";\n}\n\nexport function formatTimeForDisplay(value: string, timeFormat: \"12h\" | \"24h\"): string {\n const p = parseHm(value);\n if (!p) return value.trim() || \"—\";\n if (timeFormat === \"24h\") return toTimeStr(p.h, p.m);\n const ap = p.h >= 12 ? \"pm\" : \"am\";\n const h12 = p.h % 12 || 12;\n return `${String(h12).padStart(2, \"0\")}:${String(p.m).padStart(2, \"0\")} ${ap}`;\n}\n\nfunction split12(h24: number): { h12: number; ap: \"am\" | \"pm\" } {\n return { h12: h24 % 12 || 12, ap: h24 >= 12 ? \"pm\" : \"am\" };\n}\n\nfunction from12(h12: number, m: number, ap: \"am\" | \"pm\"): { h: number; m: number } {\n if (ap === \"am\") {\n return { h: h12 === 12 ? 0 : h12, m };\n }\n return { h: h12 === 12 ? 12 : h12 + 12, m };\n}\n\nconst HOURS_24 = Array.from({ length: 24 }, (_, i) => String(i).padStart(2, \"0\"));\nconst MINUTES = Array.from({ length: 60 }, (_, i) => String(i).padStart(2, \"0\"));\nconst HOURS_12 = Array.from({ length: 12 }, (_, i) => String(i + 1));\n\nexport function TimeField({\n value,\n onChange,\n disabled,\n id,\n placeholder = \"Select time\",\n triggerClassName,\n align = \"start\",\n timeFormat = \"24h\",\n minTime,\n allowedTimes,\n}: {\n value: string;\n onChange: (v: string) => void;\n disabled?: boolean;\n id?: string;\n placeholder?: string;\n triggerClassName?: string;\n align?: \"start\" | \"center\" | \"end\";\n timeFormat?: \"12h\" | \"24h\";\n /** Inclusive lower bound (`HH:mm`); earlier times are omitted. */\n minTime?: string;\n /** When set, only these times can be chosen (used for whole-hour ends). */\n allowedTimes?: string[];\n}) {\n const [open, setOpen] = React.useState(false);\n\n const parsed = parseHm(value);\n const minParsed = minTime ? parseHm(minTime) : undefined;\n const editor = parsed ?? minParsed ?? { h: 9, m: 0 };\n const label = parsed ? formatTimeForDisplay(value, timeFormat) : placeholder;\n const { h12, ap } = split12(editor.h);\n\n const setFrom24 = (h: number, m: number) => {\n onChange(toTimeStr(h, m));\n };\n\n const hours24 = HOURS_24.filter((h) => {\n if (!minParsed) return true;\n return Number(h) >= minParsed.h;\n });\n const minutesForHour = (h: number) =>\n MINUTES.filter((mi) => {\n if (!minParsed) return true;\n if (h > minParsed.h) return true;\n if (h < minParsed.h) return false;\n return Number(mi) >= minParsed.m;\n });\n const minutes = minutesForHour(editor.h);\n\n const hours12 = HOURS_12.filter((h) => {\n const as24 = from12(Number(h), 0, ap).h;\n if (!minParsed) return true;\n return as24 >= minParsed.h;\n });\n\n return (\n <Popover modal={false} open={open} onOpenChange={setOpen}>\n <PopoverTrigger asChild>\n <button\n type=\"button\"\n id={id}\n disabled={disabled}\n className={cn(\n \"flex w-full min-w-0 items-center gap-2 rounded-md border border-border bg-card px-3 h-9 text-left text-sm text-muted-foreground outline-none transition-colors hover:bg-muted/80 focus-visible:border-blue-400 focus-visible:ring-[3px] focus-visible:ring-blue-500/25 disabled:cursor-not-allowed disabled:opacity-50\",\n triggerClassName,\n )}\n >\n <Clock size={13} className=\"shrink-0 text-muted-foreground\" aria-hidden />\n <span className={cn(\"min-w-0 flex-1 truncate\", !parsed && \"text-muted-foreground\")}>{label}</span>\n </button>\n </PopoverTrigger>\n <PopoverContent className=\"z-[100] w-auto p-3\" align={align}>\n {allowedTimes ? (\n <div className=\"flex max-h-56 flex-col gap-0.5 overflow-y-auto\">\n {allowedTimes.length === 0 ? (\n <p className=\"px-1 py-2 text-xs text-muted-foreground\">No later times today</p>\n ) : (\n allowedTimes.map((t) => (\n <button\n key={t}\n type=\"button\"\n onClick={() => {\n onChange(t);\n setOpen(false);\n }}\n className={cn(\n \"rounded-md px-2.5 py-1.5 text-left text-xs tabular-nums hover:bg-accent\",\n t === value && \"bg-blue-50 font-medium text-blue-700 dark:bg-blue-950/40 dark:text-blue-300\",\n )}\n >\n {formatTimeForDisplay(t, timeFormat)}\n </button>\n ))\n )}\n </div>\n ) : timeFormat === \"24h\" ? (\n <div className=\"flex items-center gap-2\">\n <Select\n value={String(editor.h).padStart(2, \"0\")}\n onValueChange={(v) => setFrom24(Number(v), editor.m)}\n >\n <SelectTrigger size=\"sm\" className={cn(\"h-8 w-[4.75rem] text-xs\", TIME_SELECT_TRIGGER_CLASS)}>\n <SelectValue />\n </SelectTrigger>\n <SelectContent position=\"popper\" className={SELECT_CONTENT_Z}>\n {hours24.map((h) => (\n <SelectItem key={h} value={h} className=\"text-xs\">\n {h}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n <span className=\"text-xs font-medium text-white/60\">:</span>\n <Select\n value={String(editor.m).padStart(2, \"0\")}\n onValueChange={(v) => setFrom24(editor.h, Number(v))}\n >\n <SelectTrigger size=\"sm\" className={cn(\"h-8 w-[4.75rem] text-xs\", TIME_SELECT_TRIGGER_CLASS)}>\n <SelectValue />\n </SelectTrigger>\n <SelectContent position=\"popper\" className={SELECT_CONTENT_Z}>\n {minutes.map((mi) => (\n <SelectItem key={mi} value={mi} className=\"text-xs\">\n {mi}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n ) : (\n <div className=\"flex items-center gap-2\">\n <Select\n value={String(h12)}\n onValueChange={(v) => {\n const next = from12(Number(v), editor.m, ap);\n setFrom24(next.h, next.m);\n }}\n >\n <SelectTrigger size=\"sm\" className={cn(\"h-8 w-[3.75rem] text-xs\", TIME_SELECT_TRIGGER_CLASS)}>\n <SelectValue />\n </SelectTrigger>\n <SelectContent position=\"popper\" className={SELECT_CONTENT_Z}>\n {hours12.map((h) => (\n <SelectItem key={h} value={h} className=\"text-xs\">\n {h}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n <span className=\"text-xs font-medium text-white/60\">:</span>\n <Select\n value={String(editor.m).padStart(2, \"0\")}\n onValueChange={(v) => {\n const next = from12(h12, Number(v), ap);\n setFrom24(next.h, next.m);\n }}\n >\n <SelectTrigger size=\"sm\" className={cn(\"h-8 w-[4.75rem] text-xs\", TIME_SELECT_TRIGGER_CLASS)}>\n <SelectValue />\n </SelectTrigger>\n <SelectContent position=\"popper\" className={SELECT_CONTENT_Z}>\n {minutes.map((mi) => (\n <SelectItem key={mi} value={mi} className=\"text-xs\">\n {mi}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n <Select\n value={ap}\n onValueChange={(v) => {\n const next = from12(h12, editor.m, v as \"am\" | \"pm\");\n setFrom24(next.h, next.m);\n }}\n >\n <SelectTrigger size=\"sm\" className={cn(\"h-8 w-[4.25rem] text-xs\", TIME_SELECT_TRIGGER_CLASS)}>\n <SelectValue />\n </SelectTrigger>\n <SelectContent position=\"popper\" className={SELECT_CONTENT_Z}>\n <SelectItem value=\"am\" className=\"text-xs\">\n am\n </SelectItem>\n <SelectItem value=\"pm\" className=\"text-xs\">\n pm\n </SelectItem>\n </SelectContent>\n </Select>\n </div>\n )}\n </PopoverContent>\n </Popover>\n );\n}\n"]}
|
package/dist/chunk-PBNBLCC2.js
DELETED
|
@@ -1,84 +0,0 @@
|
|
|
1
|
-
// src/lib/dateDisplay.ts
|
|
2
|
-
function parseWallClockHm(value) {
|
|
3
|
-
const m = /^([01]\d|2[0-3]):([0-5]\d)$/.exec(value.trim());
|
|
4
|
-
if (!m) return void 0;
|
|
5
|
-
const h = Number(m[1]);
|
|
6
|
-
const min = Number(m[2]);
|
|
7
|
-
if (h > 23 || min > 59) return void 0;
|
|
8
|
-
return { h, m: min };
|
|
9
|
-
}
|
|
10
|
-
function toWallClockHmStr(h, m) {
|
|
11
|
-
return `${String(h).padStart(2, "0")}:${String(m).padStart(2, "0")}`;
|
|
12
|
-
}
|
|
13
|
-
function formatWallClockTime(value, timeFormat) {
|
|
14
|
-
const p = parseWallClockHm(value);
|
|
15
|
-
if (!p) return value.trim() || "\u2014";
|
|
16
|
-
if (timeFormat === "24h") return toWallClockHmStr(p.h, p.m);
|
|
17
|
-
const ap = p.h >= 12 ? "PM" : "AM";
|
|
18
|
-
const h12 = p.h % 12 || 12;
|
|
19
|
-
return `${h12}:${String(p.m).padStart(2, "0")} ${ap}`;
|
|
20
|
-
}
|
|
21
|
-
function addWallClockMinutes(value, minutes) {
|
|
22
|
-
const p = parseWallClockHm(value);
|
|
23
|
-
if (!p) return value;
|
|
24
|
-
const total = p.h * 60 + p.m + minutes;
|
|
25
|
-
const wrapped = (total % (24 * 60) + 24 * 60) % (24 * 60);
|
|
26
|
-
return toWallClockHmStr(Math.floor(wrapped / 60), wrapped % 60);
|
|
27
|
-
}
|
|
28
|
-
function formatCalendarDate(ymd) {
|
|
29
|
-
if (!ymd || !/^\d{4}-\d{2}-\d{2}$/.test(ymd)) return ymd || "\u2014";
|
|
30
|
-
const [y, m, d] = ymd.split("-").map(Number);
|
|
31
|
-
return new Date(y, m - 1, d).toLocaleDateString("en-US", {
|
|
32
|
-
month: "short",
|
|
33
|
-
day: "numeric",
|
|
34
|
-
year: "numeric"
|
|
35
|
-
});
|
|
36
|
-
}
|
|
37
|
-
function toDateStr(date) {
|
|
38
|
-
const y = date.getFullYear();
|
|
39
|
-
const m = String(date.getMonth() + 1).padStart(2, "0");
|
|
40
|
-
const d = String(date.getDate()).padStart(2, "0");
|
|
41
|
-
return `${y}-${m}-${d}`;
|
|
42
|
-
}
|
|
43
|
-
function isSameDay(a, b) {
|
|
44
|
-
return a.getFullYear() === b.getFullYear() && a.getMonth() === b.getMonth() && a.getDate() === b.getDate();
|
|
45
|
-
}
|
|
46
|
-
function formatDate(date) {
|
|
47
|
-
if (isSameDay(date, /* @__PURE__ */ new Date())) return "Today";
|
|
48
|
-
return date.toLocaleDateString("en-US", {
|
|
49
|
-
weekday: "short",
|
|
50
|
-
month: "short",
|
|
51
|
-
day: "numeric"
|
|
52
|
-
});
|
|
53
|
-
}
|
|
54
|
-
var MS_MIN = 6e4;
|
|
55
|
-
var MS_HOUR = 60 * MS_MIN;
|
|
56
|
-
var MS_DAY = 24 * MS_HOUR;
|
|
57
|
-
function formatRelativeTimeAgo(iso, now = /* @__PURE__ */ new Date()) {
|
|
58
|
-
try {
|
|
59
|
-
const d = new Date(iso.trim());
|
|
60
|
-
if (!Number.isFinite(d.getTime())) return "";
|
|
61
|
-
let diffMs = now.getTime() - d.getTime();
|
|
62
|
-
if (diffMs < 0) diffMs = 0;
|
|
63
|
-
const sec = Math.floor(diffMs / 1e3);
|
|
64
|
-
if (sec < 60) return "just now";
|
|
65
|
-
const min = Math.floor(diffMs / MS_MIN);
|
|
66
|
-
if (min < 60) return `${min}m ago`;
|
|
67
|
-
const hr = Math.floor(diffMs / MS_HOUR);
|
|
68
|
-
if (hr < 24) return `${hr}h ago`;
|
|
69
|
-
const day = Math.floor(diffMs / MS_DAY);
|
|
70
|
-
if (day < 7) return `${day}d ago`;
|
|
71
|
-
const week = Math.floor(day / 7);
|
|
72
|
-
if (week < 5) return `${week}w ago`;
|
|
73
|
-
const mo = Math.floor(day / 30);
|
|
74
|
-
if (mo < 12) return `${mo}mo ago`;
|
|
75
|
-
const yr = Math.floor(day / 365);
|
|
76
|
-
return `${Math.max(1, yr)}y ago`;
|
|
77
|
-
} catch {
|
|
78
|
-
return "";
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
export { addWallClockMinutes, formatCalendarDate, formatDate, formatRelativeTimeAgo, formatWallClockTime, isSameDay, parseWallClockHm, toDateStr, toWallClockHmStr };
|
|
83
|
-
//# sourceMappingURL=chunk-PBNBLCC2.js.map
|
|
84
|
-
//# sourceMappingURL=chunk-PBNBLCC2.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/lib/dateDisplay.ts"],"names":[],"mappings":"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","file":"chunk-PBNBLCC2.js","sourcesContent":["/** Parse `HH:mm` wall-clock time. */\nexport function parseWallClockHm(value: string): { h: number; m: number } | undefined {\n const m = /^([01]\\d|2[0-3]):([0-5]\\d)$/.exec(value.trim());\n if (!m) return undefined;\n const h = Number(m[1]);\n const min = Number(m[2]);\n if (h > 23 || min > 59) return undefined;\n return { h, m: min };\n}\n\nexport function toWallClockHmStr(h: number, m: number): string {\n return `${String(h).padStart(2, \"0\")}:${String(m).padStart(2, \"0\")}`;\n}\n\n/** Format stored `HH:mm` without timezone conversion. */\nexport function formatWallClockTime(value: string, timeFormat: \"12h\" | \"24h\"): string {\n const p = parseWallClockHm(value);\n if (!p) return value.trim() || \"—\";\n if (timeFormat === \"24h\") return toWallClockHmStr(p.h, p.m);\n const ap = p.h >= 12 ? \"PM\" : \"AM\";\n const h12 = p.h % 12 || 12;\n return `${h12}:${String(p.m).padStart(2, \"0\")} ${ap}`;\n}\n\n/** Add minutes to a wall-clock `HH:mm`, wrapping at 24h. */\nexport function addWallClockMinutes(value: string, minutes: number): string {\n const p = parseWallClockHm(value);\n if (!p) return value;\n const total = p.h * 60 + p.m + minutes;\n const wrapped = ((total % (24 * 60)) + 24 * 60) % (24 * 60);\n return toWallClockHmStr(Math.floor(wrapped / 60), wrapped % 60);\n}\n\n/** Format `YYYY-MM-DD` as a calendar date (no timezone shift). */\nexport function formatCalendarDate(ymd: string): string {\n if (!ymd || !/^\\d{4}-\\d{2}-\\d{2}$/.test(ymd)) return ymd || \"—\";\n const [y, m, d] = ymd.split(\"-\").map(Number);\n return new Date(y, m - 1, d).toLocaleDateString(\"en-US\", {\n month: \"short\",\n day: \"numeric\",\n year: \"numeric\",\n });\n}\n\n/** ISO `yyyy-mm-dd` for a local calendar date. */\nexport function toDateStr(date: Date): string {\n const y = date.getFullYear();\n const m = String(date.getMonth() + 1).padStart(2, \"0\");\n const d = String(date.getDate()).padStart(2, \"0\");\n return `${y}-${m}-${d}`;\n}\n\nexport function isSameDay(a: Date, b: Date): boolean {\n return (\n a.getFullYear() === b.getFullYear() &&\n a.getMonth() === b.getMonth() &&\n a.getDate() === b.getDate()\n );\n}\n\n/** Short label for a date; shows \"Today\" when it matches the current local day. */\nexport function formatDate(date: Date): string {\n if (isSameDay(date, new Date())) return \"Today\";\n return date.toLocaleDateString(\"en-US\", {\n weekday: \"short\",\n month: \"short\",\n day: \"numeric\",\n });\n}\n\nconst MS_MIN = 60_000;\nconst MS_HOUR = 60 * MS_MIN;\nconst MS_DAY = 24 * MS_HOUR;\n\n/**\n * Compact relative time for feeds (e.g. announcements, notifications): `2m ago`, `2d ago`.\n * Uses elapsed wall time from `now` (defaults to current time). Returns \"\" if `iso` is unparseable.\n */\nexport function formatRelativeTimeAgo(iso: string, now: Date = new Date()): string {\n try {\n const d = new Date(iso.trim());\n if (!Number.isFinite(d.getTime())) return \"\";\n let diffMs = now.getTime() - d.getTime();\n if (diffMs < 0) diffMs = 0;\n const sec = Math.floor(diffMs / 1000);\n if (sec < 60) return \"just now\";\n const min = Math.floor(diffMs / MS_MIN);\n if (min < 60) return `${min}m ago`;\n const hr = Math.floor(diffMs / MS_HOUR);\n if (hr < 24) return `${hr}h ago`;\n const day = Math.floor(diffMs / MS_DAY);\n if (day < 7) return `${day}d ago`;\n const week = Math.floor(day / 7);\n if (week < 5) return `${week}w ago`;\n const mo = Math.floor(day / 30);\n if (mo < 12) return `${mo}mo ago`;\n const yr = Math.floor(day / 365);\n return `${Math.max(1, yr)}y ago`;\n } catch {\n return \"\";\n }\n}\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/live-space/layout-canvas-types.ts","../src/live-space/plan-color.ts","../src/live-space/layout-canvas-view.tsx"],"names":[],"mappings":"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","file":"chunk-RC5SWZPB.js","sourcesContent":["export type LayoutCanvasResourceType = \"desks\" | \"rooms\" | \"other\";\n\nexport interface LayoutCanvasRect {\n x: number;\n y: number;\n w: number;\n h: number;\n}\n\nexport interface LayoutCanvasFloorLayout {\n placedItems: Record<string, LayoutCanvasRect>;\n bgImage: string | null;\n canvasWidth?: number;\n canvasHeight?: number;\n}\n\nexport const DEFAULT_CANVAS_WIDTH = 1200;\nexport const DEFAULT_CANVAS_HEIGHT = 900;\n\nexport interface LayoutCanvasPlanHint {\n id: string;\n name: string;\n color?: string;\n}\n","/** Hex colors offered as presets when creating/editing a plan. */\nexport const PLAN_COLOR_PRESETS = [\n \"#4285F4\",\n \"#10b981\",\n \"#06b6d4\",\n \"#f59e0b\",\n \"#ef4444\",\n \"#6366f1\",\n \"#a16207\",\n \"#64748b\",\n] as const;\n\nconst DEFAULT_PLAN_COLOR = PLAN_COLOR_PRESETS[0];\n\nconst HEX_RE = /^#[0-9A-Fa-f]{6}$/;\n\nexport function isPlanColorHex(value: string | undefined | null): value is string {\n return typeof value === \"string\" && HEX_RE.test(value);\n}\n\n/** Normalize stored/custom colors; fall back to a default when missing. */\nexport function resolvePlanColor(color: string | undefined | null): string {\n if (isPlanColorHex(color)) return color.toUpperCase();\n return DEFAULT_PLAN_COLOR;\n}\n\n/**\n * Soft badge / chip style from a plan hex: tinted background + saturated text.\n * Works for light surfaces; readable on dark UIs as well via alpha tint.\n */\nexport function planColorBadgeStyle(hex: string): {\n backgroundColor: string;\n color: string;\n} {\n const normalized = isPlanColorHex(hex) ? hex : DEFAULT_PLAN_COLOR;\n return {\n backgroundColor: `${normalized}1F`,\n color: normalized,\n };\n}\n\n/**\n * Subtle card wash + border from a plan hex, mixed with the theme card/border\n * so foreground text stays readable. Background is partly transparent so floor\n * plans show through underneath.\n */\nexport function planColorCardStyle(hex: string): {\n backgroundColor: string;\n borderColor: string;\n} {\n const normalized = isPlanColorHex(hex) ? hex : DEFAULT_PLAN_COLOR;\n return {\n backgroundColor: `color-mix(in srgb, ${normalized} 9%, color-mix(in srgb, var(--card) 78%, transparent))`,\n borderColor: `color-mix(in srgb, ${normalized} 28%, color-mix(in srgb, var(--border) 82%, transparent))`,\n };\n}\n","import {\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n type PointerEvent as ReactPointerEvent,\n type ReactNode,\n} from \"react\";\nimport { Box, Calendar, Maximize2, Minus, Plus } from \"lucide-react\";\nimport {\n DEFAULT_CANVAS_HEIGHT,\n DEFAULT_CANVAS_WIDTH,\n type LayoutCanvasFloorLayout,\n type LayoutCanvasPlanHint,\n type LayoutCanvasResourceType,\n} from \"./layout-canvas-types\";\nimport { LIVE_RESOURCE_TYPE_META } from \"./live-resource-meta\";\nimport { planColorBadgeStyle, planColorCardStyle, resolvePlanColor } from \"./plan-color\";\nimport { PageListSearchField } from \"../shell/page-list-chrome\";\nimport { Button } from \"../ui/button\";\nimport { cn } from \"../ui/utils\";\nimport { Popover, PopoverAnchor, PopoverContent } from \"../ui/popover\";\nimport { Tooltip, TooltipContent, TooltipTrigger } from \"../ui/tooltip\";\nimport { useTheme } from \"../theme/theme-provider\";\n\ninterface Rect {\n x: number;\n y: number;\n w: number;\n h: number;\n}\n\nexport interface LayoutCanvasViewRow {\n resource: {\n id: string;\n name: string;\n pricingPlanId: string;\n resourceType: LayoutCanvasResourceType;\n totalSlots?: number;\n };\n merged: { occupied: boolean; manual?: boolean; expectedFreeLabel?: string };\n plan?: LayoutCanvasPlanHint;\n}\n\nexport interface LayoutCanvasResourceQuickBook {\n /** When omitted, popover shows that booking is unavailable for this member. */\n onBook?: (resourceId: string) => void;\n /** Optional href for the book action (middle-click / fallback). */\n getBookingHref?: (resourceId: string) => string;\n}\n\nexport interface LayoutCanvasViewProps {\n layout: LayoutCanvasFloorLayout;\n rows: LayoutCanvasViewRow[];\n onResourceSelect?: (id: string) => void;\n /** Hover/tap popover with a quick book action (member live space). */\n resourceQuickBook?: LayoutCanvasResourceQuickBook;\n /** When set with `onSearchQueryChange`, shows a search bar and dims non-matching resources. */\n searchQuery?: string;\n onSearchQueryChange?: (value: string) => void;\n searchPlaceholder?: string;\n /** Occupancy green/red dots. Off for booking pickers. */\n showStatusDot?: boolean;\n selectedIds?: string[];\n /** Rendered on the left of the zoom toolbar (e.g. floor select). */\n toolbarStart?: ReactNode;\n className?: string;\n viewportClassName?: string;\n}\n\nexport function matchesCanvasResourceSearch(\n resourceName: string,\n planName: string | undefined,\n query: string,\n): boolean {\n const q = query.trim().toLowerCase();\n if (!q) return true;\n const name = resourceName.toLowerCase();\n const plan = planName?.toLowerCase() ?? \"\";\n return name.includes(q) || plan.includes(q);\n}\n\nfunction resourceMatchesSearch(row: LayoutCanvasViewRow, query: string): boolean {\n return matchesCanvasResourceSearch(row.resource.name, row.plan?.name, query);\n}\n\nconst CLICK_THRESHOLD_PX = 5;\nconst POPOVER_CLOSE_DELAY_MS = 250;\nconst CANVAS_QUICK_BOOK_POPOVER_CLASS =\n \"z-[100] w-56 border-border bg-card p-3 text-card-foreground shadow-lg\";\n\nfunction usePrefersHover() {\n const [prefersHover, setPrefersHover] = useState(\n () => typeof window !== \"undefined\" && window.matchMedia(\"(hover: hover)\").matches,\n );\n\n useEffect(() => {\n const mql = window.matchMedia(\"(hover: hover)\");\n const onChange = () => setPrefersHover(mql.matches);\n mql.addEventListener(\"change\", onChange);\n return () => mql.removeEventListener(\"change\", onChange);\n }, []);\n\n return prefersHover;\n}\n\ntype PopoverHoverHandlers = {\n prefersHover: boolean;\n clearClose: () => void;\n scheduleClose: () => void;\n};\n\ntype ResourceQuickBookConfig = {\n quickBook: LayoutCanvasResourceQuickBook;\n open: boolean;\n onOpenChange: (open: boolean) => void;\n hover: PopoverHoverHandlers;\n onOpen: () => void;\n onToggle: () => void;\n shouldIgnoreToggle: () => boolean;\n};\n\nfunction isCanvasResourceTarget(target: EventTarget | null): boolean {\n return target instanceof HTMLElement && target.closest(\"[data-canvas-resource]\") != null;\n}\n\nfunction ResourceQuickBookPopoverContent({\n row,\n onBook,\n getBookingHref,\n}: {\n row: LayoutCanvasViewRow;\n onBook?: (resourceId: string) => void;\n getBookingHref?: (resourceId: string) => string;\n}) {\n const { resource, merged } = row;\n const meta = LIVE_RESOURCE_TYPE_META[resource.resourceType];\n const TypeIcon = meta.Icon;\n const bookingHref = getBookingHref?.(resource.id);\n\n const handleBookPointerDown = (e: ReactPointerEvent) => {\n // Radix popover can close before click fires; book on pointerdown instead.\n e.preventDefault();\n e.stopPropagation();\n onBook?.(resource.id);\n };\n\n const bookLabel = (\n <>\n <Calendar size={14} />\n Book\n </>\n );\n\n return (\n <div className=\"space-y-3\">\n <div className=\"flex min-w-0 items-start gap-2.5\">\n <span\n className={cn(\n \"flex h-8 w-8 shrink-0 items-center justify-center rounded-lg border\",\n meta.iconTile,\n )}\n aria-hidden\n >\n <TypeIcon size={16} strokeWidth={1.75} />\n </span>\n <div className=\"min-w-0 flex-1\">\n <p className=\"truncate text-sm font-semibold leading-snug text-card-foreground\">\n {resource.name}\n </p>\n <span\n className={cn(\n \"mt-1.5 inline-flex items-center gap-1 rounded-full border px-2 py-0.5 text-[11px] font-medium\",\n merged.occupied\n ? \"border-red-100 bg-red-50 text-red-700 dark:border-red-900/50 dark:bg-red-950/50 dark:text-red-300\"\n : \"border-emerald-100 bg-emerald-50 text-emerald-800 dark:border-emerald-900/50 dark:bg-emerald-950/50 dark:text-emerald-300\",\n )}\n >\n <span\n className={cn(\n \"h-1.5 w-1.5 shrink-0 rounded-full\",\n merged.occupied ? \"bg-red-500\" : \"bg-emerald-500\",\n )}\n />\n {merged.occupied ? \"Occupied\" : \"Free\"}\n </span>\n {merged.occupied && merged.expectedFreeLabel && merged.expectedFreeLabel !== \"—\" ? (\n <p className=\"mt-1 text-xs text-muted-foreground\">{merged.expectedFreeLabel}</p>\n ) : null}\n </div>\n </div>\n {onBook ? (\n bookingHref ? (\n <Button asChild size=\"sm\" className=\"w-full\">\n <a href={bookingHref} onPointerDown={handleBookPointerDown}>\n {bookLabel}\n </a>\n </Button>\n ) : (\n <Button\n type=\"button\"\n size=\"sm\"\n className=\"w-full\"\n onPointerDown={handleBookPointerDown}\n >\n {bookLabel}\n </Button>\n )\n ) : (\n <p className=\"text-xs leading-relaxed text-muted-foreground\">\n Booking is not available for your account.\n </p>\n )}\n </div>\n );\n}\n\nconst MIN_ZOOM = 0.12;\nconst MAX_ZOOM = 4;\nconst MIN_CARD_W = 90;\nconst MIN_CARD_H = 56;\nconst CANVAS_GRID_SIZE = 40;\n\nfunction canvasGridBackground(isDark: boolean): string {\n const line = isDark ? \"oklch(0.35 0 0)\" : \"#e5e7eb\";\n return (\n `linear-gradient(to right, ${line} 1px, transparent 1px),` +\n `linear-gradient(to bottom, ${line} 1px, transparent 1px)`\n );\n}\n\nconst CANVAS_GRID_BG_SIZE = `${CANVAS_GRID_SIZE}px ${CANVAS_GRID_SIZE}px`;\n\nfunction isFloorResourceType(type: LayoutCanvasResourceType): boolean {\n return type === \"desks\" || type === \"rooms\";\n}\n\nfunction poolSlotsLabel(totalSlots: number | undefined): string | null {\n if (totalSlots == null) return null;\n return `${totalSlots} slot${totalSlots !== 1 ? \"s\" : \"\"}`;\n}\n\nfunction PoolResourceChip({\n row,\n onClick,\n quickBookConfig,\n searchQuery,\n isMatch,\n}: {\n row: LayoutCanvasViewRow;\n onClick?: () => void;\n quickBookConfig?: ResourceQuickBookConfig;\n searchQuery: string;\n isMatch: boolean;\n}) {\n const { resource, merged, plan } = row;\n const planColor = resolvePlanColor(plan?.color);\n const slots = poolSlotsLabel(resource.totalSlots);\n const searchActive = searchQuery.trim().length > 0;\n\n const chip = (\n <button\n type=\"button\"\n data-canvas-resource=\"\"\n onClick={(e) => {\n e.stopPropagation();\n if (quickBookConfig) {\n if (!quickBookConfig.shouldIgnoreToggle()) quickBookConfig.onToggle();\n } else onClick?.();\n }}\n onMouseEnter={() => {\n if (quickBookConfig?.hover.prefersHover) {\n quickBookConfig.hover.clearClose();\n quickBookConfig.onOpen();\n }\n }}\n onMouseLeave={() => {\n if (quickBookConfig?.hover.prefersHover) quickBookConfig.hover.scheduleClose();\n }}\n className={cn(\n \"inline-flex items-center gap-2 shrink-0 px-3 py-1.5 rounded-lg border hover:bg-accent transition-colors text-left\",\n searchActive && !isMatch && \"opacity-40 saturate-50\",\n )}\n style={planColorCardStyle(planColor)}\n >\n <div\n className=\"w-6 h-6 rounded-md flex items-center justify-center shrink-0\"\n style={planColorBadgeStyle(planColor)}\n >\n <Box size={12} />\n </div>\n <span className=\"text-xs font-medium text-foreground whitespace-nowrap\">{resource.name}</span>\n <span\n className={cn(\n \"h-2 w-2 rounded-full shrink-0\",\n merged.occupied ? \"bg-red-500\" : \"bg-emerald-500\",\n )}\n />\n {slots && (\n <span className=\"text-[10px] text-muted-foreground whitespace-nowrap\">{slots}</span>\n )}\n </button>\n );\n\n if (!quickBookConfig) return chip;\n\n return (\n <Popover\n modal={false}\n open={quickBookConfig.open}\n onOpenChange={quickBookConfig.onOpenChange}\n >\n <PopoverAnchor asChild>{chip}</PopoverAnchor>\n <PopoverContent\n side=\"top\"\n align=\"center\"\n sideOffset={6}\n className={CANVAS_QUICK_BOOK_POPOVER_CLASS}\n onOpenAutoFocus={(e) => e.preventDefault()}\n onMouseEnter={quickBookConfig.hover.clearClose}\n onMouseLeave={quickBookConfig.hover.scheduleClose}\n >\n <ResourceQuickBookPopoverContent\n row={row}\n onBook={quickBookConfig.quickBook.onBook}\n getBookingHref={quickBookConfig.quickBook.getBookingHref}\n />\n </PopoverContent>\n </Popover>\n );\n}\n\nfunction PlacedCardView({\n id,\n rect,\n row,\n onSelect,\n quickBookConfig,\n searchQuery,\n isMatch,\n selected = false,\n showStatusDot = true,\n}: {\n id: string;\n rect: Rect;\n row: LayoutCanvasViewRow;\n onSelect?: (id: string) => void;\n quickBookConfig?: ResourceQuickBookConfig;\n searchQuery: string;\n isMatch: boolean;\n selected?: boolean;\n showStatusDot?: boolean;\n}) {\n const { resource, merged, plan } = row;\n const planColor = resolvePlanColor(plan?.color);\n const w = Math.max(rect.w, MIN_CARD_W);\n const h = Math.max(rect.h, MIN_CARD_H);\n const statusLabel = merged.occupied ? \"Occupied\" : merged.manual ? \"Vacant\" : \"Free\";\n const pointerStart = useRef<{ x: number; y: number } | null>(null);\n const searchActive = searchQuery.trim().length > 0;\n\n const handlePointerDown = (e: ReactPointerEvent) => {\n if (e.button !== 0) return;\n // Keep viewport pan/zoom from capturing the pointer before tap completes.\n e.stopPropagation();\n pointerStart.current = { x: e.clientX, y: e.clientY };\n };\n\n const handlePointerUp = (e: ReactPointerEvent) => {\n e.stopPropagation();\n const start = pointerStart.current;\n pointerStart.current = null;\n if (!start || quickBookConfig) return;\n if (Math.hypot(e.clientX - start.x, e.clientY - start.y) < CLICK_THRESHOLD_PX) {\n onSelect?.(id);\n }\n };\n\n const statusDot = (\n <span\n className={cn(\n \"block h-2.5 w-2.5 rounded-full ring-2 ring-white shadow-sm\",\n merged.occupied ? \"bg-red-500 animate-pulse\" : \"bg-emerald-500\",\n )}\n aria-label={statusLabel}\n />\n );\n\n const card = (\n <button\n type=\"button\"\n data-canvas-resource=\"\"\n style={{\n position: \"absolute\",\n left: rect.x,\n top: rect.y,\n width: w,\n height: h,\n touchAction: \"manipulation\",\n ...planColorCardStyle(planColor),\n }}\n className={cn(\n \"rounded-xl border shadow-sm overflow-hidden select-none text-left cursor-pointer hover:shadow-md transition-shadow focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-blue-500/40\",\n searchActive && !isMatch && \"opacity-40 saturate-50\",\n selected && \"ring-2 ring-blue-500 border-blue-400\",\n )}\n onPointerDown={handlePointerDown}\n onPointerUp={handlePointerUp}\n onPointerCancel={handlePointerUp}\n onClick={(e) => {\n e.stopPropagation();\n if (quickBookConfig && !quickBookConfig.shouldIgnoreToggle()) {\n quickBookConfig.onToggle();\n }\n }}\n onMouseEnter={() => {\n if (quickBookConfig?.hover.prefersHover) {\n quickBookConfig.hover.clearClose();\n quickBookConfig.onOpen();\n }\n }}\n onMouseLeave={() => {\n if (quickBookConfig?.hover.prefersHover) quickBookConfig.hover.scheduleClose();\n }}\n >\n {showStatusDot ? (\n <div className=\"absolute top-2 right-2 z-10 pointer-events-none\">\n {quickBookConfig ? (\n statusDot\n ) : (\n <Tooltip>\n <TooltipTrigger asChild>{statusDot}</TooltipTrigger>\n <TooltipContent side=\"top\" className=\"text-xs\">\n {statusLabel}\n </TooltipContent>\n </Tooltip>\n )}\n </div>\n ) : null}\n\n <div className=\"absolute inset-0 flex flex-col justify-between p-3 pointer-events-none\">\n <div className=\"min-w-0 pr-4\">\n <span\n className=\"text-xs font-semibold text-foreground leading-tight line-clamp-2\"\n style={{ wordBreak: \"break-word\" }}\n >\n {resource.name}\n </span>\n </div>\n\n {plan && (\n <span\n className=\"text-[9px] font-medium px-1.5 py-0.5 rounded-md self-start\"\n style={planColorBadgeStyle(planColor)}\n >\n {plan.name}\n </span>\n )}\n </div>\n </button>\n );\n\n if (!quickBookConfig) return card;\n\n return (\n <Popover\n modal={false}\n open={quickBookConfig.open}\n onOpenChange={quickBookConfig.onOpenChange}\n >\n <PopoverAnchor asChild>{card}</PopoverAnchor>\n <PopoverContent\n side=\"top\"\n align=\"center\"\n sideOffset={6}\n className={CANVAS_QUICK_BOOK_POPOVER_CLASS}\n onOpenAutoFocus={(e) => e.preventDefault()}\n onMouseEnter={quickBookConfig.hover.clearClose}\n onMouseLeave={quickBookConfig.hover.scheduleClose}\n >\n <ResourceQuickBookPopoverContent\n row={row}\n onBook={quickBookConfig.quickBook.onBook}\n getBookingHref={quickBookConfig.quickBook.getBookingHref}\n />\n </PopoverContent>\n </Popover>\n );\n}\n\ntype PanGesture = {\n type: \"pan\";\n startMX: number;\n startMY: number;\n startPanX: number;\n startPanY: number;\n};\n\nexport function LayoutCanvasView({\n layout,\n rows,\n onResourceSelect,\n resourceQuickBook,\n searchQuery = \"\",\n onSearchQueryChange,\n searchPlaceholder = \"Search resources…\",\n showStatusDot = true,\n selectedIds,\n toolbarStart,\n className,\n viewportClassName,\n}: LayoutCanvasViewProps) {\n const { resolvedTheme } = useTheme();\n const isDarkCanvas = resolvedTheme === \"dark\";\n const { placedItems, bgImage } = layout;\n const prefersHover = usePrefersHover();\n\n const canvasSize = useMemo(\n () => ({\n w: layout.canvasWidth ?? DEFAULT_CANVAS_WIDTH,\n h: layout.canvasHeight ?? DEFAULT_CANVAS_HEIGHT,\n }),\n [layout.canvasWidth, layout.canvasHeight],\n );\n\n const [zoom, setZoom] = useState(0.5);\n const [pan, setPan] = useState({ x: 40, y: 40 });\n const [isPanning, setIsPanning] = useState(false);\n const [openResourceId, setOpenResourceId] = useState<string | null>(null);\n\n const viewportRef = useRef<HTMLDivElement>(null);\n const gestureRef = useRef<PanGesture | null>(null);\n const zoomRef = useRef(zoom);\n const panRef = useRef(pan);\n const popoverCloseTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n const suppressResourceToggleRef = useRef(false);\n\n const clearPopoverCloseTimer = useCallback(() => {\n if (popoverCloseTimerRef.current) {\n clearTimeout(popoverCloseTimerRef.current);\n popoverCloseTimerRef.current = null;\n }\n }, []);\n\n const schedulePopoverClose = useCallback(() => {\n clearPopoverCloseTimer();\n popoverCloseTimerRef.current = setTimeout(() => {\n setOpenResourceId(null);\n popoverCloseTimerRef.current = null;\n }, POPOVER_CLOSE_DELAY_MS);\n }, [clearPopoverCloseTimer]);\n\n const popoverHover = useMemo<PopoverHoverHandlers>(\n () => ({\n prefersHover,\n clearClose: clearPopoverCloseTimer,\n scheduleClose: schedulePopoverClose,\n }),\n [prefersHover, clearPopoverCloseTimer, schedulePopoverClose],\n );\n\n const openPopover = useCallback(\n (id: string) => {\n clearPopoverCloseTimer();\n setOpenResourceId(id);\n },\n [clearPopoverCloseTimer],\n );\n\n const togglePopover = useCallback(\n (id: string) => {\n clearPopoverCloseTimer();\n setOpenResourceId((current) => (current === id ? null : id));\n },\n [clearPopoverCloseTimer],\n );\n\n useEffect(() => () => clearPopoverCloseTimer(), [clearPopoverCloseTimer]);\n\n useEffect(() => {\n zoomRef.current = zoom;\n }, [zoom]);\n useEffect(() => {\n panRef.current = pan;\n }, [pan]);\n\n const rowById = useMemo(() => new Map(rows.map((r) => [r.resource.id, r])), [rows]);\n const otherRows = useMemo(\n () => rows.filter((r) => r.resource.resourceType === \"other\"),\n [rows],\n );\n\n const fitCanvas = useCallback(() => {\n const vp = viewportRef.current;\n if (!vp) return;\n const vpRect = vp.getBoundingClientRect();\n const newZoom = Math.max(\n MIN_ZOOM,\n Math.min(\n MAX_ZOOM,\n Math.min((vpRect.width - 80) / canvasSize.w, (vpRect.height - 80) / canvasSize.h),\n ),\n );\n setPan({\n x: (vpRect.width - canvasSize.w * newZoom) / 2,\n y: (vpRect.height - canvasSize.h * newZoom) / 2,\n });\n setZoom(newZoom);\n }, [canvasSize.h, canvasSize.w]);\n\n useEffect(() => {\n fitCanvas();\n }, [fitCanvas]);\n\n useEffect(() => {\n const el = viewportRef.current;\n if (!el) return;\n const observer = new ResizeObserver(() => fitCanvas());\n observer.observe(el);\n return () => observer.disconnect();\n }, [fitCanvas]);\n\n useEffect(() => {\n const el = viewportRef.current;\n if (!el) return;\n const onWheel = (e: WheelEvent) => {\n e.preventDefault();\n const vpRect = el.getBoundingClientRect();\n const mx = e.clientX - vpRect.left;\n const my = e.clientY - vpRect.top;\n const factor = e.deltaY < 0 ? 1.08 : 1 / 1.08;\n const curZ = zoomRef.current;\n const newZ = Math.max(MIN_ZOOM, Math.min(MAX_ZOOM, curZ * factor));\n const curP = panRef.current;\n setZoom(newZ);\n setPan({\n x: mx - (mx - curP.x) * (newZ / curZ),\n y: my - (my - curP.y) * (newZ / curZ),\n });\n };\n el.addEventListener(\"wheel\", onWheel, { passive: false });\n return () => el.removeEventListener(\"wheel\", onWheel);\n }, []);\n\n const stepZoom = (delta: number) => {\n const vp = viewportRef.current;\n const curZ = zoomRef.current;\n const newZ = Math.max(MIN_ZOOM, Math.min(MAX_ZOOM, curZ + delta));\n if (vp) {\n const vpRect = vp.getBoundingClientRect();\n const cx = vpRect.width / 2;\n const cy = vpRect.height / 2;\n const curP = panRef.current;\n setPan({\n x: cx - (cx - curP.x) * (newZ / curZ),\n y: cy - (cy - curP.y) * (newZ / curZ),\n });\n }\n setZoom(newZ);\n };\n\n useEffect(() => {\n const onKeyDown = (e: KeyboardEvent) => {\n const tag = (e.target as HTMLElement)?.tagName;\n if (tag === \"INPUT\" || tag === \"TEXTAREA\" || tag === \"SELECT\") return;\n if (e.key === \"+\" || e.key === \"=\") {\n e.preventDefault();\n stepZoom(0.15);\n } else if (e.key === \"-\" || e.key === \"_\") {\n e.preventDefault();\n stepZoom(-0.15);\n }\n };\n window.addEventListener(\"keydown\", onKeyDown);\n return () => window.removeEventListener(\"keydown\", onKeyDown);\n });\n\n const handleViewportPointerDown = (e: React.PointerEvent) => {\n if (e.button !== 0 && e.button !== 1) return;\n if (isCanvasResourceTarget(e.target)) return;\n clearPopoverCloseTimer();\n setOpenResourceId(null);\n e.preventDefault();\n e.currentTarget.setPointerCapture(e.pointerId);\n setIsPanning(true);\n gestureRef.current = {\n type: \"pan\",\n startMX: e.clientX,\n startMY: e.clientY,\n startPanX: panRef.current.x,\n startPanY: panRef.current.y,\n };\n };\n\n const handleViewportPointerMove = (e: React.PointerEvent) => {\n const g = gestureRef.current;\n if (g?.type !== \"pan\") return;\n setPan({\n x: g.startPanX + (e.clientX - g.startMX),\n y: g.startPanY + (e.clientY - g.startMY),\n });\n };\n\n const handleViewportPointerUp = () => {\n if (gestureRef.current?.type === \"pan\") {\n gestureRef.current = null;\n setIsPanning(false);\n }\n };\n\n const handleSelect = (id: string) => onResourceSelect?.(id);\n\n const quickBookConfigFor = useCallback(\n (resourceId: string): ResourceQuickBookConfig | undefined => {\n if (!resourceQuickBook) return undefined;\n const wrappedOnBook = resourceQuickBook.onBook\n ? (id: string) => {\n suppressResourceToggleRef.current = true;\n clearPopoverCloseTimer();\n setOpenResourceId(null);\n resourceQuickBook.onBook?.(id);\n window.setTimeout(() => {\n suppressResourceToggleRef.current = false;\n }, 400);\n }\n : undefined;\n\n return {\n quickBook: {\n ...resourceQuickBook,\n onBook: wrappedOnBook,\n },\n open: openResourceId === resourceId,\n onOpenChange: (open) => {\n clearPopoverCloseTimer();\n setOpenResourceId(open ? resourceId : null);\n },\n hover: popoverHover,\n onOpen: () => openPopover(resourceId),\n onToggle: () => togglePopover(resourceId),\n shouldIgnoreToggle: () => suppressResourceToggleRef.current,\n };\n },\n [\n resourceQuickBook,\n openResourceId,\n clearPopoverCloseTimer,\n popoverHover,\n openPopover,\n togglePopover,\n ],\n );\n\n return (\n <div className={cn(\"flex min-h-0 flex-1 flex-col bg-card\", className)}>\n <div className=\"flex shrink-0 items-center gap-2 border-b border-border bg-card px-2 py-1\">\n {toolbarStart ? <div className=\"min-w-0 flex-1\">{toolbarStart}</div> : null}\n {onSearchQueryChange != null ? (\n <PageListSearchField\n value={searchQuery}\n onChange={onSearchQueryChange}\n placeholder={searchPlaceholder}\n className=\"h-8 min-w-0 max-w-md flex-1\"\n />\n ) : null}\n <div className=\"ml-auto flex shrink-0 items-center gap-1\">\n <button\n type=\"button\"\n onClick={() => stepZoom(-0.15)}\n className=\"w-7 h-7 rounded-lg border border-border bg-card flex items-center justify-center text-muted-foreground hover:bg-accent transition-colors\"\n aria-label=\"Zoom out\"\n >\n <Minus size={12} />\n </button>\n <span className=\"text-xs text-muted-foreground w-10 text-center tabular-nums select-none\">\n {Math.round(zoom * 100)}%\n </span>\n <button\n type=\"button\"\n onClick={() => stepZoom(0.15)}\n className=\"w-7 h-7 rounded-lg border border-border bg-card flex items-center justify-center text-muted-foreground hover:bg-accent transition-colors\"\n aria-label=\"Zoom in\"\n >\n <Plus size={12} />\n </button>\n <button\n type=\"button\"\n onClick={fitCanvas}\n className=\"inline-flex items-center gap-1 px-2.5 h-7 rounded-lg border border-border bg-card text-xs text-muted-foreground hover:bg-accent transition-colors\"\n >\n <Maximize2 size={11} />\n Fit\n </button>\n </div>\n </div>\n\n <div className=\"flex flex-col flex-1 min-w-0 min-h-0\">\n <div\n ref={viewportRef}\n tabIndex={0}\n className={cn(\n \"relative min-h-0 flex-1 overflow-hidden bg-card outline-none\",\n viewportClassName ?? \"min-h-[420px]\",\n )}\n style={{ cursor: isPanning ? \"grabbing\" : \"grab\" }}\n onPointerDown={handleViewportPointerDown}\n onPointerMove={handleViewportPointerMove}\n onPointerUp={handleViewportPointerUp}\n onPointerCancel={handleViewportPointerUp}\n >\n <div\n style={{\n position: \"absolute\",\n transformOrigin: \"0px 0px\",\n transform: `translate(${pan.x}px, ${pan.y}px) scale(${zoom})`,\n width: canvasSize.w,\n height: canvasSize.h,\n backgroundImage: bgImage ? \"none\" : canvasGridBackground(isDarkCanvas),\n backgroundSize: bgImage ? \"auto\" : CANVAS_GRID_BG_SIZE,\n backgroundColor: \"var(--card)\",\n boxShadow: isDarkCanvas\n ? \"0 2px 16px rgba(0,0,0,0.45)\"\n : \"0 2px 16px rgba(0,0,0,0.12)\",\n }}\n >\n {bgImage && (\n <img\n src={bgImage}\n alt=\"Floor plan\"\n draggable={false}\n style={{\n position: \"absolute\",\n inset: 0,\n width: \"100%\",\n height: \"100%\",\n objectFit: \"cover\",\n pointerEvents: \"none\",\n userSelect: \"none\",\n }}\n />\n )}\n\n {Object.entries(placedItems).map(([id, rect]) => {\n const row = rowById.get(id);\n if (!row || !isFloorResourceType(row.resource.resourceType)) return null;\n return (\n <PlacedCardView\n key={id}\n id={id}\n rect={rect as Rect}\n row={row}\n onSelect={resourceQuickBook ? undefined : handleSelect}\n quickBookConfig={quickBookConfigFor(id)}\n searchQuery={searchQuery}\n isMatch={resourceMatchesSearch(row, searchQuery)}\n selected={selectedIds?.includes(id) ?? false}\n showStatusDot={showStatusDot}\n />\n );\n })}\n </div>\n </div>\n\n {otherRows.length > 0 && (\n <div className=\"shrink-0 border-t border-border bg-card px-4 py-2.5\">\n <div className=\"flex items-center gap-2 overflow-x-auto pb-0.5\">\n {otherRows.map((row) => {\n const resourceId = row.resource.id;\n return (\n <PoolResourceChip\n key={resourceId}\n row={row}\n onClick={resourceQuickBook ? undefined : () => handleSelect(resourceId)}\n quickBookConfig={quickBookConfigFor(resourceId)}\n searchQuery={searchQuery}\n isMatch={resourceMatchesSearch(row, searchQuery)}\n />\n );\n })}\n </div>\n </div>\n )}\n </div>\n </div>\n );\n}\n"]}
|