@elizaos/plugin-shopify-ui 2.0.3-beta.6 → 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.
- package/dist/CustomersPanel.d.ts +11 -0
- package/dist/CustomersPanel.d.ts.map +1 -0
- package/dist/CustomersPanel.js +86 -0
- package/dist/CustomersPanel.js.map +1 -0
- package/dist/InventoryLevelsPanel.d.ts +10 -0
- package/dist/InventoryLevelsPanel.d.ts.map +1 -0
- package/dist/InventoryLevelsPanel.js +190 -0
- package/dist/InventoryLevelsPanel.js.map +1 -0
- package/dist/OrdersPanel.d.ts +12 -0
- package/dist/OrdersPanel.d.ts.map +1 -0
- package/dist/OrdersPanel.js +170 -0
- package/dist/OrdersPanel.js.map +1 -0
- package/dist/ProductsPanel.d.ts +13 -0
- package/dist/ProductsPanel.d.ts.map +1 -0
- package/dist/ProductsPanel.js +419 -0
- package/dist/ProductsPanel.js.map +1 -0
- package/dist/ShopifyAppView.d.ts +3 -0
- package/dist/ShopifyAppView.d.ts.map +1 -0
- package/dist/ShopifyAppView.helpers.d.ts +11 -0
- package/dist/ShopifyAppView.helpers.d.ts.map +1 -0
- package/dist/ShopifyAppView.helpers.js +59 -0
- package/dist/ShopifyAppView.helpers.js.map +1 -0
- package/dist/ShopifyAppView.interact.d.ts +2 -0
- package/dist/ShopifyAppView.interact.d.ts.map +1 -0
- package/dist/ShopifyAppView.interact.js +93 -0
- package/dist/ShopifyAppView.interact.js.map +1 -0
- package/dist/ShopifyAppView.js +667 -0
- package/dist/ShopifyAppView.js.map +1 -0
- package/dist/ShopifyView.d.ts +18 -0
- package/dist/ShopifyView.d.ts.map +1 -0
- package/dist/ShopifyView.js +143 -0
- package/dist/ShopifyView.js.map +1 -0
- package/dist/StoreOverviewCard.d.ts +13 -0
- package/dist/StoreOverviewCard.d.ts.map +1 -0
- package/dist/StoreOverviewCard.js +23 -0
- package/dist/StoreOverviewCard.js.map +1 -0
- package/dist/components/ShopifySpatialView.d.ts +57 -0
- package/dist/components/ShopifySpatialView.d.ts.map +1 -0
- package/dist/components/ShopifySpatialView.js +419 -0
- package/dist/components/ShopifySpatialView.js.map +1 -0
- package/dist/index.d.ts +14 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +20 -0
- package/dist/index.js.map +1 -0
- package/dist/plugin.d.ts +14 -0
- package/dist/plugin.d.ts.map +1 -0
- package/dist/plugin.js +94 -0
- package/dist/plugin.js.map +1 -0
- package/dist/register-routes.d.ts +2 -0
- package/dist/register-routes.d.ts.map +1 -0
- package/dist/register-routes.js +6 -0
- package/dist/register-routes.js.map +1 -0
- package/dist/register-terminal-view.d.ts +15 -0
- package/dist/register-terminal-view.d.ts.map +1 -0
- package/dist/register-terminal-view.js +37 -0
- package/dist/register-terminal-view.js.map +1 -0
- package/dist/register.d.ts +2 -0
- package/dist/register.d.ts.map +1 -0
- package/dist/register.js +17 -0
- package/dist/register.js.map +1 -0
- package/dist/routes.d.ts +18 -0
- package/dist/routes.d.ts.map +1 -0
- package/dist/routes.js +518 -0
- package/dist/routes.js.map +1 -0
- package/dist/shopify-app.d.ts +11 -0
- package/dist/shopify-app.d.ts.map +1 -0
- package/dist/shopify-app.js +16 -0
- package/dist/shopify-app.js.map +1 -0
- package/dist/shopify-view-bundle.d.ts +3 -0
- package/dist/shopify-view-bundle.d.ts.map +1 -0
- package/dist/shopify-view-bundle.js +7 -0
- package/dist/shopify-view-bundle.js.map +1 -0
- package/dist/useShopifyDashboard.d.ts +118 -0
- package/dist/useShopifyDashboard.d.ts.map +1 -0
- package/dist/useShopifyDashboard.js +212 -0
- package/dist/useShopifyDashboard.js.map +1 -0
- package/dist/views/bundle.js +948 -0
- package/dist/views/bundle.js.map +1 -0
- 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"}
|