@elizaos/plugin-shopify-ui 2.0.3-beta.5 → 2.0.3-beta.7

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 (79) hide show
  1. package/dist/CustomersPanel.d.ts +11 -0
  2. package/dist/CustomersPanel.d.ts.map +1 -0
  3. package/dist/CustomersPanel.js +86 -0
  4. package/dist/CustomersPanel.js.map +1 -0
  5. package/dist/InventoryLevelsPanel.d.ts +10 -0
  6. package/dist/InventoryLevelsPanel.d.ts.map +1 -0
  7. package/dist/InventoryLevelsPanel.js +190 -0
  8. package/dist/InventoryLevelsPanel.js.map +1 -0
  9. package/dist/OrdersPanel.d.ts +12 -0
  10. package/dist/OrdersPanel.d.ts.map +1 -0
  11. package/dist/OrdersPanel.js +170 -0
  12. package/dist/OrdersPanel.js.map +1 -0
  13. package/dist/ProductsPanel.d.ts +13 -0
  14. package/dist/ProductsPanel.d.ts.map +1 -0
  15. package/dist/ProductsPanel.js +419 -0
  16. package/dist/ProductsPanel.js.map +1 -0
  17. package/dist/ShopifyAppView.d.ts +3 -0
  18. package/dist/ShopifyAppView.d.ts.map +1 -0
  19. package/dist/ShopifyAppView.helpers.d.ts +11 -0
  20. package/dist/ShopifyAppView.helpers.d.ts.map +1 -0
  21. package/dist/ShopifyAppView.helpers.js +59 -0
  22. package/dist/ShopifyAppView.helpers.js.map +1 -0
  23. package/dist/ShopifyAppView.interact.d.ts +2 -0
  24. package/dist/ShopifyAppView.interact.d.ts.map +1 -0
  25. package/dist/ShopifyAppView.interact.js +93 -0
  26. package/dist/ShopifyAppView.interact.js.map +1 -0
  27. package/dist/ShopifyAppView.js +667 -0
  28. package/dist/ShopifyAppView.js.map +1 -0
  29. package/dist/ShopifyView.d.ts +18 -0
  30. package/dist/ShopifyView.d.ts.map +1 -0
  31. package/dist/ShopifyView.js +143 -0
  32. package/dist/ShopifyView.js.map +1 -0
  33. package/dist/StoreOverviewCard.d.ts +13 -0
  34. package/dist/StoreOverviewCard.d.ts.map +1 -0
  35. package/dist/StoreOverviewCard.js +23 -0
  36. package/dist/StoreOverviewCard.js.map +1 -0
  37. package/dist/components/ShopifySpatialView.d.ts +57 -0
  38. package/dist/components/ShopifySpatialView.d.ts.map +1 -0
  39. package/dist/components/ShopifySpatialView.js +419 -0
  40. package/dist/components/ShopifySpatialView.js.map +1 -0
  41. package/dist/index.d.ts +14 -0
  42. package/dist/index.d.ts.map +1 -0
  43. package/dist/index.js +20 -0
  44. package/dist/index.js.map +1 -0
  45. package/dist/plugin.d.ts +14 -0
  46. package/dist/plugin.d.ts.map +1 -0
  47. package/dist/plugin.js +94 -0
  48. package/dist/plugin.js.map +1 -0
  49. package/dist/register-routes.d.ts +2 -0
  50. package/dist/register-routes.d.ts.map +1 -0
  51. package/dist/register-routes.js +6 -0
  52. package/dist/register-routes.js.map +1 -0
  53. package/dist/register-terminal-view.d.ts +15 -0
  54. package/dist/register-terminal-view.d.ts.map +1 -0
  55. package/dist/register-terminal-view.js +37 -0
  56. package/dist/register-terminal-view.js.map +1 -0
  57. package/dist/register.d.ts +2 -0
  58. package/dist/register.d.ts.map +1 -0
  59. package/dist/register.js +17 -0
  60. package/dist/register.js.map +1 -0
  61. package/dist/routes.d.ts +18 -0
  62. package/dist/routes.d.ts.map +1 -0
  63. package/dist/routes.js +518 -0
  64. package/dist/routes.js.map +1 -0
  65. package/dist/shopify-app.d.ts +11 -0
  66. package/dist/shopify-app.d.ts.map +1 -0
  67. package/dist/shopify-app.js +16 -0
  68. package/dist/shopify-app.js.map +1 -0
  69. package/dist/shopify-view-bundle.d.ts +3 -0
  70. package/dist/shopify-view-bundle.d.ts.map +1 -0
  71. package/dist/shopify-view-bundle.js +7 -0
  72. package/dist/shopify-view-bundle.js.map +1 -0
  73. package/dist/useShopifyDashboard.d.ts +118 -0
  74. package/dist/useShopifyDashboard.d.ts.map +1 -0
  75. package/dist/useShopifyDashboard.js +212 -0
  76. package/dist/useShopifyDashboard.js.map +1 -0
  77. package/dist/views/bundle.js +948 -0
  78. package/dist/views/bundle.js.map +1 -0
  79. package/package.json +5 -5
@@ -0,0 +1,11 @@
1
+ import type { ShopifyCustomer } from "./useShopifyDashboard";
2
+ interface CustomersPanelProps {
3
+ customers: ShopifyCustomer[];
4
+ total: number;
5
+ loading: boolean;
6
+ error: string | null;
7
+ search: string;
8
+ }
9
+ export declare function CustomersPanel({ customers, total, loading, error, }: CustomersPanelProps): import("react/jsx-runtime").JSX.Element;
10
+ export {};
11
+ //# sourceMappingURL=CustomersPanel.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CustomersPanel.d.ts","sourceRoot":"","sources":["../src/CustomersPanel.tsx"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAgD7D,UAAU,mBAAmB;IAC3B,SAAS,EAAE,eAAe,EAAE,CAAC;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,wBAAgB,cAAc,CAAC,EAC7B,SAAS,EACT,KAAK,EACL,OAAO,EACP,KAAK,GACN,EAAE,mBAAmB,2CAyCrB"}
@@ -0,0 +1,86 @@
1
+ import { jsx, jsxs } from "react/jsx-runtime";
2
+ import { formatShortDate, Skeleton } from "@elizaos/ui";
3
+ import {
4
+ CalendarDays,
5
+ CircleDollarSign,
6
+ ShoppingCart,
7
+ Users
8
+ } from "lucide-react";
9
+ function CustomerRow({ customer }) {
10
+ const fullName = [customer.firstName, customer.lastName].filter(Boolean).join(" ") || "\u2014";
11
+ return /* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-center gap-3 px-2 py-2 transition-colors hover:bg-bg-muted/20", children: [
12
+ /* @__PURE__ */ jsx("div", { className: "flex h-8 w-8 shrink-0 items-center justify-center text-xs-tight font-semibold uppercase text-muted-strong", children: (customer.firstName?.[0] ?? customer.email[0] ?? "?").toUpperCase() }),
13
+ /* @__PURE__ */ jsxs("div", { className: "min-w-0 flex-1", children: [
14
+ /* @__PURE__ */ jsx("div", { className: "truncate text-sm font-semibold text-txt", children: fullName }),
15
+ /* @__PURE__ */ jsx("div", { className: "mt-0.5 truncate text-xs-tight text-muted", children: customer.email })
16
+ ] }),
17
+ /* @__PURE__ */ jsxs(
18
+ "div",
19
+ {
20
+ className: "flex shrink-0 items-center gap-1.5 text-sm font-semibold text-txt",
21
+ title: "Orders",
22
+ children: [
23
+ /* @__PURE__ */ jsx(ShoppingCart, { className: "h-3.5 w-3.5 text-muted", "aria-hidden": true }),
24
+ customer.ordersCount.toLocaleString()
25
+ ]
26
+ }
27
+ ),
28
+ /* @__PURE__ */ jsxs(
29
+ "div",
30
+ {
31
+ className: "flex shrink-0 items-center gap-1.5 text-sm font-semibold text-txt",
32
+ title: "Total spent",
33
+ children: [
34
+ /* @__PURE__ */ jsx(CircleDollarSign, { className: "h-3.5 w-3.5 text-muted", "aria-hidden": true }),
35
+ customer.totalSpent,
36
+ " ",
37
+ customer.currencyCode
38
+ ]
39
+ }
40
+ ),
41
+ /* @__PURE__ */ jsxs(
42
+ "div",
43
+ {
44
+ className: "hidden shrink-0 items-center gap-1.5 text-xs-tight text-muted sm:flex",
45
+ title: "Joined",
46
+ children: [
47
+ /* @__PURE__ */ jsx(CalendarDays, { className: "h-3.5 w-3.5", "aria-hidden": true }),
48
+ formatShortDate(customer.createdAt)
49
+ ]
50
+ }
51
+ )
52
+ ] });
53
+ }
54
+ function CustomersPanel({
55
+ customers,
56
+ total,
57
+ loading,
58
+ error
59
+ }) {
60
+ return /* @__PURE__ */ jsxs("div", { className: "space-y-3", children: [
61
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between gap-2", children: [
62
+ /* @__PURE__ */ jsx(
63
+ "p",
64
+ {
65
+ "data-testid": "chat-search-hint",
66
+ className: "sr-only text-[13px] leading-relaxed text-txt/60",
67
+ children: "Search customers by typing in the chat."
68
+ }
69
+ ),
70
+ !loading ? /* @__PURE__ */ jsxs("span", { className: "shrink-0 text-xs text-muted", children: [
71
+ total.toLocaleString(),
72
+ " customer",
73
+ total !== 1 ? "s" : ""
74
+ ] }) : null
75
+ ] }),
76
+ error ? /* @__PURE__ */ jsx("div", { className: "px-1 py-2 text-sm text-danger", children: error }) : null,
77
+ loading && customers.length === 0 ? /* @__PURE__ */ jsx("div", { className: "space-y-2", children: Array.from({ length: 8 }, (_, i) => i).map((i) => /* @__PURE__ */ jsx(Skeleton, { className: "h-14 w-full" }, i)) }) : customers.length === 0 ? /* @__PURE__ */ jsxs("div", { className: "flex flex-col items-center gap-3 py-10 text-center", children: [
78
+ /* @__PURE__ */ jsx(Users, { className: "h-8 w-8 text-muted/40" }),
79
+ /* @__PURE__ */ jsx("div", { className: "text-sm text-muted", children: "None" })
80
+ ] }) : /* @__PURE__ */ jsx("div", { className: "space-y-1.5", children: customers.map((customer) => /* @__PURE__ */ jsx(CustomerRow, { customer }, customer.id)) })
81
+ ] });
82
+ }
83
+ export {
84
+ CustomersPanel
85
+ };
86
+ //# sourceMappingURL=CustomersPanel.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/CustomersPanel.tsx"],"sourcesContent":["import { formatShortDate, Skeleton } from \"@elizaos/ui\";\nimport {\n CalendarDays,\n CircleDollarSign,\n ShoppingCart,\n Users,\n} from \"lucide-react\";\nimport type { ShopifyCustomer } from \"./useShopifyDashboard.js\";\n\nfunction CustomerRow({ customer }: { customer: ShopifyCustomer }) {\n const fullName =\n [customer.firstName, customer.lastName].filter(Boolean).join(\" \") || \"—\";\n\n return (\n <div className=\"flex flex-wrap items-center gap-3 px-2 py-2 transition-colors hover:bg-bg-muted/20\">\n <div className=\"flex h-8 w-8 shrink-0 items-center justify-center text-xs-tight font-semibold uppercase text-muted-strong\">\n {(customer.firstName?.[0] ?? customer.email[0] ?? \"?\").toUpperCase()}\n </div>\n\n <div className=\"min-w-0 flex-1\">\n <div className=\"truncate text-sm font-semibold text-txt\">\n {fullName}\n </div>\n <div className=\"mt-0.5 truncate text-xs-tight text-muted\">\n {customer.email}\n </div>\n </div>\n\n <div\n className=\"flex shrink-0 items-center gap-1.5 text-sm font-semibold text-txt\"\n title=\"Orders\"\n >\n <ShoppingCart className=\"h-3.5 w-3.5 text-muted\" aria-hidden />\n {customer.ordersCount.toLocaleString()}\n </div>\n\n <div\n className=\"flex shrink-0 items-center gap-1.5 text-sm font-semibold text-txt\"\n title=\"Total spent\"\n >\n <CircleDollarSign className=\"h-3.5 w-3.5 text-muted\" aria-hidden />\n {customer.totalSpent} {customer.currencyCode}\n </div>\n\n <div\n className=\"hidden shrink-0 items-center gap-1.5 text-xs-tight text-muted sm:flex\"\n title=\"Joined\"\n >\n <CalendarDays className=\"h-3.5 w-3.5\" aria-hidden />\n {formatShortDate(customer.createdAt)}\n </div>\n </div>\n );\n}\n\ninterface CustomersPanelProps {\n customers: ShopifyCustomer[];\n total: number;\n loading: boolean;\n error: string | null;\n search: string;\n}\n\nexport function CustomersPanel({\n customers,\n total,\n loading,\n error,\n}: CustomersPanelProps) {\n return (\n <div className=\"space-y-3\">\n <div className=\"flex items-center justify-between gap-2\">\n <p\n data-testid=\"chat-search-hint\"\n className=\"sr-only text-[13px] leading-relaxed text-txt/60\"\n >\n Search customers by typing in the chat.\n </p>\n {!loading ? (\n <span className=\"shrink-0 text-xs text-muted\">\n {total.toLocaleString()} customer{total !== 1 ? \"s\" : \"\"}\n </span>\n ) : null}\n </div>\n\n {error ? (\n <div className=\"px-1 py-2 text-sm text-danger\">{error}</div>\n ) : null}\n\n {loading && customers.length === 0 ? (\n <div className=\"space-y-2\">\n {Array.from({ length: 8 }, (_, i) => i).map((i) => (\n <Skeleton key={i} className=\"h-14 w-full\" />\n ))}\n </div>\n ) : customers.length === 0 ? (\n <div className=\"flex flex-col items-center gap-3 py-10 text-center\">\n <Users className=\"h-8 w-8 text-muted/40\" />\n <div className=\"text-sm text-muted\">None</div>\n </div>\n ) : (\n <div className=\"space-y-1.5\">\n {customers.map((customer) => (\n <CustomerRow key={customer.id} customer={customer} />\n ))}\n </div>\n )}\n </div>\n );\n}\n"],"mappings":"AAeM,cAIA,YAJA;AAfN,SAAS,iBAAiB,gBAAgB;AAC1C;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAGP,SAAS,YAAY,EAAE,SAAS,GAAkC;AAChE,QAAM,WACJ,CAAC,SAAS,WAAW,SAAS,QAAQ,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG,KAAK;AAEvE,SACE,qBAAC,SAAI,WAAU,sFACb;AAAA,wBAAC,SAAI,WAAU,6GACX,oBAAS,YAAY,CAAC,KAAK,SAAS,MAAM,CAAC,KAAK,KAAK,YAAY,GACrE;AAAA,IAEA,qBAAC,SAAI,WAAU,kBACb;AAAA,0BAAC,SAAI,WAAU,2CACZ,oBACH;AAAA,MACA,oBAAC,SAAI,WAAU,4CACZ,mBAAS,OACZ;AAAA,OACF;AAAA,IAEA;AAAA,MAAC;AAAA;AAAA,QACC,WAAU;AAAA,QACV,OAAM;AAAA,QAEN;AAAA,8BAAC,gBAAa,WAAU,0BAAyB,eAAW,MAAC;AAAA,UAC5D,SAAS,YAAY,eAAe;AAAA;AAAA;AAAA,IACvC;AAAA,IAEA;AAAA,MAAC;AAAA;AAAA,QACC,WAAU;AAAA,QACV,OAAM;AAAA,QAEN;AAAA,8BAAC,oBAAiB,WAAU,0BAAyB,eAAW,MAAC;AAAA,UAChE,SAAS;AAAA,UAAW;AAAA,UAAE,SAAS;AAAA;AAAA;AAAA,IAClC;AAAA,IAEA;AAAA,MAAC;AAAA;AAAA,QACC,WAAU;AAAA,QACV,OAAM;AAAA,QAEN;AAAA,8BAAC,gBAAa,WAAU,eAAc,eAAW,MAAC;AAAA,UACjD,gBAAgB,SAAS,SAAS;AAAA;AAAA;AAAA,IACrC;AAAA,KACF;AAEJ;AAUO,SAAS,eAAe;AAAA,EAC7B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAAwB;AACtB,SACE,qBAAC,SAAI,WAAU,aACb;AAAA,yBAAC,SAAI,WAAU,2CACb;AAAA;AAAA,QAAC;AAAA;AAAA,UACC,eAAY;AAAA,UACZ,WAAU;AAAA,UACX;AAAA;AAAA,MAED;AAAA,MACC,CAAC,UACA,qBAAC,UAAK,WAAU,+BACb;AAAA,cAAM,eAAe;AAAA,QAAE;AAAA,QAAU,UAAU,IAAI,MAAM;AAAA,SACxD,IACE;AAAA,OACN;AAAA,IAEC,QACC,oBAAC,SAAI,WAAU,iCAAiC,iBAAM,IACpD;AAAA,IAEH,WAAW,UAAU,WAAW,IAC/B,oBAAC,SAAI,WAAU,aACZ,gBAAM,KAAK,EAAE,QAAQ,EAAE,GAAG,CAAC,GAAG,MAAM,CAAC,EAAE,IAAI,CAAC,MAC3C,oBAAC,YAAiB,WAAU,iBAAb,CAA2B,CAC3C,GACH,IACE,UAAU,WAAW,IACvB,qBAAC,SAAI,WAAU,sDACb;AAAA,0BAAC,SAAM,WAAU,yBAAwB;AAAA,MACzC,oBAAC,SAAI,WAAU,sBAAqB,kBAAI;AAAA,OAC1C,IAEA,oBAAC,SAAI,WAAU,eACZ,oBAAU,IAAI,CAAC,aACd,oBAAC,eAA8B,YAAb,SAAS,EAAwB,CACpD,GACH;AAAA,KAEJ;AAEJ;","names":[]}
@@ -0,0 +1,10 @@
1
+ import type { ShopifyInventoryItem } from "./useShopifyDashboard";
2
+ interface InventoryLevelsPanelProps {
3
+ items: ShopifyInventoryItem[];
4
+ locations: string[];
5
+ loading: boolean;
6
+ error: string | null;
7
+ }
8
+ export declare function InventoryLevelsPanel({ items, locations, loading, error, }: InventoryLevelsPanelProps): import("react/jsx-runtime").JSX.Element;
9
+ export {};
10
+ //# sourceMappingURL=InventoryLevelsPanel.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"InventoryLevelsPanel.d.ts","sourceRoot":"","sources":["../src/InventoryLevelsPanel.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,uBAAuB,CAAC;AAgIlE,UAAU,yBAAyB;IACjC,KAAK,EAAE,oBAAoB,EAAE,CAAC;IAC9B,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;CACtB;AAED,wBAAgB,oBAAoB,CAAC,EACnC,KAAK,EACL,SAAS,EACT,OAAO,EACP,KAAK,GACN,EAAE,yBAAyB,2CA8F3B"}
@@ -0,0 +1,190 @@
1
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
2
+ import { Button, Skeleton } from "@elizaos/ui";
3
+ import { useAgentElement } from "@elizaos/ui/agent-surface";
4
+ import { Minus, Package, Plus } from "lucide-react";
5
+ import { useState } from "react";
6
+ function InventoryAdjustButton({
7
+ itemKey,
8
+ itemLabel,
9
+ delta,
10
+ disabled,
11
+ onActivate
12
+ }) {
13
+ const { ref, agentProps } = useAgentElement({
14
+ id: `inventory-adjust-${delta > 0 ? "increase" : "decrease"}-${itemKey}`,
15
+ role: "button",
16
+ label: `${delta > 0 ? "Increase" : "Decrease"} inventory for ${itemLabel}`,
17
+ group: "inventory",
18
+ description: `Adjust available quantity by ${delta} for ${itemLabel}`,
19
+ onActivate
20
+ });
21
+ return /* @__PURE__ */ jsx(
22
+ Button,
23
+ {
24
+ ref,
25
+ type: "button",
26
+ variant: "outline",
27
+ size: "icon",
28
+ className: "h-7 w-7",
29
+ disabled,
30
+ onClick: onActivate,
31
+ "aria-label": `${delta > 0 ? "Increase" : "Decrease"} inventory by 1`,
32
+ ...agentProps,
33
+ children: delta > 0 ? /* @__PURE__ */ jsx(Plus, { className: "h-3 w-3" }) : /* @__PURE__ */ jsx(Minus, { className: "h-3 w-3" })
34
+ }
35
+ );
36
+ }
37
+ function InventoryRow({ item, onAdjust }) {
38
+ const [adjusting, setAdjusting] = useState(false);
39
+ const [adjustError, setAdjustError] = useState(null);
40
+ const [localAvailable, setLocalAvailable] = useState(item.available);
41
+ const itemKey = `${item.id}:${item.locationName}`;
42
+ const itemLabel = item.variantTitle ? `${item.productTitle} \u2014 ${item.variantTitle}` : item.productTitle;
43
+ async function handleAdjust(delta) {
44
+ setAdjusting(true);
45
+ setAdjustError(null);
46
+ try {
47
+ await onAdjust(item.id, item.locationId, delta);
48
+ setLocalAvailable((prev) => prev + delta);
49
+ } catch (err) {
50
+ setAdjustError(err instanceof Error ? err.message : "Adjustment failed.");
51
+ } finally {
52
+ setAdjusting(false);
53
+ }
54
+ }
55
+ return /* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-center gap-3 px-2 py-2", children: [
56
+ /* @__PURE__ */ jsxs("div", { className: "min-w-0 flex-1", children: [
57
+ /* @__PURE__ */ jsx("div", { className: "truncate text-sm font-semibold text-txt", children: item.productTitle }),
58
+ /* @__PURE__ */ jsxs("div", { className: "mt-0.5 flex flex-wrap items-center gap-1.5 text-xs-tight text-muted", children: [
59
+ item.variantTitle ? /* @__PURE__ */ jsx("span", { children: item.variantTitle }) : null,
60
+ item.sku ? /* @__PURE__ */ jsxs(Fragment, { children: [
61
+ item.variantTitle ? /* @__PURE__ */ jsx("span", { children: "\xB7" }) : null,
62
+ /* @__PURE__ */ jsx("span", { className: "font-mono", children: item.sku })
63
+ ] }) : null
64
+ ] }),
65
+ adjustError ? /* @__PURE__ */ jsx("div", { className: "mt-1 text-xs-tight text-danger", children: adjustError }) : null
66
+ ] }),
67
+ /* @__PURE__ */ jsxs(
68
+ "div",
69
+ {
70
+ className: "flex shrink-0 items-center gap-1.5 text-sm font-semibold text-txt",
71
+ title: "Available",
72
+ children: [
73
+ /* @__PURE__ */ jsx(Package, { className: "h-3.5 w-3.5 text-muted", "aria-hidden": true }),
74
+ localAvailable.toLocaleString()
75
+ ]
76
+ }
77
+ ),
78
+ /* @__PURE__ */ jsxs(
79
+ "div",
80
+ {
81
+ className: "flex shrink-0 items-center gap-1.5 text-sm font-semibold text-txt",
82
+ title: "Incoming",
83
+ children: [
84
+ /* @__PURE__ */ jsx(Plus, { className: "h-3.5 w-3.5 text-muted", "aria-hidden": true }),
85
+ item.incoming.toLocaleString()
86
+ ]
87
+ }
88
+ ),
89
+ /* @__PURE__ */ jsxs("div", { className: "flex shrink-0 items-center gap-1", children: [
90
+ /* @__PURE__ */ jsx(
91
+ InventoryAdjustButton,
92
+ {
93
+ itemKey,
94
+ itemLabel,
95
+ delta: -1,
96
+ disabled: adjusting,
97
+ onActivate: () => void handleAdjust(-1)
98
+ }
99
+ ),
100
+ /* @__PURE__ */ jsx(
101
+ InventoryAdjustButton,
102
+ {
103
+ itemKey,
104
+ itemLabel,
105
+ delta: 1,
106
+ disabled: adjusting,
107
+ onActivate: () => void handleAdjust(1)
108
+ }
109
+ )
110
+ ] })
111
+ ] });
112
+ }
113
+ function InventoryLevelsPanel({
114
+ items,
115
+ locations,
116
+ loading,
117
+ error
118
+ }) {
119
+ const [selectedLocation, setSelectedLocation] = useState("all");
120
+ const locationSelect = useAgentElement({
121
+ id: "inventory-location-filter",
122
+ role: "select",
123
+ label: "Inventory location filter",
124
+ group: "inventory",
125
+ description: "Filter inventory levels by store location",
126
+ options: ["all", ...locations],
127
+ getValue: () => selectedLocation,
128
+ onFill: (value) => setSelectedLocation(value)
129
+ });
130
+ const displayedItems = selectedLocation === "all" ? items : items.filter((item) => item.locationName === selectedLocation);
131
+ async function handleAdjust(itemId, locationId, delta) {
132
+ const res = await fetch(`/api/shopify/inventory/${itemId}/adjust`, {
133
+ method: "POST",
134
+ headers: { "Content-Type": "application/json" },
135
+ body: JSON.stringify({ delta, locationId })
136
+ });
137
+ if (!res.ok) {
138
+ const text = await res.text().catch(() => "Unknown error");
139
+ throw new Error(text);
140
+ }
141
+ }
142
+ return /* @__PURE__ */ jsxs("div", { className: "space-y-3", children: [
143
+ locations.length > 0 ? /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
144
+ /* @__PURE__ */ jsx(
145
+ "label",
146
+ {
147
+ className: "shrink-0 text-xs font-semibold text-muted-strong",
148
+ htmlFor: "inventory-location",
149
+ children: "Location"
150
+ }
151
+ ),
152
+ /* @__PURE__ */ jsxs(
153
+ "select",
154
+ {
155
+ ref: locationSelect.ref,
156
+ id: "inventory-location",
157
+ value: selectedLocation,
158
+ onChange: (e) => setSelectedLocation(e.target.value),
159
+ className: "flex h-10 w-full max-w-xs rounded-md border border-input bg-bg px-3 py-2 text-sm ring-offset-bg focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
160
+ ...locationSelect.agentProps,
161
+ children: [
162
+ /* @__PURE__ */ jsx("option", { value: "all", children: "All locations" }),
163
+ locations.map((loc) => /* @__PURE__ */ jsx("option", { value: loc, children: loc }, loc))
164
+ ]
165
+ }
166
+ ),
167
+ /* @__PURE__ */ jsxs("span", { className: "text-xs text-muted", children: [
168
+ displayedItems.length,
169
+ " item",
170
+ displayedItems.length !== 1 ? "s" : ""
171
+ ] })
172
+ ] }) : null,
173
+ error ? /* @__PURE__ */ jsx("div", { className: "px-1 py-2 text-sm text-danger", children: error }) : null,
174
+ loading && items.length === 0 ? /* @__PURE__ */ jsx("div", { className: "space-y-2", children: Array.from({ length: 6 }, (_, i) => i).map((i) => /* @__PURE__ */ jsx(Skeleton, { className: "h-16 w-full" }, i)) }) : displayedItems.length === 0 ? /* @__PURE__ */ jsxs("div", { className: "flex flex-col items-center gap-3 py-10 text-center", children: [
175
+ /* @__PURE__ */ jsx(Package, { className: "h-8 w-8 text-muted/40" }),
176
+ /* @__PURE__ */ jsx("div", { className: "text-sm text-muted", children: "None" })
177
+ ] }) : /* @__PURE__ */ jsx("div", { className: "space-y-1.5", children: displayedItems.map((item) => /* @__PURE__ */ jsx(
178
+ InventoryRow,
179
+ {
180
+ item,
181
+ onAdjust: handleAdjust
182
+ },
183
+ `${item.id}:${item.locationName}`
184
+ )) })
185
+ ] });
186
+ }
187
+ export {
188
+ InventoryLevelsPanel
189
+ };
190
+ //# sourceMappingURL=InventoryLevelsPanel.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/InventoryLevelsPanel.tsx"],"sourcesContent":["import { Button, Skeleton } from \"@elizaos/ui\";\nimport { useAgentElement } from \"@elizaos/ui/agent-surface\";\nimport { Minus, Package, Plus } from \"lucide-react\";\nimport { useState } from \"react\";\nimport type { ShopifyInventoryItem } from \"./useShopifyDashboard.js\";\n\nfunction InventoryAdjustButton({\n itemKey,\n itemLabel,\n delta,\n disabled,\n onActivate,\n}: {\n itemKey: string;\n itemLabel: string;\n delta: 1 | -1;\n disabled: boolean;\n onActivate: () => void;\n}) {\n const { ref, agentProps } = useAgentElement<HTMLButtonElement>({\n id: `inventory-adjust-${delta > 0 ? \"increase\" : \"decrease\"}-${itemKey}`,\n role: \"button\",\n label: `${delta > 0 ? \"Increase\" : \"Decrease\"} inventory for ${itemLabel}`,\n group: \"inventory\",\n description: `Adjust available quantity by ${delta} for ${itemLabel}`,\n onActivate,\n });\n return (\n <Button\n ref={ref}\n type=\"button\"\n variant=\"outline\"\n size=\"icon\"\n className=\"h-7 w-7\"\n disabled={disabled}\n onClick={onActivate}\n aria-label={`${delta > 0 ? \"Increase\" : \"Decrease\"} inventory by 1`}\n {...agentProps}\n >\n {delta > 0 ? <Plus className=\"h-3 w-3\" /> : <Minus className=\"h-3 w-3\" />}\n </Button>\n );\n}\n\ninterface InventoryRowProps {\n item: ShopifyInventoryItem;\n onAdjust: (\n itemId: string,\n locationId: string | null,\n delta: number,\n ) => Promise<void>;\n}\n\nfunction InventoryRow({ item, onAdjust }: InventoryRowProps) {\n const [adjusting, setAdjusting] = useState(false);\n const [adjustError, setAdjustError] = useState<string | null>(null);\n const [localAvailable, setLocalAvailable] = useState(item.available);\n\n const itemKey = `${item.id}:${item.locationName}`;\n const itemLabel = item.variantTitle\n ? `${item.productTitle} — ${item.variantTitle}`\n : item.productTitle;\n\n async function handleAdjust(delta: number) {\n setAdjusting(true);\n setAdjustError(null);\n try {\n await onAdjust(item.id, item.locationId, delta);\n setLocalAvailable((prev) => prev + delta);\n } catch (err) {\n setAdjustError(err instanceof Error ? err.message : \"Adjustment failed.\");\n } finally {\n setAdjusting(false);\n }\n }\n\n return (\n <div className=\"flex flex-wrap items-center gap-3 px-2 py-2\">\n <div className=\"min-w-0 flex-1\">\n <div className=\"truncate text-sm font-semibold text-txt\">\n {item.productTitle}\n </div>\n <div className=\"mt-0.5 flex flex-wrap items-center gap-1.5 text-xs-tight text-muted\">\n {item.variantTitle ? <span>{item.variantTitle}</span> : null}\n {item.sku ? (\n <>\n {item.variantTitle ? <span>·</span> : null}\n <span className=\"font-mono\">{item.sku}</span>\n </>\n ) : null}\n </div>\n {adjustError ? (\n <div className=\"mt-1 text-xs-tight text-danger\">{adjustError}</div>\n ) : null}\n </div>\n\n <div\n className=\"flex shrink-0 items-center gap-1.5 text-sm font-semibold text-txt\"\n title=\"Available\"\n >\n <Package className=\"h-3.5 w-3.5 text-muted\" aria-hidden />\n {localAvailable.toLocaleString()}\n </div>\n\n <div\n className=\"flex shrink-0 items-center gap-1.5 text-sm font-semibold text-txt\"\n title=\"Incoming\"\n >\n <Plus className=\"h-3.5 w-3.5 text-muted\" aria-hidden />\n {item.incoming.toLocaleString()}\n </div>\n\n <div className=\"flex shrink-0 items-center gap-1\">\n <InventoryAdjustButton\n itemKey={itemKey}\n itemLabel={itemLabel}\n delta={-1}\n disabled={adjusting}\n onActivate={() => void handleAdjust(-1)}\n />\n <InventoryAdjustButton\n itemKey={itemKey}\n itemLabel={itemLabel}\n delta={1}\n disabled={adjusting}\n onActivate={() => void handleAdjust(1)}\n />\n </div>\n </div>\n );\n}\n\ninterface InventoryLevelsPanelProps {\n items: ShopifyInventoryItem[];\n locations: string[];\n loading: boolean;\n error: string | null;\n}\n\nexport function InventoryLevelsPanel({\n items,\n locations,\n loading,\n error,\n}: InventoryLevelsPanelProps) {\n const [selectedLocation, setSelectedLocation] = useState<string>(\"all\");\n\n const locationSelect = useAgentElement<HTMLSelectElement>({\n id: \"inventory-location-filter\",\n role: \"select\",\n label: \"Inventory location filter\",\n group: \"inventory\",\n description: \"Filter inventory levels by store location\",\n options: [\"all\", ...locations],\n getValue: () => selectedLocation,\n onFill: (value) => setSelectedLocation(value),\n });\n\n const displayedItems =\n selectedLocation === \"all\"\n ? items\n : items.filter((item) => item.locationName === selectedLocation);\n\n async function handleAdjust(\n itemId: string,\n locationId: string | null,\n delta: number,\n ): Promise<void> {\n const res = await fetch(`/api/shopify/inventory/${itemId}/adjust`, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({ delta, locationId }),\n });\n if (!res.ok) {\n const text = await res.text().catch(() => \"Unknown error\");\n throw new Error(text);\n }\n }\n\n return (\n <div className=\"space-y-3\">\n {locations.length > 0 ? (\n <div className=\"flex items-center gap-2\">\n <label\n className=\"shrink-0 text-xs font-semibold text-muted-strong\"\n htmlFor=\"inventory-location\"\n >\n Location\n </label>\n <select\n ref={locationSelect.ref}\n id=\"inventory-location\"\n value={selectedLocation}\n onChange={(e) => setSelectedLocation(e.target.value)}\n className=\"flex h-10 w-full max-w-xs rounded-md border border-input bg-bg px-3 py-2 text-sm ring-offset-bg focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2\"\n {...locationSelect.agentProps}\n >\n <option value=\"all\">All locations</option>\n {locations.map((loc) => (\n <option key={loc} value={loc}>\n {loc}\n </option>\n ))}\n </select>\n <span className=\"text-xs text-muted\">\n {displayedItems.length} item{displayedItems.length !== 1 ? \"s\" : \"\"}\n </span>\n </div>\n ) : null}\n\n {error ? (\n <div className=\"px-1 py-2 text-sm text-danger\">{error}</div>\n ) : null}\n\n {loading && items.length === 0 ? (\n <div className=\"space-y-2\">\n {Array.from({ length: 6 }, (_, i) => i).map((i) => (\n <Skeleton key={i} className=\"h-16 w-full\" />\n ))}\n </div>\n ) : displayedItems.length === 0 ? (\n <div className=\"flex flex-col items-center gap-3 py-10 text-center\">\n <Package className=\"h-8 w-8 text-muted/40\" />\n <div className=\"text-sm text-muted\">None</div>\n </div>\n ) : (\n <div className=\"space-y-1.5\">\n {displayedItems.map((item) => (\n <InventoryRow\n key={`${item.id}:${item.locationName}`}\n item={item}\n onAdjust={handleAdjust}\n />\n ))}\n </div>\n )}\n </div>\n );\n}\n"],"mappings":"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","names":[]}
@@ -0,0 +1,12 @@
1
+ import type { ShopifyOrder } from "./useShopifyDashboard";
2
+ interface OrdersPanelProps {
3
+ orders: ShopifyOrder[];
4
+ total: number;
5
+ loading: boolean;
6
+ error: string | null;
7
+ statusFilter: string;
8
+ onStatusFilterChange: (status: string) => void;
9
+ }
10
+ export declare function OrdersPanel({ orders, total, loading, error, statusFilter, onStatusFilterChange, }: OrdersPanelProps): import("react/jsx-runtime").JSX.Element;
11
+ export {};
12
+ //# sourceMappingURL=OrdersPanel.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"OrdersPanel.d.ts","sourceRoot":"","sources":["../src/OrdersPanel.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AA8J1D,UAAU,gBAAgB;IACxB,MAAM,EAAE,YAAY,EAAE,CAAC;IACvB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,YAAY,EAAE,MAAM,CAAC;IACrB,oBAAoB,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;CAChD;AAED,wBAAgB,WAAW,CAAC,EAC1B,MAAM,EACN,KAAK,EACL,OAAO,EACP,KAAK,EACL,YAAY,EACZ,oBAAoB,GACrB,EAAE,gBAAgB,2CAuDlB"}
@@ -0,0 +1,170 @@
1
+ import { jsx, jsxs } from "react/jsx-runtime";
2
+ import { formatShortDate, SegmentedControl, Skeleton } from "@elizaos/ui";
3
+ import { useAgentElement } from "@elizaos/ui/agent-surface";
4
+ import { ChevronDown, ChevronUp, ShoppingCart } from "lucide-react";
5
+ import { useState } from "react";
6
+ function FulfillmentBadge({
7
+ status
8
+ }) {
9
+ if (!status) return null;
10
+ const styles = {
11
+ FULFILLED: "bg-ok",
12
+ UNFULFILLED: "bg-warn",
13
+ PARTIALLY_FULFILLED: "bg-warn"
14
+ };
15
+ const labels = {
16
+ FULFILLED: "Fulfilled",
17
+ UNFULFILLED: "Unfulfilled",
18
+ PARTIALLY_FULFILLED: "Partial"
19
+ };
20
+ return /* @__PURE__ */ jsx(
21
+ "span",
22
+ {
23
+ role: "img",
24
+ "aria-label": labels[status],
25
+ title: labels[status],
26
+ className: `inline-flex h-2.5 w-2.5 rounded-full ${styles[status]}`
27
+ }
28
+ );
29
+ }
30
+ function FinancialBadge({
31
+ status
32
+ }) {
33
+ const styles = {
34
+ PAID: "bg-ok",
35
+ PENDING: "bg-warn",
36
+ REFUNDED: "bg-danger",
37
+ PARTIALLY_REFUNDED: "bg-danger"
38
+ };
39
+ const labels = {
40
+ PAID: "Paid",
41
+ PENDING: "Pending",
42
+ REFUNDED: "Refunded",
43
+ PARTIALLY_REFUNDED: "Partial refund"
44
+ };
45
+ return /* @__PURE__ */ jsx(
46
+ "span",
47
+ {
48
+ role: "img",
49
+ "aria-label": labels[status],
50
+ title: labels[status],
51
+ className: `inline-flex h-2.5 w-2.5 rounded-full ${styles[status]}`
52
+ }
53
+ );
54
+ }
55
+ function OrderRow({ order }) {
56
+ const [expanded, setExpanded] = useState(false);
57
+ const toggle = useAgentElement({
58
+ id: `order-toggle-${order.id}`,
59
+ role: "button",
60
+ label: `Order ${order.name} details`,
61
+ group: "orders",
62
+ status: expanded ? "active" : "inactive",
63
+ description: `Expand or collapse details for order ${order.name}`,
64
+ onActivate: () => setExpanded((prev) => !prev)
65
+ });
66
+ return /* @__PURE__ */ jsxs("div", { children: [
67
+ /* @__PURE__ */ jsxs(
68
+ "button",
69
+ {
70
+ ref: toggle.ref,
71
+ type: "button",
72
+ onClick: () => setExpanded((prev) => !prev),
73
+ "aria-expanded": expanded,
74
+ className: "flex w-full items-center gap-3 px-2 py-2 text-left transition-colors hover:bg-bg-muted/20",
75
+ ...toggle.agentProps,
76
+ children: [
77
+ /* @__PURE__ */ jsxs("div", { className: "min-w-[4rem] shrink-0", children: [
78
+ /* @__PURE__ */ jsx("div", { className: "text-sm font-semibold text-txt", children: order.name }),
79
+ /* @__PURE__ */ jsxs("div", { className: "mt-0.5 text-xs-tight text-muted", children: [
80
+ order.lineItemCount,
81
+ " item",
82
+ order.lineItemCount !== 1 ? "s" : ""
83
+ ] })
84
+ ] }),
85
+ /* @__PURE__ */ jsx("div", { className: "min-w-0 flex-1 truncate text-xs text-muted", children: order.email || "\u2014" }),
86
+ /* @__PURE__ */ jsxs("div", { className: "shrink-0 text-right", children: [
87
+ /* @__PURE__ */ jsxs("div", { className: "text-sm font-semibold text-txt", children: [
88
+ order.totalPrice,
89
+ " ",
90
+ order.currencyCode
91
+ ] }),
92
+ /* @__PURE__ */ jsx("div", { className: "mt-0.5 text-xs-tight text-muted", children: formatShortDate(order.createdAt) })
93
+ ] }),
94
+ /* @__PURE__ */ jsxs("div", { className: "flex shrink-0 flex-wrap gap-1.5", children: [
95
+ /* @__PURE__ */ jsx(FulfillmentBadge, { status: order.fulfillmentStatus }),
96
+ /* @__PURE__ */ jsx(FinancialBadge, { status: order.financialStatus })
97
+ ] }),
98
+ /* @__PURE__ */ jsx("div", { className: "shrink-0 text-muted", children: expanded ? /* @__PURE__ */ jsx(ChevronUp, { className: "h-4 w-4" }) : /* @__PURE__ */ jsx(ChevronDown, { className: "h-4 w-4" }) })
99
+ ]
100
+ }
101
+ ),
102
+ expanded ? /* @__PURE__ */ jsx("div", { className: "px-3 pb-3", children: /* @__PURE__ */ jsxs("dl", { className: "grid grid-cols-[6rem_minmax(0,1fr)] gap-x-3 gap-y-1.5 text-xs", children: [
103
+ /* @__PURE__ */ jsx("dt", { className: "text-muted", children: "Order ID" }),
104
+ /* @__PURE__ */ jsx("dd", { className: "font-semibold text-txt break-all", children: order.id }),
105
+ /* @__PURE__ */ jsx("dt", { className: "text-muted", children: "Customer" }),
106
+ /* @__PURE__ */ jsx("dd", { className: "font-semibold text-txt", children: order.email || "\u2014" }),
107
+ /* @__PURE__ */ jsx("dt", { className: "text-muted", children: "Total" }),
108
+ /* @__PURE__ */ jsxs("dd", { className: "font-semibold text-txt", children: [
109
+ order.totalPrice,
110
+ " ",
111
+ order.currencyCode
112
+ ] }),
113
+ /* @__PURE__ */ jsx("dt", { className: "text-muted", children: "Fulfillment" }),
114
+ /* @__PURE__ */ jsx("dd", { children: /* @__PURE__ */ jsx(FulfillmentBadge, { status: order.fulfillmentStatus }) }),
115
+ /* @__PURE__ */ jsx("dt", { className: "text-muted", children: "Payment" }),
116
+ /* @__PURE__ */ jsx("dd", { children: /* @__PURE__ */ jsx(FinancialBadge, { status: order.financialStatus }) }),
117
+ /* @__PURE__ */ jsx("dt", { className: "text-muted", children: "Created" }),
118
+ /* @__PURE__ */ jsx("dd", { className: "font-semibold text-txt", children: formatShortDate(order.createdAt) })
119
+ ] }) }) : null
120
+ ] });
121
+ }
122
+ const ORDER_TABS = [
123
+ { value: "any", label: "All" },
124
+ { value: "unfulfilled", label: "Unfulfilled" },
125
+ { value: "fulfilled", label: "Fulfilled" }
126
+ ];
127
+ function OrdersPanel({
128
+ orders,
129
+ total,
130
+ loading,
131
+ error,
132
+ statusFilter,
133
+ onStatusFilterChange
134
+ }) {
135
+ const activeTab = ORDER_TABS.some((t) => t.value === statusFilter) ? statusFilter : "any";
136
+ const statusFilterControl = useAgentElement({
137
+ id: "select-order-status",
138
+ role: "select",
139
+ label: "Order status filter",
140
+ group: "orders",
141
+ description: "Filter orders by fulfillment status",
142
+ options: ORDER_TABS.map((t) => t.value)
143
+ });
144
+ return /* @__PURE__ */ jsxs("div", { className: "space-y-3", children: [
145
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between gap-3", children: [
146
+ /* @__PURE__ */ jsx("div", { ref: statusFilterControl.ref, ...statusFilterControl.agentProps, children: /* @__PURE__ */ jsx(
147
+ SegmentedControl,
148
+ {
149
+ value: activeTab,
150
+ onValueChange: (v) => onStatusFilterChange(v),
151
+ items: ORDER_TABS
152
+ }
153
+ ) }),
154
+ !loading ? /* @__PURE__ */ jsxs("span", { className: "text-xs text-muted", children: [
155
+ total.toLocaleString(),
156
+ " order",
157
+ total !== 1 ? "s" : ""
158
+ ] }) : null
159
+ ] }),
160
+ error ? /* @__PURE__ */ jsx("div", { className: "px-1 py-2 text-sm text-danger", children: error }) : null,
161
+ loading && orders.length === 0 ? /* @__PURE__ */ jsx("div", { className: "space-y-2", children: Array.from({ length: 6 }, (_, i) => i).map((i) => /* @__PURE__ */ jsx(Skeleton, { className: "h-16 w-full" }, i)) }) : orders.length === 0 ? /* @__PURE__ */ jsxs("div", { className: "flex flex-col items-center gap-3 py-10 text-center", children: [
162
+ /* @__PURE__ */ jsx(ShoppingCart, { className: "h-8 w-8 text-muted/40" }),
163
+ /* @__PURE__ */ jsx("div", { className: "text-sm text-muted", children: "None" })
164
+ ] }) : /* @__PURE__ */ jsx("div", { className: "space-y-1.5", children: orders.map((order) => /* @__PURE__ */ jsx(OrderRow, { order }, order.id)) })
165
+ ] });
166
+ }
167
+ export {
168
+ OrdersPanel
169
+ };
170
+ //# sourceMappingURL=OrdersPanel.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/OrdersPanel.tsx"],"sourcesContent":["import { formatShortDate, SegmentedControl, Skeleton } from \"@elizaos/ui\";\nimport { useAgentElement } from \"@elizaos/ui/agent-surface\";\nimport { ChevronDown, ChevronUp, ShoppingCart } from \"lucide-react\";\nimport { useState } from \"react\";\nimport type { ShopifyOrder } from \"./useShopifyDashboard.js\";\n\nfunction FulfillmentBadge({\n status,\n}: {\n status: ShopifyOrder[\"fulfillmentStatus\"];\n}) {\n if (!status) return null;\n\n const styles = {\n FULFILLED: \"bg-ok\",\n UNFULFILLED: \"bg-warn\",\n PARTIALLY_FULFILLED: \"bg-warn\",\n } satisfies Record<NonNullable<ShopifyOrder[\"fulfillmentStatus\"]>, string>;\n\n const labels: Record<\n NonNullable<ShopifyOrder[\"fulfillmentStatus\"]>,\n string\n > = {\n FULFILLED: \"Fulfilled\",\n UNFULFILLED: \"Unfulfilled\",\n PARTIALLY_FULFILLED: \"Partial\",\n };\n\n return (\n <span\n role=\"img\"\n aria-label={labels[status]}\n title={labels[status]}\n className={`inline-flex h-2.5 w-2.5 rounded-full ${styles[status]}`}\n />\n );\n}\n\nfunction FinancialBadge({\n status,\n}: {\n status: ShopifyOrder[\"financialStatus\"];\n}) {\n const styles = {\n PAID: \"bg-ok\",\n PENDING: \"bg-warn\",\n REFUNDED: \"bg-danger\",\n PARTIALLY_REFUNDED: \"bg-danger\",\n } satisfies Record<ShopifyOrder[\"financialStatus\"], string>;\n\n const labels: Record<ShopifyOrder[\"financialStatus\"], string> = {\n PAID: \"Paid\",\n PENDING: \"Pending\",\n REFUNDED: \"Refunded\",\n PARTIALLY_REFUNDED: \"Partial refund\",\n };\n\n return (\n <span\n role=\"img\"\n aria-label={labels[status]}\n title={labels[status]}\n className={`inline-flex h-2.5 w-2.5 rounded-full ${styles[status]}`}\n />\n );\n}\n\nfunction OrderRow({ order }: { order: ShopifyOrder }) {\n const [expanded, setExpanded] = useState(false);\n\n const toggle = useAgentElement<HTMLButtonElement>({\n id: `order-toggle-${order.id}`,\n role: \"button\",\n label: `Order ${order.name} details`,\n group: \"orders\",\n status: expanded ? \"active\" : \"inactive\",\n description: `Expand or collapse details for order ${order.name}`,\n onActivate: () => setExpanded((prev) => !prev),\n });\n\n return (\n <div>\n <button\n ref={toggle.ref}\n type=\"button\"\n onClick={() => setExpanded((prev) => !prev)}\n aria-expanded={expanded}\n className=\"flex w-full items-center gap-3 px-2 py-2 text-left transition-colors hover:bg-bg-muted/20\"\n {...toggle.agentProps}\n >\n <div className=\"min-w-[4rem] shrink-0\">\n <div className=\"text-sm font-semibold text-txt\">{order.name}</div>\n <div className=\"mt-0.5 text-xs-tight text-muted\">\n {order.lineItemCount} item{order.lineItemCount !== 1 ? \"s\" : \"\"}\n </div>\n </div>\n\n <div className=\"min-w-0 flex-1 truncate text-xs text-muted\">\n {order.email || \"—\"}\n </div>\n\n <div className=\"shrink-0 text-right\">\n <div className=\"text-sm font-semibold text-txt\">\n {order.totalPrice} {order.currencyCode}\n </div>\n <div className=\"mt-0.5 text-xs-tight text-muted\">\n {formatShortDate(order.createdAt)}\n </div>\n </div>\n\n <div className=\"flex shrink-0 flex-wrap gap-1.5\">\n <FulfillmentBadge status={order.fulfillmentStatus} />\n <FinancialBadge status={order.financialStatus} />\n </div>\n\n <div className=\"shrink-0 text-muted\">\n {expanded ? (\n <ChevronUp className=\"h-4 w-4\" />\n ) : (\n <ChevronDown className=\"h-4 w-4\" />\n )}\n </div>\n </button>\n\n {expanded ? (\n <div className=\"px-3 pb-3\">\n <dl className=\"grid grid-cols-[6rem_minmax(0,1fr)] gap-x-3 gap-y-1.5 text-xs\">\n <dt className=\"text-muted\">Order ID</dt>\n <dd className=\"font-semibold text-txt break-all\">{order.id}</dd>\n <dt className=\"text-muted\">Customer</dt>\n <dd className=\"font-semibold text-txt\">{order.email || \"—\"}</dd>\n <dt className=\"text-muted\">Total</dt>\n <dd className=\"font-semibold text-txt\">\n {order.totalPrice} {order.currencyCode}\n </dd>\n <dt className=\"text-muted\">Fulfillment</dt>\n <dd>\n <FulfillmentBadge status={order.fulfillmentStatus} />\n </dd>\n <dt className=\"text-muted\">Payment</dt>\n <dd>\n <FinancialBadge status={order.financialStatus} />\n </dd>\n <dt className=\"text-muted\">Created</dt>\n <dd className=\"font-semibold text-txt\">\n {formatShortDate(order.createdAt)}\n </dd>\n </dl>\n </div>\n ) : null}\n </div>\n );\n}\n\ntype OrderTab = \"any\" | \"unfulfilled\" | \"fulfilled\";\n\nconst ORDER_TABS = [\n { value: \"any\" as const, label: \"All\" },\n { value: \"unfulfilled\" as const, label: \"Unfulfilled\" },\n { value: \"fulfilled\" as const, label: \"Fulfilled\" },\n];\n\ninterface OrdersPanelProps {\n orders: ShopifyOrder[];\n total: number;\n loading: boolean;\n error: string | null;\n statusFilter: string;\n onStatusFilterChange: (status: string) => void;\n}\n\nexport function OrdersPanel({\n orders,\n total,\n loading,\n error,\n statusFilter,\n onStatusFilterChange,\n}: OrdersPanelProps) {\n const activeTab = (\n ORDER_TABS.some((t) => t.value === statusFilter) ? statusFilter : \"any\"\n ) as OrderTab;\n\n const statusFilterControl = useAgentElement<HTMLDivElement>({\n id: \"select-order-status\",\n role: \"select\",\n label: \"Order status filter\",\n group: \"orders\",\n description: \"Filter orders by fulfillment status\",\n options: ORDER_TABS.map((t) => t.value),\n });\n\n return (\n <div className=\"space-y-3\">\n <div className=\"flex items-center justify-between gap-3\">\n <div ref={statusFilterControl.ref} {...statusFilterControl.agentProps}>\n <SegmentedControl\n value={activeTab}\n onValueChange={(v) => onStatusFilterChange(v)}\n items={ORDER_TABS}\n />\n </div>\n {!loading ? (\n <span className=\"text-xs text-muted\">\n {total.toLocaleString()} order{total !== 1 ? \"s\" : \"\"}\n </span>\n ) : null}\n </div>\n\n {error ? (\n <div className=\"px-1 py-2 text-sm text-danger\">{error}</div>\n ) : null}\n\n {loading && orders.length === 0 ? (\n <div className=\"space-y-2\">\n {Array.from({ length: 6 }, (_, i) => i).map((i) => (\n <Skeleton key={i} className=\"h-16 w-full\" />\n ))}\n </div>\n ) : orders.length === 0 ? (\n <div className=\"flex flex-col items-center gap-3 py-10 text-center\">\n <ShoppingCart className=\"h-8 w-8 text-muted/40\" />\n <div className=\"text-sm text-muted\">None</div>\n </div>\n ) : (\n <div className=\"space-y-1.5\">\n {orders.map((order) => (\n <OrderRow key={order.id} order={order} />\n ))}\n </div>\n )}\n </div>\n );\n}\n"],"mappings":"AA6BI,cA+DM,YA/DN;AA7BJ,SAAS,iBAAiB,kBAAkB,gBAAgB;AAC5D,SAAS,uBAAuB;AAChC,SAAS,aAAa,WAAW,oBAAoB;AACrD,SAAS,gBAAgB;AAGzB,SAAS,iBAAiB;AAAA,EACxB;AACF,GAEG;AACD,MAAI,CAAC,OAAQ,QAAO;AAEpB,QAAM,SAAS;AAAA,IACb,WAAW;AAAA,IACX,aAAa;AAAA,IACb,qBAAqB;AAAA,EACvB;AAEA,QAAM,SAGF;AAAA,IACF,WAAW;AAAA,IACX,aAAa;AAAA,IACb,qBAAqB;AAAA,EACvB;AAEA,SACE;AAAA,IAAC;AAAA;AAAA,MACC,MAAK;AAAA,MACL,cAAY,OAAO,MAAM;AAAA,MACzB,OAAO,OAAO,MAAM;AAAA,MACpB,WAAW,wCAAwC,OAAO,MAAM,CAAC;AAAA;AAAA,EACnE;AAEJ;AAEA,SAAS,eAAe;AAAA,EACtB;AACF,GAEG;AACD,QAAM,SAAS;AAAA,IACb,MAAM;AAAA,IACN,SAAS;AAAA,IACT,UAAU;AAAA,IACV,oBAAoB;AAAA,EACtB;AAEA,QAAM,SAA0D;AAAA,IAC9D,MAAM;AAAA,IACN,SAAS;AAAA,IACT,UAAU;AAAA,IACV,oBAAoB;AAAA,EACtB;AAEA,SACE;AAAA,IAAC;AAAA;AAAA,MACC,MAAK;AAAA,MACL,cAAY,OAAO,MAAM;AAAA,MACzB,OAAO,OAAO,MAAM;AAAA,MACpB,WAAW,wCAAwC,OAAO,MAAM,CAAC;AAAA;AAAA,EACnE;AAEJ;AAEA,SAAS,SAAS,EAAE,MAAM,GAA4B;AACpD,QAAM,CAAC,UAAU,WAAW,IAAI,SAAS,KAAK;AAE9C,QAAM,SAAS,gBAAmC;AAAA,IAChD,IAAI,gBAAgB,MAAM,EAAE;AAAA,IAC5B,MAAM;AAAA,IACN,OAAO,SAAS,MAAM,IAAI;AAAA,IAC1B,OAAO;AAAA,IACP,QAAQ,WAAW,WAAW;AAAA,IAC9B,aAAa,wCAAwC,MAAM,IAAI;AAAA,IAC/D,YAAY,MAAM,YAAY,CAAC,SAAS,CAAC,IAAI;AAAA,EAC/C,CAAC;AAED,SACE,qBAAC,SACC;AAAA;AAAA,MAAC;AAAA;AAAA,QACC,KAAK,OAAO;AAAA,QACZ,MAAK;AAAA,QACL,SAAS,MAAM,YAAY,CAAC,SAAS,CAAC,IAAI;AAAA,QAC1C,iBAAe;AAAA,QACf,WAAU;AAAA,QACT,GAAG,OAAO;AAAA,QAEX;AAAA,+BAAC,SAAI,WAAU,yBACb;AAAA,gCAAC,SAAI,WAAU,kCAAkC,gBAAM,MAAK;AAAA,YAC5D,qBAAC,SAAI,WAAU,mCACZ;AAAA,oBAAM;AAAA,cAAc;AAAA,cAAM,MAAM,kBAAkB,IAAI,MAAM;AAAA,eAC/D;AAAA,aACF;AAAA,UAEA,oBAAC,SAAI,WAAU,8CACZ,gBAAM,SAAS,UAClB;AAAA,UAEA,qBAAC,SAAI,WAAU,uBACb;AAAA,iCAAC,SAAI,WAAU,kCACZ;AAAA,oBAAM;AAAA,cAAW;AAAA,cAAE,MAAM;AAAA,eAC5B;AAAA,YACA,oBAAC,SAAI,WAAU,mCACZ,0BAAgB,MAAM,SAAS,GAClC;AAAA,aACF;AAAA,UAEA,qBAAC,SAAI,WAAU,mCACb;AAAA,gCAAC,oBAAiB,QAAQ,MAAM,mBAAmB;AAAA,YACnD,oBAAC,kBAAe,QAAQ,MAAM,iBAAiB;AAAA,aACjD;AAAA,UAEA,oBAAC,SAAI,WAAU,uBACZ,qBACC,oBAAC,aAAU,WAAU,WAAU,IAE/B,oBAAC,eAAY,WAAU,WAAU,GAErC;AAAA;AAAA;AAAA,IACF;AAAA,IAEC,WACC,oBAAC,SAAI,WAAU,aACb,+BAAC,QAAG,WAAU,iEACZ;AAAA,0BAAC,QAAG,WAAU,cAAa,sBAAQ;AAAA,MACnC,oBAAC,QAAG,WAAU,oCAAoC,gBAAM,IAAG;AAAA,MAC3D,oBAAC,QAAG,WAAU,cAAa,sBAAQ;AAAA,MACnC,oBAAC,QAAG,WAAU,0BAA0B,gBAAM,SAAS,UAAI;AAAA,MAC3D,oBAAC,QAAG,WAAU,cAAa,mBAAK;AAAA,MAChC,qBAAC,QAAG,WAAU,0BACX;AAAA,cAAM;AAAA,QAAW;AAAA,QAAE,MAAM;AAAA,SAC5B;AAAA,MACA,oBAAC,QAAG,WAAU,cAAa,yBAAW;AAAA,MACtC,oBAAC,QACC,8BAAC,oBAAiB,QAAQ,MAAM,mBAAmB,GACrD;AAAA,MACA,oBAAC,QAAG,WAAU,cAAa,qBAAO;AAAA,MAClC,oBAAC,QACC,8BAAC,kBAAe,QAAQ,MAAM,iBAAiB,GACjD;AAAA,MACA,oBAAC,QAAG,WAAU,cAAa,qBAAO;AAAA,MAClC,oBAAC,QAAG,WAAU,0BACX,0BAAgB,MAAM,SAAS,GAClC;AAAA,OACF,GACF,IACE;AAAA,KACN;AAEJ;AAIA,MAAM,aAAa;AAAA,EACjB,EAAE,OAAO,OAAgB,OAAO,MAAM;AAAA,EACtC,EAAE,OAAO,eAAwB,OAAO,cAAc;AAAA,EACtD,EAAE,OAAO,aAAsB,OAAO,YAAY;AACpD;AAWO,SAAS,YAAY;AAAA,EAC1B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAAqB;AACnB,QAAM,YACJ,WAAW,KAAK,CAAC,MAAM,EAAE,UAAU,YAAY,IAAI,eAAe;AAGpE,QAAM,sBAAsB,gBAAgC;AAAA,IAC1D,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,OAAO;AAAA,IACP,OAAO;AAAA,IACP,aAAa;AAAA,IACb,SAAS,WAAW,IAAI,CAAC,MAAM,EAAE,KAAK;AAAA,EACxC,CAAC;AAED,SACE,qBAAC,SAAI,WAAU,aACb;AAAA,yBAAC,SAAI,WAAU,2CACb;AAAA,0BAAC,SAAI,KAAK,oBAAoB,KAAM,GAAG,oBAAoB,YACzD;AAAA,QAAC;AAAA;AAAA,UACC,OAAO;AAAA,UACP,eAAe,CAAC,MAAM,qBAAqB,CAAC;AAAA,UAC5C,OAAO;AAAA;AAAA,MACT,GACF;AAAA,MACC,CAAC,UACA,qBAAC,UAAK,WAAU,sBACb;AAAA,cAAM,eAAe;AAAA,QAAE;AAAA,QAAO,UAAU,IAAI,MAAM;AAAA,SACrD,IACE;AAAA,OACN;AAAA,IAEC,QACC,oBAAC,SAAI,WAAU,iCAAiC,iBAAM,IACpD;AAAA,IAEH,WAAW,OAAO,WAAW,IAC5B,oBAAC,SAAI,WAAU,aACZ,gBAAM,KAAK,EAAE,QAAQ,EAAE,GAAG,CAAC,GAAG,MAAM,CAAC,EAAE,IAAI,CAAC,MAC3C,oBAAC,YAAiB,WAAU,iBAAb,CAA2B,CAC3C,GACH,IACE,OAAO,WAAW,IACpB,qBAAC,SAAI,WAAU,sDACb;AAAA,0BAAC,gBAAa,WAAU,yBAAwB;AAAA,MAChD,oBAAC,SAAI,WAAU,sBAAqB,kBAAI;AAAA,OAC1C,IAEA,oBAAC,SAAI,WAAU,eACZ,iBAAO,IAAI,CAAC,UACX,oBAAC,YAAwB,SAAV,MAAM,EAAkB,CACxC,GACH;AAAA,KAEJ;AAEJ;","names":[]}
@@ -0,0 +1,13 @@
1
+ import type { ShopifyProduct } from "./useShopifyDashboard";
2
+ interface ProductsPanelProps {
3
+ products: ShopifyProduct[];
4
+ total: number;
5
+ page: number;
6
+ loading: boolean;
7
+ error: string | null;
8
+ search: string;
9
+ onPageChange: (page: number) => void;
10
+ }
11
+ export declare function ProductsPanel({ products, total, page, loading, error, onPageChange, }: ProductsPanelProps): import("react/jsx-runtime").JSX.Element;
12
+ export {};
13
+ //# sourceMappingURL=ProductsPanel.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ProductsPanel.d.ts","sourceRoot":"","sources":["../src/ProductsPanel.tsx"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAoS5D,UAAU,kBAAkB;IAC1B,QAAQ,EAAE,cAAc,EAAE,CAAC;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,MAAM,EAAE,MAAM,CAAC;IACf,YAAY,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;CACtC;AAID,wBAAgB,aAAa,CAAC,EAC5B,QAAQ,EACR,KAAK,EACL,IAAI,EACJ,OAAO,EACP,KAAK,EACL,YAAY,GACb,EAAE,kBAAkB,2CAmHpB"}