@pattern-stack/frontend-patterns 0.2.0-alpha.0 → 0.2.0-alpha.3

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.
Files changed (56) hide show
  1. package/cli/commands/generate-hooks.ts +13 -4
  2. package/cli/src/codegen/openapi/__tests__/naming-utils.test.js +367 -0
  3. package/cli/src/codegen/openapi/client-generator.js +87 -19
  4. package/cli/src/codegen/openapi/confidence-scorer.js +93 -0
  5. package/cli/src/codegen/openapi/hook-config.js +48 -0
  6. package/cli/src/codegen/openapi/hook-generator.js +100 -62
  7. package/cli/src/codegen/openapi/naming-constants.js +98 -0
  8. package/cli/src/codegen/openapi/naming-utils.js +149 -0
  9. package/dist/atoms/components/core/Badge/Badge.d.ts +1 -1
  10. package/dist/atoms/components/data/DataTable/DataTable.d.ts.map +1 -1
  11. package/dist/atoms/components/data/DataTable/DataTable.types.d.ts +15 -3
  12. package/dist/atoms/components/data/DataTable/DataTable.types.d.ts.map +1 -1
  13. package/dist/atoms/hooks/index.d.ts +2 -0
  14. package/dist/atoms/hooks/index.d.ts.map +1 -1
  15. package/dist/atoms/hooks/useFieldMetadata.d.ts +18 -0
  16. package/dist/atoms/hooks/useFieldMetadata.d.ts.map +1 -0
  17. package/dist/atoms/hooks/useResponsiveTable.d.ts +103 -0
  18. package/dist/atoms/hooks/useResponsiveTable.d.ts.map +1 -0
  19. package/dist/atoms/primitives/sheet.d.ts +23 -0
  20. package/dist/atoms/primitives/sheet.d.ts.map +1 -0
  21. package/dist/atoms/services/auth-service.d.ts.map +1 -1
  22. package/dist/atoms/types/auth.d.ts +51 -0
  23. package/dist/atoms/types/auth.d.ts.map +1 -1
  24. package/dist/atoms/types/index.d.ts +1 -0
  25. package/dist/atoms/types/index.d.ts.map +1 -1
  26. package/dist/atoms/types/ui-config.d.ts +25 -8
  27. package/dist/atoms/types/ui-config.d.ts.map +1 -1
  28. package/dist/atoms/types/ui-metadata.d.ts +112 -0
  29. package/dist/atoms/types/ui-metadata.d.ts.map +1 -0
  30. package/dist/atoms/utils/ui-mapping.d.ts +9 -3
  31. package/dist/atoms/utils/ui-mapping.d.ts.map +1 -1
  32. package/dist/features/auth/hooks/useAuth.d.ts.map +1 -1
  33. package/dist/frontend-patterns.css +82 -0
  34. package/dist/index.d.ts +4 -1
  35. package/dist/index.d.ts.map +1 -1
  36. package/dist/index.es.js +1030 -248
  37. package/dist/index.es.js.map +1 -1
  38. package/dist/index.js +1031 -248
  39. package/dist/index.js.map +1 -1
  40. package/dist/molecules/layout/ListToolbar/ListToolbar.d.ts +37 -0
  41. package/dist/molecules/layout/ListToolbar/ListToolbar.d.ts.map +1 -0
  42. package/dist/molecules/layout/ListToolbar/index.d.ts +2 -0
  43. package/dist/molecules/layout/ListToolbar/index.d.ts.map +1 -0
  44. package/dist/molecules/layout/PageTitle/PageTitle.d.ts +17 -0
  45. package/dist/molecules/layout/PageTitle/PageTitle.d.ts.map +1 -0
  46. package/dist/molecules/layout/PageTitle/index.d.ts +2 -0
  47. package/dist/molecules/layout/PageTitle/index.d.ts.map +1 -0
  48. package/dist/molecules/layout/index.d.ts +2 -0
  49. package/dist/molecules/layout/index.d.ts.map +1 -1
  50. package/dist/templates/ListPageTemplate.d.ts +21 -0
  51. package/dist/templates/ListPageTemplate.d.ts.map +1 -0
  52. package/dist/templates/admin/AdminCRUDTemplate.d.ts.map +1 -1
  53. package/dist/templates/factory.d.ts.map +1 -1
  54. package/dist/templates/index.d.ts +1 -0
  55. package/dist/templates/index.d.ts.map +1 -1
  56. package/package.json +4 -3
package/dist/index.es.js CHANGED
@@ -8,9 +8,10 @@ import axios from "axios";
8
8
  import { jsxDEV, Fragment } from "react/jsx-dev-runtime";
9
9
  import * as React from "react";
10
10
  import React__default, { useRef, useState, useEffect, useMemo, forwardRef, useCallback, useContext, createContext, useId, Component, Suspense } from "react";
11
+ import * as SheetPrimitive from "@radix-ui/react-dialog";
12
+ import { Map as Map$1, Calculator, Brain, User, Handshake, Truck, Building, HelpCircle, Info, AlertCircle, Check, ArrowDown, ArrowUp, ArrowLeft, ArrowRight, ChevronUp, ChevronLeft, ChevronDown, ChevronRight, Music, Video, Image, Folder, File, Flag, Tag, Bookmark, Heart, Star, MapPin, Clock, Calendar, Phone, Mail, Unlock, Lock, Share, Upload, Download, Eye, Trash2, Edit, Plus, Search, Bell, Settings, Home, Layout, TrendingUp, Database, BarChart3, Users, Shield, X, Menu, Palette, Loader2, EyeOff, InfoIcon, Circle, ChevronsUpDown, AreaChart, LineChart, TrendingDown, Minus, AlertTriangle, Activity, CheckCircle, FileX, Sun, Moon, LogOut, Square, Waves, Zap, TreePine, Sparkles, Sunset, Building2, DollarSign, ShoppingCart, Target, ExternalLink, MoreHorizontal, Filter, Edit2, Undo2, RefreshCw, FileText, History, Save, Copy, Grid3X3, Layers, XCircle, Briefcase } from "lucide-react";
11
13
  import * as LabelPrimitive from "@radix-ui/react-label";
12
14
  import { cva } from "class-variance-authority";
13
- import { Map as Map$1, Calculator, Brain, User, Handshake, Truck, Building, HelpCircle, Info, AlertCircle, Check, ArrowDown, ArrowUp, ArrowLeft, ArrowRight, ChevronUp, ChevronLeft, ChevronDown, ChevronRight, Music, Video, Image, Folder, File, Flag, Tag, Bookmark, Heart, Star, MapPin, Clock, Calendar, Phone, Mail, Unlock, Lock, Share, Upload, Download, Eye, Trash2, Edit, Plus, Search, Bell, Settings, Home, Layout, TrendingUp, Database, BarChart3, Users, Shield, X, Menu, Palette, Loader2, EyeOff, InfoIcon, Circle, ChevronsUpDown, AreaChart, LineChart, TrendingDown, Minus, AlertTriangle, Activity, CheckCircle, FileX, Sun, Moon, LogOut, Square, Waves, Zap, TreePine, Sparkles, Sunset, Building2, DollarSign, ShoppingCart, Target, ExternalLink, MoreHorizontal, Filter, Edit2, Undo2, RefreshCw, FileText, History, Save, Copy, Grid3X3, Layers, XCircle, Briefcase } from "lucide-react";
14
15
  import * as AvatarPrimitive from "@radix-ui/react-avatar";
15
16
  import { useQuery, useQueryClient, useMutation, QueryClient, QueryClientProvider } from "@tanstack/react-query";
16
17
  import { Slot } from "@radix-ui/react-slot";
@@ -653,11 +654,11 @@ const DEFAULT_FIELD_MAPPINGS = {
653
654
  state: "status",
654
655
  orderStatus: "status",
655
656
  paymentStatus: "status",
656
- // Category fields
657
- category: "category",
658
- type: "category",
659
- tag: "category",
660
- label: "category",
657
+ // Badge fields (categories, tags, labels)
658
+ category: "badge",
659
+ type: "badge",
660
+ tag: "badge",
661
+ label: "badge",
661
662
  // Money fields
662
663
  amount: "money",
663
664
  price: "money",
@@ -733,7 +734,7 @@ const FIELD_PATTERNS = [
733
734
  // discount_rate, tax_percent
734
735
  { pattern: /status|state/, type: "status" },
735
736
  // order_status, state
736
- { pattern: /category|type|tag|label/, type: "category" },
737
+ { pattern: /category|type|tag|label/, type: "badge" },
737
738
  // product_category
738
739
  { pattern: /email/i, type: "email" },
739
740
  // user_email, emailAddress
@@ -1946,18 +1947,46 @@ const globalColorManager = new CategoryColorManager("sequential");
1946
1947
  function useCategoryColors(strategy) {
1947
1948
  return strategy ? new CategoryColorManager(strategy) : globalColorManager;
1948
1949
  }
1949
- function formatMoney(value, currency = "USD") {
1950
- return new Intl.NumberFormat("en-US", {
1950
+ const LEGACY_TYPE_MAP = {
1951
+ // Old frontend names
1952
+ category: "badge",
1953
+ // Backend names that differ
1954
+ currency: "money",
1955
+ percentage: "percent",
1956
+ // Input-focused types (deprecated)
1957
+ select: "badge",
1958
+ multiselect: "badge",
1959
+ textarea: "text",
1960
+ reference: "entity",
1961
+ enum: "badge"
1962
+ };
1963
+ function normalizeFieldType(type) {
1964
+ return LEGACY_TYPE_MAP[type] ?? type ?? "text";
1965
+ }
1966
+ function formatMoney(value, currency = "USD", decimals = 2, locale = "en-US") {
1967
+ return new Intl.NumberFormat(locale, {
1951
1968
  style: "currency",
1952
1969
  currency,
1953
- minimumFractionDigits: 2,
1954
- maximumFractionDigits: 2
1970
+ minimumFractionDigits: decimals,
1971
+ maximumFractionDigits: decimals
1955
1972
  }).format(value);
1956
1973
  }
1957
- function formatPercent(value, decimals = 1) {
1958
- return `${value.toFixed(decimals)}%`;
1974
+ function formatPercent(value, decimals = 1, locale = "en-US") {
1975
+ return new Intl.NumberFormat(locale, {
1976
+ style: "percent",
1977
+ minimumFractionDigits: decimals,
1978
+ maximumFractionDigits: decimals
1979
+ }).format(value / 100);
1980
+ }
1981
+ function formatNumber(value, decimals, locale = "en-US") {
1982
+ const options = {};
1983
+ if (decimals !== void 0) {
1984
+ options.minimumFractionDigits = decimals;
1985
+ options.maximumFractionDigits = decimals;
1986
+ }
1987
+ return new Intl.NumberFormat(locale, options).format(value);
1959
1988
  }
1960
- function formatDate(value, includeTime = false) {
1989
+ function formatDate(value, includeTime = false, locale = "en-US") {
1961
1990
  const date = typeof value === "string" ? new Date(value) : value;
1962
1991
  if (isNaN(date.getTime())) return String(value);
1963
1992
  const options = {
@@ -1970,7 +1999,7 @@ function formatDate(value, includeTime = false) {
1970
1999
  options.minute = "2-digit";
1971
2000
  options.hour12 = true;
1972
2001
  }
1973
- return date.toLocaleDateString("en-US", options);
2002
+ return date.toLocaleDateString(locale, options);
1974
2003
  }
1975
2004
  function getSizeForBreakpoint(breakpoint) {
1976
2005
  switch (breakpoint) {
@@ -1998,35 +2027,36 @@ function getDisplayForBreakpoint(breakpoint) {
1998
2027
  return "full";
1999
2028
  }
2000
2029
  }
2030
+ const DEFAULT_STATUS_COLORS = {
2031
+ active: "success",
2032
+ completed: "success",
2033
+ approved: "success",
2034
+ published: "success",
2035
+ pending: "warning",
2036
+ processing: "warning",
2037
+ scheduled: "warning",
2038
+ draft: "warning",
2039
+ failed: "error",
2040
+ rejected: "error",
2041
+ cancelled: "error",
2042
+ deleted: "error",
2043
+ inactive: "neutral",
2044
+ archived: "neutral",
2045
+ closed: "neutral"
2046
+ };
2001
2047
  const defaultFieldRenderers = {
2002
- status: (value, _fieldName, breakpoint) => {
2048
+ status: (value, _fieldName, breakpoint, _item, format) => {
2003
2049
  const size = getSizeForBreakpoint(breakpoint);
2004
2050
  const display = getDisplayForBreakpoint(breakpoint);
2005
- const statusColorMap = {
2006
- active: "success",
2007
- completed: "success",
2008
- approved: "success",
2009
- published: "success",
2010
- pending: "warning",
2011
- processing: "warning",
2012
- scheduled: "warning",
2013
- draft: "warning",
2014
- failed: "error",
2015
- rejected: "error",
2016
- cancelled: "error",
2017
- deleted: "error",
2018
- inactive: "neutral",
2019
- archived: "neutral",
2020
- closed: "neutral"
2021
- };
2022
- const status = statusColorMap[String(value).toLowerCase()] || "info";
2051
+ const colorMap = (format == null ? void 0 : format.statusColors) ?? DEFAULT_STATUS_COLORS;
2052
+ const status = colorMap[String(value).toLowerCase()] ?? "info";
2023
2053
  return /* @__PURE__ */ jsxDEV(DataBadge, { variant: "status", status, size, display, children: String(value) }, void 0, false, {
2024
2054
  fileName: "/Users/dug/Projects/pattern-stack/frontend-patterns/src/atoms/utils/ui-mapping.tsx",
2025
- lineNumber: 134,
2055
+ lineNumber: 209,
2026
2056
  columnNumber: 7
2027
2057
  }, void 0);
2028
2058
  },
2029
- category: (value, _fieldName, breakpoint) => {
2059
+ badge: (value, _fieldName, breakpoint) => {
2030
2060
  const size = getSizeForBreakpoint(breakpoint);
2031
2061
  const display = getDisplayForBreakpoint(breakpoint);
2032
2062
  const color = globalColorManager.getColor(String(value));
@@ -2043,45 +2073,62 @@ const defaultFieldRenderers = {
2043
2073
  false,
2044
2074
  {
2045
2075
  fileName: "/Users/dug/Projects/pattern-stack/frontend-patterns/src/atoms/utils/ui-mapping.tsx",
2046
- lineNumber: 146,
2076
+ lineNumber: 221,
2047
2077
  columnNumber: 7
2048
2078
  },
2049
2079
  void 0
2050
2080
  );
2051
2081
  },
2052
- money: (value) => {
2053
- const formatted = formatMoney(Number(value));
2082
+ money: (value, _fieldName, _breakpoint, _item, format) => {
2083
+ const formatted = formatMoney(
2084
+ Number(value),
2085
+ (format == null ? void 0 : format.currency) ?? "USD",
2086
+ (format == null ? void 0 : format.decimals) ?? 2,
2087
+ (format == null ? void 0 : format.locale) ?? "en-US"
2088
+ );
2054
2089
  return /* @__PURE__ */ jsxDEV("span", { className: "font-mono tabular-nums", children: formatted }, void 0, false, {
2055
2090
  fileName: "/Users/dug/Projects/pattern-stack/frontend-patterns/src/atoms/utils/ui-mapping.tsx",
2056
- lineNumber: 159,
2091
+ lineNumber: 239,
2057
2092
  columnNumber: 12
2058
2093
  }, void 0);
2059
2094
  },
2060
- percent: (value) => {
2061
- const formatted = formatPercent(Number(value));
2095
+ percent: (value, _fieldName, _breakpoint, _item, format) => {
2096
+ const formatted = formatPercent(
2097
+ Number(value),
2098
+ (format == null ? void 0 : format.decimals) ?? 1,
2099
+ (format == null ? void 0 : format.locale) ?? "en-US"
2100
+ );
2062
2101
  return /* @__PURE__ */ jsxDEV("span", { className: "font-mono tabular-nums", children: formatted }, void 0, false, {
2063
2102
  fileName: "/Users/dug/Projects/pattern-stack/frontend-patterns/src/atoms/utils/ui-mapping.tsx",
2064
- lineNumber: 164,
2103
+ lineNumber: 248,
2065
2104
  columnNumber: 12
2066
2105
  }, void 0);
2067
2106
  },
2068
- date: (value) => {
2069
- const formatted = formatDate(value, false);
2107
+ date: (value, _fieldName, _breakpoint, _item, format) => {
2108
+ const formatted = formatDate(
2109
+ value,
2110
+ false,
2111
+ (format == null ? void 0 : format.locale) ?? "en-US"
2112
+ );
2070
2113
  return /* @__PURE__ */ jsxDEV("span", { className: "text-muted-foreground", children: formatted }, void 0, false, {
2071
2114
  fileName: "/Users/dug/Projects/pattern-stack/frontend-patterns/src/atoms/utils/ui-mapping.tsx",
2072
- lineNumber: 169,
2115
+ lineNumber: 257,
2073
2116
  columnNumber: 12
2074
2117
  }, void 0);
2075
2118
  },
2076
- datetime: (value) => {
2077
- const formatted = formatDate(value, true);
2119
+ datetime: (value, _fieldName, _breakpoint, _item, format) => {
2120
+ const formatted = formatDate(
2121
+ value,
2122
+ true,
2123
+ (format == null ? void 0 : format.locale) ?? "en-US"
2124
+ );
2078
2125
  return /* @__PURE__ */ jsxDEV("span", { className: "text-muted-foreground text-sm", children: formatted }, void 0, false, {
2079
2126
  fileName: "/Users/dug/Projects/pattern-stack/frontend-patterns/src/atoms/utils/ui-mapping.tsx",
2080
- lineNumber: 174,
2127
+ lineNumber: 266,
2081
2128
  columnNumber: 12
2082
2129
  }, void 0);
2083
2130
  },
2084
- user: (value, _fieldName, breakpoint, _item) => {
2131
+ user: (value, _fieldName, breakpoint) => {
2085
2132
  const sizeMap2 = {
2086
2133
  xs: "xs",
2087
2134
  sm: "sm",
@@ -2093,31 +2140,31 @@ const defaultFieldRenderers = {
2093
2140
  if (breakpoint === "xs" || breakpoint === "2xs") {
2094
2141
  return /* @__PURE__ */ jsxDEV(Avatar, { size, fallback: initials }, void 0, false, {
2095
2142
  fileName: "/Users/dug/Projects/pattern-stack/frontend-patterns/src/atoms/utils/ui-mapping.tsx",
2096
- lineNumber: 196,
2143
+ lineNumber: 288,
2097
2144
  columnNumber: 14
2098
2145
  }, void 0);
2099
2146
  }
2100
2147
  return /* @__PURE__ */ jsxDEV("div", { className: "flex items-center gap-2", children: [
2101
2148
  /* @__PURE__ */ jsxDEV(Avatar, { size, fallback: initials }, void 0, false, {
2102
2149
  fileName: "/Users/dug/Projects/pattern-stack/frontend-patterns/src/atoms/utils/ui-mapping.tsx",
2103
- lineNumber: 202,
2150
+ lineNumber: 294,
2104
2151
  columnNumber: 9
2105
2152
  }, void 0),
2106
2153
  /* @__PURE__ */ jsxDEV("span", { className: "text-sm", children: String(value) }, void 0, false, {
2107
2154
  fileName: "/Users/dug/Projects/pattern-stack/frontend-patterns/src/atoms/utils/ui-mapping.tsx",
2108
- lineNumber: 203,
2155
+ lineNumber: 295,
2109
2156
  columnNumber: 9
2110
2157
  }, void 0)
2111
2158
  ] }, void 0, true, {
2112
2159
  fileName: "/Users/dug/Projects/pattern-stack/frontend-patterns/src/atoms/utils/ui-mapping.tsx",
2113
- lineNumber: 201,
2160
+ lineNumber: 293,
2114
2161
  columnNumber: 7
2115
2162
  }, void 0);
2116
2163
  },
2117
- entity: (value, fieldName, breakpoint, _item) => {
2164
+ entity: (value, fieldName, breakpoint, _item, format) => {
2118
2165
  const size = getSizeForBreakpoint(breakpoint);
2119
2166
  const showName = breakpoint !== "xs" && breakpoint !== "2xs";
2120
- const type = fieldName.includes("vendor") || fieldName.includes("supplier") ? "vendor" : fieldName.includes("partner") ? "partner" : fieldName.includes("company") || fieldName.includes("organization") ? "company" : "customer";
2167
+ const type = (format == null ? void 0 : format.entityType) ?? (fieldName.includes("vendor") || fieldName.includes("supplier") ? "vendor" : fieldName.includes("partner") ? "partner" : fieldName.includes("company") || fieldName.includes("organization") ? "company" : "customer");
2121
2168
  return /* @__PURE__ */ jsxDEV(
2122
2169
  EntityIcon,
2123
2170
  {
@@ -2131,20 +2178,20 @@ const defaultFieldRenderers = {
2131
2178
  false,
2132
2179
  {
2133
2180
  fileName: "/Users/dug/Projects/pattern-stack/frontend-patterns/src/atoms/utils/ui-mapping.tsx",
2134
- lineNumber: 223,
2181
+ lineNumber: 316,
2135
2182
  columnNumber: 7
2136
2183
  },
2137
2184
  void 0
2138
2185
  );
2139
2186
  },
2140
- boolean: (value, _fieldName, _breakpoint) => {
2187
+ boolean: (value) => {
2141
2188
  return /* @__PURE__ */ jsxDEV(Checkbox, { checked: Boolean(value), disabled: true }, void 0, false, {
2142
2189
  fileName: "/Users/dug/Projects/pattern-stack/frontend-patterns/src/atoms/utils/ui-mapping.tsx",
2143
- lineNumber: 234,
2190
+ lineNumber: 327,
2144
2191
  columnNumber: 12
2145
2192
  }, void 0);
2146
2193
  },
2147
- email: (value, _fieldName, _breakpoint) => {
2194
+ email: (value) => {
2148
2195
  return /* @__PURE__ */ jsxDEV(
2149
2196
  "a",
2150
2197
  {
@@ -2156,13 +2203,13 @@ const defaultFieldRenderers = {
2156
2203
  false,
2157
2204
  {
2158
2205
  fileName: "/Users/dug/Projects/pattern-stack/frontend-patterns/src/atoms/utils/ui-mapping.tsx",
2159
- lineNumber: 239,
2206
+ lineNumber: 332,
2160
2207
  columnNumber: 7
2161
2208
  },
2162
2209
  void 0
2163
2210
  );
2164
2211
  },
2165
- url: (value, _fieldName, _breakpoint) => {
2212
+ url: (value) => {
2166
2213
  const url = String(value);
2167
2214
  const display = url.replace(/^https?:\/\/(www\.)?/, "").split("/")[0];
2168
2215
  return /* @__PURE__ */ jsxDEV(
@@ -2178,13 +2225,13 @@ const defaultFieldRenderers = {
2178
2225
  false,
2179
2226
  {
2180
2227
  fileName: "/Users/dug/Projects/pattern-stack/frontend-patterns/src/atoms/utils/ui-mapping.tsx",
2181
- lineNumber: 253,
2228
+ lineNumber: 346,
2182
2229
  columnNumber: 7
2183
2230
  },
2184
2231
  void 0
2185
2232
  );
2186
2233
  },
2187
- phone: (value, _fieldName, _breakpoint) => {
2234
+ phone: (value) => {
2188
2235
  const phone = String(value);
2189
2236
  const cleaned = phone.replace(/\D/g, "");
2190
2237
  return /* @__PURE__ */ jsxDEV(
@@ -2198,40 +2245,111 @@ const defaultFieldRenderers = {
2198
2245
  false,
2199
2246
  {
2200
2247
  fileName: "/Users/dug/Projects/pattern-stack/frontend-patterns/src/atoms/utils/ui-mapping.tsx",
2201
- lineNumber: 269,
2248
+ lineNumber: 362,
2202
2249
  columnNumber: 7
2203
2250
  },
2204
2251
  void 0
2205
2252
  );
2206
2253
  },
2207
- text: (value, _fieldName, _breakpoint) => {
2254
+ text: (value) => {
2208
2255
  return /* @__PURE__ */ jsxDEV("span", { children: String(value) }, void 0, false, {
2209
2256
  fileName: "/Users/dug/Projects/pattern-stack/frontend-patterns/src/atoms/utils/ui-mapping.tsx",
2210
- lineNumber: 279,
2257
+ lineNumber: 372,
2211
2258
  columnNumber: 12
2212
2259
  }, void 0);
2213
2260
  },
2214
- number: (value, _fieldName, _breakpoint) => {
2215
- const num = Number(value);
2216
- const formatted = num.toLocaleString();
2261
+ number: (value, _fieldName, _breakpoint, _item, format) => {
2262
+ const formatted = formatNumber(
2263
+ Number(value),
2264
+ format == null ? void 0 : format.decimals,
2265
+ (format == null ? void 0 : format.locale) ?? "en-US"
2266
+ );
2217
2267
  return /* @__PURE__ */ jsxDEV("span", { className: "font-mono tabular-nums", children: formatted }, void 0, false, {
2218
2268
  fileName: "/Users/dug/Projects/pattern-stack/frontend-patterns/src/atoms/utils/ui-mapping.tsx",
2219
- lineNumber: 285,
2269
+ lineNumber: 381,
2270
+ columnNumber: 12
2271
+ }, void 0);
2272
+ },
2273
+ json: (value) => {
2274
+ const str = typeof value === "object" ? JSON.stringify(value, null, 2) : String(value);
2275
+ return /* @__PURE__ */ jsxDEV("code", { className: "text-xs bg-muted px-1 py-0.5 rounded font-mono", children: str.length > 50 ? str.slice(0, 50) + "..." : str }, void 0, false, {
2276
+ fileName: "/Users/dug/Projects/pattern-stack/frontend-patterns/src/atoms/utils/ui-mapping.tsx",
2277
+ lineNumber: 386,
2278
+ columnNumber: 12
2279
+ }, void 0);
2280
+ },
2281
+ image: (value) => {
2282
+ return /* @__PURE__ */ jsxDEV("img", { src: String(value), alt: "", className: "w-8 h-8 rounded object-cover" }, void 0, false, {
2283
+ fileName: "/Users/dug/Projects/pattern-stack/frontend-patterns/src/atoms/utils/ui-mapping.tsx",
2284
+ lineNumber: 390,
2220
2285
  columnNumber: 12
2221
2286
  }, void 0);
2287
+ },
2288
+ rating: (value, _fieldName, _breakpoint, _item, format) => {
2289
+ const max = (format == null ? void 0 : format.max) ?? 5;
2290
+ const filled = Math.round(Number(value));
2291
+ return (
2292
+ // eslint-disable-next-line design-system/no-hardcoded-colors -- amber is standard for star ratings
2293
+ /* @__PURE__ */ jsxDEV("span", { className: "text-amber-500", children: [
2294
+ "★".repeat(Math.min(filled, max)),
2295
+ "☆".repeat(Math.max(0, max - filled))
2296
+ ] }, void 0, true, {
2297
+ fileName: "/Users/dug/Projects/pattern-stack/frontend-patterns/src/atoms/utils/ui-mapping.tsx",
2298
+ lineNumber: 398,
2299
+ columnNumber: 7
2300
+ }, void 0)
2301
+ );
2302
+ },
2303
+ color: (value) => {
2304
+ return /* @__PURE__ */ jsxDEV("div", { className: "flex items-center gap-2", children: [
2305
+ /* @__PURE__ */ jsxDEV("div", { className: "w-4 h-4 rounded border", style: { backgroundColor: String(value) } }, void 0, false, {
2306
+ fileName: "/Users/dug/Projects/pattern-stack/frontend-patterns/src/atoms/utils/ui-mapping.tsx",
2307
+ lineNumber: 407,
2308
+ columnNumber: 9
2309
+ }, void 0),
2310
+ /* @__PURE__ */ jsxDEV("span", { className: "text-xs font-mono", children: String(value) }, void 0, false, {
2311
+ fileName: "/Users/dug/Projects/pattern-stack/frontend-patterns/src/atoms/utils/ui-mapping.tsx",
2312
+ lineNumber: 408,
2313
+ columnNumber: 9
2314
+ }, void 0)
2315
+ ] }, void 0, true, {
2316
+ fileName: "/Users/dug/Projects/pattern-stack/frontend-patterns/src/atoms/utils/ui-mapping.tsx",
2317
+ lineNumber: 406,
2318
+ columnNumber: 7
2319
+ }, void 0);
2320
+ },
2321
+ file: (value, _fieldName, _breakpoint, item) => {
2322
+ const filename = (item == null ? void 0 : item.filename) ?? String(value).split("/").pop() ?? "file";
2323
+ return /* @__PURE__ */ jsxDEV("a", { href: String(value), className: "flex items-center gap-1 text-primary hover:underline", children: [
2324
+ /* @__PURE__ */ jsxDEV(File, { className: "w-4 h-4" }, void 0, false, {
2325
+ fileName: "/Users/dug/Projects/pattern-stack/frontend-patterns/src/atoms/utils/ui-mapping.tsx",
2326
+ lineNumber: 417,
2327
+ columnNumber: 9
2328
+ }, void 0),
2329
+ /* @__PURE__ */ jsxDEV("span", { className: "text-sm truncate max-w-[150px]", children: filename }, void 0, false, {
2330
+ fileName: "/Users/dug/Projects/pattern-stack/frontend-patterns/src/atoms/utils/ui-mapping.tsx",
2331
+ lineNumber: 418,
2332
+ columnNumber: 9
2333
+ }, void 0)
2334
+ ] }, void 0, true, {
2335
+ fileName: "/Users/dug/Projects/pattern-stack/frontend-patterns/src/atoms/utils/ui-mapping.tsx",
2336
+ lineNumber: 416,
2337
+ columnNumber: 7
2338
+ }, void 0);
2222
2339
  }
2223
2340
  };
2224
- function renderField(value, fieldName, fieldType, breakpoint, item, customRenderers) {
2225
- const renderer = (customRenderers == null ? void 0 : customRenderers[fieldType]) || defaultFieldRenderers[fieldType];
2341
+ function renderField(value, fieldName, fieldType, breakpoint, item, customRenderers, format) {
2342
+ const normalizedType = normalizeFieldType(fieldType);
2343
+ const renderer = (customRenderers == null ? void 0 : customRenderers[normalizedType]) || defaultFieldRenderers[normalizedType];
2226
2344
  if (!renderer) {
2227
- console.warn(`No renderer found for field type: ${fieldType}`);
2345
+ console.warn(`No renderer found for field type: ${fieldType} (normalized: ${normalizedType})`);
2228
2346
  return /* @__PURE__ */ jsxDEV("span", { children: String(value) }, void 0, false, {
2229
2347
  fileName: "/Users/dug/Projects/pattern-stack/frontend-patterns/src/atoms/utils/ui-mapping.tsx",
2230
- lineNumber: 306,
2348
+ lineNumber: 443,
2231
2349
  columnNumber: 12
2232
2350
  }, this);
2233
2351
  }
2234
- return renderer(value, fieldName, breakpoint, item);
2352
+ return renderer(value, fieldName, breakpoint, item, format);
2235
2353
  }
2236
2354
  function cn(...inputs) {
2237
2355
  return twMerge(clsx(inputs));
@@ -2448,6 +2566,149 @@ function useHealth() {
2448
2566
  retry: 2
2449
2567
  });
2450
2568
  }
2569
+ function useFieldMetadata({
2570
+ entity,
2571
+ view = "list",
2572
+ enabled = true
2573
+ }) {
2574
+ return useQuery({
2575
+ queryKey: ["metadata", entity, view],
2576
+ queryFn: async () => {
2577
+ const response = await fetch(`/api/v1/${entity}/metadata?view=${view}`);
2578
+ if (!response.ok) {
2579
+ throw new Error(`Failed to fetch metadata for ${entity}`);
2580
+ }
2581
+ return response.json();
2582
+ },
2583
+ enabled,
2584
+ staleTime: 1e3 * 60 * 30
2585
+ // 30 minutes - metadata rarely changes
2586
+ });
2587
+ }
2588
+ function useResponsiveTable(options = {}) {
2589
+ const {
2590
+ initialView = "full",
2591
+ autoSwitch = true,
2592
+ minWidthForCompact = 400,
2593
+ debounceMs = 100,
2594
+ onViewChange
2595
+ } = options;
2596
+ const [viewMode, setViewModeState] = useState(initialView);
2597
+ const [isAutoSwitching, setIsAutoSwitching] = useState(autoSwitch);
2598
+ const [overflowState, setOverflowState] = useState({
2599
+ fullOverflows: false,
2600
+ compactOverflows: false
2601
+ });
2602
+ const fullTableRef = useRef(null);
2603
+ const compactTableRef = useRef(null);
2604
+ const debounceTimerRef = useRef(null);
2605
+ const isTransitioningRef = useRef(false);
2606
+ const hasOverflow = useCallback((element) => {
2607
+ if (!element) return false;
2608
+ return element.scrollWidth > element.clientWidth + 2;
2609
+ }, []);
2610
+ const determineView = useCallback(() => {
2611
+ var _a, _b, _c, _d;
2612
+ const containerWidth = ((_b = (_a = fullTableRef.current) == null ? void 0 : _a.parentElement) == null ? void 0 : _b.clientWidth) || ((_d = (_c = compactTableRef.current) == null ? void 0 : _c.parentElement) == null ? void 0 : _d.clientWidth) || window.innerWidth;
2613
+ if (containerWidth < minWidthForCompact) {
2614
+ return "cards";
2615
+ }
2616
+ const fullOverflows = hasOverflow(fullTableRef.current);
2617
+ const compactOverflows = hasOverflow(compactTableRef.current);
2618
+ setOverflowState({ fullOverflows, compactOverflows });
2619
+ if (!fullOverflows) {
2620
+ return "full";
2621
+ }
2622
+ if (!compactOverflows) {
2623
+ return "compact";
2624
+ }
2625
+ return "cards";
2626
+ }, [hasOverflow, minWidthForCompact]);
2627
+ const checkAndUpdate = useCallback(() => {
2628
+ if (!isAutoSwitching || isTransitioningRef.current) return;
2629
+ if (debounceTimerRef.current) {
2630
+ clearTimeout(debounceTimerRef.current);
2631
+ }
2632
+ debounceTimerRef.current = setTimeout(() => {
2633
+ const newView = determineView();
2634
+ if (newView !== viewMode) {
2635
+ isTransitioningRef.current = true;
2636
+ setViewModeState(newView);
2637
+ onViewChange == null ? void 0 : onViewChange(newView);
2638
+ setTimeout(() => {
2639
+ isTransitioningRef.current = false;
2640
+ }, 50);
2641
+ }
2642
+ }, debounceMs);
2643
+ }, [isAutoSwitching, determineView, viewMode, debounceMs, onViewChange]);
2644
+ const setViewMode = useCallback(
2645
+ (mode) => {
2646
+ setIsAutoSwitching(false);
2647
+ setViewModeState(mode);
2648
+ onViewChange == null ? void 0 : onViewChange(mode);
2649
+ },
2650
+ [onViewChange]
2651
+ );
2652
+ const enableAutoSwitch = useCallback(() => {
2653
+ setIsAutoSwitching(true);
2654
+ }, []);
2655
+ useEffect(() => {
2656
+ var _a, _b;
2657
+ if (!isAutoSwitching) return;
2658
+ const initialCheckTimer = setTimeout(checkAndUpdate, 50);
2659
+ const resizeObserver = new ResizeObserver(() => {
2660
+ checkAndUpdate();
2661
+ });
2662
+ if (fullTableRef.current) {
2663
+ resizeObserver.observe(fullTableRef.current);
2664
+ }
2665
+ if (compactTableRef.current) {
2666
+ resizeObserver.observe(compactTableRef.current);
2667
+ }
2668
+ const parent = ((_a = fullTableRef.current) == null ? void 0 : _a.parentElement) || ((_b = compactTableRef.current) == null ? void 0 : _b.parentElement);
2669
+ if (parent) {
2670
+ resizeObserver.observe(parent);
2671
+ }
2672
+ window.addEventListener("resize", checkAndUpdate);
2673
+ return () => {
2674
+ clearTimeout(initialCheckTimer);
2675
+ if (debounceTimerRef.current) {
2676
+ clearTimeout(debounceTimerRef.current);
2677
+ }
2678
+ resizeObserver.disconnect();
2679
+ window.removeEventListener("resize", checkAndUpdate);
2680
+ };
2681
+ }, [isAutoSwitching, checkAndUpdate]);
2682
+ useEffect(() => {
2683
+ if (!isAutoSwitching) return;
2684
+ const timer = setTimeout(checkAndUpdate, 100);
2685
+ return () => clearTimeout(timer);
2686
+ }, [viewMode, isAutoSwitching, checkAndUpdate]);
2687
+ return {
2688
+ viewMode,
2689
+ setViewMode,
2690
+ enableAutoSwitch,
2691
+ isAutoSwitching,
2692
+ fullTableRef,
2693
+ compactTableRef,
2694
+ overflowState
2695
+ };
2696
+ }
2697
+ function useOverflowDetection(ref) {
2698
+ const [hasOverflow, setHasOverflow] = useState(false);
2699
+ useEffect(() => {
2700
+ const element = ref.current;
2701
+ if (!element) return;
2702
+ const checkOverflow = () => {
2703
+ setHasOverflow(element.scrollWidth > element.clientWidth + 2);
2704
+ };
2705
+ checkOverflow();
2706
+ const observer = new ResizeObserver(checkOverflow);
2707
+ observer.observe(element);
2708
+ return () => observer.disconnect();
2709
+ }, [ref]);
2710
+ return hasOverflow;
2711
+ }
2451
2712
  const buttonVariants = cva(
2452
2713
  "inline-flex items-center justify-center whitespace-nowrap rounded-lg text-sm font-medium ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary/20 focus-visible:ring-offset-0 disabled:pointer-events-none disabled:opacity-50 active:scale-[0.98]",
2453
2714
  {
@@ -5320,6 +5581,25 @@ function DataTable({
5320
5581
  }
5321
5582
  const value = item[column.key];
5322
5583
  const fieldName = column.key;
5584
+ if (value === null || value === void 0) {
5585
+ return /* @__PURE__ */ jsxDEV("span", { className: "text-muted-foreground", children: "—" }, void 0, false, {
5586
+ fileName: "/Users/dug/Projects/pattern-stack/frontend-patterns/src/atoms/components/data/DataTable/DataTable.tsx",
5587
+ lineNumber: 179,
5588
+ columnNumber: 14
5589
+ }, this);
5590
+ }
5591
+ if (column.type) {
5592
+ return renderField(
5593
+ value,
5594
+ fieldName,
5595
+ column.type,
5596
+ currentBreakpoint,
5597
+ item,
5598
+ void 0,
5599
+ // customRenderers
5600
+ column.format
5601
+ );
5602
+ }
5323
5603
  const fieldType = getFieldType(fieldName, value, effectiveUI);
5324
5604
  return renderField(value, fieldName, fieldType, currentBreakpoint, item);
5325
5605
  };
@@ -5332,99 +5612,99 @@ function DataTable({
5332
5612
  children: [
5333
5613
  showSearch && /* @__PURE__ */ jsxDEV("div", { className: "flex items-center gap-2", children: /* @__PURE__ */ jsxDEV("div", { className: "relative flex-1 max-w-sm", children: /* @__PURE__ */ jsxDEV(Skeleton$1, { className: "h-10 w-full" }, void 0, false, {
5334
5614
  fileName: "/Users/dug/Projects/pattern-stack/frontend-patterns/src/atoms/components/data/DataTable/DataTable.tsx",
5335
- lineNumber: 195,
5615
+ lineNumber: 213,
5336
5616
  columnNumber: 15
5337
5617
  }, this) }, void 0, false, {
5338
5618
  fileName: "/Users/dug/Projects/pattern-stack/frontend-patterns/src/atoms/components/data/DataTable/DataTable.tsx",
5339
- lineNumber: 194,
5619
+ lineNumber: 212,
5340
5620
  columnNumber: 13
5341
5621
  }, this) }, void 0, false, {
5342
5622
  fileName: "/Users/dug/Projects/pattern-stack/frontend-patterns/src/atoms/components/data/DataTable/DataTable.tsx",
5343
- lineNumber: 193,
5623
+ lineNumber: 211,
5344
5624
  columnNumber: 11
5345
5625
  }, this),
5346
5626
  /* @__PURE__ */ jsxDEV("div", { className: "rounded border overflow-hidden", children: /* @__PURE__ */ jsxDEV(Table$1, { children: [
5347
5627
  /* @__PURE__ */ jsxDEV(TableHeader$1, { children: /* @__PURE__ */ jsxDEV(TableRow$1, { children: visibleColumns.map((column) => /* @__PURE__ */ jsxDEV(TableHead$1, { style: { width: column.width }, children: /* @__PURE__ */ jsxDEV("div", { className: "flex items-center gap-2", children: /* @__PURE__ */ jsxDEV(Skeleton$1, { className: "h-4 w-20" }, void 0, false, {
5348
5628
  fileName: "/Users/dug/Projects/pattern-stack/frontend-patterns/src/atoms/components/data/DataTable/DataTable.tsx",
5349
- lineNumber: 208,
5629
+ lineNumber: 226,
5350
5630
  columnNumber: 23
5351
5631
  }, this) }, void 0, false, {
5352
5632
  fileName: "/Users/dug/Projects/pattern-stack/frontend-patterns/src/atoms/components/data/DataTable/DataTable.tsx",
5353
- lineNumber: 207,
5633
+ lineNumber: 225,
5354
5634
  columnNumber: 21
5355
5635
  }, this) }, column.key, false, {
5356
5636
  fileName: "/Users/dug/Projects/pattern-stack/frontend-patterns/src/atoms/components/data/DataTable/DataTable.tsx",
5357
- lineNumber: 206,
5637
+ lineNumber: 224,
5358
5638
  columnNumber: 19
5359
5639
  }, this)) }, void 0, false, {
5360
5640
  fileName: "/Users/dug/Projects/pattern-stack/frontend-patterns/src/atoms/components/data/DataTable/DataTable.tsx",
5361
- lineNumber: 204,
5641
+ lineNumber: 222,
5362
5642
  columnNumber: 15
5363
5643
  }, this) }, void 0, false, {
5364
5644
  fileName: "/Users/dug/Projects/pattern-stack/frontend-patterns/src/atoms/components/data/DataTable/DataTable.tsx",
5365
- lineNumber: 203,
5645
+ lineNumber: 221,
5366
5646
  columnNumber: 13
5367
5647
  }, this),
5368
5648
  /* @__PURE__ */ jsxDEV(TableBody$1, { children: Array.from({ length: loadingItemCount }, (_, index) => /* @__PURE__ */ jsxDEV(TableRow$1, { children: visibleColumns.map((column) => /* @__PURE__ */ jsxDEV(TableCell$1, { children: /* @__PURE__ */ jsxDEV(Skeleton$1, { className: "h-4 w-full max-w-32" }, void 0, false, {
5369
5649
  fileName: "/Users/dug/Projects/pattern-stack/frontend-patterns/src/atoms/components/data/DataTable/DataTable.tsx",
5370
- lineNumber: 219,
5650
+ lineNumber: 237,
5371
5651
  columnNumber: 23
5372
5652
  }, this) }, column.key, false, {
5373
5653
  fileName: "/Users/dug/Projects/pattern-stack/frontend-patterns/src/atoms/components/data/DataTable/DataTable.tsx",
5374
- lineNumber: 218,
5654
+ lineNumber: 236,
5375
5655
  columnNumber: 21
5376
5656
  }, this)) }, index, false, {
5377
5657
  fileName: "/Users/dug/Projects/pattern-stack/frontend-patterns/src/atoms/components/data/DataTable/DataTable.tsx",
5378
- lineNumber: 216,
5658
+ lineNumber: 234,
5379
5659
  columnNumber: 17
5380
5660
  }, this)) }, void 0, false, {
5381
5661
  fileName: "/Users/dug/Projects/pattern-stack/frontend-patterns/src/atoms/components/data/DataTable/DataTable.tsx",
5382
- lineNumber: 214,
5662
+ lineNumber: 232,
5383
5663
  columnNumber: 13
5384
5664
  }, this)
5385
5665
  ] }, void 0, true, {
5386
5666
  fileName: "/Users/dug/Projects/pattern-stack/frontend-patterns/src/atoms/components/data/DataTable/DataTable.tsx",
5387
- lineNumber: 202,
5667
+ lineNumber: 220,
5388
5668
  columnNumber: 11
5389
5669
  }, this) }, void 0, false, {
5390
5670
  fileName: "/Users/dug/Projects/pattern-stack/frontend-patterns/src/atoms/components/data/DataTable/DataTable.tsx",
5391
- lineNumber: 201,
5671
+ lineNumber: 219,
5392
5672
  columnNumber: 9
5393
5673
  }, this),
5394
5674
  showPagination && /* @__PURE__ */ jsxDEV("div", { className: "flex items-center justify-between", children: [
5395
5675
  /* @__PURE__ */ jsxDEV(Skeleton$1, { className: "h-4 w-48" }, void 0, false, {
5396
5676
  fileName: "/Users/dug/Projects/pattern-stack/frontend-patterns/src/atoms/components/data/DataTable/DataTable.tsx",
5397
- lineNumber: 231,
5677
+ lineNumber: 249,
5398
5678
  columnNumber: 13
5399
5679
  }, this),
5400
5680
  /* @__PURE__ */ jsxDEV("div", { className: "flex items-center gap-2", children: [
5401
5681
  /* @__PURE__ */ jsxDEV(Skeleton$1, { className: "h-8 w-20" }, void 0, false, {
5402
5682
  fileName: "/Users/dug/Projects/pattern-stack/frontend-patterns/src/atoms/components/data/DataTable/DataTable.tsx",
5403
- lineNumber: 233,
5683
+ lineNumber: 251,
5404
5684
  columnNumber: 15
5405
5685
  }, this),
5406
5686
  /* @__PURE__ */ jsxDEV("div", { className: "flex items-center gap-1", children: Array.from({ length: 3 }, (_, i) => /* @__PURE__ */ jsxDEV(Skeleton$1, { className: "h-8 w-8" }, i, false, {
5407
5687
  fileName: "/Users/dug/Projects/pattern-stack/frontend-patterns/src/atoms/components/data/DataTable/DataTable.tsx",
5408
- lineNumber: 236,
5688
+ lineNumber: 254,
5409
5689
  columnNumber: 19
5410
5690
  }, this)) }, void 0, false, {
5411
5691
  fileName: "/Users/dug/Projects/pattern-stack/frontend-patterns/src/atoms/components/data/DataTable/DataTable.tsx",
5412
- lineNumber: 234,
5692
+ lineNumber: 252,
5413
5693
  columnNumber: 15
5414
5694
  }, this),
5415
5695
  /* @__PURE__ */ jsxDEV(Skeleton$1, { className: "h-8 w-16" }, void 0, false, {
5416
5696
  fileName: "/Users/dug/Projects/pattern-stack/frontend-patterns/src/atoms/components/data/DataTable/DataTable.tsx",
5417
- lineNumber: 239,
5697
+ lineNumber: 257,
5418
5698
  columnNumber: 15
5419
5699
  }, this)
5420
5700
  ] }, void 0, true, {
5421
5701
  fileName: "/Users/dug/Projects/pattern-stack/frontend-patterns/src/atoms/components/data/DataTable/DataTable.tsx",
5422
- lineNumber: 232,
5702
+ lineNumber: 250,
5423
5703
  columnNumber: 13
5424
5704
  }, this)
5425
5705
  ] }, void 0, true, {
5426
5706
  fileName: "/Users/dug/Projects/pattern-stack/frontend-patterns/src/atoms/components/data/DataTable/DataTable.tsx",
5427
- lineNumber: 230,
5707
+ lineNumber: 248,
5428
5708
  columnNumber: 11
5429
5709
  }, this)
5430
5710
  ]
@@ -5433,7 +5713,7 @@ function DataTable({
5433
5713
  true,
5434
5714
  {
5435
5715
  fileName: "/Users/dug/Projects/pattern-stack/frontend-patterns/src/atoms/components/data/DataTable/DataTable.tsx",
5436
- lineNumber: 187,
5716
+ lineNumber: 205,
5437
5717
  columnNumber: 7
5438
5718
  },
5439
5719
  this
@@ -5452,7 +5732,7 @@ function DataTable({
5452
5732
  false,
5453
5733
  {
5454
5734
  fileName: "/Users/dug/Projects/pattern-stack/frontend-patterns/src/atoms/components/data/DataTable/DataTable.tsx",
5455
- lineNumber: 253,
5735
+ lineNumber: 271,
5456
5736
  columnNumber: 13
5457
5737
  },
5458
5738
  this
@@ -5473,7 +5753,7 @@ function DataTable({
5473
5753
  false,
5474
5754
  {
5475
5755
  fileName: "/Users/dug/Projects/pattern-stack/frontend-patterns/src/atoms/components/data/DataTable/DataTable.tsx",
5476
- lineNumber: 257,
5756
+ lineNumber: 275,
5477
5757
  columnNumber: 13
5478
5758
  },
5479
5759
  this
@@ -5491,7 +5771,7 @@ function DataTable({
5491
5771
  "aria-label": tooltipContent.clearSearch,
5492
5772
  children: /* @__PURE__ */ jsxDEV(X, { className: "w-4 h-4", "data-component-name": "DataTableClear" }, void 0, false, {
5493
5773
  fileName: "/Users/dug/Projects/pattern-stack/frontend-patterns/src/atoms/components/data/DataTable/DataTable.tsx",
5494
- lineNumber: 278,
5774
+ lineNumber: 296,
5495
5775
  columnNumber: 17
5496
5776
  }, this)
5497
5777
  },
@@ -5499,14 +5779,14 @@ function DataTable({
5499
5779
  false,
5500
5780
  {
5501
5781
  fileName: "/Users/dug/Projects/pattern-stack/frontend-patterns/src/atoms/components/data/DataTable/DataTable.tsx",
5502
- lineNumber: 268,
5782
+ lineNumber: 286,
5503
5783
  columnNumber: 15
5504
5784
  },
5505
5785
  this
5506
5786
  )
5507
5787
  ] }, void 0, true, {
5508
5788
  fileName: "/Users/dug/Projects/pattern-stack/frontend-patterns/src/atoms/components/data/DataTable/DataTable.tsx",
5509
- lineNumber: 252,
5789
+ lineNumber: 270,
5510
5790
  columnNumber: 11
5511
5791
  }, this),
5512
5792
  searchTerm && /* @__PURE__ */ jsxDEV("div", { className: "text-muted-foreground text-sm", children: [
@@ -5515,12 +5795,12 @@ function DataTable({
5515
5795
  sortedData.length !== 1 ? "s" : ""
5516
5796
  ] }, void 0, true, {
5517
5797
  fileName: "/Users/dug/Projects/pattern-stack/frontend-patterns/src/atoms/components/data/DataTable/DataTable.tsx",
5518
- lineNumber: 283,
5798
+ lineNumber: 301,
5519
5799
  columnNumber: 13
5520
5800
  }, this)
5521
5801
  ] }, void 0, true, {
5522
5802
  fileName: "/Users/dug/Projects/pattern-stack/frontend-patterns/src/atoms/components/data/DataTable/DataTable.tsx",
5523
- lineNumber: 251,
5803
+ lineNumber: 269,
5524
5804
  columnNumber: 9
5525
5805
  }, this),
5526
5806
  renderMobileCard && isMobile ? /* @__PURE__ */ jsxDEV("div", { children: renderMobileCard({
@@ -5528,7 +5808,7 @@ function DataTable({
5528
5808
  onItemClick: onRowClick
5529
5809
  }) }, void 0, false, {
5530
5810
  fileName: "/Users/dug/Projects/pattern-stack/frontend-patterns/src/atoms/components/data/DataTable/DataTable.tsx",
5531
- lineNumber: 292,
5811
+ lineNumber: 310,
5532
5812
  columnNumber: 9
5533
5813
  }, this) : /* @__PURE__ */ jsxDEV("div", { className: "rounded border overflow-hidden", children: /* @__PURE__ */ jsxDEV(Table$1, { children: [
5534
5814
  /* @__PURE__ */ jsxDEV(TableHeader$1, { children: /* @__PURE__ */ jsxDEV(TableRow$1, { children: visibleColumns.map((column) => {
@@ -5546,17 +5826,17 @@ function DataTable({
5546
5826
  children: /* @__PURE__ */ jsxDEV("div", { className: "flex items-center gap-1 xs:gap-2", children: typeof column.header === "string" ? /* @__PURE__ */ jsxDEV(Fragment, { children: [
5547
5827
  /* @__PURE__ */ jsxDEV("span", { className: "truncate", children: column.header }, void 0, false, {
5548
5828
  fileName: "/Users/dug/Projects/pattern-stack/frontend-patterns/src/atoms/components/data/DataTable/DataTable.tsx",
5549
- lineNumber: 328,
5829
+ lineNumber: 346,
5550
5830
  columnNumber: 29
5551
5831
  }, this),
5552
5832
  column.sortable !== false && getSortIcon(column.key)
5553
5833
  ] }, void 0, true, {
5554
5834
  fileName: "/Users/dug/Projects/pattern-stack/frontend-patterns/src/atoms/components/data/DataTable/DataTable.tsx",
5555
- lineNumber: 327,
5835
+ lineNumber: 345,
5556
5836
  columnNumber: 27
5557
5837
  }, this) : column.header }, void 0, false, {
5558
5838
  fileName: "/Users/dug/Projects/pattern-stack/frontend-patterns/src/atoms/components/data/DataTable/DataTable.tsx",
5559
- lineNumber: 325,
5839
+ lineNumber: 343,
5560
5840
  columnNumber: 23
5561
5841
  }, this)
5562
5842
  },
@@ -5564,18 +5844,18 @@ function DataTable({
5564
5844
  false,
5565
5845
  {
5566
5846
  fileName: "/Users/dug/Projects/pattern-stack/frontend-patterns/src/atoms/components/data/DataTable/DataTable.tsx",
5567
- lineNumber: 308,
5847
+ lineNumber: 326,
5568
5848
  columnNumber: 21
5569
5849
  },
5570
5850
  this
5571
5851
  );
5572
5852
  }) }, void 0, false, {
5573
5853
  fileName: "/Users/dug/Projects/pattern-stack/frontend-patterns/src/atoms/components/data/DataTable/DataTable.tsx",
5574
- lineNumber: 302,
5854
+ lineNumber: 320,
5575
5855
  columnNumber: 15
5576
5856
  }, this) }, void 0, false, {
5577
5857
  fileName: "/Users/dug/Projects/pattern-stack/frontend-patterns/src/atoms/components/data/DataTable/DataTable.tsx",
5578
- lineNumber: 301,
5858
+ lineNumber: 319,
5579
5859
  columnNumber: 13
5580
5860
  }, this),
5581
5861
  /* @__PURE__ */ jsxDEV(TableBody$1, { children: paginatedData.length === 0 ? /* @__PURE__ */ jsxDEV(TableRow$1, { children: /* @__PURE__ */ jsxDEV(
@@ -5589,13 +5869,13 @@ function DataTable({
5589
5869
  false,
5590
5870
  {
5591
5871
  fileName: "/Users/dug/Projects/pattern-stack/frontend-patterns/src/atoms/components/data/DataTable/DataTable.tsx",
5592
- lineNumber: 344,
5872
+ lineNumber: 362,
5593
5873
  columnNumber: 19
5594
5874
  },
5595
5875
  this
5596
5876
  ) }, void 0, false, {
5597
5877
  fileName: "/Users/dug/Projects/pattern-stack/frontend-patterns/src/atoms/components/data/DataTable/DataTable.tsx",
5598
- lineNumber: 343,
5878
+ lineNumber: 361,
5599
5879
  columnNumber: 17
5600
5880
  }, this) : paginatedData.map((item, index) => /* @__PURE__ */ jsxDEV(
5601
5881
  TableRow$1,
@@ -5607,7 +5887,7 @@ function DataTable({
5607
5887
  onClick: () => onRowClick == null ? void 0 : onRowClick(item),
5608
5888
  children: visibleColumns.map((column) => /* @__PURE__ */ jsxDEV(TableCell$1, { children: renderCell(column, item) }, column.key, false, {
5609
5889
  fileName: "/Users/dug/Projects/pattern-stack/frontend-patterns/src/atoms/components/data/DataTable/DataTable.tsx",
5610
- lineNumber: 362,
5890
+ lineNumber: 380,
5611
5891
  columnNumber: 23
5612
5892
  }, this))
5613
5893
  },
@@ -5615,22 +5895,22 @@ function DataTable({
5615
5895
  false,
5616
5896
  {
5617
5897
  fileName: "/Users/dug/Projects/pattern-stack/frontend-patterns/src/atoms/components/data/DataTable/DataTable.tsx",
5618
- lineNumber: 353,
5898
+ lineNumber: 371,
5619
5899
  columnNumber: 19
5620
5900
  },
5621
5901
  this
5622
5902
  )) }, void 0, false, {
5623
5903
  fileName: "/Users/dug/Projects/pattern-stack/frontend-patterns/src/atoms/components/data/DataTable/DataTable.tsx",
5624
- lineNumber: 341,
5904
+ lineNumber: 359,
5625
5905
  columnNumber: 13
5626
5906
  }, this)
5627
5907
  ] }, void 0, true, {
5628
5908
  fileName: "/Users/dug/Projects/pattern-stack/frontend-patterns/src/atoms/components/data/DataTable/DataTable.tsx",
5629
- lineNumber: 300,
5909
+ lineNumber: 318,
5630
5910
  columnNumber: 11
5631
5911
  }, this) }, void 0, false, {
5632
5912
  fileName: "/Users/dug/Projects/pattern-stack/frontend-patterns/src/atoms/components/data/DataTable/DataTable.tsx",
5633
- lineNumber: 299,
5913
+ lineNumber: 317,
5634
5914
  columnNumber: 9
5635
5915
  }, this),
5636
5916
  showPagination && totalPages > 1 && /* @__PURE__ */ jsxDEV("div", { className: "flex items-center justify-between", children: [
@@ -5646,7 +5926,7 @@ function DataTable({
5646
5926
  " entries"
5647
5927
  ] }, void 0, true, {
5648
5928
  fileName: "/Users/dug/Projects/pattern-stack/frontend-patterns/src/atoms/components/data/DataTable/DataTable.tsx",
5649
- lineNumber: 377,
5929
+ lineNumber: 395,
5650
5930
  columnNumber: 11
5651
5931
  }, this),
5652
5932
  /* @__PURE__ */ jsxDEV("div", { className: "flex items-center gap-2", children: [
@@ -5664,7 +5944,7 @@ function DataTable({
5664
5944
  false,
5665
5945
  {
5666
5946
  fileName: "/Users/dug/Projects/pattern-stack/frontend-patterns/src/atoms/components/data/DataTable/DataTable.tsx",
5667
- lineNumber: 383,
5947
+ lineNumber: 401,
5668
5948
  columnNumber: 13
5669
5949
  },
5670
5950
  this
@@ -5693,14 +5973,14 @@ function DataTable({
5693
5973
  false,
5694
5974
  {
5695
5975
  fileName: "/Users/dug/Projects/pattern-stack/frontend-patterns/src/atoms/components/data/DataTable/DataTable.tsx",
5696
- lineNumber: 406,
5976
+ lineNumber: 424,
5697
5977
  columnNumber: 19
5698
5978
  },
5699
5979
  this
5700
5980
  );
5701
5981
  }) }, void 0, false, {
5702
5982
  fileName: "/Users/dug/Projects/pattern-stack/frontend-patterns/src/atoms/components/data/DataTable/DataTable.tsx",
5703
- lineNumber: 392,
5983
+ lineNumber: 410,
5704
5984
  columnNumber: 13
5705
5985
  }, this),
5706
5986
  /* @__PURE__ */ jsxDEV(
@@ -5717,24 +5997,24 @@ function DataTable({
5717
5997
  false,
5718
5998
  {
5719
5999
  fileName: "/Users/dug/Projects/pattern-stack/frontend-patterns/src/atoms/components/data/DataTable/DataTable.tsx",
5720
- lineNumber: 418,
6000
+ lineNumber: 436,
5721
6001
  columnNumber: 13
5722
6002
  },
5723
6003
  this
5724
6004
  )
5725
6005
  ] }, void 0, true, {
5726
6006
  fileName: "/Users/dug/Projects/pattern-stack/frontend-patterns/src/atoms/components/data/DataTable/DataTable.tsx",
5727
- lineNumber: 382,
6007
+ lineNumber: 400,
5728
6008
  columnNumber: 11
5729
6009
  }, this)
5730
6010
  ] }, void 0, true, {
5731
6011
  fileName: "/Users/dug/Projects/pattern-stack/frontend-patterns/src/atoms/components/data/DataTable/DataTable.tsx",
5732
- lineNumber: 376,
6012
+ lineNumber: 394,
5733
6013
  columnNumber: 9
5734
6014
  }, this)
5735
6015
  ] }, void 0, true, {
5736
6016
  fileName: "/Users/dug/Projects/pattern-stack/frontend-patterns/src/atoms/components/data/DataTable/DataTable.tsx",
5737
- lineNumber: 248,
6017
+ lineNumber: 266,
5738
6018
  columnNumber: 5
5739
6019
  }, this);
5740
6020
  }
@@ -13942,6 +14222,98 @@ const SectionHeader = ({
13942
14222
  void 0
13943
14223
  );
13944
14224
  };
14225
+ const PageTitle = ({
14226
+ children,
14227
+ icon,
14228
+ actions,
14229
+ size = "lg",
14230
+ className,
14231
+ as: Component2 = "h1"
14232
+ }) => {
14233
+ const titleSizes = {
14234
+ sm: "text-xl",
14235
+ md: "text-2xl",
14236
+ lg: "text-3xl",
14237
+ xl: "text-4xl"
14238
+ };
14239
+ const iconSizes = {
14240
+ sm: "h-5 w-5",
14241
+ md: "h-6 w-6",
14242
+ lg: "h-7 w-7",
14243
+ xl: "h-8 w-8"
14244
+ };
14245
+ const gapSizes = {
14246
+ sm: "gap-2",
14247
+ md: "gap-2.5",
14248
+ lg: "gap-3",
14249
+ xl: "gap-4"
14250
+ };
14251
+ return /* @__PURE__ */ jsxDEV(
14252
+ "div",
14253
+ {
14254
+ className: cn(
14255
+ "flex items-center justify-between",
14256
+ gapSizes[size],
14257
+ className
14258
+ ),
14259
+ "data-component-name": "PageTitle",
14260
+ children: [
14261
+ /* @__PURE__ */ jsxDEV("div", { className: cn("flex items-center", gapSizes[size]), children: [
14262
+ icon && /* @__PURE__ */ jsxDEV(
14263
+ "div",
14264
+ {
14265
+ className: cn(
14266
+ "flex items-center justify-center text-foreground",
14267
+ iconSizes[size]
14268
+ ),
14269
+ children: icon
14270
+ },
14271
+ void 0,
14272
+ false,
14273
+ {
14274
+ fileName: "/Users/dug/Projects/pattern-stack/frontend-patterns/src/molecules/layout/PageTitle/PageTitle.tsx",
14275
+ lineNumber: 59,
14276
+ columnNumber: 11
14277
+ },
14278
+ void 0
14279
+ ),
14280
+ /* @__PURE__ */ jsxDEV(
14281
+ Component2,
14282
+ {
14283
+ className: cn("font-semibold text-foreground", titleSizes[size]),
14284
+ children
14285
+ },
14286
+ void 0,
14287
+ false,
14288
+ {
14289
+ fileName: "/Users/dug/Projects/pattern-stack/frontend-patterns/src/molecules/layout/PageTitle/PageTitle.tsx",
14290
+ lineNumber: 68,
14291
+ columnNumber: 9
14292
+ },
14293
+ void 0
14294
+ )
14295
+ ] }, void 0, true, {
14296
+ fileName: "/Users/dug/Projects/pattern-stack/frontend-patterns/src/molecules/layout/PageTitle/PageTitle.tsx",
14297
+ lineNumber: 57,
14298
+ columnNumber: 7
14299
+ }, void 0),
14300
+ actions && /* @__PURE__ */ jsxDEV("div", { className: "flex items-center gap-2", children: actions }, void 0, false, {
14301
+ fileName: "/Users/dug/Projects/pattern-stack/frontend-patterns/src/molecules/layout/PageTitle/PageTitle.tsx",
14302
+ lineNumber: 75,
14303
+ columnNumber: 19
14304
+ }, void 0)
14305
+ ]
14306
+ },
14307
+ void 0,
14308
+ true,
14309
+ {
14310
+ fileName: "/Users/dug/Projects/pattern-stack/frontend-patterns/src/molecules/layout/PageTitle/PageTitle.tsx",
14311
+ lineNumber: 49,
14312
+ columnNumber: 5
14313
+ },
14314
+ void 0
14315
+ );
14316
+ };
13945
14317
  const SidebarProvider = ({
13946
14318
  children
13947
14319
  }) => {
@@ -14150,6 +14522,56 @@ const BulkSelectionBar = ({
14150
14522
  void 0
14151
14523
  );
14152
14524
  };
14525
+ const ListToolbar = ({
14526
+ search,
14527
+ buttons,
14528
+ primaryAction,
14529
+ className,
14530
+ gap = "md"
14531
+ }) => {
14532
+ const gapSizes = {
14533
+ sm: "gap-2",
14534
+ md: "gap-4",
14535
+ lg: "gap-6"
14536
+ };
14537
+ return /* @__PURE__ */ jsxDEV(
14538
+ "div",
14539
+ {
14540
+ className: cn("flex items-center", gapSizes[gap], className),
14541
+ "data-component-name": "ListToolbar",
14542
+ children: [
14543
+ search && /* @__PURE__ */ jsxDEV("div", { className: "flex-shrink-0", children: search }, void 0, false, {
14544
+ fileName: "/Users/dug/Projects/pattern-stack/frontend-patterns/src/molecules/layout/ListToolbar/ListToolbar.tsx",
14545
+ lineNumber: 58,
14546
+ columnNumber: 18
14547
+ }, void 0),
14548
+ buttons && /* @__PURE__ */ jsxDEV("div", { className: cn("flex items-center", gapSizes[gap === "lg" ? "md" : "sm"]), children: buttons }, void 0, false, {
14549
+ fileName: "/Users/dug/Projects/pattern-stack/frontend-patterns/src/molecules/layout/ListToolbar/ListToolbar.tsx",
14550
+ lineNumber: 62,
14551
+ columnNumber: 9
14552
+ }, void 0),
14553
+ primaryAction && /* @__PURE__ */ jsxDEV("div", { className: "flex-grow" }, void 0, false, {
14554
+ fileName: "/Users/dug/Projects/pattern-stack/frontend-patterns/src/molecules/layout/ListToolbar/ListToolbar.tsx",
14555
+ lineNumber: 68,
14556
+ columnNumber: 25
14557
+ }, void 0),
14558
+ primaryAction && /* @__PURE__ */ jsxDEV("div", { className: "flex-shrink-0", children: primaryAction }, void 0, false, {
14559
+ fileName: "/Users/dug/Projects/pattern-stack/frontend-patterns/src/molecules/layout/ListToolbar/ListToolbar.tsx",
14560
+ lineNumber: 71,
14561
+ columnNumber: 25
14562
+ }, void 0)
14563
+ ]
14564
+ },
14565
+ void 0,
14566
+ true,
14567
+ {
14568
+ fileName: "/Users/dug/Projects/pattern-stack/frontend-patterns/src/molecules/layout/ListToolbar/ListToolbar.tsx",
14569
+ lineNumber: 53,
14570
+ columnNumber: 5
14571
+ },
14572
+ void 0
14573
+ );
14574
+ };
14153
14575
  const Pagination = ({
14154
14576
  currentPage,
14155
14577
  totalPages,
@@ -15536,11 +15958,21 @@ class AuthService {
15536
15958
  this.removeItem("user");
15537
15959
  }
15538
15960
  async login(credentials) {
15539
- const response = await apiClient.post(
15540
- `${this.config.apiUrl}${this.config.endpoints.login}`,
15541
- credentials
15542
- );
15543
- const { token, refreshToken, user, expiresIn } = response;
15961
+ const response = await apiClient.post(`${this.config.apiUrl}${this.config.endpoints.login}`, credentials);
15962
+ let token;
15963
+ let refreshToken;
15964
+ let expiresIn;
15965
+ if ("access_token" in response) {
15966
+ const backendResponse = response;
15967
+ token = backendResponse.access_token;
15968
+ refreshToken = backendResponse.refresh_token;
15969
+ } else {
15970
+ const oldResponse = response;
15971
+ token = oldResponse.token;
15972
+ refreshToken = oldResponse.refreshToken;
15973
+ expiresIn = oldResponse.expiresIn;
15974
+ }
15975
+ const user = response.user;
15544
15976
  const expiresAt = expiresIn ? Date.now() + expiresIn * 1e3 : void 0;
15545
15977
  this.setTokenData({ token, refreshToken, expiresAt });
15546
15978
  this.setStoredUser(user);
@@ -15564,17 +15996,28 @@ class AuthService {
15564
15996
  this.refreshPromise = null;
15565
15997
  }
15566
15998
  }
15567
- async performTokenRefresh(refreshToken) {
15999
+ async performTokenRefresh(currentRefreshToken) {
15568
16000
  try {
15569
- const response = await apiClient.post(
15570
- `${this.config.apiUrl}${this.config.endpoints.refresh}`,
15571
- { refreshToken }
15572
- );
15573
- const { token, refreshToken: newRefreshToken, expiresIn } = response;
16001
+ const response = await apiClient.post(`${this.config.apiUrl}${this.config.endpoints.refresh}`, {
16002
+ refresh_token: currentRefreshToken
16003
+ });
16004
+ let token;
16005
+ let newRefreshToken;
16006
+ let expiresIn;
16007
+ if ("access_token" in response) {
16008
+ const backendResponse = response;
16009
+ token = backendResponse.access_token;
16010
+ newRefreshToken = currentRefreshToken;
16011
+ } else {
16012
+ const oldResponse = response;
16013
+ token = oldResponse.token;
16014
+ newRefreshToken = oldResponse.refreshToken;
16015
+ expiresIn = oldResponse.expiresIn;
16016
+ }
15574
16017
  const expiresAt = expiresIn ? Date.now() + expiresIn * 1e3 : void 0;
15575
16018
  this.setTokenData({
15576
16019
  token,
15577
- refreshToken: newRefreshToken || refreshToken,
16020
+ refreshToken: newRefreshToken || currentRefreshToken,
15578
16021
  expiresAt
15579
16022
  });
15580
16023
  if (this.config.autoRefresh && expiresAt) {
@@ -15772,7 +16215,7 @@ function AuthProvider({
15772
16215
  };
15773
16216
  return /* @__PURE__ */ jsxDEV(AuthContext.Provider, { value, children }, void 0, false, {
15774
16217
  fileName: "/Users/dug/Projects/pattern-stack/frontend-patterns/src/features/auth/hooks/useAuth.tsx",
15775
- lineNumber: 201,
16218
+ lineNumber: 205,
15776
16219
  columnNumber: 10
15777
16220
  }, this);
15778
16221
  }
@@ -16364,7 +16807,7 @@ const DashboardCard = ({
16364
16807
  category,
16365
16808
  padding = "md"
16366
16809
  }) => {
16367
- const paddingClasses = {
16810
+ const paddingClasses2 = {
16368
16811
  sm: "p-4",
16369
16812
  md: "p-6",
16370
16813
  lg: "p-8"
@@ -16372,7 +16815,7 @@ const DashboardCard = ({
16372
16815
  return /* @__PURE__ */ jsxDEV(
16373
16816
  Card,
16374
16817
  {
16375
- className: cn(paddingClasses[padding], className),
16818
+ className: cn(paddingClasses2[padding], className),
16376
16819
  category,
16377
16820
  children: [
16378
16821
  (title || description || actions) && /* @__PURE__ */ jsxDEV("div", { className: "mb-4", children: /* @__PURE__ */ jsxDEV("div", { className: "flex items-start justify-between", children: [
@@ -17048,6 +17491,130 @@ const DataDetailTemplate = ({
17048
17491
  columnNumber: 5
17049
17492
  }, void 0);
17050
17493
  };
17494
+ const maxWidthClasses = {
17495
+ sm: "max-w-screen-sm",
17496
+ md: "max-w-screen-md",
17497
+ lg: "max-w-screen-lg",
17498
+ xl: "max-w-screen-xl",
17499
+ "2xl": "max-w-screen-2xl",
17500
+ full: "max-w-full",
17501
+ none: ""
17502
+ };
17503
+ const paddingClasses = {
17504
+ none: "p-0",
17505
+ sm: "p-4",
17506
+ md: "p-6",
17507
+ lg: "p-8"
17508
+ };
17509
+ const ListPageTemplate = ({
17510
+ title,
17511
+ toolbar,
17512
+ children,
17513
+ footer,
17514
+ className,
17515
+ contentClassName,
17516
+ maxWidth = "full",
17517
+ padding = "md"
17518
+ }) => {
17519
+ return /* @__PURE__ */ jsxDEV("div", { className: cn("flex flex-col min-h-0 flex-1", className), children: [
17520
+ /* @__PURE__ */ jsxDEV("div", { className: "flex-shrink-0 border-b border-border bg-background/95 backdrop-blur supports-[backdrop-filter]:bg-background/60", children: /* @__PURE__ */ jsxDEV(
17521
+ "div",
17522
+ {
17523
+ className: cn(
17524
+ "mx-auto",
17525
+ maxWidthClasses[maxWidth],
17526
+ paddingClasses[padding]
17527
+ ),
17528
+ children: title
17529
+ },
17530
+ void 0,
17531
+ false,
17532
+ {
17533
+ fileName: "/Users/dug/Projects/pattern-stack/frontend-patterns/src/templates/ListPageTemplate.tsx",
17534
+ lineNumber: 54,
17535
+ columnNumber: 9
17536
+ },
17537
+ void 0
17538
+ ) }, void 0, false, {
17539
+ fileName: "/Users/dug/Projects/pattern-stack/frontend-patterns/src/templates/ListPageTemplate.tsx",
17540
+ lineNumber: 53,
17541
+ columnNumber: 7
17542
+ }, void 0),
17543
+ toolbar && /* @__PURE__ */ jsxDEV("div", { className: "flex-shrink-0 border-b border-border bg-muted/30", children: /* @__PURE__ */ jsxDEV(
17544
+ "div",
17545
+ {
17546
+ className: cn(
17547
+ "mx-auto",
17548
+ maxWidthClasses[maxWidth],
17549
+ paddingClasses[padding]
17550
+ ),
17551
+ children: toolbar
17552
+ },
17553
+ void 0,
17554
+ false,
17555
+ {
17556
+ fileName: "/Users/dug/Projects/pattern-stack/frontend-patterns/src/templates/ListPageTemplate.tsx",
17557
+ lineNumber: 68,
17558
+ columnNumber: 11
17559
+ },
17560
+ void 0
17561
+ ) }, void 0, false, {
17562
+ fileName: "/Users/dug/Projects/pattern-stack/frontend-patterns/src/templates/ListPageTemplate.tsx",
17563
+ lineNumber: 67,
17564
+ columnNumber: 9
17565
+ }, void 0),
17566
+ /* @__PURE__ */ jsxDEV("div", { className: cn("flex-1 min-h-0 overflow-auto", contentClassName), children: /* @__PURE__ */ jsxDEV(
17567
+ "div",
17568
+ {
17569
+ className: cn(
17570
+ "mx-auto h-full",
17571
+ maxWidthClasses[maxWidth],
17572
+ paddingClasses[padding]
17573
+ ),
17574
+ children
17575
+ },
17576
+ void 0,
17577
+ false,
17578
+ {
17579
+ fileName: "/Users/dug/Projects/pattern-stack/frontend-patterns/src/templates/ListPageTemplate.tsx",
17580
+ lineNumber: 82,
17581
+ columnNumber: 9
17582
+ },
17583
+ void 0
17584
+ ) }, void 0, false, {
17585
+ fileName: "/Users/dug/Projects/pattern-stack/frontend-patterns/src/templates/ListPageTemplate.tsx",
17586
+ lineNumber: 81,
17587
+ columnNumber: 7
17588
+ }, void 0),
17589
+ footer && /* @__PURE__ */ jsxDEV("div", { className: "flex-shrink-0 border-t border-border bg-background/95 backdrop-blur supports-[backdrop-filter]:bg-background/60", children: /* @__PURE__ */ jsxDEV(
17590
+ "div",
17591
+ {
17592
+ className: cn(
17593
+ "mx-auto",
17594
+ maxWidthClasses[maxWidth],
17595
+ paddingClasses[padding]
17596
+ ),
17597
+ children: footer
17598
+ },
17599
+ void 0,
17600
+ false,
17601
+ {
17602
+ fileName: "/Users/dug/Projects/pattern-stack/frontend-patterns/src/templates/ListPageTemplate.tsx",
17603
+ lineNumber: 96,
17604
+ columnNumber: 11
17605
+ },
17606
+ void 0
17607
+ ) }, void 0, false, {
17608
+ fileName: "/Users/dug/Projects/pattern-stack/frontend-patterns/src/templates/ListPageTemplate.tsx",
17609
+ lineNumber: 95,
17610
+ columnNumber: 9
17611
+ }, void 0)
17612
+ ] }, void 0, true, {
17613
+ fileName: "/Users/dug/Projects/pattern-stack/frontend-patterns/src/templates/ListPageTemplate.tsx",
17614
+ lineNumber: 51,
17615
+ columnNumber: 5
17616
+ }, void 0);
17617
+ };
17051
17618
  function debounce(func, wait) {
17052
17619
  let timeout = null;
17053
17620
  return function debounced(...args) {
@@ -19369,16 +19936,16 @@ const AdminCRUDTemplate = ({
19369
19936
  },
19370
19937
  // Data columns
19371
19938
  ...schema.fields.filter((field) => field.showInTable !== false).map((field) => {
19372
- let columnType = "default";
19939
+ let columnType = void 0;
19373
19940
  if (field.type === "boolean" || field.name.toLowerCase().includes("status")) {
19374
19941
  columnType = "status";
19375
19942
  } else if (field.name.toLowerCase().includes("category")) {
19376
- columnType = "category";
19943
+ columnType = "badge";
19377
19944
  }
19378
19945
  return {
19379
19946
  key: field.name,
19380
19947
  header: field.label,
19381
- type: columnType,
19948
+ ...columnType && { type: columnType },
19382
19949
  cell: field.render ? (item) => field.render(item[field.name], item) : void 0,
19383
19950
  sortable: true,
19384
19951
  width: field.width ? `${field.width}px` : void 0
@@ -19401,7 +19968,7 @@ const AdminCRUDTemplate = ({
19401
19968
  tooltip: "View details",
19402
19969
  children: /* @__PURE__ */ jsxDEV(Eye, { className: "w-4 h-4" }, void 0, false, {
19403
19970
  fileName: "/Users/dug/Projects/pattern-stack/frontend-patterns/src/templates/admin/AdminCRUDTemplate.tsx",
19404
- lineNumber: 241,
19971
+ lineNumber: 242,
19405
19972
  columnNumber: 13
19406
19973
  }, void 0)
19407
19974
  },
@@ -19409,7 +19976,7 @@ const AdminCRUDTemplate = ({
19409
19976
  false,
19410
19977
  {
19411
19978
  fileName: "/Users/dug/Projects/pattern-stack/frontend-patterns/src/templates/admin/AdminCRUDTemplate.tsx",
19412
- lineNumber: 232,
19979
+ lineNumber: 233,
19413
19980
  columnNumber: 11
19414
19981
  },
19415
19982
  void 0
@@ -19426,7 +19993,7 @@ const AdminCRUDTemplate = ({
19426
19993
  tooltip: "Edit",
19427
19994
  children: /* @__PURE__ */ jsxDEV(Edit, { className: "w-4 h-4" }, void 0, false, {
19428
19995
  fileName: "/Users/dug/Projects/pattern-stack/frontend-patterns/src/templates/admin/AdminCRUDTemplate.tsx",
19429
- lineNumber: 253,
19996
+ lineNumber: 254,
19430
19997
  columnNumber: 15
19431
19998
  }, void 0)
19432
19999
  },
@@ -19434,7 +20001,7 @@ const AdminCRUDTemplate = ({
19434
20001
  false,
19435
20002
  {
19436
20003
  fileName: "/Users/dug/Projects/pattern-stack/frontend-patterns/src/templates/admin/AdminCRUDTemplate.tsx",
19437
- lineNumber: 244,
20004
+ lineNumber: 245,
19438
20005
  columnNumber: 13
19439
20006
  },
19440
20007
  void 0
@@ -19451,7 +20018,7 @@ const AdminCRUDTemplate = ({
19451
20018
  tooltip: "Delete",
19452
20019
  children: /* @__PURE__ */ jsxDEV(Trash2, { className: "w-4 h-4" }, void 0, false, {
19453
20020
  fileName: "/Users/dug/Projects/pattern-stack/frontend-patterns/src/templates/admin/AdminCRUDTemplate.tsx",
19454
- lineNumber: 266,
20021
+ lineNumber: 267,
19455
20022
  columnNumber: 15
19456
20023
  }, void 0)
19457
20024
  },
@@ -19459,14 +20026,14 @@ const AdminCRUDTemplate = ({
19459
20026
  false,
19460
20027
  {
19461
20028
  fileName: "/Users/dug/Projects/pattern-stack/frontend-patterns/src/templates/admin/AdminCRUDTemplate.tsx",
19462
- lineNumber: 257,
20029
+ lineNumber: 258,
19463
20030
  columnNumber: 13
19464
20031
  },
19465
20032
  void 0
19466
20033
  )
19467
20034
  ] }, void 0, true, {
19468
20035
  fileName: "/Users/dug/Projects/pattern-stack/frontend-patterns/src/templates/admin/AdminCRUDTemplate.tsx",
19469
- lineNumber: 231,
20036
+ lineNumber: 232,
19470
20037
  columnNumber: 9
19471
20038
  }, void 0),
19472
20039
  sortable: false,
@@ -19541,12 +20108,12 @@ const AdminCRUDTemplate = ({
19541
20108
  field.label
19542
20109
  ] }, void 0, true, {
19543
20110
  fileName: "/Users/dug/Projects/pattern-stack/frontend-patterns/src/templates/admin/AdminCRUDTemplate.tsx",
19544
- lineNumber: 349,
20111
+ lineNumber: 350,
19545
20112
  columnNumber: 13
19546
20113
  }, void 0),
19547
20114
  (_a2 = field.options) == null ? void 0 : _a2.map((option) => /* @__PURE__ */ jsxDEV("option", { value: option.value, children: option.label }, option.value, false, {
19548
20115
  fileName: "/Users/dug/Projects/pattern-stack/frontend-patterns/src/templates/admin/AdminCRUDTemplate.tsx",
19549
- lineNumber: 351,
20116
+ lineNumber: 352,
19550
20117
  columnNumber: 15
19551
20118
  }, void 0))
19552
20119
  ]
@@ -19555,7 +20122,7 @@ const AdminCRUDTemplate = ({
19555
20122
  true,
19556
20123
  {
19557
20124
  fileName: "/Users/dug/Projects/pattern-stack/frontend-patterns/src/templates/admin/AdminCRUDTemplate.tsx",
19558
- lineNumber: 342,
20125
+ lineNumber: 343,
19559
20126
  columnNumber: 11
19560
20127
  },
19561
20128
  void 0
@@ -19571,7 +20138,7 @@ const AdminCRUDTemplate = ({
19571
20138
  false,
19572
20139
  {
19573
20140
  fileName: "/Users/dug/Projects/pattern-stack/frontend-patterns/src/templates/admin/AdminCRUDTemplate.tsx",
19574
- lineNumber: 357,
20141
+ lineNumber: 358,
19575
20142
  columnNumber: 11
19576
20143
  },
19577
20144
  void 0
@@ -19590,7 +20157,7 @@ const AdminCRUDTemplate = ({
19590
20157
  false,
19591
20158
  {
19592
20159
  fileName: "/Users/dug/Projects/pattern-stack/frontend-patterns/src/templates/admin/AdminCRUDTemplate.tsx",
19593
- lineNumber: 366,
20160
+ lineNumber: 367,
19594
20161
  columnNumber: 11
19595
20162
  },
19596
20163
  void 0
@@ -19606,7 +20173,7 @@ const AdminCRUDTemplate = ({
19606
20173
  false,
19607
20174
  {
19608
20175
  fileName: "/Users/dug/Projects/pattern-stack/frontend-patterns/src/templates/admin/AdminCRUDTemplate.tsx",
19609
- lineNumber: 378,
20176
+ lineNumber: 379,
19610
20177
  columnNumber: 11
19611
20178
  },
19612
20179
  void 0
@@ -19616,7 +20183,7 @@ const AdminCRUDTemplate = ({
19616
20183
  false,
19617
20184
  {
19618
20185
  fileName: "/Users/dug/Projects/pattern-stack/frontend-patterns/src/templates/admin/AdminCRUDTemplate.tsx",
19619
- lineNumber: 335,
20186
+ lineNumber: 336,
19620
20187
  columnNumber: 7
19621
20188
  },
19622
20189
  void 0
@@ -19633,7 +20200,7 @@ const AdminCRUDTemplate = ({
19633
20200
  size: "lg",
19634
20201
  icon: /* @__PURE__ */ jsxDEV(Plus, { className: "w-5 h-5" }, void 0, false, {
19635
20202
  fileName: "/Users/dug/Projects/pattern-stack/frontend-patterns/src/templates/admin/AdminCRUDTemplate.tsx",
19636
- lineNumber: 410,
20203
+ lineNumber: 411,
19637
20204
  columnNumber: 23
19638
20205
  }, void 0)
19639
20206
  },
@@ -19641,7 +20208,7 @@ const AdminCRUDTemplate = ({
19641
20208
  false,
19642
20209
  {
19643
20210
  fileName: "/Users/dug/Projects/pattern-stack/frontend-patterns/src/templates/admin/AdminCRUDTemplate.tsx",
19644
- lineNumber: 406,
20211
+ lineNumber: 407,
19645
20212
  columnNumber: 15
19646
20213
  },
19647
20214
  void 0
@@ -19649,7 +20216,7 @@ const AdminCRUDTemplate = ({
19649
20216
  /* @__PURE__ */ jsxDEV("div", { children: [
19650
20217
  /* @__PURE__ */ jsxDEV("h1", { className: "text-4xl font-bold text-foreground", children: schema.displayNamePlural }, void 0, false, {
19651
20218
  fileName: "/Users/dug/Projects/pattern-stack/frontend-patterns/src/templates/admin/AdminCRUDTemplate.tsx",
19652
- lineNumber: 413,
20219
+ lineNumber: 414,
19653
20220
  columnNumber: 17
19654
20221
  }, void 0),
19655
20222
  /* @__PURE__ */ jsxDEV("p", { className: "text-lg text-muted-foreground mt-2", children: [
@@ -19658,17 +20225,17 @@ const AdminCRUDTemplate = ({
19658
20225
  " with comprehensive CRUD operations"
19659
20226
  ] }, void 0, true, {
19660
20227
  fileName: "/Users/dug/Projects/pattern-stack/frontend-patterns/src/templates/admin/AdminCRUDTemplate.tsx",
19661
- lineNumber: 416,
20228
+ lineNumber: 417,
19662
20229
  columnNumber: 17
19663
20230
  }, void 0)
19664
20231
  ] }, void 0, true, {
19665
20232
  fileName: "/Users/dug/Projects/pattern-stack/frontend-patterns/src/templates/admin/AdminCRUDTemplate.tsx",
19666
- lineNumber: 412,
20233
+ lineNumber: 413,
19667
20234
  columnNumber: 15
19668
20235
  }, void 0)
19669
20236
  ] }, void 0, true, {
19670
20237
  fileName: "/Users/dug/Projects/pattern-stack/frontend-patterns/src/templates/admin/AdminCRUDTemplate.tsx",
19671
- lineNumber: 405,
20238
+ lineNumber: 406,
19672
20239
  columnNumber: 13
19673
20240
  }, void 0),
19674
20241
  /* @__PURE__ */ jsxDEV("div", { className: "flex items-center gap-2", children: [
@@ -19688,7 +20255,7 @@ const AdminCRUDTemplate = ({
19688
20255
  false,
19689
20256
  {
19690
20257
  fileName: "/Users/dug/Projects/pattern-stack/frontend-patterns/src/templates/admin/AdminCRUDTemplate.tsx",
19691
- lineNumber: 430,
20258
+ lineNumber: 431,
19692
20259
  columnNumber: 19
19693
20260
  },
19694
20261
  void 0
@@ -19700,7 +20267,7 @@ const AdminCRUDTemplate = ({
19700
20267
  true,
19701
20268
  {
19702
20269
  fileName: "/Users/dug/Projects/pattern-stack/frontend-patterns/src/templates/admin/AdminCRUDTemplate.tsx",
19703
- lineNumber: 425,
20270
+ lineNumber: 426,
19704
20271
  columnNumber: 17
19705
20272
  },
19706
20273
  void 0
@@ -19708,32 +20275,32 @@ const AdminCRUDTemplate = ({
19708
20275
  permissions.create && /* @__PURE__ */ jsxDEV(Button, { onClick: handleCreate, variant: "default", children: [
19709
20276
  /* @__PURE__ */ jsxDEV(Plus, { className: "w-4 h-4 mr-2" }, void 0, false, {
19710
20277
  fileName: "/Users/dug/Projects/pattern-stack/frontend-patterns/src/templates/admin/AdminCRUDTemplate.tsx",
19711
- lineNumber: 439,
20278
+ lineNumber: 440,
19712
20279
  columnNumber: 19
19713
20280
  }, void 0),
19714
20281
  "Create ",
19715
20282
  schema.displayName
19716
20283
  ] }, void 0, true, {
19717
20284
  fileName: "/Users/dug/Projects/pattern-stack/frontend-patterns/src/templates/admin/AdminCRUDTemplate.tsx",
19718
- lineNumber: 438,
20285
+ lineNumber: 439,
19719
20286
  columnNumber: 17
19720
20287
  }, void 0)
19721
20288
  ] }, void 0, true, {
19722
20289
  fileName: "/Users/dug/Projects/pattern-stack/frontend-patterns/src/templates/admin/AdminCRUDTemplate.tsx",
19723
- lineNumber: 423,
20290
+ lineNumber: 424,
19724
20291
  columnNumber: 13
19725
20292
  }, void 0)
19726
20293
  ] }, void 0, true, {
19727
20294
  fileName: "/Users/dug/Projects/pattern-stack/frontend-patterns/src/templates/admin/AdminCRUDTemplate.tsx",
19728
- lineNumber: 404,
20295
+ lineNumber: 405,
19729
20296
  columnNumber: 11
19730
20297
  }, void 0) }, void 0, false, {
19731
20298
  fileName: "/Users/dug/Projects/pattern-stack/frontend-patterns/src/templates/admin/AdminCRUDTemplate.tsx",
19732
- lineNumber: 403,
20299
+ lineNumber: 404,
19733
20300
  columnNumber: 9
19734
20301
  }, void 0) }, void 0, false, {
19735
20302
  fileName: "/Users/dug/Projects/pattern-stack/frontend-patterns/src/templates/admin/AdminCRUDTemplate.tsx",
19736
- lineNumber: 402,
20303
+ lineNumber: 403,
19737
20304
  columnNumber: 7
19738
20305
  }, void 0),
19739
20306
  /* @__PURE__ */ jsxDEV("div", { className: "flex-shrink-0 border-b border-border bg-muted/30", children: /* @__PURE__ */ jsxDEV("div", { className: "mx-auto max-w-7xl px-4 sm:px-6 lg:px-8 py-4", children: /* @__PURE__ */ jsxDEV("div", { className: "flex items-center justify-between", children: [
@@ -19747,13 +20314,13 @@ const AdminCRUDTemplate = ({
19747
20314
  children: [
19748
20315
  /* @__PURE__ */ jsxDEV(Filter, { className: "w-4 h-4 mr-2" }, void 0, false, {
19749
20316
  fileName: "/Users/dug/Projects/pattern-stack/frontend-patterns/src/templates/admin/AdminCRUDTemplate.tsx",
19750
- lineNumber: 460,
20317
+ lineNumber: 461,
19751
20318
  columnNumber: 19
19752
20319
  }, void 0),
19753
20320
  "Filters",
19754
20321
  activeFilterCount > 0 && /* @__PURE__ */ jsxDEV("span", { className: "absolute -top-2 -right-2 min-w-5 h-5 rounded-full text-xs bg-destructive text-destructive-foreground flex items-center justify-center", children: activeFilterCount }, void 0, false, {
19755
20322
  fileName: "/Users/dug/Projects/pattern-stack/frontend-patterns/src/templates/admin/AdminCRUDTemplate.tsx",
19756
- lineNumber: 463,
20323
+ lineNumber: 464,
19757
20324
  columnNumber: 21
19758
20325
  }, void 0)
19759
20326
  ]
@@ -19762,7 +20329,7 @@ const AdminCRUDTemplate = ({
19762
20329
  true,
19763
20330
  {
19764
20331
  fileName: "/Users/dug/Projects/pattern-stack/frontend-patterns/src/templates/admin/AdminCRUDTemplate.tsx",
19765
- lineNumber: 455,
20332
+ lineNumber: 456,
19766
20333
  columnNumber: 17
19767
20334
  },
19768
20335
  void 0
@@ -19784,7 +20351,7 @@ const AdminCRUDTemplate = ({
19784
20351
  true,
19785
20352
  {
19786
20353
  fileName: "/Users/dug/Projects/pattern-stack/frontend-patterns/src/templates/admin/AdminCRUDTemplate.tsx",
19787
- lineNumber: 475,
20354
+ lineNumber: 476,
19788
20355
  columnNumber: 23
19789
20356
  },
19790
20357
  void 0
@@ -19801,19 +20368,19 @@ const AdminCRUDTemplate = ({
19801
20368
  false,
19802
20369
  {
19803
20370
  fileName: "/Users/dug/Projects/pattern-stack/frontend-patterns/src/templates/admin/AdminCRUDTemplate.tsx",
19804
- lineNumber: 484,
20371
+ lineNumber: 485,
19805
20372
  columnNumber: 21
19806
20373
  },
19807
20374
  void 0
19808
20375
  )
19809
20376
  ] }, void 0, true, {
19810
20377
  fileName: "/Users/dug/Projects/pattern-stack/frontend-patterns/src/templates/admin/AdminCRUDTemplate.tsx",
19811
- lineNumber: 473,
20378
+ lineNumber: 474,
19812
20379
  columnNumber: 19
19813
20380
  }, void 0)
19814
20381
  ] }, void 0, true, {
19815
20382
  fileName: "/Users/dug/Projects/pattern-stack/frontend-patterns/src/templates/admin/AdminCRUDTemplate.tsx",
19816
- lineNumber: 453,
20383
+ lineNumber: 454,
19817
20384
  columnNumber: 13
19818
20385
  }, void 0),
19819
20386
  /* @__PURE__ */ jsxDEV("div", { className: "flex items-center gap-2", children: [
@@ -19823,7 +20390,7 @@ const AdminCRUDTemplate = ({
19823
20390
  " selected"
19824
20391
  ] }, void 0, true, {
19825
20392
  fileName: "/Users/dug/Projects/pattern-stack/frontend-patterns/src/templates/admin/AdminCRUDTemplate.tsx",
19826
- lineNumber: 500,
20393
+ lineNumber: 501,
19827
20394
  columnNumber: 19
19828
20395
  }, void 0),
19829
20396
  permissions.delete && /* @__PURE__ */ jsxDEV(
@@ -19835,7 +20402,7 @@ const AdminCRUDTemplate = ({
19835
20402
  children: [
19836
20403
  /* @__PURE__ */ jsxDEV(Trash2, { className: "w-4 h-4 mr-2" }, void 0, false, {
19837
20404
  fileName: "/Users/dug/Projects/pattern-stack/frontend-patterns/src/templates/admin/AdminCRUDTemplate.tsx",
19838
- lineNumber: 509,
20405
+ lineNumber: 510,
19839
20406
  columnNumber: 23
19840
20407
  }, void 0),
19841
20408
  "Delete"
@@ -19845,14 +20412,14 @@ const AdminCRUDTemplate = ({
19845
20412
  true,
19846
20413
  {
19847
20414
  fileName: "/Users/dug/Projects/pattern-stack/frontend-patterns/src/templates/admin/AdminCRUDTemplate.tsx",
19848
- lineNumber: 504,
20415
+ lineNumber: 505,
19849
20416
  columnNumber: 21
19850
20417
  },
19851
20418
  void 0
19852
20419
  )
19853
20420
  ] }, void 0, true, {
19854
20421
  fileName: "/Users/dug/Projects/pattern-stack/frontend-patterns/src/templates/admin/AdminCRUDTemplate.tsx",
19855
- lineNumber: 499,
20422
+ lineNumber: 500,
19856
20423
  columnNumber: 17
19857
20424
  }, void 0),
19858
20425
  permissions.export && /* @__PURE__ */ jsxDEV(
@@ -19866,7 +20433,7 @@ const AdminCRUDTemplate = ({
19866
20433
  children: [
19867
20434
  /* @__PURE__ */ jsxDEV(Download, { className: "w-4 h-4 mr-2" }, void 0, false, {
19868
20435
  fileName: "/Users/dug/Projects/pattern-stack/frontend-patterns/src/templates/admin/AdminCRUDTemplate.tsx",
19869
- lineNumber: 522,
20436
+ lineNumber: 523,
19870
20437
  columnNumber: 19
19871
20438
  }, void 0),
19872
20439
  "Export"
@@ -19876,7 +20443,7 @@ const AdminCRUDTemplate = ({
19876
20443
  true,
19877
20444
  {
19878
20445
  fileName: "/Users/dug/Projects/pattern-stack/frontend-patterns/src/templates/admin/AdminCRUDTemplate.tsx",
19879
- lineNumber: 518,
20446
+ lineNumber: 519,
19880
20447
  columnNumber: 17
19881
20448
  },
19882
20449
  void 0
@@ -19901,7 +20468,7 @@ const AdminCRUDTemplate = ({
19901
20468
  children: [
19902
20469
  /* @__PURE__ */ jsxDEV(Upload, { className: "w-4 h-4 mr-2" }, void 0, false, {
19903
20470
  fileName: "/Users/dug/Projects/pattern-stack/frontend-patterns/src/templates/admin/AdminCRUDTemplate.tsx",
19904
- lineNumber: 543,
20471
+ lineNumber: 544,
19905
20472
  columnNumber: 19
19906
20473
  }, void 0),
19907
20474
  "Import"
@@ -19911,7 +20478,7 @@ const AdminCRUDTemplate = ({
19911
20478
  true,
19912
20479
  {
19913
20480
  fileName: "/Users/dug/Projects/pattern-stack/frontend-patterns/src/templates/admin/AdminCRUDTemplate.tsx",
19914
- lineNumber: 528,
20481
+ lineNumber: 529,
19915
20482
  columnNumber: 17
19916
20483
  },
19917
20484
  void 0
@@ -19930,27 +20497,27 @@ const AdminCRUDTemplate = ({
19930
20497
  true,
19931
20498
  {
19932
20499
  fileName: "/Users/dug/Projects/pattern-stack/frontend-patterns/src/templates/admin/AdminCRUDTemplate.tsx",
19933
- lineNumber: 550,
20500
+ lineNumber: 551,
19934
20501
  columnNumber: 17
19935
20502
  },
19936
20503
  void 0
19937
20504
  ))
19938
20505
  ] }, void 0, true, {
19939
20506
  fileName: "/Users/dug/Projects/pattern-stack/frontend-patterns/src/templates/admin/AdminCRUDTemplate.tsx",
19940
- lineNumber: 496,
20507
+ lineNumber: 497,
19941
20508
  columnNumber: 13
19942
20509
  }, void 0)
19943
20510
  ] }, void 0, true, {
19944
20511
  fileName: "/Users/dug/Projects/pattern-stack/frontend-patterns/src/templates/admin/AdminCRUDTemplate.tsx",
19945
- lineNumber: 451,
20512
+ lineNumber: 452,
19946
20513
  columnNumber: 11
19947
20514
  }, void 0) }, void 0, false, {
19948
20515
  fileName: "/Users/dug/Projects/pattern-stack/frontend-patterns/src/templates/admin/AdminCRUDTemplate.tsx",
19949
- lineNumber: 450,
20516
+ lineNumber: 451,
19950
20517
  columnNumber: 9
19951
20518
  }, void 0) }, void 0, false, {
19952
20519
  fileName: "/Users/dug/Projects/pattern-stack/frontend-patterns/src/templates/admin/AdminCRUDTemplate.tsx",
19953
- lineNumber: 449,
20520
+ lineNumber: 450,
19954
20521
  columnNumber: 7
19955
20522
  }, void 0),
19956
20523
  /* @__PURE__ */ jsxDEV("div", { className: "flex-1 min-h-0 overflow-auto", children: /* @__PURE__ */ jsxDEV("div", { className: "mx-auto max-w-7xl px-4 sm:px-6 lg:px-8 py-8", children: hasData ? /* @__PURE__ */ jsxDEV(Card, { className: "p-6", category, children: /* @__PURE__ */ jsxDEV(
@@ -19970,13 +20537,13 @@ const AdminCRUDTemplate = ({
19970
20537
  false,
19971
20538
  {
19972
20539
  fileName: "/Users/dug/Projects/pattern-stack/frontend-patterns/src/templates/admin/AdminCRUDTemplate.tsx",
19973
- lineNumber: 569,
20540
+ lineNumber: 570,
19974
20541
  columnNumber: 15
19975
20542
  },
19976
20543
  void 0
19977
20544
  ) }, void 0, false, {
19978
20545
  fileName: "/Users/dug/Projects/pattern-stack/frontend-patterns/src/templates/admin/AdminCRUDTemplate.tsx",
19979
- lineNumber: 568,
20546
+ lineNumber: 569,
19980
20547
  columnNumber: 13
19981
20548
  }, void 0) : /* @__PURE__ */ jsxDEV("div", { className: "flex items-center justify-center min-h-96", children: emptyState || /* @__PURE__ */ jsxDEV(
19982
20549
  EmptyState,
@@ -19992,21 +20559,21 @@ const AdminCRUDTemplate = ({
19992
20559
  false,
19993
20560
  {
19994
20561
  fileName: "/Users/dug/Projects/pattern-stack/frontend-patterns/src/templates/admin/AdminCRUDTemplate.tsx",
19995
- lineNumber: 584,
20562
+ lineNumber: 585,
19996
20563
  columnNumber: 17
19997
20564
  },
19998
20565
  void 0
19999
20566
  ) }, void 0, false, {
20000
20567
  fileName: "/Users/dug/Projects/pattern-stack/frontend-patterns/src/templates/admin/AdminCRUDTemplate.tsx",
20001
- lineNumber: 582,
20568
+ lineNumber: 583,
20002
20569
  columnNumber: 13
20003
20570
  }, void 0) }, void 0, false, {
20004
20571
  fileName: "/Users/dug/Projects/pattern-stack/frontend-patterns/src/templates/admin/AdminCRUDTemplate.tsx",
20005
- lineNumber: 566,
20572
+ lineNumber: 567,
20006
20573
  columnNumber: 9
20007
20574
  }, void 0) }, void 0, false, {
20008
20575
  fileName: "/Users/dug/Projects/pattern-stack/frontend-patterns/src/templates/admin/AdminCRUDTemplate.tsx",
20009
- lineNumber: 565,
20576
+ lineNumber: 566,
20010
20577
  columnNumber: 7
20011
20578
  }, void 0),
20012
20579
  /* @__PURE__ */ jsxDEV(
@@ -20021,22 +20588,22 @@ const AdminCRUDTemplate = ({
20021
20588
  /* @__PURE__ */ jsxDEV("div", { className: "flex justify-end gap-2 pt-4", children: [
20022
20589
  /* @__PURE__ */ jsxDEV(Button, { variant: "outline", onClick: () => setShowCreateModal(false), children: "Cancel" }, void 0, false, {
20023
20590
  fileName: "/Users/dug/Projects/pattern-stack/frontend-patterns/src/templates/admin/AdminCRUDTemplate.tsx",
20024
- lineNumber: 613,
20591
+ lineNumber: 614,
20025
20592
  columnNumber: 13
20026
20593
  }, void 0),
20027
20594
  /* @__PURE__ */ jsxDEV(Button, { onClick: () => handleSubmit(false), variant: "default", children: "Create" }, void 0, false, {
20028
20595
  fileName: "/Users/dug/Projects/pattern-stack/frontend-patterns/src/templates/admin/AdminCRUDTemplate.tsx",
20029
- lineNumber: 616,
20596
+ lineNumber: 617,
20030
20597
  columnNumber: 13
20031
20598
  }, void 0)
20032
20599
  ] }, void 0, true, {
20033
20600
  fileName: "/Users/dug/Projects/pattern-stack/frontend-patterns/src/templates/admin/AdminCRUDTemplate.tsx",
20034
- lineNumber: 612,
20601
+ lineNumber: 613,
20035
20602
  columnNumber: 11
20036
20603
  }, void 0)
20037
20604
  ] }, void 0, true, {
20038
20605
  fileName: "/Users/dug/Projects/pattern-stack/frontend-patterns/src/templates/admin/AdminCRUDTemplate.tsx",
20039
- lineNumber: 609,
20606
+ lineNumber: 610,
20040
20607
  columnNumber: 9
20041
20608
  }, void 0)
20042
20609
  },
@@ -20044,7 +20611,7 @@ const AdminCRUDTemplate = ({
20044
20611
  false,
20045
20612
  {
20046
20613
  fileName: "/Users/dug/Projects/pattern-stack/frontend-patterns/src/templates/admin/AdminCRUDTemplate.tsx",
20047
- lineNumber: 603,
20614
+ lineNumber: 604,
20048
20615
  columnNumber: 7
20049
20616
  },
20050
20617
  void 0
@@ -20061,22 +20628,22 @@ const AdminCRUDTemplate = ({
20061
20628
  /* @__PURE__ */ jsxDEV("div", { className: "flex justify-end gap-2 pt-4", children: [
20062
20629
  /* @__PURE__ */ jsxDEV(Button, { variant: "outline", onClick: () => setShowEditModal(false), children: "Cancel" }, void 0, false, {
20063
20630
  fileName: "/Users/dug/Projects/pattern-stack/frontend-patterns/src/templates/admin/AdminCRUDTemplate.tsx",
20064
- lineNumber: 634,
20631
+ lineNumber: 635,
20065
20632
  columnNumber: 13
20066
20633
  }, void 0),
20067
20634
  /* @__PURE__ */ jsxDEV(Button, { onClick: () => handleSubmit(true), variant: "default", children: "Update" }, void 0, false, {
20068
20635
  fileName: "/Users/dug/Projects/pattern-stack/frontend-patterns/src/templates/admin/AdminCRUDTemplate.tsx",
20069
- lineNumber: 637,
20636
+ lineNumber: 638,
20070
20637
  columnNumber: 13
20071
20638
  }, void 0)
20072
20639
  ] }, void 0, true, {
20073
20640
  fileName: "/Users/dug/Projects/pattern-stack/frontend-patterns/src/templates/admin/AdminCRUDTemplate.tsx",
20074
- lineNumber: 633,
20641
+ lineNumber: 634,
20075
20642
  columnNumber: 11
20076
20643
  }, void 0)
20077
20644
  ] }, void 0, true, {
20078
20645
  fileName: "/Users/dug/Projects/pattern-stack/frontend-patterns/src/templates/admin/AdminCRUDTemplate.tsx",
20079
- lineNumber: 630,
20646
+ lineNumber: 631,
20080
20647
  columnNumber: 9
20081
20648
  }, void 0)
20082
20649
  },
@@ -20084,7 +20651,7 @@ const AdminCRUDTemplate = ({
20084
20651
  false,
20085
20652
  {
20086
20653
  fileName: "/Users/dug/Projects/pattern-stack/frontend-patterns/src/templates/admin/AdminCRUDTemplate.tsx",
20087
- lineNumber: 624,
20654
+ lineNumber: 625,
20088
20655
  columnNumber: 7
20089
20656
  },
20090
20657
  void 0
@@ -20104,7 +20671,7 @@ const AdminCRUDTemplate = ({
20104
20671
  "? This action cannot be undone."
20105
20672
  ] }, void 0, true, {
20106
20673
  fileName: "/Users/dug/Projects/pattern-stack/frontend-patterns/src/templates/admin/AdminCRUDTemplate.tsx",
20107
- lineNumber: 652,
20674
+ lineNumber: 653,
20108
20675
  columnNumber: 11
20109
20676
  }, void 0),
20110
20677
  /* @__PURE__ */ jsxDEV("div", { className: "flex justify-end gap-2", children: [
@@ -20119,24 +20686,24 @@ const AdminCRUDTemplate = ({
20119
20686
  false,
20120
20687
  {
20121
20688
  fileName: "/Users/dug/Projects/pattern-stack/frontend-patterns/src/templates/admin/AdminCRUDTemplate.tsx",
20122
- lineNumber: 658,
20689
+ lineNumber: 659,
20123
20690
  columnNumber: 13
20124
20691
  },
20125
20692
  void 0
20126
20693
  ),
20127
20694
  /* @__PURE__ */ jsxDEV(Button, { variant: "destructive", onClick: confirmDelete, children: "Delete" }, void 0, false, {
20128
20695
  fileName: "/Users/dug/Projects/pattern-stack/frontend-patterns/src/templates/admin/AdminCRUDTemplate.tsx",
20129
- lineNumber: 664,
20696
+ lineNumber: 665,
20130
20697
  columnNumber: 13
20131
20698
  }, void 0)
20132
20699
  ] }, void 0, true, {
20133
20700
  fileName: "/Users/dug/Projects/pattern-stack/frontend-patterns/src/templates/admin/AdminCRUDTemplate.tsx",
20134
- lineNumber: 657,
20701
+ lineNumber: 658,
20135
20702
  columnNumber: 11
20136
20703
  }, void 0)
20137
20704
  ] }, void 0, true, {
20138
20705
  fileName: "/Users/dug/Projects/pattern-stack/frontend-patterns/src/templates/admin/AdminCRUDTemplate.tsx",
20139
- lineNumber: 651,
20706
+ lineNumber: 652,
20140
20707
  columnNumber: 9
20141
20708
  }, void 0)
20142
20709
  },
@@ -20144,14 +20711,14 @@ const AdminCRUDTemplate = ({
20144
20711
  false,
20145
20712
  {
20146
20713
  fileName: "/Users/dug/Projects/pattern-stack/frontend-patterns/src/templates/admin/AdminCRUDTemplate.tsx",
20147
- lineNumber: 645,
20714
+ lineNumber: 646,
20148
20715
  columnNumber: 7
20149
20716
  },
20150
20717
  void 0
20151
20718
  )
20152
20719
  ] }, void 0, true, {
20153
20720
  fileName: "/Users/dug/Projects/pattern-stack/frontend-patterns/src/templates/admin/AdminCRUDTemplate.tsx",
20154
- lineNumber: 400,
20721
+ lineNumber: 401,
20155
20722
  columnNumber: 5
20156
20723
  }, void 0);
20157
20724
  };
@@ -21267,6 +21834,26 @@ const ReactQueryDevtools = React__default.lazy(
21267
21834
  default: mod.ReactQueryDevtools
21268
21835
  }))
21269
21836
  );
21837
+ class DevtoolsErrorBoundary extends React__default.Component {
21838
+ constructor(props) {
21839
+ super(props);
21840
+ this.state = { hasError: false };
21841
+ }
21842
+ static getDerivedStateFromError() {
21843
+ return { hasError: true };
21844
+ }
21845
+ componentDidCatch(error) {
21846
+ {
21847
+ console.debug("[DevTools] Failed to initialize:", error.message);
21848
+ }
21849
+ }
21850
+ render() {
21851
+ if (this.state.hasError) {
21852
+ return null;
21853
+ }
21854
+ return this.props.children;
21855
+ }
21856
+ }
21270
21857
  function createReactApp(config) {
21271
21858
  const appConfig = typeof config === "string" ? { title: config } : config;
21272
21859
  const {
@@ -21297,18 +21884,18 @@ function createReactApp(config) {
21297
21884
  title
21298
21885
  ] }, void 0, true, {
21299
21886
  fileName: "/Users/dug/Projects/pattern-stack/frontend-patterns/src/templates/factory.tsx",
21300
- lineNumber: 81,
21887
+ lineNumber: 110,
21301
21888
  columnNumber: 9
21302
21889
  }, this),
21303
21890
  /* @__PURE__ */ jsxDEV("p", { className: "text-lg text-muted-foreground mb-6", children: description }, void 0, false, {
21304
21891
  fileName: "/Users/dug/Projects/pattern-stack/frontend-patterns/src/templates/factory.tsx",
21305
- lineNumber: 82,
21892
+ lineNumber: 111,
21306
21893
  columnNumber: 9
21307
21894
  }, this),
21308
21895
  /* @__PURE__ */ jsxDEV("div", { className: "space-y-2 text-sm text-muted-foreground", children: [
21309
21896
  /* @__PURE__ */ jsxDEV("p", { children: "✅ Template integration successful" }, void 0, false, {
21310
21897
  fileName: "/Users/dug/Projects/pattern-stack/frontend-patterns/src/templates/factory.tsx",
21311
- lineNumber: 84,
21898
+ lineNumber: 113,
21312
21899
  columnNumber: 11
21313
21900
  }, this),
21314
21901
  /* @__PURE__ */ jsxDEV("p", { children: [
@@ -21316,26 +21903,26 @@ function createReactApp(config) {
21316
21903
  version
21317
21904
  ] }, void 0, true, {
21318
21905
  fileName: "/Users/dug/Projects/pattern-stack/frontend-patterns/src/templates/factory.tsx",
21319
- lineNumber: 85,
21906
+ lineNumber: 114,
21320
21907
  columnNumber: 11
21321
21908
  }, this),
21322
21909
  /* @__PURE__ */ jsxDEV("p", { children: "🚀 Ready for development" }, void 0, false, {
21323
21910
  fileName: "/Users/dug/Projects/pattern-stack/frontend-patterns/src/templates/factory.tsx",
21324
- lineNumber: 86,
21911
+ lineNumber: 115,
21325
21912
  columnNumber: 11
21326
21913
  }, this)
21327
21914
  ] }, void 0, true, {
21328
21915
  fileName: "/Users/dug/Projects/pattern-stack/frontend-patterns/src/templates/factory.tsx",
21329
- lineNumber: 83,
21916
+ lineNumber: 112,
21330
21917
  columnNumber: 9
21331
21918
  }, this)
21332
21919
  ] }, void 0, true, {
21333
21920
  fileName: "/Users/dug/Projects/pattern-stack/frontend-patterns/src/templates/factory.tsx",
21334
- lineNumber: 80,
21921
+ lineNumber: 109,
21335
21922
  columnNumber: 7
21336
21923
  }, this) }, void 0, false, {
21337
21924
  fileName: "/Users/dug/Projects/pattern-stack/frontend-patterns/src/templates/factory.tsx",
21338
- lineNumber: 79,
21925
+ lineNumber: 108,
21339
21926
  columnNumber: 5
21340
21927
  }, this);
21341
21928
  const createProviderTree = (children) => {
@@ -21343,50 +21930,54 @@ function createReactApp(config) {
21343
21930
  customProviders.reverse().forEach((Provider) => {
21344
21931
  tree = /* @__PURE__ */ jsxDEV(Provider, { children: tree }, Provider.name, false, {
21345
21932
  fileName: "/Users/dug/Projects/pattern-stack/frontend-patterns/src/templates/factory.tsx",
21346
- lineNumber: 98,
21933
+ lineNumber: 127,
21347
21934
  columnNumber: 14
21348
21935
  }, this);
21349
21936
  });
21350
21937
  if (enableRouting) {
21351
21938
  tree = /* @__PURE__ */ jsxDEV(NavigationProvider, { initialNavigation: navigation, children: /* @__PURE__ */ jsxDEV(SidebarProvider, { children: tree }, void 0, false, {
21352
21939
  fileName: "/Users/dug/Projects/pattern-stack/frontend-patterns/src/templates/factory.tsx",
21353
- lineNumber: 105,
21940
+ lineNumber: 134,
21354
21941
  columnNumber: 11
21355
21942
  }, this) }, void 0, false, {
21356
21943
  fileName: "/Users/dug/Projects/pattern-stack/frontend-patterns/src/templates/factory.tsx",
21357
- lineNumber: 104,
21944
+ lineNumber: 133,
21358
21945
  columnNumber: 9
21359
21946
  }, this);
21360
21947
  }
21361
21948
  if (enableAuth) {
21362
21949
  tree = /* @__PURE__ */ jsxDEV(AuthProvider, { config: auth, children: tree }, void 0, false, {
21363
21950
  fileName: "/Users/dug/Projects/pattern-stack/frontend-patterns/src/templates/factory.tsx",
21364
- lineNumber: 112,
21951
+ lineNumber: 141,
21365
21952
  columnNumber: 14
21366
21953
  }, this);
21367
21954
  }
21368
21955
  if (enableQuery) {
21369
21956
  tree = /* @__PURE__ */ jsxDEV(QueryClientProvider, { client: queryClient, children: [
21370
21957
  tree,
21371
- /* @__PURE__ */ jsxDEV(Suspense, { fallback: null, children: /* @__PURE__ */ jsxDEV(ReactQueryDevtools, { initialIsOpen: false }, void 0, false, {
21958
+ /* @__PURE__ */ jsxDEV(DevtoolsErrorBoundary, { children: /* @__PURE__ */ jsxDEV(Suspense, { fallback: null, children: /* @__PURE__ */ jsxDEV(ReactQueryDevtools, { initialIsOpen: false }, void 0, false, {
21959
+ fileName: "/Users/dug/Projects/pattern-stack/frontend-patterns/src/templates/factory.tsx",
21960
+ lineNumber: 152,
21961
+ columnNumber: 17
21962
+ }, this) }, void 0, false, {
21372
21963
  fileName: "/Users/dug/Projects/pattern-stack/frontend-patterns/src/templates/factory.tsx",
21373
- lineNumber: 122,
21964
+ lineNumber: 151,
21374
21965
  columnNumber: 15
21375
21966
  }, this) }, void 0, false, {
21376
21967
  fileName: "/Users/dug/Projects/pattern-stack/frontend-patterns/src/templates/factory.tsx",
21377
- lineNumber: 121,
21968
+ lineNumber: 150,
21378
21969
  columnNumber: 13
21379
21970
  }, this)
21380
21971
  ] }, void 0, true, {
21381
21972
  fileName: "/Users/dug/Projects/pattern-stack/frontend-patterns/src/templates/factory.tsx",
21382
- lineNumber: 118,
21973
+ lineNumber: 147,
21383
21974
  columnNumber: 9
21384
21975
  }, this);
21385
21976
  }
21386
21977
  if (enableRouting) {
21387
21978
  tree = /* @__PURE__ */ jsxDEV(BrowserRouter, { children: tree }, void 0, false, {
21388
21979
  fileName: "/Users/dug/Projects/pattern-stack/frontend-patterns/src/templates/factory.tsx",
21389
- lineNumber: 131,
21980
+ lineNumber: 162,
21390
21981
  columnNumber: 14
21391
21982
  }, this);
21392
21983
  }
@@ -21397,37 +21988,52 @@ function createReactApp(config) {
21397
21988
  routes.push({ path, component });
21398
21989
  },
21399
21990
  render() {
21991
+ const shouldProtect = enableAuth && (auth == null ? void 0 : auth.requireAuth) !== false;
21992
+ const publicPaths = (auth == null ? void 0 : auth.publicPaths) ?? ["/login", "/register", "/forgot-password"];
21993
+ const isPublicPath = (path) => {
21994
+ return publicPaths.some((p) => path === p || path.startsWith(p + "/"));
21995
+ };
21996
+ const wrapWithProtection = (path, component) => {
21997
+ if (shouldProtect && !isPublicPath(path)) {
21998
+ return /* @__PURE__ */ jsxDEV(ProtectedRoute, { children: component }, void 0, false, {
21999
+ fileName: "/Users/dug/Projects/pattern-stack/frontend-patterns/src/templates/factory.tsx",
22000
+ lineNumber: 187,
22001
+ columnNumber: 18
22002
+ }, this);
22003
+ }
22004
+ return component;
22005
+ };
21400
22006
  const AppContent = () => /* @__PURE__ */ jsxDEV(Routes, { children: /* @__PURE__ */ jsxDEV(Route, { path: "/", element: /* @__PURE__ */ jsxDEV(AppLayout, {}, void 0, false, {
21401
22007
  fileName: "/Users/dug/Projects/pattern-stack/frontend-patterns/src/templates/factory.tsx",
21402
- lineNumber: 146,
22008
+ lineNumber: 194,
21403
22009
  columnNumber: 36
21404
22010
  }, this), children: [
21405
- /* @__PURE__ */ jsxDEV(Route, { index: true, element: /* @__PURE__ */ jsxDEV(DefaultHome, {}, void 0, false, {
22011
+ /* @__PURE__ */ jsxDEV(Route, { index: true, element: wrapWithProtection("/", /* @__PURE__ */ jsxDEV(DefaultHome, {}, void 0, false, {
21406
22012
  fileName: "/Users/dug/Projects/pattern-stack/frontend-patterns/src/templates/factory.tsx",
21407
- lineNumber: 147,
21408
- columnNumber: 35
21409
- }, this) }, void 0, false, {
22013
+ lineNumber: 195,
22014
+ columnNumber: 59
22015
+ }, this)) }, void 0, false, {
21410
22016
  fileName: "/Users/dug/Projects/pattern-stack/frontend-patterns/src/templates/factory.tsx",
21411
- lineNumber: 147,
22017
+ lineNumber: 195,
21412
22018
  columnNumber: 13
21413
22019
  }, this),
21414
- routes.map(({ path, component }, index) => /* @__PURE__ */ jsxDEV(Route, { path, element: component }, index, false, {
22020
+ routes.map(({ path, component }, index) => /* @__PURE__ */ jsxDEV(Route, { path, element: wrapWithProtection(path, component) }, index, false, {
21415
22021
  fileName: "/Users/dug/Projects/pattern-stack/frontend-patterns/src/templates/factory.tsx",
21416
- lineNumber: 149,
22022
+ lineNumber: 197,
21417
22023
  columnNumber: 15
21418
22024
  }, this))
21419
22025
  ] }, void 0, true, {
21420
22026
  fileName: "/Users/dug/Projects/pattern-stack/frontend-patterns/src/templates/factory.tsx",
21421
- lineNumber: 146,
22027
+ lineNumber: 194,
21422
22028
  columnNumber: 11
21423
22029
  }, this) }, void 0, false, {
21424
22030
  fileName: "/Users/dug/Projects/pattern-stack/frontend-patterns/src/templates/factory.tsx",
21425
- lineNumber: 145,
22031
+ lineNumber: 193,
21426
22032
  columnNumber: 9
21427
22033
  }, this);
21428
22034
  return createProviderTree(/* @__PURE__ */ jsxDEV(AppContent, {}, void 0, false, {
21429
22035
  fileName: "/Users/dug/Projects/pattern-stack/frontend-patterns/src/templates/factory.tsx",
21430
- lineNumber: 155,
22036
+ lineNumber: 203,
21431
22037
  columnNumber: 33
21432
22038
  }, this));
21433
22039
  },
@@ -21439,7 +22045,7 @@ function createReactApp(config) {
21439
22045
  const root = createRoot(element);
21440
22046
  root.render(/* @__PURE__ */ jsxDEV(React__default.StrictMode, { children: this.render() }, void 0, false, {
21441
22047
  fileName: "/Users/dug/Projects/pattern-stack/frontend-patterns/src/templates/factory.tsx",
21442
- lineNumber: 165,
22048
+ lineNumber: 213,
21443
22049
  columnNumber: 19
21444
22050
  }, this));
21445
22051
  }
@@ -21539,7 +22145,7 @@ const ResponsiveShowcaseContent = () => {
21539
22145
  {
21540
22146
  key: "category",
21541
22147
  header: "Category",
21542
- type: "category",
22148
+ type: "badge",
21543
22149
  icon: /* @__PURE__ */ jsxDEV(Briefcase, { className: "w-3 h-3" }, void 0, false, {
21544
22150
  fileName: "/Users/dug/Projects/pattern-stack/frontend-patterns/src/organisms/showcase/ComponentShowcasePage.tsx",
21545
22151
  lineNumber: 168,
@@ -22113,7 +22719,7 @@ const ComponentShowcasePage = () => {
22113
22719
  const tableColumns = [
22114
22720
  { key: "name", header: "Model Name" },
22115
22721
  { key: "status", header: "Status", type: "status" },
22116
- { key: "category", header: "Category", type: "category" },
22722
+ { key: "category", header: "Category", type: "badge" },
22117
22723
  { key: "runs", header: "Runs" }
22118
22724
  ];
22119
22725
  return /* @__PURE__ */ jsxDEV("div", { className: "min-h-screen bg-background", children: [
@@ -23546,7 +24152,7 @@ const ComponentShowcasePage = () => {
23546
24152
  columns={[
23547
24153
  { key: 'name', header: 'Model Name' },
23548
24154
  { key: 'status', header: 'Status', type: 'status' },
23549
- { key: 'category', header: 'Category', type: 'category' }
24155
+ { key: 'category', header: 'Category', type: 'badge' }
23550
24156
  ]}
23551
24157
  searchPlaceholder="Search models..."
23552
24158
  onRowClick={(item) => alert(item.name)}
@@ -28511,6 +29117,165 @@ const ComponentShowcasePage = () => {
28511
29117
  columnNumber: 5
28512
29118
  }, void 0);
28513
29119
  };
29120
+ const Sheet = SheetPrimitive.Root;
29121
+ const SheetTrigger = SheetPrimitive.Trigger;
29122
+ const SheetClose = SheetPrimitive.Close;
29123
+ const SheetPortal = SheetPrimitive.Portal;
29124
+ const SheetOverlay = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsxDEV(
29125
+ SheetPrimitive.Overlay,
29126
+ {
29127
+ className: cn(
29128
+ "fixed inset-0 z-50 bg-black/80 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0",
29129
+ className
29130
+ ),
29131
+ ...props,
29132
+ ref
29133
+ },
29134
+ void 0,
29135
+ false,
29136
+ {
29137
+ fileName: "/Users/dug/Projects/pattern-stack/frontend-patterns/src/atoms/primitives/sheet.tsx",
29138
+ lineNumber: 15,
29139
+ columnNumber: 3
29140
+ },
29141
+ void 0
29142
+ ));
29143
+ SheetOverlay.displayName = SheetPrimitive.Overlay.displayName;
29144
+ const sheetVariants = {
29145
+ top: "inset-x-0 top-0 border-b data-[state=closed]:slide-out-to-top data-[state=open]:slide-in-from-top",
29146
+ bottom: "inset-x-0 bottom-0 border-t data-[state=closed]:slide-out-to-bottom data-[state=open]:slide-in-from-bottom",
29147
+ left: "inset-y-0 left-0 h-full w-3/4 border-r data-[state=closed]:slide-out-to-left data-[state=open]:slide-in-from-left sm:max-w-sm",
29148
+ right: "inset-y-0 right-0 h-full w-3/4 border-l data-[state=closed]:slide-out-to-right data-[state=open]:slide-in-from-right sm:max-w-sm"
29149
+ };
29150
+ const SheetContent = React.forwardRef(({ side = "right", className, children, ...props }, ref) => /* @__PURE__ */ jsxDEV(SheetPortal, { children: [
29151
+ /* @__PURE__ */ jsxDEV(SheetOverlay, {}, void 0, false, {
29152
+ fileName: "/Users/dug/Projects/pattern-stack/frontend-patterns/src/atoms/primitives/sheet.tsx",
29153
+ lineNumber: 43,
29154
+ columnNumber: 5
29155
+ }, void 0),
29156
+ /* @__PURE__ */ jsxDEV(
29157
+ SheetPrimitive.Content,
29158
+ {
29159
+ ref,
29160
+ className: cn(
29161
+ "fixed z-50 gap-4 bg-background p-6 shadow-lg transition ease-in-out data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:duration-300 data-[state=open]:duration-500",
29162
+ sheetVariants[side],
29163
+ className
29164
+ ),
29165
+ ...props,
29166
+ children: [
29167
+ children,
29168
+ /* @__PURE__ */ jsxDEV(SheetPrimitive.Close, { className: "absolute right-4 top-4 rounded-sm opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none data-[state=open]:bg-secondary", children: [
29169
+ /* @__PURE__ */ jsxDEV(X, { className: "h-4 w-4" }, void 0, false, {
29170
+ fileName: "/Users/dug/Projects/pattern-stack/frontend-patterns/src/atoms/primitives/sheet.tsx",
29171
+ lineNumber: 55,
29172
+ columnNumber: 9
29173
+ }, void 0),
29174
+ /* @__PURE__ */ jsxDEV("span", { className: "sr-only", children: "Close" }, void 0, false, {
29175
+ fileName: "/Users/dug/Projects/pattern-stack/frontend-patterns/src/atoms/primitives/sheet.tsx",
29176
+ lineNumber: 56,
29177
+ columnNumber: 9
29178
+ }, void 0)
29179
+ ] }, void 0, true, {
29180
+ fileName: "/Users/dug/Projects/pattern-stack/frontend-patterns/src/atoms/primitives/sheet.tsx",
29181
+ lineNumber: 54,
29182
+ columnNumber: 7
29183
+ }, void 0)
29184
+ ]
29185
+ },
29186
+ void 0,
29187
+ true,
29188
+ {
29189
+ fileName: "/Users/dug/Projects/pattern-stack/frontend-patterns/src/atoms/primitives/sheet.tsx",
29190
+ lineNumber: 44,
29191
+ columnNumber: 5
29192
+ },
29193
+ void 0
29194
+ )
29195
+ ] }, void 0, true, {
29196
+ fileName: "/Users/dug/Projects/pattern-stack/frontend-patterns/src/atoms/primitives/sheet.tsx",
29197
+ lineNumber: 42,
29198
+ columnNumber: 3
29199
+ }, void 0));
29200
+ SheetContent.displayName = SheetPrimitive.Content.displayName;
29201
+ const SheetHeader = ({
29202
+ className,
29203
+ ...props
29204
+ }) => /* @__PURE__ */ jsxDEV(
29205
+ "div",
29206
+ {
29207
+ className: cn(
29208
+ "flex flex-col space-y-2 text-center sm:text-left",
29209
+ className
29210
+ ),
29211
+ ...props
29212
+ },
29213
+ void 0,
29214
+ false,
29215
+ {
29216
+ fileName: "/Users/dug/Projects/pattern-stack/frontend-patterns/src/atoms/primitives/sheet.tsx",
29217
+ lineNumber: 67,
29218
+ columnNumber: 3
29219
+ },
29220
+ void 0
29221
+ );
29222
+ SheetHeader.displayName = "SheetHeader";
29223
+ const SheetFooter = ({
29224
+ className,
29225
+ ...props
29226
+ }) => /* @__PURE__ */ jsxDEV(
29227
+ "div",
29228
+ {
29229
+ className: cn(
29230
+ "flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2",
29231
+ className
29232
+ ),
29233
+ ...props
29234
+ },
29235
+ void 0,
29236
+ false,
29237
+ {
29238
+ fileName: "/Users/dug/Projects/pattern-stack/frontend-patterns/src/atoms/primitives/sheet.tsx",
29239
+ lineNumber: 81,
29240
+ columnNumber: 3
29241
+ },
29242
+ void 0
29243
+ );
29244
+ SheetFooter.displayName = "SheetFooter";
29245
+ const SheetTitle = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsxDEV(
29246
+ SheetPrimitive.Title,
29247
+ {
29248
+ ref,
29249
+ className: cn("text-lg font-semibold text-foreground", className),
29250
+ ...props
29251
+ },
29252
+ void 0,
29253
+ false,
29254
+ {
29255
+ fileName: "/Users/dug/Projects/pattern-stack/frontend-patterns/src/atoms/primitives/sheet.tsx",
29256
+ lineNumber: 95,
29257
+ columnNumber: 3
29258
+ },
29259
+ void 0
29260
+ ));
29261
+ SheetTitle.displayName = SheetPrimitive.Title.displayName;
29262
+ const SheetDescription = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsxDEV(
29263
+ SheetPrimitive.Description,
29264
+ {
29265
+ ref,
29266
+ className: cn("text-sm text-muted-foreground", className),
29267
+ ...props
29268
+ },
29269
+ void 0,
29270
+ false,
29271
+ {
29272
+ fileName: "/Users/dug/Projects/pattern-stack/frontend-patterns/src/atoms/primitives/sheet.tsx",
29273
+ lineNumber: 107,
29274
+ columnNumber: 3
29275
+ },
29276
+ void 0
29277
+ ));
29278
+ SheetDescription.displayName = SheetPrimitive.Description.displayName;
28514
29279
  function isBulkOperation(path, _method, requestBody) {
28515
29280
  const bulkPatterns = [
28516
29281
  /\/bulk[-_]?delete$/i,
@@ -28666,6 +29431,8 @@ export {
28666
29431
  Input,
28667
29432
  Label,
28668
29433
  ListCard,
29434
+ ListPageTemplate,
29435
+ ListToolbar,
28669
29436
  Loading,
28670
29437
  LoginForm,
28671
29438
  LogoutButton,
@@ -28675,6 +29442,7 @@ export {
28675
29442
  NavMenu,
28676
29443
  NavigationProvider,
28677
29444
  PageTemplate,
29445
+ PageTitle,
28678
29446
  Pagination,
28679
29447
  PaletteSwitcher,
28680
29448
  ProgressBar,
@@ -28689,6 +29457,16 @@ export {
28689
29457
  SelectItem,
28690
29458
  SelectTrigger,
28691
29459
  SelectValue,
29460
+ Sheet,
29461
+ SheetClose,
29462
+ SheetContent,
29463
+ SheetDescription,
29464
+ SheetFooter,
29465
+ SheetHeader,
29466
+ SheetOverlay,
29467
+ SheetPortal,
29468
+ SheetTitle,
29469
+ SheetTrigger,
28692
29470
  ShowcaseSection,
28693
29471
  Sidebar,
28694
29472
  SidebarButton,
@@ -28748,6 +29526,7 @@ export {
28748
29526
  isBulkOperation,
28749
29527
  isValidIcon,
28750
29528
  legacyPatterns,
29529
+ normalizeFieldType,
28751
29530
  renderField,
28752
29531
  responsiveScales,
28753
29532
  setGlobalAuthService,
@@ -28761,6 +29540,7 @@ export {
28761
29540
  useCreateExample,
28762
29541
  useDeleteExample,
28763
29542
  useErrorBoundary,
29543
+ useFieldMetadata,
28764
29544
  useGetExample,
28765
29545
  useHealth,
28766
29546
  useIsDesktop,
@@ -28770,8 +29550,10 @@ export {
28770
29550
  useMediaQuery,
28771
29551
  useMockAuth,
28772
29552
  useNavigation,
29553
+ useOverflowDetection,
28773
29554
  usePermissions,
28774
29555
  useResponsiveClasses,
29556
+ useResponsiveTable,
28775
29557
  useResponsiveValue,
28776
29558
  useSidebar,
28777
29559
  useTextOverflow,