@hanzo/ui 8.0.13 → 8.0.15
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/chunk-23V6BPHG.js +1142 -0
- package/dist/chunk-23V6BPHG.js.map +1 -0
- package/dist/chunk-5MBAHVEO.cjs +1182 -0
- package/dist/chunk-5MBAHVEO.cjs.map +1 -0
- package/dist/chunk-MWBFAV3D.cjs +105 -0
- package/dist/chunk-MWBFAV3D.cjs.map +1 -0
- package/dist/chunk-ZGTJCJ55.js +93 -0
- package/dist/chunk-ZGTJCJ55.js.map +1 -0
- package/dist/product/index.cjs +223 -1291
- package/dist/product/index.cjs.map +1 -1
- package/dist/product/index.js +22 -1239
- package/dist/product/index.js.map +1 -1
- package/dist/product/social/api.cjs +53 -0
- package/dist/product/social/api.cjs.map +1 -0
- package/dist/product/social/api.js +4 -0
- package/dist/product/social/api.js.map +1 -0
- package/dist/product/social/index.cjs +110 -0
- package/dist/product/social/index.cjs.map +1 -0
- package/dist/product/social/index.js +5 -0
- package/dist/product/social/index.js.map +1 -0
- package/package.json +14 -2
package/dist/product/index.cjs
CHANGED
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
'use strict';
|
|
3
3
|
|
|
4
4
|
var chunkYBXVUV7P_cjs = require('../chunk-YBXVUV7P.cjs');
|
|
5
|
+
var chunk5MBAHVEO_cjs = require('../chunk-5MBAHVEO.cjs');
|
|
6
|
+
var chunkMWBFAV3D_cjs = require('../chunk-MWBFAV3D.cjs');
|
|
5
7
|
var react = require('react');
|
|
6
8
|
var gui = require('@hanzo/gui');
|
|
7
9
|
var jsxRuntime = require('react/jsx-runtime');
|
|
@@ -674,12 +676,12 @@ function menuKeyDown(e, onClose) {
|
|
|
674
676
|
if (items.length === 0) return;
|
|
675
677
|
e.preventDefault();
|
|
676
678
|
const active = document.activeElement;
|
|
677
|
-
const
|
|
679
|
+
const current = active ? items.indexOf(active) : -1;
|
|
678
680
|
let next;
|
|
679
681
|
if (e.key === "Home") next = 0;
|
|
680
682
|
else if (e.key === "End") next = items.length - 1;
|
|
681
|
-
else if (e.key === "ArrowDown") next =
|
|
682
|
-
else next =
|
|
683
|
+
else if (e.key === "ArrowDown") next = current < 0 ? 0 : (current + 1) % items.length;
|
|
684
|
+
else next = current <= 0 ? items.length - 1 : current - 1;
|
|
683
685
|
items[next]?.focus();
|
|
684
686
|
}
|
|
685
687
|
var EDGE = 8;
|
|
@@ -854,8 +856,8 @@ var SURFACES = ORDER.map((id) => {
|
|
|
854
856
|
const s = products.surfaceById(id);
|
|
855
857
|
return { id, label: s.label, href: s.href, hint: s.domain };
|
|
856
858
|
});
|
|
857
|
-
function otherSurfaces(
|
|
858
|
-
return
|
|
859
|
+
function otherSurfaces(current) {
|
|
860
|
+
return current ? SURFACES.filter((s) => s.id !== current) : SURFACES;
|
|
859
861
|
}
|
|
860
862
|
function HanzoMark({ size = 22, color = "currentColor" }) {
|
|
861
863
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
@@ -912,7 +914,7 @@ function AppHeader({
|
|
|
912
914
|
onBrand,
|
|
913
915
|
org,
|
|
914
916
|
children,
|
|
915
|
-
current
|
|
917
|
+
current,
|
|
916
918
|
surfaces,
|
|
917
919
|
open,
|
|
918
920
|
user,
|
|
@@ -925,7 +927,7 @@ function AppHeader({
|
|
|
925
927
|
}) {
|
|
926
928
|
const [appsOpen, setAppsOpen] = react.useState(false);
|
|
927
929
|
const [menuOpen, setMenuOpen] = react.useState(false);
|
|
928
|
-
const items = surfaces ?? otherSurfaces(
|
|
930
|
+
const items = surfaces ?? otherSurfaces(current);
|
|
929
931
|
const launch = (s) => {
|
|
930
932
|
setAppsOpen(false);
|
|
931
933
|
if (open) open(s);
|
|
@@ -1076,7 +1078,7 @@ function OrgSwitcher({ scope, orgs, pageSize = 20, current: given, create, picke
|
|
|
1076
1078
|
const [open, setOpen] = react.useState(false);
|
|
1077
1079
|
const [query, setQuery] = react.useState("");
|
|
1078
1080
|
const [debounced, setDebounced] = react.useState("");
|
|
1079
|
-
const [
|
|
1081
|
+
const [rows, setRows] = react.useState([]);
|
|
1080
1082
|
const [loading, setLoading] = react.useState(false);
|
|
1081
1083
|
const [loadingMore, setLoadingMore] = react.useState(false);
|
|
1082
1084
|
const [hasMore, setHasMore] = react.useState(false);
|
|
@@ -1128,14 +1130,14 @@ function OrgSwitcher({ scope, orgs, pageSize = 20, current: given, create, picke
|
|
|
1128
1130
|
void fetchPage(pageRef.current + 1, debounced, true);
|
|
1129
1131
|
}, [loading, loadingMore, hasMore, debounced, fetchPage]);
|
|
1130
1132
|
const visible = react.useMemo(() => {
|
|
1131
|
-
if (orgs) return filterOrgs(
|
|
1133
|
+
if (orgs) return filterOrgs(rows, query);
|
|
1132
1134
|
return [{ name: currentId, displayName: titleCase(currentId) }];
|
|
1133
|
-
}, [orgs,
|
|
1134
|
-
const
|
|
1135
|
+
}, [orgs, rows, query, currentId]);
|
|
1136
|
+
const current = react.useMemo(() => {
|
|
1135
1137
|
if (given && given.name === currentId) return given;
|
|
1136
|
-
return
|
|
1137
|
-
}, [given,
|
|
1138
|
-
const currentLabel =
|
|
1138
|
+
return rows.find((o) => o.name === currentId) ?? { name: currentId, displayName: titleCase(currentId) };
|
|
1139
|
+
}, [given, rows, currentId]);
|
|
1140
|
+
const currentLabel = current.displayName || titleCase(current.name);
|
|
1139
1141
|
const select = react.useCallback(
|
|
1140
1142
|
(org) => {
|
|
1141
1143
|
setOpen(false);
|
|
@@ -1158,7 +1160,7 @@ function OrgSwitcher({ scope, orgs, pageSize = 20, current: given, create, picke
|
|
|
1158
1160
|
};
|
|
1159
1161
|
return /* @__PURE__ */ jsxRuntime.jsxs(gui.Popover, { open, onOpenChange: setOpen, placement: "bottom-start", children: [
|
|
1160
1162
|
/* @__PURE__ */ jsxRuntime.jsx(gui.Popover.Trigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(gui.Button, { chromeless: true, height: 44, px: "$2", justify: "flex-start", "aria-label": `${currentLabel} \xB7 switch organization`, children: /* @__PURE__ */ jsxRuntime.jsxs(gui.XStack, { items: "center", gap: "$2.5", flex: 1, minW: 0, children: [
|
|
1161
|
-
/* @__PURE__ */ jsxRuntime.jsx(OrgMark, { org:
|
|
1163
|
+
/* @__PURE__ */ jsxRuntime.jsx(OrgMark, { org: current, size: 30 }),
|
|
1162
1164
|
/* @__PURE__ */ jsxRuntime.jsx(gui.Text, { flex: 1, minW: 0, fontSize: "$4", fontWeight: "800", color: "$color12", numberOfLines: 1, children: currentLabel }),
|
|
1163
1165
|
/* @__PURE__ */ jsxRuntime.jsx(lucideIcons2.ChevronsUpDown, { size: 15, color: "$color9" })
|
|
1164
1166
|
] }) }) }),
|
|
@@ -1589,203 +1591,6 @@ function SiteFooter({ footer, brand, tagline, meta, link = defaultLink2 }) {
|
|
|
1589
1591
|
] })
|
|
1590
1592
|
] });
|
|
1591
1593
|
}
|
|
1592
|
-
var HostCtx = react.createContext({});
|
|
1593
|
-
var HostProvider = ({ actions, children }) => /* @__PURE__ */ jsxRuntime.jsx(HostCtx.Provider, { value: actions, children });
|
|
1594
|
-
var useHost = () => react.useContext(HostCtx);
|
|
1595
|
-
function classifyBackend(e) {
|
|
1596
|
-
const status = typeof e?.status === "number" ? e.status : 0;
|
|
1597
|
-
const message = e instanceof Error ? e.message : String(e);
|
|
1598
|
-
if (status === 503) return { kind: "not-initialized", message };
|
|
1599
|
-
if (status === 404 || status === 405) return { kind: "unavailable", message };
|
|
1600
|
-
if (status === 501) return { kind: "not-implemented", message };
|
|
1601
|
-
if (status === 402) return { kind: "billing", message };
|
|
1602
|
-
if (status === 401) return { kind: "signin", message };
|
|
1603
|
-
if (status === 403) return { kind: "access", message };
|
|
1604
|
-
return { kind: "error", message };
|
|
1605
|
-
}
|
|
1606
|
-
function classifyRead(e) {
|
|
1607
|
-
const s = classifyBackend(e);
|
|
1608
|
-
return s.kind === "billing" ? null : s;
|
|
1609
|
-
}
|
|
1610
|
-
var TITLES = {
|
|
1611
|
-
"not-initialized": "Backend not initialized",
|
|
1612
|
-
unavailable: "Not available on this deployment yet",
|
|
1613
|
-
"not-implemented": "Not yet available",
|
|
1614
|
-
access: "Not enabled for your account",
|
|
1615
|
-
signin: "Your session expired",
|
|
1616
|
-
billing: "Add credits to continue",
|
|
1617
|
-
error: "Could not reach the backend"
|
|
1618
|
-
};
|
|
1619
|
-
var BODIES = {
|
|
1620
|
-
"not-initialized": "The /v1 route is mounted but its runtime (or the console API key it proxies to) is not configured on this deployment yet. Real data appears here once it is \u2014 no placeholder data is shown.",
|
|
1621
|
-
unavailable: "This endpoint is not mounted at the gateway on this host yet. The view lights up automatically once the route is live.",
|
|
1622
|
-
// 501 — a real, planned capability whose body ships in a later phase.
|
|
1623
|
-
"not-implemented": "This capability is planned but not wired yet. The backend answers honestly rather than pretending it worked \u2014 nothing here is fabricated, and the view lights up automatically once it ships.",
|
|
1624
|
-
// 403 for a SIGNED-IN user — never "sign in".
|
|
1625
|
-
access: "You're signed in, but this isn't enabled for your organization on this deployment, or it's an admin-only surface. It appears here automatically once your account has access \u2014 nothing is fabricated.",
|
|
1626
|
-
// 401 — the session itself lapsed; re-auth returns to this exact page.
|
|
1627
|
-
signin: "Your session has expired or isn\u2019t recognized here. Sign in again to continue where you left off.",
|
|
1628
|
-
// Empty → the card shows the backend's own message (the honest "Insufficient
|
|
1629
|
-
// balance. Please add credits…" from the gateway billing gate).
|
|
1630
|
-
billing: "",
|
|
1631
|
-
error: ""
|
|
1632
|
-
};
|
|
1633
|
-
function BackendStateCard({
|
|
1634
|
-
state,
|
|
1635
|
-
onRetry,
|
|
1636
|
-
hint
|
|
1637
|
-
}) {
|
|
1638
|
-
const { signIn, addCredits } = useHost();
|
|
1639
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(gui.Card, { borderWidth: 1, borderColor: "$borderColor", p: "$4", gap: "$2", maxWidth: 640, children: [
|
|
1640
|
-
/* @__PURE__ */ jsxRuntime.jsxs(gui.XStack, { gap: "$2", items: "center", children: [
|
|
1641
|
-
/* @__PURE__ */ jsxRuntime.jsx(lucideIcons2.TriangleAlert, { size: 16 }),
|
|
1642
|
-
/* @__PURE__ */ jsxRuntime.jsx(gui.Text, { fontSize: "$4", fontWeight: "700", children: TITLES[state.kind] })
|
|
1643
|
-
] }),
|
|
1644
|
-
/* @__PURE__ */ jsxRuntime.jsx(gui.Text, { fontSize: "$3", color: "$color11", children: BODIES[state.kind] || state.message }),
|
|
1645
|
-
hint ? /* @__PURE__ */ jsxRuntime.jsx(gui.Text, { fontSize: "$2", color: "$color10", children: hint }) : null,
|
|
1646
|
-
state.kind === "signin" && signIn ? /* @__PURE__ */ jsxRuntime.jsx(gui.Button, { size: "$2", theme: "light", self: "flex-start", onPress: signIn, children: "Sign in again" }) : state.kind === "billing" && addCredits ? (
|
|
1647
|
-
// 402 — the org has no funded balance. Offer a top-up CTA (and keep Retry so
|
|
1648
|
-
// a returning, funded caller can reload in place).
|
|
1649
|
-
/* @__PURE__ */ jsxRuntime.jsxs(gui.XStack, { gap: "$2", items: "center", flexWrap: "wrap", children: [
|
|
1650
|
-
/* @__PURE__ */ jsxRuntime.jsx(gui.Button, { size: "$2", theme: "light", self: "flex-start", icon: /* @__PURE__ */ jsxRuntime.jsx(lucideIcons2.CreditCard, { size: 14 }), onPress: addCredits, children: "Add credits" }),
|
|
1651
|
-
onRetry ? /* @__PURE__ */ jsxRuntime.jsx(gui.Button, { size: "$2", self: "flex-start", onPress: onRetry, children: "Retry" }) : null
|
|
1652
|
-
] })
|
|
1653
|
-
) : onRetry ? /* @__PURE__ */ jsxRuntime.jsx(gui.Button, { size: "$2", self: "flex-start", onPress: onRetry, children: "Retry" }) : null
|
|
1654
|
-
] });
|
|
1655
|
-
}
|
|
1656
|
-
function PageHeader({
|
|
1657
|
-
title,
|
|
1658
|
-
subtitle,
|
|
1659
|
-
actions
|
|
1660
|
-
}) {
|
|
1661
|
-
return (
|
|
1662
|
-
// flexWrap lets the actions drop below the title on narrow screens; flex={1}
|
|
1663
|
-
// minW={0} lets the title column shrink so a long subtitle WRAPS instead of
|
|
1664
|
-
// running off the viewport (a flex child defaults to min-width:auto = content
|
|
1665
|
-
// width, which would overflow on mobile).
|
|
1666
|
-
/* @__PURE__ */ jsxRuntime.jsxs(gui.XStack, { justify: "space-between", items: "flex-start", gap: "$3", flexWrap: "wrap", children: [
|
|
1667
|
-
/* @__PURE__ */ jsxRuntime.jsxs(gui.YStack, { gap: "$1", flex: 1, minW: 200, children: [
|
|
1668
|
-
/* @__PURE__ */ jsxRuntime.jsx(gui.Text, { fontSize: "$7", fontWeight: "500", letterSpacing: -0.4, children: title }),
|
|
1669
|
-
subtitle ? /* @__PURE__ */ jsxRuntime.jsx(gui.Text, { fontSize: "$3", color: "$color11", children: subtitle }) : null
|
|
1670
|
-
] }),
|
|
1671
|
-
actions ? /* @__PURE__ */ jsxRuntime.jsx(gui.XStack, { gap: "$2", items: "center", flexWrap: "wrap", width: "100%", $md: { width: "auto", justify: "flex-end" }, children: actions }) : null
|
|
1672
|
-
] })
|
|
1673
|
-
);
|
|
1674
|
-
}
|
|
1675
|
-
function SkeletonRows({ columns, count = 6 }) {
|
|
1676
|
-
return /* @__PURE__ */ jsxRuntime.jsx(gui.YStack, { children: Array.from({ length: count }).map((_, r) => /* @__PURE__ */ jsxRuntime.jsx(gui.XStack, { py: "$2.5", px: "$3", gap: "$3", borderTopWidth: 1, borderColor: "$borderColor", items: "center", children: columns.map((c, i) => /* @__PURE__ */ jsxRuntime.jsx(gui.YStack, { width: c.width, flex: c.width ? void 0 : 1, minW: c.width ? void 0 : FLEX_MIN_COL_W, items: c.align === "right" ? "flex-end" : "flex-start", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
1677
|
-
"div",
|
|
1678
|
-
{
|
|
1679
|
-
className: "hz-skeleton",
|
|
1680
|
-
style: { height: 12, borderRadius: 6, width: `${[62, 40, 54, 34, 48][(i + r) % 5]}%` },
|
|
1681
|
-
"aria-hidden": true
|
|
1682
|
-
}
|
|
1683
|
-
) }, c.key)) }, r)) });
|
|
1684
|
-
}
|
|
1685
|
-
function DataTable({
|
|
1686
|
-
columns,
|
|
1687
|
-
rows: rows2,
|
|
1688
|
-
loading,
|
|
1689
|
-
empty = "Nothing here yet.",
|
|
1690
|
-
rowKey,
|
|
1691
|
-
onRowPress,
|
|
1692
|
-
isRowExpanded,
|
|
1693
|
-
renderExpanded,
|
|
1694
|
-
sort,
|
|
1695
|
-
onSortChange
|
|
1696
|
-
}) {
|
|
1697
|
-
const minTableW = columns.reduce((sum, c) => sum + (c.width ?? FLEX_MIN_COL_W), 0) + (columns.length + 1) * 12;
|
|
1698
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(gui.YStack, { borderWidth: 1, borderColor: "$borderColor", rounded: "$4", overflow: "hidden", children: [
|
|
1699
|
-
/* @__PURE__ */ jsxRuntime.jsx(gui.YStack, { style: { overflowX: "auto", overflowY: "visible" }, children: /* @__PURE__ */ jsxRuntime.jsxs(gui.YStack, { minW: minTableW, children: [
|
|
1700
|
-
/* @__PURE__ */ jsxRuntime.jsx(gui.XStack, { bg: "$color1", py: "$2.5", px: "$3", gap: "$3", borderBottomWidth: 1, borderColor: "$borderColor", role: "row", children: columns.map((c) => {
|
|
1701
|
-
const sortable = c.sortable === true && !!onSortChange;
|
|
1702
|
-
const active = sortable && sort?.key === c.key;
|
|
1703
|
-
const Caret = !sortable ? null : !active ? lucideIcons2.ChevronsUpDown : sort?.dir === "asc" ? lucideIcons2.ChevronUp : lucideIcons2.ChevronDown;
|
|
1704
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
1705
|
-
gui.XStack,
|
|
1706
|
-
{
|
|
1707
|
-
width: c.width,
|
|
1708
|
-
flex: c.width ? void 0 : 1,
|
|
1709
|
-
minW: c.width ? void 0 : FLEX_MIN_COL_W,
|
|
1710
|
-
items: "center",
|
|
1711
|
-
gap: "$1",
|
|
1712
|
-
justify: c.align === "right" ? "flex-end" : "flex-start",
|
|
1713
|
-
role: "columnheader",
|
|
1714
|
-
"aria-sort": sortable ? active ? sort?.dir === "asc" ? "ascending" : "descending" : "none" : void 0,
|
|
1715
|
-
"aria-label": sortable ? `Sort by ${c.header}` : void 0,
|
|
1716
|
-
cursor: sortable ? "pointer" : void 0,
|
|
1717
|
-
hoverStyle: sortable ? { opacity: 0.75 } : void 0,
|
|
1718
|
-
onPress: sortable ? () => onSortChange?.(c.key) : void 0,
|
|
1719
|
-
children: [
|
|
1720
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1721
|
-
gui.Text,
|
|
1722
|
-
{
|
|
1723
|
-
fontSize: "$1",
|
|
1724
|
-
fontWeight: "500",
|
|
1725
|
-
color: active ? "$color12" : "$color10",
|
|
1726
|
-
text: c.align === "right" ? "right" : "left",
|
|
1727
|
-
className: c.mono ? "hz-tnum" : void 0,
|
|
1728
|
-
children: c.header
|
|
1729
|
-
}
|
|
1730
|
-
),
|
|
1731
|
-
Caret ? /* @__PURE__ */ jsxRuntime.jsx(Caret, { size: 12, color: active ? "$color12" : "$color9" }) : null
|
|
1732
|
-
]
|
|
1733
|
-
},
|
|
1734
|
-
c.key
|
|
1735
|
-
);
|
|
1736
|
-
}) }),
|
|
1737
|
-
loading ? /* @__PURE__ */ jsxRuntime.jsx(SkeletonRows, { columns }) : rows2.length > 0 ? /* @__PURE__ */ jsxRuntime.jsx(gui.YStack, { children: rows2.map((row) => {
|
|
1738
|
-
const expanded = (isRowExpanded?.(row) ?? false) && !!renderExpanded;
|
|
1739
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(gui.YStack, { children: [
|
|
1740
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1741
|
-
gui.XStack,
|
|
1742
|
-
{
|
|
1743
|
-
className: "hz-row",
|
|
1744
|
-
py: "$2.5",
|
|
1745
|
-
px: "$3",
|
|
1746
|
-
gap: "$3",
|
|
1747
|
-
borderTopWidth: 1,
|
|
1748
|
-
borderColor: "$borderColor",
|
|
1749
|
-
items: "center",
|
|
1750
|
-
bg: expanded ? "$color2" : void 0,
|
|
1751
|
-
hoverStyle: onRowPress ? { bg: "$color2" } : void 0,
|
|
1752
|
-
cursor: onRowPress ? "pointer" : void 0,
|
|
1753
|
-
onPress: onRowPress ? () => onRowPress(row) : void 0,
|
|
1754
|
-
children: columns.map((c) => {
|
|
1755
|
-
const cell = c.render ? c.render(row) : String(row[c.key] ?? "");
|
|
1756
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
1757
|
-
gui.YStack,
|
|
1758
|
-
{
|
|
1759
|
-
width: c.width,
|
|
1760
|
-
flex: c.width ? void 0 : 1,
|
|
1761
|
-
minW: c.width ? void 0 : FLEX_MIN_COL_W,
|
|
1762
|
-
justify: "center",
|
|
1763
|
-
items: c.align === "right" ? "flex-end" : "flex-start",
|
|
1764
|
-
children: typeof cell === "string" || typeof cell === "number" ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
1765
|
-
gui.Text,
|
|
1766
|
-
{
|
|
1767
|
-
fontSize: "$3",
|
|
1768
|
-
numberOfLines: 1,
|
|
1769
|
-
color: "$color12",
|
|
1770
|
-
text: c.align === "right" ? "right" : "left",
|
|
1771
|
-
className: c.mono ? "hz-mono" : void 0,
|
|
1772
|
-
children: cell
|
|
1773
|
-
}
|
|
1774
|
-
) : cell
|
|
1775
|
-
},
|
|
1776
|
-
c.key
|
|
1777
|
-
);
|
|
1778
|
-
})
|
|
1779
|
-
}
|
|
1780
|
-
),
|
|
1781
|
-
expanded && renderExpanded ? /* @__PURE__ */ jsxRuntime.jsx(gui.YStack, { borderTopWidth: 1, borderColor: "$borderColor", bg: "$color1", children: renderExpanded(row) }) : null
|
|
1782
|
-
] }, rowKey(row));
|
|
1783
|
-
}) }) : null
|
|
1784
|
-
] }) }),
|
|
1785
|
-
!loading && rows2.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx(gui.YStack, { py: "$8", px: "$4", items: "center", gap: "$1", borderTopWidth: 1, borderColor: "$borderColor", children: /* @__PURE__ */ jsxRuntime.jsx(gui.Text, { color: "$color10", fontSize: "$3", text: "center", children: empty }) }) : null
|
|
1786
|
-
] });
|
|
1787
|
-
}
|
|
1788
|
-
var FLEX_MIN_COL_W = 120;
|
|
1789
1594
|
function CommerceResource({
|
|
1790
1595
|
title,
|
|
1791
1596
|
subtitle,
|
|
@@ -1801,14 +1606,14 @@ function CommerceResource({
|
|
|
1801
1606
|
loadRef.current = load;
|
|
1802
1607
|
const reload = react.useCallback(() => {
|
|
1803
1608
|
setState({ phase: "loading" });
|
|
1804
|
-
loadRef.current().then((r) => setState({ phase: "ready", data: r.rows })).catch((e) => setState({ phase: "error", error: classifyBackend(e) }));
|
|
1609
|
+
loadRef.current().then((r) => setState({ phase: "ready", data: r.rows })).catch((e) => setState({ phase: "error", error: chunk5MBAHVEO_cjs.classifyBackend(e) }));
|
|
1805
1610
|
}, []);
|
|
1806
1611
|
react.useEffect(() => {
|
|
1807
1612
|
reload();
|
|
1808
1613
|
}, [reload]);
|
|
1809
1614
|
return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
1810
1615
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1811
|
-
PageHeader,
|
|
1616
|
+
chunk5MBAHVEO_cjs.PageHeader,
|
|
1812
1617
|
{
|
|
1813
1618
|
title,
|
|
1814
1619
|
subtitle,
|
|
@@ -1818,8 +1623,8 @@ function CommerceResource({
|
|
|
1818
1623
|
] })
|
|
1819
1624
|
}
|
|
1820
1625
|
),
|
|
1821
|
-
state.phase === "error" ? /* @__PURE__ */ jsxRuntime.jsx(BackendStateCard, { state: state.error, onRetry: reload, hint }) : /* @__PURE__ */ jsxRuntime.jsx(
|
|
1822
|
-
DataTable,
|
|
1626
|
+
state.phase === "error" ? /* @__PURE__ */ jsxRuntime.jsx(chunk5MBAHVEO_cjs.BackendStateCard, { state: state.error, onRetry: reload, hint }) : /* @__PURE__ */ jsxRuntime.jsx(
|
|
1627
|
+
chunk5MBAHVEO_cjs.DataTable,
|
|
1823
1628
|
{
|
|
1824
1629
|
columns,
|
|
1825
1630
|
rows: state.phase === "ready" ? state.data : [],
|
|
@@ -1845,7 +1650,7 @@ function ConfirmDelete({
|
|
|
1845
1650
|
await run();
|
|
1846
1651
|
onDone();
|
|
1847
1652
|
} catch (e) {
|
|
1848
|
-
setErr(classifyBackend(e).message || "Failed to delete.");
|
|
1653
|
+
setErr(chunk5MBAHVEO_cjs.classifyBackend(e).message || "Failed to delete.");
|
|
1849
1654
|
setBusy(false);
|
|
1850
1655
|
}
|
|
1851
1656
|
};
|
|
@@ -2068,131 +1873,6 @@ function AnimatedLogo({
|
|
|
2068
1873
|
}
|
|
2069
1874
|
);
|
|
2070
1875
|
}
|
|
2071
|
-
function isHexColor(v) {
|
|
2072
|
-
return typeof v === "string" && /^#([0-9a-fA-F]{3}|[0-9a-fA-F]{6})$/.test(v.trim());
|
|
2073
|
-
}
|
|
2074
|
-
function resolveAccent(theme) {
|
|
2075
|
-
if (!theme || !theme.isEnabled) return null;
|
|
2076
|
-
const hex = (theme.colorPrimary ?? "").trim();
|
|
2077
|
-
return isHexColor(hex) ? hex : null;
|
|
2078
|
-
}
|
|
2079
|
-
function expandHex(hex) {
|
|
2080
|
-
const h = hex.trim().toLowerCase();
|
|
2081
|
-
if (h.length === 4) return `#${h[1]}${h[1]}${h[2]}${h[2]}${h[3]}${h[3]}`;
|
|
2082
|
-
return h;
|
|
2083
|
-
}
|
|
2084
|
-
function contrastText(hex) {
|
|
2085
|
-
if (!isHexColor(hex)) return "#ffffff";
|
|
2086
|
-
const h = expandHex(hex);
|
|
2087
|
-
const r = parseInt(h.slice(1, 3), 16) / 255;
|
|
2088
|
-
const g = parseInt(h.slice(3, 5), 16) / 255;
|
|
2089
|
-
const b = parseInt(h.slice(5, 7), 16) / 255;
|
|
2090
|
-
const lin = (c) => c <= 0.03928 ? c / 12.92 : ((c + 0.055) / 1.055) ** 2.4;
|
|
2091
|
-
const luminance = 0.2126 * lin(r) + 0.7152 * lin(g) + 0.0722 * lin(b);
|
|
2092
|
-
return luminance > 0.5 ? "#000000" : "#ffffff";
|
|
2093
|
-
}
|
|
2094
|
-
function accentFor(theme) {
|
|
2095
|
-
const hex = resolveAccent(theme);
|
|
2096
|
-
return { accent: hex, contrast: hex ? contrastText(hex) : "#ffffff" };
|
|
2097
|
-
}
|
|
2098
|
-
var DEFAULT = { accent: null, contrast: "#ffffff" };
|
|
2099
|
-
var current = DEFAULT;
|
|
2100
|
-
var listeners = /* @__PURE__ */ new Set();
|
|
2101
|
-
function setOrgAccent(theme) {
|
|
2102
|
-
const next = accentFor(theme);
|
|
2103
|
-
if (next.accent === current.accent) return;
|
|
2104
|
-
current = next.accent ? next : DEFAULT;
|
|
2105
|
-
for (const l of listeners) l();
|
|
2106
|
-
}
|
|
2107
|
-
function subscribe(cb) {
|
|
2108
|
-
listeners.add(cb);
|
|
2109
|
-
return () => {
|
|
2110
|
-
listeners.delete(cb);
|
|
2111
|
-
};
|
|
2112
|
-
}
|
|
2113
|
-
function useAccent() {
|
|
2114
|
-
return react.useSyncExternalStore(
|
|
2115
|
-
subscribe,
|
|
2116
|
-
() => current,
|
|
2117
|
-
() => DEFAULT
|
|
2118
|
-
);
|
|
2119
|
-
}
|
|
2120
|
-
function PrimaryButton(props) {
|
|
2121
|
-
const { accent, contrast } = useAccent();
|
|
2122
|
-
if (accent) {
|
|
2123
|
-
return /* @__PURE__ */ jsxRuntime.jsx(gui.Button, { style: { backgroundColor: accent, color: contrast, borderColor: accent }, ...props });
|
|
2124
|
-
}
|
|
2125
|
-
return /* @__PURE__ */ jsxRuntime.jsx(gui.Button, { theme: "light", ...props });
|
|
2126
|
-
}
|
|
2127
|
-
function openHref2(href) {
|
|
2128
|
-
if (typeof window !== "undefined") window.open(href, "_blank", "noopener");
|
|
2129
|
-
}
|
|
2130
|
-
function EmptyState({
|
|
2131
|
-
icon: Icon,
|
|
2132
|
-
title,
|
|
2133
|
-
description,
|
|
2134
|
-
bullets,
|
|
2135
|
-
primary,
|
|
2136
|
-
secondary
|
|
2137
|
-
}) {
|
|
2138
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
2139
|
-
gui.Card,
|
|
2140
|
-
{
|
|
2141
|
-
borderWidth: 1,
|
|
2142
|
-
borderColor: "$borderColor",
|
|
2143
|
-
borderStyle: "dashed",
|
|
2144
|
-
p: "$6",
|
|
2145
|
-
gap: "$4",
|
|
2146
|
-
items: "center",
|
|
2147
|
-
maxWidth: 640,
|
|
2148
|
-
self: "center",
|
|
2149
|
-
width: "100%",
|
|
2150
|
-
children: [
|
|
2151
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2152
|
-
gui.YStack,
|
|
2153
|
-
{
|
|
2154
|
-
width: 48,
|
|
2155
|
-
height: 48,
|
|
2156
|
-
items: "center",
|
|
2157
|
-
justify: "center",
|
|
2158
|
-
rounded: "$4",
|
|
2159
|
-
bg: "$color3",
|
|
2160
|
-
children: /* @__PURE__ */ jsxRuntime.jsx(Icon, { size: 24 })
|
|
2161
|
-
}
|
|
2162
|
-
),
|
|
2163
|
-
/* @__PURE__ */ jsxRuntime.jsxs(gui.YStack, { gap: "$2", items: "center", maxW: 480, children: [
|
|
2164
|
-
/* @__PURE__ */ jsxRuntime.jsx(gui.Text, { fontSize: "$6", fontWeight: "500", text: "center", letterSpacing: -0.3, children: title }),
|
|
2165
|
-
/* @__PURE__ */ jsxRuntime.jsx(gui.Text, { fontSize: "$3", color: "$color11", text: "center", children: description })
|
|
2166
|
-
] }),
|
|
2167
|
-
bullets && bullets.length ? /* @__PURE__ */ jsxRuntime.jsx(gui.YStack, { gap: "$2", self: "stretch", maxW: 420, mx: "auto", children: bullets.map((b) => /* @__PURE__ */ jsxRuntime.jsxs(gui.XStack, { gap: "$2", items: "flex-start", children: [
|
|
2168
|
-
/* @__PURE__ */ jsxRuntime.jsx(gui.YStack, { pt: "$1", children: /* @__PURE__ */ jsxRuntime.jsx(lucideIcons2.Check, { size: 14, color: "$color10" }) }),
|
|
2169
|
-
/* @__PURE__ */ jsxRuntime.jsx(gui.Text, { fontSize: "$3", color: "$color11", flex: 1, children: b })
|
|
2170
|
-
] }, b)) }) : null,
|
|
2171
|
-
primary || secondary ? /* @__PURE__ */ jsxRuntime.jsxs(gui.XStack, { gap: "$2", items: "center", flexWrap: "wrap", justify: "center", children: [
|
|
2172
|
-
primary ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
2173
|
-
PrimaryButton,
|
|
2174
|
-
{
|
|
2175
|
-
icon: primary.icon,
|
|
2176
|
-
iconAfter: primary.href ? /* @__PURE__ */ jsxRuntime.jsx(lucideIcons2.ExternalLink, { size: 15 }) : /* @__PURE__ */ jsxRuntime.jsx(lucideIcons2.ArrowRight, { size: 15 }),
|
|
2177
|
-
onPress: () => primary.href ? openHref2(primary.href) : primary.onPress?.(),
|
|
2178
|
-
children: primary.label
|
|
2179
|
-
}
|
|
2180
|
-
) : null,
|
|
2181
|
-
secondary ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
2182
|
-
gui.Button,
|
|
2183
|
-
{
|
|
2184
|
-
chromeless: true,
|
|
2185
|
-
icon: secondary.icon,
|
|
2186
|
-
iconAfter: secondary.href ? /* @__PURE__ */ jsxRuntime.jsx(lucideIcons2.ExternalLink, { size: 14 }) : void 0,
|
|
2187
|
-
onPress: () => secondary.href ? openHref2(secondary.href) : secondary.onPress?.(),
|
|
2188
|
-
children: secondary.label
|
|
2189
|
-
}
|
|
2190
|
-
) : null
|
|
2191
|
-
] }) : null
|
|
2192
|
-
]
|
|
2193
|
-
}
|
|
2194
|
-
);
|
|
2195
|
-
}
|
|
2196
1876
|
function FadeIn({
|
|
2197
1877
|
children,
|
|
2198
1878
|
index = 0,
|
|
@@ -2203,125 +1883,6 @@ function FadeIn({
|
|
|
2203
1883
|
const delay = delayMs ?? index * step;
|
|
2204
1884
|
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "hz-fade-up", style: { animationDelay: `${delay}ms`, ...style }, children });
|
|
2205
1885
|
}
|
|
2206
|
-
function FieldRow({ label, children }) {
|
|
2207
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(gui.XStack, { gap: "$3", items: "flex-start", flexWrap: "wrap", children: [
|
|
2208
|
-
/* @__PURE__ */ jsxRuntime.jsx(gui.Label, { width: "100%", pt: "$2", color: "$color11", fontSize: "$3", $md: { width: 180 }, children: label }),
|
|
2209
|
-
/* @__PURE__ */ jsxRuntime.jsx(gui.YStack, { flex: 1, minW: 0, $md: { minW: 240 }, children })
|
|
2210
|
-
] });
|
|
2211
|
-
}
|
|
2212
|
-
function FieldText({
|
|
2213
|
-
value,
|
|
2214
|
-
onChange,
|
|
2215
|
-
disabled,
|
|
2216
|
-
secure,
|
|
2217
|
-
placeholder
|
|
2218
|
-
}) {
|
|
2219
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
2220
|
-
gui.Input,
|
|
2221
|
-
{
|
|
2222
|
-
value,
|
|
2223
|
-
onChangeText: onChange,
|
|
2224
|
-
disabled,
|
|
2225
|
-
secureTextEntry: secure,
|
|
2226
|
-
placeholder,
|
|
2227
|
-
autoCapitalize: "none"
|
|
2228
|
-
}
|
|
2229
|
-
);
|
|
2230
|
-
}
|
|
2231
|
-
function FieldTextArea({
|
|
2232
|
-
value,
|
|
2233
|
-
onChange,
|
|
2234
|
-
disabled,
|
|
2235
|
-
rows: rows2 = 6
|
|
2236
|
-
}) {
|
|
2237
|
-
return /* @__PURE__ */ jsxRuntime.jsx(gui.TextArea, { value, onChangeText: onChange, disabled, numberOfLines: rows2 });
|
|
2238
|
-
}
|
|
2239
|
-
function FieldSwitch({
|
|
2240
|
-
checked,
|
|
2241
|
-
onChange,
|
|
2242
|
-
disabled
|
|
2243
|
-
}) {
|
|
2244
|
-
return /* @__PURE__ */ jsxRuntime.jsx(gui.Switch, { checked, onCheckedChange: onChange, disabled, size: "$3", children: /* @__PURE__ */ jsxRuntime.jsx(gui.Switch.Thumb, {}) });
|
|
2245
|
-
}
|
|
2246
|
-
var CHEVRON = `data:image/svg+xml,${encodeURIComponent(
|
|
2247
|
-
'<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="#9a9a9a" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="m6 9 6 6 6-6"/></svg>'
|
|
2248
|
-
)}`;
|
|
2249
|
-
function selectStyle(disabled) {
|
|
2250
|
-
return {
|
|
2251
|
-
width: "100%",
|
|
2252
|
-
boxSizing: "border-box",
|
|
2253
|
-
appearance: "none",
|
|
2254
|
-
WebkitAppearance: "none",
|
|
2255
|
-
MozAppearance: "none",
|
|
2256
|
-
background: `var(--background) url("${CHEVRON}") no-repeat right 10px center`,
|
|
2257
|
-
color: "var(--color12)",
|
|
2258
|
-
border: "1px solid var(--borderColor)",
|
|
2259
|
-
borderRadius: 9,
|
|
2260
|
-
padding: "9px 34px 9px 12px",
|
|
2261
|
-
fontSize: 14,
|
|
2262
|
-
lineHeight: "20px",
|
|
2263
|
-
fontFamily: "inherit",
|
|
2264
|
-
height: 40,
|
|
2265
|
-
outline: "none",
|
|
2266
|
-
cursor: disabled ? "not-allowed" : "pointer",
|
|
2267
|
-
opacity: disabled ? 0.5 : 1
|
|
2268
|
-
};
|
|
2269
|
-
}
|
|
2270
|
-
var OPTION_STYLE = { background: "var(--color2)", color: "var(--color12)" };
|
|
2271
|
-
function FieldSelect({
|
|
2272
|
-
value,
|
|
2273
|
-
options,
|
|
2274
|
-
onChange,
|
|
2275
|
-
disabled,
|
|
2276
|
-
placeholder = "Select\u2026"
|
|
2277
|
-
}) {
|
|
2278
|
-
const showPlaceholder = value === "" || !options.includes(value);
|
|
2279
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
2280
|
-
"select",
|
|
2281
|
-
{
|
|
2282
|
-
value: showPlaceholder ? "" : value,
|
|
2283
|
-
onChange: (e) => onChange(e.currentTarget.value),
|
|
2284
|
-
disabled,
|
|
2285
|
-
"aria-label": placeholder,
|
|
2286
|
-
style: selectStyle(disabled),
|
|
2287
|
-
children: [
|
|
2288
|
-
showPlaceholder ? /* @__PURE__ */ jsxRuntime.jsx("option", { value: "", disabled: true, style: OPTION_STYLE, children: placeholder }) : null,
|
|
2289
|
-
options.map((opt) => /* @__PURE__ */ jsxRuntime.jsx("option", { value: opt, style: OPTION_STYLE, children: opt }, opt))
|
|
2290
|
-
]
|
|
2291
|
-
}
|
|
2292
|
-
);
|
|
2293
|
-
}
|
|
2294
|
-
function FieldSlider({
|
|
2295
|
-
value,
|
|
2296
|
-
min,
|
|
2297
|
-
max,
|
|
2298
|
-
step,
|
|
2299
|
-
onChange,
|
|
2300
|
-
disabled
|
|
2301
|
-
}) {
|
|
2302
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(gui.XStack, { gap: "$3", items: "center", children: [
|
|
2303
|
-
/* @__PURE__ */ jsxRuntime.jsx(gui.Text, { width: 56, fontSize: "$3", color: "$color11", children: value }),
|
|
2304
|
-
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
2305
|
-
gui.Slider,
|
|
2306
|
-
{
|
|
2307
|
-
flex: 1,
|
|
2308
|
-
min,
|
|
2309
|
-
max,
|
|
2310
|
-
step,
|
|
2311
|
-
value: [value],
|
|
2312
|
-
onValueChange: (v) => onChange(v[0] ?? min),
|
|
2313
|
-
disabled,
|
|
2314
|
-
children: [
|
|
2315
|
-
/* @__PURE__ */ jsxRuntime.jsx(gui.Slider.Track, { children: /* @__PURE__ */ jsxRuntime.jsx(gui.Slider.TrackActive, {}) }),
|
|
2316
|
-
/* @__PURE__ */ jsxRuntime.jsx(gui.Slider.Thumb, { index: 0, circular: true })
|
|
2317
|
-
]
|
|
2318
|
-
}
|
|
2319
|
-
)
|
|
2320
|
-
] });
|
|
2321
|
-
}
|
|
2322
|
-
|
|
2323
|
-
// src/product/color.ts
|
|
2324
|
-
var asColor = (hex) => hex;
|
|
2325
1886
|
function ProductIcon({
|
|
2326
1887
|
icon: Icon,
|
|
2327
1888
|
color,
|
|
@@ -2340,7 +1901,7 @@ function ProductIcon({
|
|
|
2340
1901
|
justify: "center",
|
|
2341
1902
|
rounded: radius,
|
|
2342
1903
|
style: { backgroundColor: color },
|
|
2343
|
-
children: /* @__PURE__ */ jsxRuntime.jsx(Icon, { size: glyph, color: asColor("#ffffff") })
|
|
1904
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(Icon, { size: glyph, color: chunk5MBAHVEO_cjs.asColor("#ffffff") })
|
|
2344
1905
|
}
|
|
2345
1906
|
);
|
|
2346
1907
|
}
|
|
@@ -2525,169 +2086,6 @@ function SelectMenu({
|
|
|
2525
2086
|
}
|
|
2526
2087
|
);
|
|
2527
2088
|
}
|
|
2528
|
-
var LG = 1024;
|
|
2529
|
-
var lockCount = 0;
|
|
2530
|
-
var savedOverflow = "";
|
|
2531
|
-
function lockScroll() {
|
|
2532
|
-
if (typeof document === "undefined") return;
|
|
2533
|
-
if (lockCount === 0) {
|
|
2534
|
-
savedOverflow = document.body.style.overflow;
|
|
2535
|
-
document.body.style.overflow = "hidden";
|
|
2536
|
-
}
|
|
2537
|
-
lockCount++;
|
|
2538
|
-
}
|
|
2539
|
-
function unlockScroll() {
|
|
2540
|
-
if (typeof document === "undefined") return;
|
|
2541
|
-
lockCount = Math.max(0, lockCount - 1);
|
|
2542
|
-
if (lockCount === 0) document.body.style.overflow = savedOverflow;
|
|
2543
|
-
}
|
|
2544
|
-
function SlideOver({
|
|
2545
|
-
open,
|
|
2546
|
-
onClose,
|
|
2547
|
-
side = "right",
|
|
2548
|
-
size = 420,
|
|
2549
|
-
title,
|
|
2550
|
-
icon: Icon,
|
|
2551
|
-
iconColor,
|
|
2552
|
-
headerRight,
|
|
2553
|
-
ariaLabel,
|
|
2554
|
-
zIndex = 1e3,
|
|
2555
|
-
children
|
|
2556
|
-
}) {
|
|
2557
|
-
const panelRef = react.useRef(null);
|
|
2558
|
-
const openerRef = react.useRef(null);
|
|
2559
|
-
react.useEffect(() => {
|
|
2560
|
-
if (!open) return;
|
|
2561
|
-
openerRef.current = typeof document !== "undefined" ? document.activeElement : null;
|
|
2562
|
-
lockScroll();
|
|
2563
|
-
const t = window.setTimeout(() => {
|
|
2564
|
-
const el = panelRef.current;
|
|
2565
|
-
if (el && typeof el.focus === "function") el.focus();
|
|
2566
|
-
}, 0);
|
|
2567
|
-
return () => {
|
|
2568
|
-
window.clearTimeout(t);
|
|
2569
|
-
unlockScroll();
|
|
2570
|
-
const opener = openerRef.current;
|
|
2571
|
-
if (opener && opener instanceof HTMLElement && typeof opener.focus === "function") opener.focus();
|
|
2572
|
-
};
|
|
2573
|
-
}, [open]);
|
|
2574
|
-
react.useEffect(() => {
|
|
2575
|
-
if (!open) return;
|
|
2576
|
-
const onKey = (e) => {
|
|
2577
|
-
if (e.key === "Escape") {
|
|
2578
|
-
e.stopPropagation();
|
|
2579
|
-
onClose();
|
|
2580
|
-
}
|
|
2581
|
-
};
|
|
2582
|
-
window.addEventListener("keydown", onKey);
|
|
2583
|
-
return () => window.removeEventListener("keydown", onKey);
|
|
2584
|
-
}, [open, onClose]);
|
|
2585
|
-
const offscreen = side === "right" ? "translateX(100%)" : "translateX(-100%)";
|
|
2586
|
-
const edge = side === "right" ? { r: 0 } : { l: 0 };
|
|
2587
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
2588
|
-
gui.YStack,
|
|
2589
|
-
{
|
|
2590
|
-
overflow: "hidden",
|
|
2591
|
-
pointerEvents: open ? "auto" : "none",
|
|
2592
|
-
"aria-hidden": !open,
|
|
2593
|
-
style: { position: "fixed", inset: 0, zIndex },
|
|
2594
|
-
children: [
|
|
2595
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2596
|
-
gui.YStack,
|
|
2597
|
-
{
|
|
2598
|
-
position: "absolute",
|
|
2599
|
-
t: 0,
|
|
2600
|
-
l: 0,
|
|
2601
|
-
r: 0,
|
|
2602
|
-
b: 0,
|
|
2603
|
-
bg: "rgba(0,0,0,0.55)",
|
|
2604
|
-
className: "hz-fade",
|
|
2605
|
-
style: { opacity: open ? 1 : 0 },
|
|
2606
|
-
onPress: onClose
|
|
2607
|
-
}
|
|
2608
|
-
),
|
|
2609
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2610
|
-
gui.YStack,
|
|
2611
|
-
{
|
|
2612
|
-
ref: panelRef,
|
|
2613
|
-
tabIndex: -1,
|
|
2614
|
-
role: "dialog",
|
|
2615
|
-
"aria-modal": open ? true : void 0,
|
|
2616
|
-
"aria-label": typeof title === "string" ? title : ariaLabel,
|
|
2617
|
-
position: "absolute",
|
|
2618
|
-
t: 0,
|
|
2619
|
-
b: 0,
|
|
2620
|
-
...edge,
|
|
2621
|
-
width: "100%",
|
|
2622
|
-
$lg: { width: size, maxW: "100vw" },
|
|
2623
|
-
bg: "$color1",
|
|
2624
|
-
borderLeftWidth: side === "right" ? 1 : 0,
|
|
2625
|
-
borderRightWidth: side === "left" ? 1 : 0,
|
|
2626
|
-
borderColor: "$borderColor",
|
|
2627
|
-
className: "hz-slide hz-elevation-4",
|
|
2628
|
-
style: {
|
|
2629
|
-
transform: open ? "translateX(0)" : offscreen,
|
|
2630
|
-
height: "100dvh",
|
|
2631
|
-
paddingTop: "env(safe-area-inset-top)",
|
|
2632
|
-
paddingBottom: "env(safe-area-inset-bottom)"
|
|
2633
|
-
},
|
|
2634
|
-
children: title !== void 0 ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
2635
|
-
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
2636
|
-
gui.XStack,
|
|
2637
|
-
{
|
|
2638
|
-
items: "center",
|
|
2639
|
-
gap: "$2.5",
|
|
2640
|
-
px: "$4",
|
|
2641
|
-
height: 56,
|
|
2642
|
-
borderBottomWidth: 1,
|
|
2643
|
-
borderColor: "$borderColor",
|
|
2644
|
-
children: [
|
|
2645
|
-
Icon ? /* @__PURE__ */ jsxRuntime.jsx(Icon, { size: 18, color: iconColor ? asColor(iconColor) : void 0 }) : null,
|
|
2646
|
-
/* @__PURE__ */ jsxRuntime.jsx(gui.Text, { flex: 1, fontSize: "$5", fontWeight: "700", color: "$color12", numberOfLines: 1, children: title }),
|
|
2647
|
-
headerRight,
|
|
2648
|
-
/* @__PURE__ */ jsxRuntime.jsx(gui.Button, { chromeless: true, width: 44, height: 44, icon: /* @__PURE__ */ jsxRuntime.jsx(lucideIcons2.X, { size: 18 }), onPress: onClose, "aria-label": "Close" })
|
|
2649
|
-
]
|
|
2650
|
-
}
|
|
2651
|
-
),
|
|
2652
|
-
/* @__PURE__ */ jsxRuntime.jsx(gui.ScrollView, { flex: 1, children: /* @__PURE__ */ jsxRuntime.jsx(gui.YStack, { flex: 1, p: "$4", gap: "$3", children }) })
|
|
2653
|
-
] }) : (
|
|
2654
|
-
// Bare mode — the caller owns the full panel layout (e.g. the nav drawer
|
|
2655
|
-
// renders its own header + scroll + footer).
|
|
2656
|
-
children
|
|
2657
|
-
)
|
|
2658
|
-
}
|
|
2659
|
-
)
|
|
2660
|
-
]
|
|
2661
|
-
}
|
|
2662
|
-
);
|
|
2663
|
-
}
|
|
2664
|
-
var toneOf = (status) => {
|
|
2665
|
-
const s = status.toLowerCase();
|
|
2666
|
-
if (s === "green") return "green";
|
|
2667
|
-
if (s === "yellow") return "yellow";
|
|
2668
|
-
if (s === "red") return "red";
|
|
2669
|
-
if (["ready", "active", "running", "available", "ok", "live", "succeeded", "connected", "synced", "imported"].includes(s)) return "green";
|
|
2670
|
-
if (["creating", "provisioning", "pending", "updating", "attaching", "building", "deploying", "queued", "importing"].includes(s))
|
|
2671
|
-
return "yellow";
|
|
2672
|
-
if (["error", "failed", "degraded", "down", "canceled", "conflict"].includes(s)) return "red";
|
|
2673
|
-
return "neutral";
|
|
2674
|
-
};
|
|
2675
|
-
var TONE_BG = {
|
|
2676
|
-
green: "$color5",
|
|
2677
|
-
yellow: "$color4",
|
|
2678
|
-
red: "$color4",
|
|
2679
|
-
neutral: "$color3"
|
|
2680
|
-
};
|
|
2681
|
-
var TONE_FG = {
|
|
2682
|
-
green: "$color12",
|
|
2683
|
-
yellow: "$color12",
|
|
2684
|
-
red: "$color12",
|
|
2685
|
-
neutral: "$color11"
|
|
2686
|
-
};
|
|
2687
|
-
function StatusTag({ status }) {
|
|
2688
|
-
const tone2 = toneOf(status ?? "");
|
|
2689
|
-
return /* @__PURE__ */ jsxRuntime.jsx(gui.Text, { fontSize: "$1", px: "$2", py: "$1", rounded: "$2", bg: TONE_BG[tone2], color: TONE_FG[tone2], children: status || "unknown" });
|
|
2690
|
-
}
|
|
2691
2089
|
var ToastContext = react.createContext(null);
|
|
2692
2090
|
var ACCENT3 = {
|
|
2693
2091
|
success: "$green10",
|
|
@@ -2785,622 +2183,6 @@ function useToast() {
|
|
|
2785
2183
|
return ctx;
|
|
2786
2184
|
}
|
|
2787
2185
|
|
|
2788
|
-
// src/product/social/api.ts
|
|
2789
|
-
var enc = encodeURIComponent;
|
|
2790
|
-
var str = (v) => typeof v === "string" ? v : v == null ? "" : String(v);
|
|
2791
|
-
var num = (v) => {
|
|
2792
|
-
if (typeof v === "number" && Number.isFinite(v)) return v;
|
|
2793
|
-
if (typeof v === "string" && v.trim() !== "" && Number.isFinite(Number(v))) return Number(v);
|
|
2794
|
-
return 0;
|
|
2795
|
-
};
|
|
2796
|
-
var strs = (v) => Array.isArray(v) ? v.filter((x) => typeof x === "string") : [];
|
|
2797
|
-
var asRecord = (v) => v && typeof v === "object" && !Array.isArray(v) ? v : {};
|
|
2798
|
-
var rows = (payload) => {
|
|
2799
|
-
if (Array.isArray(payload)) return payload.filter((x) => x && typeof x === "object");
|
|
2800
|
-
if (payload && typeof payload === "object") {
|
|
2801
|
-
for (const k of ["data", "items", "rows"]) {
|
|
2802
|
-
const v = payload[k];
|
|
2803
|
-
if (Array.isArray(v)) return v.filter((x) => x && typeof x === "object");
|
|
2804
|
-
}
|
|
2805
|
-
}
|
|
2806
|
-
return [];
|
|
2807
|
-
};
|
|
2808
|
-
var PROVIDERS = ["x", "facebook", "instagram", "linkedin", "tiktok", "youtube", "threads"];
|
|
2809
|
-
var ACCOUNT_STATUSES = ["connected", "disconnected", "error"];
|
|
2810
|
-
var POST_STATUSES = ["draft", "scheduled", "published", "failed"];
|
|
2811
|
-
function normalizeAccount(raw) {
|
|
2812
|
-
const r = asRecord(raw);
|
|
2813
|
-
return {
|
|
2814
|
-
id: str(r.id),
|
|
2815
|
-
provider: str(r.provider) || "x",
|
|
2816
|
-
handle: str(r.handle),
|
|
2817
|
-
status: str(r.status) || "connected",
|
|
2818
|
-
createdAt: num(r.createdAt),
|
|
2819
|
-
updatedAt: num(r.updatedAt)
|
|
2820
|
-
};
|
|
2821
|
-
}
|
|
2822
|
-
function normalizePost(raw) {
|
|
2823
|
-
const r = asRecord(raw);
|
|
2824
|
-
return {
|
|
2825
|
-
id: str(r.id),
|
|
2826
|
-
content: str(r.content),
|
|
2827
|
-
channel: str(r.channel) || "x",
|
|
2828
|
-
status: str(r.status) || "draft",
|
|
2829
|
-
scheduleAt: num(r.scheduleAt),
|
|
2830
|
-
media: strs(r.media),
|
|
2831
|
-
accountId: str(r.accountId) || void 0,
|
|
2832
|
-
externalId: str(r.externalId) || void 0,
|
|
2833
|
-
error: str(r.error) || void 0,
|
|
2834
|
-
createdAt: num(r.createdAt),
|
|
2835
|
-
updatedAt: num(r.updatedAt)
|
|
2836
|
-
};
|
|
2837
|
-
}
|
|
2838
|
-
function normalizeSummary(raw) {
|
|
2839
|
-
const r = asRecord(raw);
|
|
2840
|
-
return { posts: num(r.posts), scheduled: num(r.scheduled), published: num(r.published), accounts: num(r.accounts) };
|
|
2841
|
-
}
|
|
2842
|
-
function normalizeProviderCapability(raw) {
|
|
2843
|
-
const r = asRecord(raw);
|
|
2844
|
-
return {
|
|
2845
|
-
provider: str(r.provider),
|
|
2846
|
-
credentialsConfigured: Boolean(r.credentialsConfigured),
|
|
2847
|
-
missingCredentials: strs(r.missingCredentials)
|
|
2848
|
-
};
|
|
2849
|
-
}
|
|
2850
|
-
var normalizeAccounts = (p) => rows(p).map(normalizeAccount).filter((a) => a.id);
|
|
2851
|
-
var normalizePosts = (p) => rows(p).map(normalizePost).filter((x) => x.id);
|
|
2852
|
-
var normalizeProviders = (p) => rows(p).map(normalizeProviderCapability).filter((c) => c.provider);
|
|
2853
|
-
function createSocialApi(rest) {
|
|
2854
|
-
return {
|
|
2855
|
-
summary: () => rest.get("summary").then(normalizeSummary),
|
|
2856
|
-
/** Publish-readiness per network (+ the exact missing OAuth-app credentials). */
|
|
2857
|
-
providers: () => rest.get("providers").then(normalizeProviders),
|
|
2858
|
-
accounts: {
|
|
2859
|
-
list: (provider) => rest.get(`accounts${provider ? `?provider=${enc(provider)}` : ""}`).then(normalizeAccounts),
|
|
2860
|
-
get: (id) => rest.get(`accounts/${enc(id)}`).then(normalizeAccount),
|
|
2861
|
-
create: (body) => rest.post("accounts", body).then(normalizeAccount),
|
|
2862
|
-
update: (id, body) => rest.put(`accounts/${enc(id)}`, body).then(normalizeAccount),
|
|
2863
|
-
remove: (id) => rest.del(`accounts/${enc(id)}`)
|
|
2864
|
-
},
|
|
2865
|
-
posts: {
|
|
2866
|
-
list: (status) => rest.get(`posts${status ? `?status=${enc(status)}` : ""}`).then(normalizePosts),
|
|
2867
|
-
get: (id) => rest.get(`posts/${enc(id)}`).then(normalizePost),
|
|
2868
|
-
create: (body) => rest.post("posts", body).then(normalizePost),
|
|
2869
|
-
update: (id, body) => rest.put(`posts/${enc(id)}`, body).then(normalizePost),
|
|
2870
|
-
remove: (id) => rest.del(`posts/${enc(id)}`),
|
|
2871
|
-
/** Publish a post NOW to its channel's connected accounts. */
|
|
2872
|
-
publish: (id) => rest.post(`posts/${enc(id)}/publish`).then(normalizePost)
|
|
2873
|
-
}
|
|
2874
|
-
};
|
|
2875
|
-
}
|
|
2876
|
-
|
|
2877
|
-
// src/product/social/format.ts
|
|
2878
|
-
function formatPostTime(unix) {
|
|
2879
|
-
if (!unix) return "\u2014";
|
|
2880
|
-
return new Date(unix * 1e3).toLocaleString(void 0, {
|
|
2881
|
-
month: "short",
|
|
2882
|
-
day: "numeric",
|
|
2883
|
-
hour: "2-digit",
|
|
2884
|
-
minute: "2-digit"
|
|
2885
|
-
});
|
|
2886
|
-
}
|
|
2887
|
-
function postDayBucket(unix) {
|
|
2888
|
-
const d = new Date(unix * 1e3);
|
|
2889
|
-
const key = `${d.getFullYear()}-${d.getMonth()}-${d.getDate()}`;
|
|
2890
|
-
const label = d.toLocaleDateString(void 0, { weekday: "short", month: "short", day: "numeric" });
|
|
2891
|
-
return { key, label };
|
|
2892
|
-
}
|
|
2893
|
-
function postPreview(s) {
|
|
2894
|
-
const t = s.trim();
|
|
2895
|
-
return t.length > 72 ? `${t.slice(0, 72)}\u2026` : t || "\u2014";
|
|
2896
|
-
}
|
|
2897
|
-
function parsePostTime(dt) {
|
|
2898
|
-
const ms = Date.parse(dt.trim());
|
|
2899
|
-
return Number.isFinite(ms) && ms > 0 ? Math.floor(ms / 1e3) : 0;
|
|
2900
|
-
}
|
|
2901
|
-
function PostAgenda({ posts, onOpen }) {
|
|
2902
|
-
const days = react.useMemo(() => {
|
|
2903
|
-
const timed = posts.filter((p) => (p.scheduleAt ?? 0) > 0).sort((a, b) => (a.scheduleAt ?? 0) - (b.scheduleAt ?? 0));
|
|
2904
|
-
const groups = [];
|
|
2905
|
-
const index = /* @__PURE__ */ new Map();
|
|
2906
|
-
for (const p of timed) {
|
|
2907
|
-
const { key, label } = postDayBucket(p.scheduleAt ?? 0);
|
|
2908
|
-
let i = index.get(key);
|
|
2909
|
-
if (i === void 0) {
|
|
2910
|
-
i = groups.length;
|
|
2911
|
-
index.set(key, i);
|
|
2912
|
-
groups.push({ label, items: [] });
|
|
2913
|
-
}
|
|
2914
|
-
groups[i].items.push(p);
|
|
2915
|
-
}
|
|
2916
|
-
return groups;
|
|
2917
|
-
}, [posts]);
|
|
2918
|
-
if (days.length === 0) {
|
|
2919
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
2920
|
-
EmptyState,
|
|
2921
|
-
{
|
|
2922
|
-
icon: lucideIcons2.Calendar,
|
|
2923
|
-
title: "Nothing on the calendar",
|
|
2924
|
-
description: "Scheduled and timed posts appear here, grouped by day. Compose a post and pick Schedule to plan ahead."
|
|
2925
|
-
}
|
|
2926
|
-
);
|
|
2927
|
-
}
|
|
2928
|
-
return /* @__PURE__ */ jsxRuntime.jsx(gui.YStack, { gap: "$4", children: days.map((d) => /* @__PURE__ */ jsxRuntime.jsxs(gui.YStack, { gap: "$2", children: [
|
|
2929
|
-
/* @__PURE__ */ jsxRuntime.jsx(gui.Text, { fontSize: "$3", fontWeight: "500", color: "$color11", children: d.label }),
|
|
2930
|
-
d.items.map((p) => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
2931
|
-
gui.XStack,
|
|
2932
|
-
{
|
|
2933
|
-
items: "center",
|
|
2934
|
-
justify: "space-between",
|
|
2935
|
-
gap: "$3",
|
|
2936
|
-
borderWidth: 1,
|
|
2937
|
-
borderColor: "$borderColor",
|
|
2938
|
-
rounded: "$4",
|
|
2939
|
-
px: "$4",
|
|
2940
|
-
py: "$3",
|
|
2941
|
-
cursor: "pointer",
|
|
2942
|
-
hoverStyle: { bg: "$color2" },
|
|
2943
|
-
onPress: () => onOpen(p),
|
|
2944
|
-
children: [
|
|
2945
|
-
/* @__PURE__ */ jsxRuntime.jsxs(gui.YStack, { gap: "$1", flex: 1, children: [
|
|
2946
|
-
/* @__PURE__ */ jsxRuntime.jsx(gui.Text, { fontSize: "$3", children: postPreview(p.content) }),
|
|
2947
|
-
/* @__PURE__ */ jsxRuntime.jsxs(gui.XStack, { gap: "$2", items: "center", children: [
|
|
2948
|
-
/* @__PURE__ */ jsxRuntime.jsx(gui.Text, { fontSize: "$1", color: "$color10", children: p.channel }),
|
|
2949
|
-
/* @__PURE__ */ jsxRuntime.jsxs(gui.Text, { fontSize: "$1", color: "$color10", children: [
|
|
2950
|
-
"\xB7 ",
|
|
2951
|
-
formatPostTime(p.scheduleAt ?? 0)
|
|
2952
|
-
] })
|
|
2953
|
-
] })
|
|
2954
|
-
] }),
|
|
2955
|
-
/* @__PURE__ */ jsxRuntime.jsx(StatusTag, { status: p.status })
|
|
2956
|
-
]
|
|
2957
|
-
},
|
|
2958
|
-
p.id
|
|
2959
|
-
))
|
|
2960
|
-
] }, d.label)) });
|
|
2961
|
-
}
|
|
2962
|
-
var COMPOSE_MODES = ["draft", "schedule", "now"];
|
|
2963
|
-
var COMPOSE_LABEL = {
|
|
2964
|
-
draft: "Save draft",
|
|
2965
|
-
schedule: "Schedule",
|
|
2966
|
-
now: "Publish now"
|
|
2967
|
-
};
|
|
2968
|
-
function PostComposer({
|
|
2969
|
-
channels,
|
|
2970
|
-
providers,
|
|
2971
|
-
onSubmit
|
|
2972
|
-
}) {
|
|
2973
|
-
const [content, setContent] = react.useState("");
|
|
2974
|
-
const [channel, setChannel] = react.useState(channels[0] ?? "x");
|
|
2975
|
-
const [mode, setMode] = react.useState("draft");
|
|
2976
|
-
const [scheduleAt, setScheduleAt] = react.useState("");
|
|
2977
|
-
const [saving, setSaving] = react.useState(false);
|
|
2978
|
-
const [error, setError] = react.useState(null);
|
|
2979
|
-
const cap = providers.find((p) => p.provider === channel);
|
|
2980
|
-
const unconfigured = (mode === "now" || mode === "schedule") && !!cap && !cap.credentialsConfigured;
|
|
2981
|
-
const submit = async () => {
|
|
2982
|
-
if (!content.trim()) {
|
|
2983
|
-
setError("Content is required.");
|
|
2984
|
-
return;
|
|
2985
|
-
}
|
|
2986
|
-
let status = "draft";
|
|
2987
|
-
let at = 0;
|
|
2988
|
-
if (mode === "schedule") {
|
|
2989
|
-
at = parsePostTime(scheduleAt);
|
|
2990
|
-
if (at <= Math.floor(Date.now() / 1e3)) {
|
|
2991
|
-
setError("Pick a future date and time to schedule.");
|
|
2992
|
-
return;
|
|
2993
|
-
}
|
|
2994
|
-
status = "scheduled";
|
|
2995
|
-
} else if (mode === "now") {
|
|
2996
|
-
status = "scheduled";
|
|
2997
|
-
}
|
|
2998
|
-
setSaving(true);
|
|
2999
|
-
setError(null);
|
|
3000
|
-
const message = await onSubmit({ content: content.trim(), channel, status, scheduleAt: at }, mode);
|
|
3001
|
-
if (message) {
|
|
3002
|
-
setError(message);
|
|
3003
|
-
setSaving(false);
|
|
3004
|
-
}
|
|
3005
|
-
};
|
|
3006
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(gui.YStack, { gap: "$3", p: "$4", children: [
|
|
3007
|
-
/* @__PURE__ */ jsxRuntime.jsx(FieldRow, { label: "Content", children: /* @__PURE__ */ jsxRuntime.jsx(FieldTextArea, { value: content, onChange: setContent, disabled: saving }) }),
|
|
3008
|
-
/* @__PURE__ */ jsxRuntime.jsx(FieldRow, { label: "Channel", children: /* @__PURE__ */ jsxRuntime.jsx(FieldSelect, { value: channel, options: channels, onChange: setChannel, disabled: saving }) }),
|
|
3009
|
-
/* @__PURE__ */ jsxRuntime.jsx(FieldRow, { label: "When", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
3010
|
-
FieldSelect,
|
|
3011
|
-
{
|
|
3012
|
-
value: mode,
|
|
3013
|
-
options: [...COMPOSE_MODES],
|
|
3014
|
-
onChange: (v) => setMode(v),
|
|
3015
|
-
disabled: saving
|
|
3016
|
-
}
|
|
3017
|
-
) }),
|
|
3018
|
-
mode === "schedule" ? /* @__PURE__ */ jsxRuntime.jsx(FieldRow, { label: "Schedule at", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
3019
|
-
FieldText,
|
|
3020
|
-
{
|
|
3021
|
-
value: scheduleAt,
|
|
3022
|
-
onChange: setScheduleAt,
|
|
3023
|
-
placeholder: "2026-07-15 09:00",
|
|
3024
|
-
disabled: saving
|
|
3025
|
-
}
|
|
3026
|
-
) }) : null,
|
|
3027
|
-
unconfigured ? /* @__PURE__ */ jsxRuntime.jsxs(gui.XStack, { items: "flex-start", gap: "$2", children: [
|
|
3028
|
-
/* @__PURE__ */ jsxRuntime.jsx(lucideIcons2.AlertTriangle, { size: 14, color: "var(--yellow10)" }),
|
|
3029
|
-
/* @__PURE__ */ jsxRuntime.jsxs(gui.Text, { fontSize: "$1", color: "$color10", children: [
|
|
3030
|
-
channel,
|
|
3031
|
-
" isn\u2019t configured to publish yet \u2014 needs ",
|
|
3032
|
-
cap?.missingCredentials.join(", "),
|
|
3033
|
-
". The post is saved and marked failed on publish until credentials are supplied."
|
|
3034
|
-
] })
|
|
3035
|
-
] }) : null,
|
|
3036
|
-
error ? /* @__PURE__ */ jsxRuntime.jsx(gui.Text, { fontSize: "$2", color: "$red10", children: error }) : null,
|
|
3037
|
-
/* @__PURE__ */ jsxRuntime.jsx(PrimaryButton, { onPress: submit, disabled: saving, children: saving ? "Working\u2026" : COMPOSE_LABEL[mode] })
|
|
3038
|
-
] });
|
|
3039
|
-
}
|
|
3040
|
-
function ProviderReadinessList({ providers }) {
|
|
3041
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(gui.YStack, { gap: "$2", children: [
|
|
3042
|
-
/* @__PURE__ */ jsxRuntime.jsx(gui.Text, { fontSize: "$2", color: "$color10", children: "Network publish-readiness" }),
|
|
3043
|
-
providers.map((p) => /* @__PURE__ */ jsxRuntime.jsxs(gui.XStack, { items: "center", justify: "space-between", gap: "$3", py: "$1", children: [
|
|
3044
|
-
/* @__PURE__ */ jsxRuntime.jsxs(gui.XStack, { items: "center", gap: "$2", children: [
|
|
3045
|
-
p.credentialsConfigured ? /* @__PURE__ */ jsxRuntime.jsx(lucideIcons2.CheckCircle2, { size: 14, color: "var(--green10)" }) : /* @__PURE__ */ jsxRuntime.jsx(lucideIcons2.AlertTriangle, { size: 14, color: "var(--yellow10)" }),
|
|
3046
|
-
/* @__PURE__ */ jsxRuntime.jsx(gui.Text, { fontSize: "$2", children: p.provider })
|
|
3047
|
-
] }),
|
|
3048
|
-
/* @__PURE__ */ jsxRuntime.jsx(gui.Text, { fontSize: "$1", color: "$color10", children: p.credentialsConfigured ? "Ready" : `needs ${p.missingCredentials.join(", ")}` })
|
|
3049
|
-
] }, p.provider))
|
|
3050
|
-
] });
|
|
3051
|
-
}
|
|
3052
|
-
function SocialSummaryBar({ summary }) {
|
|
3053
|
-
const cells = [
|
|
3054
|
-
{ label: "Posts", value: summary.posts },
|
|
3055
|
-
{ label: "Scheduled", value: summary.scheduled },
|
|
3056
|
-
{ label: "Published", value: summary.published },
|
|
3057
|
-
{ label: "Accounts", value: summary.accounts }
|
|
3058
|
-
];
|
|
3059
|
-
return /* @__PURE__ */ jsxRuntime.jsx(gui.XStack, { gap: "$3", flexWrap: "wrap", children: cells.map((c) => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
3060
|
-
gui.YStack,
|
|
3061
|
-
{
|
|
3062
|
-
gap: "$1",
|
|
3063
|
-
borderWidth: 1,
|
|
3064
|
-
borderColor: "$borderColor",
|
|
3065
|
-
rounded: "$4",
|
|
3066
|
-
px: "$4",
|
|
3067
|
-
py: "$3",
|
|
3068
|
-
minW: 140,
|
|
3069
|
-
children: [
|
|
3070
|
-
/* @__PURE__ */ jsxRuntime.jsx(gui.Text, { fontSize: "$1", color: "$color10", children: c.label }),
|
|
3071
|
-
/* @__PURE__ */ jsxRuntime.jsx(gui.Text, { fontSize: "$6", fontWeight: "500", className: "hz-tnum", children: c.value })
|
|
3072
|
-
]
|
|
3073
|
-
},
|
|
3074
|
-
c.label
|
|
3075
|
-
)) });
|
|
3076
|
-
}
|
|
3077
|
-
var OPTIONS = [
|
|
3078
|
-
{ id: "list", label: "List", icon: lucideIcons2.List },
|
|
3079
|
-
{ id: "calendar", label: "Calendar", icon: lucideIcons2.Calendar }
|
|
3080
|
-
];
|
|
3081
|
-
function ViewToggle({
|
|
3082
|
-
view,
|
|
3083
|
-
onChange
|
|
3084
|
-
}) {
|
|
3085
|
-
return /* @__PURE__ */ jsxRuntime.jsx(gui.XStack, { borderWidth: 1, borderColor: "$borderColor", rounded: "$4", overflow: "hidden", children: OPTIONS.map((o) => {
|
|
3086
|
-
const Icon = o.icon;
|
|
3087
|
-
const active = view === o.id;
|
|
3088
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
3089
|
-
gui.XStack,
|
|
3090
|
-
{
|
|
3091
|
-
items: "center",
|
|
3092
|
-
gap: "$2",
|
|
3093
|
-
px: "$3",
|
|
3094
|
-
py: "$2",
|
|
3095
|
-
cursor: "pointer",
|
|
3096
|
-
bg: active ? "$color4" : "transparent",
|
|
3097
|
-
hoverStyle: { bg: active ? "$color4" : "$color2" },
|
|
3098
|
-
onPress: () => onChange(o.id),
|
|
3099
|
-
children: [
|
|
3100
|
-
/* @__PURE__ */ jsxRuntime.jsx(Icon, { size: 14 }),
|
|
3101
|
-
/* @__PURE__ */ jsxRuntime.jsx(gui.Text, { fontSize: "$2", fontWeight: active ? "500" : "400", children: o.label })
|
|
3102
|
-
]
|
|
3103
|
-
},
|
|
3104
|
-
o.id
|
|
3105
|
-
);
|
|
3106
|
-
}) });
|
|
3107
|
-
}
|
|
3108
|
-
var POST_COLUMNS = [
|
|
3109
|
-
{ key: "content", header: "Post", render: (p) => postPreview(p.content) },
|
|
3110
|
-
{ key: "channel", header: "Channel", render: (p) => p.channel || "\u2014" },
|
|
3111
|
-
{ key: "status", header: "Status", render: (p) => /* @__PURE__ */ jsxRuntime.jsx(StatusTag, { status: p.status }) },
|
|
3112
|
-
{ key: "scheduleAt", header: "Scheduled", render: (p) => formatPostTime(p.scheduleAt) }
|
|
3113
|
-
];
|
|
3114
|
-
var ACCOUNT_COLUMNS = [
|
|
3115
|
-
{ key: "handle", header: "Account", render: (a) => a.handle || "\u2014" },
|
|
3116
|
-
{ key: "provider", header: "Network", render: (a) => a.provider || "\u2014" },
|
|
3117
|
-
{ key: "status", header: "Status", render: (a) => /* @__PURE__ */ jsxRuntime.jsx(StatusTag, { status: a.status }) }
|
|
3118
|
-
];
|
|
3119
|
-
function PostDetail({ api, post, onChanged }) {
|
|
3120
|
-
const [publishing, setPublishing] = react.useState(false);
|
|
3121
|
-
const [error, setError] = react.useState(null);
|
|
3122
|
-
const canPublish = post.status === "draft" || post.status === "scheduled" || post.status === "failed";
|
|
3123
|
-
const publish = async () => {
|
|
3124
|
-
setPublishing(true);
|
|
3125
|
-
setError(null);
|
|
3126
|
-
try {
|
|
3127
|
-
await api.posts.publish(post.id);
|
|
3128
|
-
onChanged();
|
|
3129
|
-
} catch (e) {
|
|
3130
|
-
setError(classifyBackend(e).message || "Publish failed.");
|
|
3131
|
-
} finally {
|
|
3132
|
-
setPublishing(false);
|
|
3133
|
-
}
|
|
3134
|
-
};
|
|
3135
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(gui.YStack, { gap: "$3", p: "$4", children: [
|
|
3136
|
-
/* @__PURE__ */ jsxRuntime.jsx(FieldRow, { label: "Content", children: /* @__PURE__ */ jsxRuntime.jsx(gui.Text, { fontSize: "$3", children: post.content || "\u2014" }) }),
|
|
3137
|
-
/* @__PURE__ */ jsxRuntime.jsx(FieldRow, { label: "Channel", children: /* @__PURE__ */ jsxRuntime.jsx(gui.Text, { fontSize: "$3", children: post.channel }) }),
|
|
3138
|
-
/* @__PURE__ */ jsxRuntime.jsx(FieldRow, { label: "Status", children: /* @__PURE__ */ jsxRuntime.jsx(StatusTag, { status: post.status }) }),
|
|
3139
|
-
post.scheduleAt > 0 ? /* @__PURE__ */ jsxRuntime.jsx(FieldRow, { label: "Scheduled", children: /* @__PURE__ */ jsxRuntime.jsx(gui.Text, { fontSize: "$3", children: formatPostTime(post.scheduleAt) }) }) : null,
|
|
3140
|
-
post.media.length > 0 ? /* @__PURE__ */ jsxRuntime.jsx(FieldRow, { label: "Media", children: /* @__PURE__ */ jsxRuntime.jsx(gui.YStack, { gap: "$1", children: post.media.map((m) => /* @__PURE__ */ jsxRuntime.jsx(gui.Text, { fontSize: "$2", color: "$color11", children: m }, m)) }) }) : null,
|
|
3141
|
-
post.externalId ? /* @__PURE__ */ jsxRuntime.jsx(FieldRow, { label: "External id", children: /* @__PURE__ */ jsxRuntime.jsx(gui.Text, { fontSize: "$3", className: "hz-tnum", children: post.externalId }) }) : null,
|
|
3142
|
-
post.error ? /* @__PURE__ */ jsxRuntime.jsx(FieldRow, { label: "Last error", children: /* @__PURE__ */ jsxRuntime.jsx(gui.Text, { fontSize: "$2", color: "$red10", children: post.error }) }) : null,
|
|
3143
|
-
error ? /* @__PURE__ */ jsxRuntime.jsx(gui.Text, { fontSize: "$2", color: "$red10", children: error }) : null,
|
|
3144
|
-
canPublish ? /* @__PURE__ */ jsxRuntime.jsx(PrimaryButton, { onPress: publish, disabled: publishing, icon: /* @__PURE__ */ jsxRuntime.jsx(lucideIcons2.Send, { size: 16 }), children: publishing ? "Publishing\u2026" : "Publish now" }) : null
|
|
3145
|
-
] });
|
|
3146
|
-
}
|
|
3147
|
-
function ConnectAccount({
|
|
3148
|
-
api,
|
|
3149
|
-
providers,
|
|
3150
|
-
onCreated
|
|
3151
|
-
}) {
|
|
3152
|
-
const [provider, setProvider] = react.useState("x");
|
|
3153
|
-
const [handle, setHandle] = react.useState("");
|
|
3154
|
-
const [saving, setSaving] = react.useState(false);
|
|
3155
|
-
const [error, setError] = react.useState(null);
|
|
3156
|
-
const submit = async () => {
|
|
3157
|
-
setSaving(true);
|
|
3158
|
-
setError(null);
|
|
3159
|
-
try {
|
|
3160
|
-
await api.accounts.create({ provider, handle: handle.trim(), status: "connected" });
|
|
3161
|
-
onCreated();
|
|
3162
|
-
} catch (e) {
|
|
3163
|
-
setError(classifyBackend(e).message || "Failed to connect account.");
|
|
3164
|
-
} finally {
|
|
3165
|
-
setSaving(false);
|
|
3166
|
-
}
|
|
3167
|
-
};
|
|
3168
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(gui.YStack, { gap: "$4", p: "$4", children: [
|
|
3169
|
-
/* @__PURE__ */ jsxRuntime.jsx(ProviderReadinessList, { providers }),
|
|
3170
|
-
/* @__PURE__ */ jsxRuntime.jsxs(gui.YStack, { gap: "$3", children: [
|
|
3171
|
-
/* @__PURE__ */ jsxRuntime.jsx(FieldRow, { label: "Network", children: /* @__PURE__ */ jsxRuntime.jsx(FieldSelect, { value: provider, options: [...PROVIDERS], onChange: setProvider, disabled: saving }) }),
|
|
3172
|
-
/* @__PURE__ */ jsxRuntime.jsx(FieldRow, { label: "Handle", children: /* @__PURE__ */ jsxRuntime.jsx(FieldText, { value: handle, onChange: setHandle, placeholder: "@hanzo", disabled: saving }) }),
|
|
3173
|
-
error ? /* @__PURE__ */ jsxRuntime.jsx(gui.Text, { fontSize: "$2", color: "$red10", children: error }) : null,
|
|
3174
|
-
/* @__PURE__ */ jsxRuntime.jsx(PrimaryButton, { onPress: submit, disabled: saving, children: saving ? "Connecting\u2026" : "Connect account" })
|
|
3175
|
-
] })
|
|
3176
|
-
] });
|
|
3177
|
-
}
|
|
3178
|
-
function SocialResource({
|
|
3179
|
-
api,
|
|
3180
|
-
title = "Publish",
|
|
3181
|
-
subtitle = "Compose, schedule and publish your content across networks \u2014 per org, over the native /v1/social engine."
|
|
3182
|
-
}) {
|
|
3183
|
-
const [state, setState] = react.useState({ phase: "loading" });
|
|
3184
|
-
const [view, setView] = react.useState("list");
|
|
3185
|
-
const [composing, setComposing] = react.useState(false);
|
|
3186
|
-
const [connecting, setConnecting] = react.useState(false);
|
|
3187
|
-
const [openPost, setOpenPost] = react.useState(null);
|
|
3188
|
-
const load = react.useCallback(async () => {
|
|
3189
|
-
setState({ phase: "loading" });
|
|
3190
|
-
try {
|
|
3191
|
-
const [summary, posts2, accounts2, providers2] = await Promise.all([
|
|
3192
|
-
api.summary(),
|
|
3193
|
-
api.posts.list(),
|
|
3194
|
-
api.accounts.list(),
|
|
3195
|
-
api.providers()
|
|
3196
|
-
]);
|
|
3197
|
-
setState({ phase: "ready", data: { summary, posts: posts2, accounts: accounts2, providers: providers2 } });
|
|
3198
|
-
} catch (e) {
|
|
3199
|
-
setState({ phase: "error", error: classifyBackend(e) });
|
|
3200
|
-
}
|
|
3201
|
-
}, [api]);
|
|
3202
|
-
react.useEffect(() => {
|
|
3203
|
-
void load();
|
|
3204
|
-
}, [load]);
|
|
3205
|
-
const providers = state.phase === "ready" ? state.data.providers : [];
|
|
3206
|
-
const posts = state.phase === "ready" ? state.data.posts : [];
|
|
3207
|
-
const accounts = state.phase === "ready" ? state.data.accounts : [];
|
|
3208
|
-
const empty = state.phase === "ready" && posts.length === 0 && accounts.length === 0;
|
|
3209
|
-
const submitDraft = async (draft, mode) => {
|
|
3210
|
-
try {
|
|
3211
|
-
const created = await api.posts.create(draft);
|
|
3212
|
-
if (mode === "now" && created.status === "failed") return created.error || "Publish failed.";
|
|
3213
|
-
} catch (e) {
|
|
3214
|
-
return classifyBackend(e).message || "Failed to create post.";
|
|
3215
|
-
}
|
|
3216
|
-
setComposing(false);
|
|
3217
|
-
void load();
|
|
3218
|
-
return null;
|
|
3219
|
-
};
|
|
3220
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(gui.YStack, { gap: "$4", p: "$4", children: [
|
|
3221
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3222
|
-
PageHeader,
|
|
3223
|
-
{
|
|
3224
|
-
title,
|
|
3225
|
-
subtitle,
|
|
3226
|
-
actions: /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
3227
|
-
/* @__PURE__ */ jsxRuntime.jsx(PrimaryButton, { onPress: () => setComposing(true), icon: /* @__PURE__ */ jsxRuntime.jsx(lucideIcons2.Plus, { size: 16 }), children: "New post" }),
|
|
3228
|
-
/* @__PURE__ */ jsxRuntime.jsx(PrimaryButton, { onPress: () => setConnecting(true), icon: /* @__PURE__ */ jsxRuntime.jsx(lucideIcons2.Link2, { size: 16 }), children: "Connect account" }),
|
|
3229
|
-
/* @__PURE__ */ jsxRuntime.jsx(PrimaryButton, { onPress: () => void load(), icon: /* @__PURE__ */ jsxRuntime.jsx(lucideIcons2.RefreshCw, { size: 16 }), children: "Refresh" })
|
|
3230
|
-
] })
|
|
3231
|
-
}
|
|
3232
|
-
),
|
|
3233
|
-
state.phase === "error" ? /* @__PURE__ */ jsxRuntime.jsx(BackendStateCard, { state: state.error, onRetry: () => void load() }) : empty ? /* @__PURE__ */ jsxRuntime.jsxs(gui.YStack, { gap: "$4", children: [
|
|
3234
|
-
state.phase === "ready" ? /* @__PURE__ */ jsxRuntime.jsx(SocialSummaryBar, { summary: state.data.summary }) : null,
|
|
3235
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3236
|
-
EmptyState,
|
|
3237
|
-
{
|
|
3238
|
-
icon: lucideIcons2.Share2,
|
|
3239
|
-
title: "No posts or accounts yet",
|
|
3240
|
-
description: "Connect a social account, then compose, schedule and publish across X, Instagram, LinkedIn, TikTok and more.",
|
|
3241
|
-
primary: { label: "New post", onPress: () => setComposing(true) }
|
|
3242
|
-
}
|
|
3243
|
-
)
|
|
3244
|
-
] }) : /* @__PURE__ */ jsxRuntime.jsxs(gui.YStack, { gap: "$5", children: [
|
|
3245
|
-
state.phase === "ready" ? /* @__PURE__ */ jsxRuntime.jsx(SocialSummaryBar, { summary: state.data.summary }) : null,
|
|
3246
|
-
/* @__PURE__ */ jsxRuntime.jsxs(gui.YStack, { gap: "$3", children: [
|
|
3247
|
-
/* @__PURE__ */ jsxRuntime.jsxs(gui.XStack, { items: "center", justify: "space-between", gap: "$2", flexWrap: "wrap", children: [
|
|
3248
|
-
/* @__PURE__ */ jsxRuntime.jsxs(gui.XStack, { items: "center", gap: "$2", children: [
|
|
3249
|
-
/* @__PURE__ */ jsxRuntime.jsx(lucideIcons2.Send, { size: 16 }),
|
|
3250
|
-
/* @__PURE__ */ jsxRuntime.jsx(gui.Text, { fontSize: "$5", fontWeight: "500", children: "Posts" })
|
|
3251
|
-
] }),
|
|
3252
|
-
/* @__PURE__ */ jsxRuntime.jsx(ViewToggle, { view, onChange: setView })
|
|
3253
|
-
] }),
|
|
3254
|
-
view === "list" ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
3255
|
-
DataTable,
|
|
3256
|
-
{
|
|
3257
|
-
columns: POST_COLUMNS,
|
|
3258
|
-
rows: posts,
|
|
3259
|
-
loading: state.phase === "loading",
|
|
3260
|
-
empty: "No posts yet.",
|
|
3261
|
-
rowKey: (p) => p.id,
|
|
3262
|
-
onRowPress: (p) => setOpenPost(p)
|
|
3263
|
-
}
|
|
3264
|
-
) : /* @__PURE__ */ jsxRuntime.jsx(PostAgenda, { posts, onOpen: (p) => setOpenPost(p) })
|
|
3265
|
-
] }),
|
|
3266
|
-
/* @__PURE__ */ jsxRuntime.jsxs(gui.YStack, { gap: "$2", children: [
|
|
3267
|
-
/* @__PURE__ */ jsxRuntime.jsxs(gui.XStack, { items: "center", gap: "$2", children: [
|
|
3268
|
-
/* @__PURE__ */ jsxRuntime.jsx(lucideIcons2.Link2, { size: 16 }),
|
|
3269
|
-
/* @__PURE__ */ jsxRuntime.jsx(gui.Text, { fontSize: "$5", fontWeight: "500", children: "Accounts" })
|
|
3270
|
-
] }),
|
|
3271
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3272
|
-
DataTable,
|
|
3273
|
-
{
|
|
3274
|
-
columns: ACCOUNT_COLUMNS,
|
|
3275
|
-
rows: accounts,
|
|
3276
|
-
loading: state.phase === "loading",
|
|
3277
|
-
empty: "No accounts connected yet.",
|
|
3278
|
-
rowKey: (a) => a.id
|
|
3279
|
-
}
|
|
3280
|
-
)
|
|
3281
|
-
] })
|
|
3282
|
-
] }),
|
|
3283
|
-
/* @__PURE__ */ jsxRuntime.jsx(SlideOver, { open: composing, onClose: () => setComposing(false), title: "New post", icon: lucideIcons2.Send, ariaLabel: "New post", children: /* @__PURE__ */ jsxRuntime.jsx(PostComposer, { channels: [...PROVIDERS], providers, onSubmit: submitDraft }) }),
|
|
3284
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3285
|
-
SlideOver,
|
|
3286
|
-
{
|
|
3287
|
-
open: connecting,
|
|
3288
|
-
onClose: () => setConnecting(false),
|
|
3289
|
-
title: "Connect account",
|
|
3290
|
-
icon: lucideIcons2.Link2,
|
|
3291
|
-
ariaLabel: "Connect account",
|
|
3292
|
-
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
3293
|
-
ConnectAccount,
|
|
3294
|
-
{
|
|
3295
|
-
api,
|
|
3296
|
-
providers,
|
|
3297
|
-
onCreated: () => {
|
|
3298
|
-
setConnecting(false);
|
|
3299
|
-
void load();
|
|
3300
|
-
}
|
|
3301
|
-
}
|
|
3302
|
-
)
|
|
3303
|
-
}
|
|
3304
|
-
),
|
|
3305
|
-
/* @__PURE__ */ jsxRuntime.jsx(SlideOver, { open: openPost !== null, onClose: () => setOpenPost(null), title: "Post", icon: lucideIcons2.Send, ariaLabel: "Post detail", children: openPost ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
3306
|
-
PostDetail,
|
|
3307
|
-
{
|
|
3308
|
-
api,
|
|
3309
|
-
post: openPost,
|
|
3310
|
-
onChanged: () => {
|
|
3311
|
-
setOpenPost(null);
|
|
3312
|
-
void load();
|
|
3313
|
-
}
|
|
3314
|
-
}
|
|
3315
|
-
) : null })
|
|
3316
|
-
] });
|
|
3317
|
-
}
|
|
3318
|
-
var META = {
|
|
3319
|
-
x: { label: "X", bg: "#0f0f12", fg: "#e6e6ea", mark: "\u{1D54F}" },
|
|
3320
|
-
facebook: { label: "Facebook", bg: "#1877f2", fg: "#ffffff", mark: "f" },
|
|
3321
|
-
instagram: { label: "Instagram", bg: "#e1306c", fg: "#ffffff", mark: "IG" },
|
|
3322
|
-
linkedin: { label: "LinkedIn", bg: "#0a66c2", fg: "#ffffff", mark: "in" },
|
|
3323
|
-
tiktok: { label: "TikTok", bg: "#111114", fg: "#25f4ee", mark: "TT" },
|
|
3324
|
-
youtube: { label: "YouTube", bg: "#ff0000", fg: "#ffffff", mark: "\u25B6" },
|
|
3325
|
-
threads: { label: "Threads", bg: "#111114", fg: "#e6e6ea", mark: "@" }
|
|
3326
|
-
};
|
|
3327
|
-
function ChannelBadge({
|
|
3328
|
-
channel,
|
|
3329
|
-
showLabel = false,
|
|
3330
|
-
size = 22
|
|
3331
|
-
}) {
|
|
3332
|
-
const m = META[channel] ?? META.x;
|
|
3333
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(gui.XStack, { items: "center", gap: "$2", children: [
|
|
3334
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3335
|
-
gui.YStack,
|
|
3336
|
-
{
|
|
3337
|
-
width: size,
|
|
3338
|
-
height: size,
|
|
3339
|
-
items: "center",
|
|
3340
|
-
justify: "center",
|
|
3341
|
-
rounded: "$2",
|
|
3342
|
-
bg: m.bg,
|
|
3343
|
-
children: /* @__PURE__ */ jsxRuntime.jsx(gui.Text, { fontSize: "$1", fontWeight: "800", color: m.fg, children: m.mark })
|
|
3344
|
-
}
|
|
3345
|
-
),
|
|
3346
|
-
showLabel ? /* @__PURE__ */ jsxRuntime.jsx(gui.Text, { fontSize: "$3", color: "$color12", children: m.label }) : null
|
|
3347
|
-
] });
|
|
3348
|
-
}
|
|
3349
|
-
var money = (cents) => `$${Math.round((cents || 0) / 100).toLocaleString()}`;
|
|
3350
|
-
function CampaignCard({ campaign }) {
|
|
3351
|
-
const pct = campaign.budget > 0 ? Math.min(100, campaign.spend / campaign.budget * 100) : 0;
|
|
3352
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(gui.Card, { p: "$4", gap: "$3", borderWidth: 1, borderColor: "$borderColor", width: "100%", children: [
|
|
3353
|
-
/* @__PURE__ */ jsxRuntime.jsxs(gui.XStack, { items: "flex-start", justify: "space-between", gap: "$2", children: [
|
|
3354
|
-
/* @__PURE__ */ jsxRuntime.jsxs(gui.YStack, { gap: "$1", children: [
|
|
3355
|
-
/* @__PURE__ */ jsxRuntime.jsx(gui.Text, { fontSize: "$4", fontWeight: "700", children: campaign.name }),
|
|
3356
|
-
/* @__PURE__ */ jsxRuntime.jsx(gui.Text, { fontSize: "$2", color: "$color11", children: campaign.channel })
|
|
3357
|
-
] }),
|
|
3358
|
-
/* @__PURE__ */ jsxRuntime.jsx(StatusTag, { status: campaign.status })
|
|
3359
|
-
] }),
|
|
3360
|
-
campaign.objective ? /* @__PURE__ */ jsxRuntime.jsx(gui.Text, { fontSize: "$2", color: "$color11", children: campaign.objective }) : null,
|
|
3361
|
-
/* @__PURE__ */ jsxRuntime.jsxs(gui.YStack, { gap: "$1.5", children: [
|
|
3362
|
-
/* @__PURE__ */ jsxRuntime.jsxs(gui.XStack, { justify: "space-between", children: [
|
|
3363
|
-
/* @__PURE__ */ jsxRuntime.jsxs(gui.Text, { fontSize: "$1", color: "$color11", children: [
|
|
3364
|
-
money(campaign.spend),
|
|
3365
|
-
" spent"
|
|
3366
|
-
] }),
|
|
3367
|
-
/* @__PURE__ */ jsxRuntime.jsxs(gui.Text, { fontSize: "$1", color: "$color11", children: [
|
|
3368
|
-
money(campaign.budget),
|
|
3369
|
-
" budget"
|
|
3370
|
-
] })
|
|
3371
|
-
] }),
|
|
3372
|
-
/* @__PURE__ */ jsxRuntime.jsx(gui.YStack, { height: 6, rounded: "$2", bg: "$color3", overflow: "hidden", children: /* @__PURE__ */ jsxRuntime.jsx(gui.YStack, { height: 6, rounded: "$2", bg: "$color9", width: `${pct}%` }) })
|
|
3373
|
-
] })
|
|
3374
|
-
] });
|
|
3375
|
-
}
|
|
3376
|
-
function PostCard({
|
|
3377
|
-
post,
|
|
3378
|
-
onEdit,
|
|
3379
|
-
onDelete
|
|
3380
|
-
}) {
|
|
3381
|
-
const mediaCount = post.media?.length ?? 0;
|
|
3382
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(gui.Card, { p: "$3", gap: "$2.5", borderWidth: 1, borderColor: "$borderColor", width: "100%", children: [
|
|
3383
|
-
/* @__PURE__ */ jsxRuntime.jsxs(gui.XStack, { items: "center", justify: "space-between", gap: "$2", children: [
|
|
3384
|
-
/* @__PURE__ */ jsxRuntime.jsxs(gui.XStack, { items: "center", gap: "$2", children: [
|
|
3385
|
-
/* @__PURE__ */ jsxRuntime.jsx(ChannelBadge, { channel: post.channel }),
|
|
3386
|
-
/* @__PURE__ */ jsxRuntime.jsx(StatusTag, { status: post.status })
|
|
3387
|
-
] }),
|
|
3388
|
-
/* @__PURE__ */ jsxRuntime.jsxs(gui.XStack, { gap: "$1", children: [
|
|
3389
|
-
onEdit ? /* @__PURE__ */ jsxRuntime.jsx(gui.Button, { size: "$2", chromeless: true, icon: /* @__PURE__ */ jsxRuntime.jsx(lucideIcons2.Pencil, { size: 15 }), onPress: () => onEdit(post) }) : null,
|
|
3390
|
-
onDelete ? /* @__PURE__ */ jsxRuntime.jsx(gui.Button, { size: "$2", chromeless: true, icon: /* @__PURE__ */ jsxRuntime.jsx(lucideIcons2.Trash2, { size: 15 }), onPress: () => onDelete(post) }) : null
|
|
3391
|
-
] })
|
|
3392
|
-
] }),
|
|
3393
|
-
/* @__PURE__ */ jsxRuntime.jsx(gui.Text, { fontSize: "$3", color: "$color12", children: post.content }),
|
|
3394
|
-
/* @__PURE__ */ jsxRuntime.jsxs(gui.XStack, { items: "center", justify: "space-between", gap: "$2", children: [
|
|
3395
|
-
post.scheduleAt ? /* @__PURE__ */ jsxRuntime.jsx(gui.Text, { fontSize: "$1", color: "$color11", children: formatPostTime(post.scheduleAt) }) : /* @__PURE__ */ jsxRuntime.jsx(gui.YStack, {}),
|
|
3396
|
-
mediaCount ? /* @__PURE__ */ jsxRuntime.jsxs(gui.Text, { fontSize: "$1", color: "$color10", children: [
|
|
3397
|
-
mediaCount,
|
|
3398
|
-
" media"
|
|
3399
|
-
] }) : null
|
|
3400
|
-
] })
|
|
3401
|
-
] });
|
|
3402
|
-
}
|
|
3403
|
-
|
|
3404
2186
|
Object.defineProperty(exports, "AgnosticThemeToggle", {
|
|
3405
2187
|
enumerable: true,
|
|
3406
2188
|
get: function () { return chunkYBXVUV7P_cjs.AgnosticThemeToggle; }
|
|
@@ -3413,46 +2195,232 @@ Object.defineProperty(exports, "ThemeToggleNext", {
|
|
|
3413
2195
|
enumerable: true,
|
|
3414
2196
|
get: function () { return chunkYBXVUV7P_cjs.ThemeToggleNext; }
|
|
3415
2197
|
});
|
|
2198
|
+
Object.defineProperty(exports, "BackendStateCard", {
|
|
2199
|
+
enumerable: true,
|
|
2200
|
+
get: function () { return chunk5MBAHVEO_cjs.BackendStateCard; }
|
|
2201
|
+
});
|
|
2202
|
+
Object.defineProperty(exports, "COMPOSE_MODES", {
|
|
2203
|
+
enumerable: true,
|
|
2204
|
+
get: function () { return chunk5MBAHVEO_cjs.COMPOSE_MODES; }
|
|
2205
|
+
});
|
|
2206
|
+
Object.defineProperty(exports, "CampaignCard", {
|
|
2207
|
+
enumerable: true,
|
|
2208
|
+
get: function () { return chunk5MBAHVEO_cjs.CampaignCard; }
|
|
2209
|
+
});
|
|
2210
|
+
Object.defineProperty(exports, "ChannelBadge", {
|
|
2211
|
+
enumerable: true,
|
|
2212
|
+
get: function () { return chunk5MBAHVEO_cjs.ChannelBadge; }
|
|
2213
|
+
});
|
|
2214
|
+
Object.defineProperty(exports, "DataTable", {
|
|
2215
|
+
enumerable: true,
|
|
2216
|
+
get: function () { return chunk5MBAHVEO_cjs.DataTable; }
|
|
2217
|
+
});
|
|
2218
|
+
Object.defineProperty(exports, "EmptyState", {
|
|
2219
|
+
enumerable: true,
|
|
2220
|
+
get: function () { return chunk5MBAHVEO_cjs.EmptyState; }
|
|
2221
|
+
});
|
|
2222
|
+
Object.defineProperty(exports, "FieldRow", {
|
|
2223
|
+
enumerable: true,
|
|
2224
|
+
get: function () { return chunk5MBAHVEO_cjs.FieldRow; }
|
|
2225
|
+
});
|
|
2226
|
+
Object.defineProperty(exports, "FieldSelect", {
|
|
2227
|
+
enumerable: true,
|
|
2228
|
+
get: function () { return chunk5MBAHVEO_cjs.FieldSelect; }
|
|
2229
|
+
});
|
|
2230
|
+
Object.defineProperty(exports, "FieldSlider", {
|
|
2231
|
+
enumerable: true,
|
|
2232
|
+
get: function () { return chunk5MBAHVEO_cjs.FieldSlider; }
|
|
2233
|
+
});
|
|
2234
|
+
Object.defineProperty(exports, "FieldSwitch", {
|
|
2235
|
+
enumerable: true,
|
|
2236
|
+
get: function () { return chunk5MBAHVEO_cjs.FieldSwitch; }
|
|
2237
|
+
});
|
|
2238
|
+
Object.defineProperty(exports, "FieldText", {
|
|
2239
|
+
enumerable: true,
|
|
2240
|
+
get: function () { return chunk5MBAHVEO_cjs.FieldText; }
|
|
2241
|
+
});
|
|
2242
|
+
Object.defineProperty(exports, "FieldTextArea", {
|
|
2243
|
+
enumerable: true,
|
|
2244
|
+
get: function () { return chunk5MBAHVEO_cjs.FieldTextArea; }
|
|
2245
|
+
});
|
|
2246
|
+
Object.defineProperty(exports, "HostProvider", {
|
|
2247
|
+
enumerable: true,
|
|
2248
|
+
get: function () { return chunk5MBAHVEO_cjs.HostProvider; }
|
|
2249
|
+
});
|
|
2250
|
+
Object.defineProperty(exports, "PageHeader", {
|
|
2251
|
+
enumerable: true,
|
|
2252
|
+
get: function () { return chunk5MBAHVEO_cjs.PageHeader; }
|
|
2253
|
+
});
|
|
2254
|
+
Object.defineProperty(exports, "PostAgenda", {
|
|
2255
|
+
enumerable: true,
|
|
2256
|
+
get: function () { return chunk5MBAHVEO_cjs.PostAgenda; }
|
|
2257
|
+
});
|
|
2258
|
+
Object.defineProperty(exports, "PostCard", {
|
|
2259
|
+
enumerable: true,
|
|
2260
|
+
get: function () { return chunk5MBAHVEO_cjs.PostCard; }
|
|
2261
|
+
});
|
|
2262
|
+
Object.defineProperty(exports, "PostComposer", {
|
|
2263
|
+
enumerable: true,
|
|
2264
|
+
get: function () { return chunk5MBAHVEO_cjs.PostComposer; }
|
|
2265
|
+
});
|
|
2266
|
+
Object.defineProperty(exports, "PrimaryButton", {
|
|
2267
|
+
enumerable: true,
|
|
2268
|
+
get: function () { return chunk5MBAHVEO_cjs.PrimaryButton; }
|
|
2269
|
+
});
|
|
2270
|
+
Object.defineProperty(exports, "ProviderReadinessList", {
|
|
2271
|
+
enumerable: true,
|
|
2272
|
+
get: function () { return chunk5MBAHVEO_cjs.ProviderReadinessList; }
|
|
2273
|
+
});
|
|
2274
|
+
Object.defineProperty(exports, "SLIDEOVER_LG", {
|
|
2275
|
+
enumerable: true,
|
|
2276
|
+
get: function () { return chunk5MBAHVEO_cjs.LG; }
|
|
2277
|
+
});
|
|
2278
|
+
Object.defineProperty(exports, "SlideOver", {
|
|
2279
|
+
enumerable: true,
|
|
2280
|
+
get: function () { return chunk5MBAHVEO_cjs.SlideOver; }
|
|
2281
|
+
});
|
|
2282
|
+
Object.defineProperty(exports, "SocialResource", {
|
|
2283
|
+
enumerable: true,
|
|
2284
|
+
get: function () { return chunk5MBAHVEO_cjs.SocialResource; }
|
|
2285
|
+
});
|
|
2286
|
+
Object.defineProperty(exports, "SocialSummaryBar", {
|
|
2287
|
+
enumerable: true,
|
|
2288
|
+
get: function () { return chunk5MBAHVEO_cjs.SocialSummaryBar; }
|
|
2289
|
+
});
|
|
2290
|
+
Object.defineProperty(exports, "StatusTag", {
|
|
2291
|
+
enumerable: true,
|
|
2292
|
+
get: function () { return chunk5MBAHVEO_cjs.StatusTag; }
|
|
2293
|
+
});
|
|
2294
|
+
Object.defineProperty(exports, "ViewToggle", {
|
|
2295
|
+
enumerable: true,
|
|
2296
|
+
get: function () { return chunk5MBAHVEO_cjs.ViewToggle; }
|
|
2297
|
+
});
|
|
2298
|
+
Object.defineProperty(exports, "accentFor", {
|
|
2299
|
+
enumerable: true,
|
|
2300
|
+
get: function () { return chunk5MBAHVEO_cjs.accentFor; }
|
|
2301
|
+
});
|
|
2302
|
+
Object.defineProperty(exports, "asColor", {
|
|
2303
|
+
enumerable: true,
|
|
2304
|
+
get: function () { return chunk5MBAHVEO_cjs.asColor; }
|
|
2305
|
+
});
|
|
2306
|
+
Object.defineProperty(exports, "classifyBackend", {
|
|
2307
|
+
enumerable: true,
|
|
2308
|
+
get: function () { return chunk5MBAHVEO_cjs.classifyBackend; }
|
|
2309
|
+
});
|
|
2310
|
+
Object.defineProperty(exports, "classifyRead", {
|
|
2311
|
+
enumerable: true,
|
|
2312
|
+
get: function () { return chunk5MBAHVEO_cjs.classifyRead; }
|
|
2313
|
+
});
|
|
2314
|
+
Object.defineProperty(exports, "contrastText", {
|
|
2315
|
+
enumerable: true,
|
|
2316
|
+
get: function () { return chunk5MBAHVEO_cjs.contrastText; }
|
|
2317
|
+
});
|
|
2318
|
+
Object.defineProperty(exports, "formatPostTime", {
|
|
2319
|
+
enumerable: true,
|
|
2320
|
+
get: function () { return chunk5MBAHVEO_cjs.formatPostTime; }
|
|
2321
|
+
});
|
|
2322
|
+
Object.defineProperty(exports, "isHexColor", {
|
|
2323
|
+
enumerable: true,
|
|
2324
|
+
get: function () { return chunk5MBAHVEO_cjs.isHexColor; }
|
|
2325
|
+
});
|
|
2326
|
+
Object.defineProperty(exports, "parsePostTime", {
|
|
2327
|
+
enumerable: true,
|
|
2328
|
+
get: function () { return chunk5MBAHVEO_cjs.parsePostTime; }
|
|
2329
|
+
});
|
|
2330
|
+
Object.defineProperty(exports, "postDayBucket", {
|
|
2331
|
+
enumerable: true,
|
|
2332
|
+
get: function () { return chunk5MBAHVEO_cjs.postDayBucket; }
|
|
2333
|
+
});
|
|
2334
|
+
Object.defineProperty(exports, "postPreview", {
|
|
2335
|
+
enumerable: true,
|
|
2336
|
+
get: function () { return chunk5MBAHVEO_cjs.postPreview; }
|
|
2337
|
+
});
|
|
2338
|
+
Object.defineProperty(exports, "resolveAccent", {
|
|
2339
|
+
enumerable: true,
|
|
2340
|
+
get: function () { return chunk5MBAHVEO_cjs.resolveAccent; }
|
|
2341
|
+
});
|
|
2342
|
+
Object.defineProperty(exports, "setOrgAccent", {
|
|
2343
|
+
enumerable: true,
|
|
2344
|
+
get: function () { return chunk5MBAHVEO_cjs.setOrgAccent; }
|
|
2345
|
+
});
|
|
2346
|
+
Object.defineProperty(exports, "useAccent", {
|
|
2347
|
+
enumerable: true,
|
|
2348
|
+
get: function () { return chunk5MBAHVEO_cjs.useAccent; }
|
|
2349
|
+
});
|
|
2350
|
+
Object.defineProperty(exports, "useHost", {
|
|
2351
|
+
enumerable: true,
|
|
2352
|
+
get: function () { return chunk5MBAHVEO_cjs.useHost; }
|
|
2353
|
+
});
|
|
2354
|
+
Object.defineProperty(exports, "ACCOUNT_STATUSES", {
|
|
2355
|
+
enumerable: true,
|
|
2356
|
+
get: function () { return chunkMWBFAV3D_cjs.ACCOUNT_STATUSES; }
|
|
2357
|
+
});
|
|
2358
|
+
Object.defineProperty(exports, "POST_STATUSES", {
|
|
2359
|
+
enumerable: true,
|
|
2360
|
+
get: function () { return chunkMWBFAV3D_cjs.POST_STATUSES; }
|
|
2361
|
+
});
|
|
2362
|
+
Object.defineProperty(exports, "PROVIDERS", {
|
|
2363
|
+
enumerable: true,
|
|
2364
|
+
get: function () { return chunkMWBFAV3D_cjs.PROVIDERS; }
|
|
2365
|
+
});
|
|
2366
|
+
Object.defineProperty(exports, "createSocialApi", {
|
|
2367
|
+
enumerable: true,
|
|
2368
|
+
get: function () { return chunkMWBFAV3D_cjs.createSocialApi; }
|
|
2369
|
+
});
|
|
2370
|
+
Object.defineProperty(exports, "normalizeAccount", {
|
|
2371
|
+
enumerable: true,
|
|
2372
|
+
get: function () { return chunkMWBFAV3D_cjs.normalizeAccount; }
|
|
2373
|
+
});
|
|
2374
|
+
Object.defineProperty(exports, "normalizeAccounts", {
|
|
2375
|
+
enumerable: true,
|
|
2376
|
+
get: function () { return chunkMWBFAV3D_cjs.normalizeAccounts; }
|
|
2377
|
+
});
|
|
2378
|
+
Object.defineProperty(exports, "normalizePost", {
|
|
2379
|
+
enumerable: true,
|
|
2380
|
+
get: function () { return chunkMWBFAV3D_cjs.normalizePost; }
|
|
2381
|
+
});
|
|
2382
|
+
Object.defineProperty(exports, "normalizePosts", {
|
|
2383
|
+
enumerable: true,
|
|
2384
|
+
get: function () { return chunkMWBFAV3D_cjs.normalizePosts; }
|
|
2385
|
+
});
|
|
2386
|
+
Object.defineProperty(exports, "normalizeProviderCapability", {
|
|
2387
|
+
enumerable: true,
|
|
2388
|
+
get: function () { return chunkMWBFAV3D_cjs.normalizeProviderCapability; }
|
|
2389
|
+
});
|
|
2390
|
+
Object.defineProperty(exports, "normalizeProviders", {
|
|
2391
|
+
enumerable: true,
|
|
2392
|
+
get: function () { return chunkMWBFAV3D_cjs.normalizeProviders; }
|
|
2393
|
+
});
|
|
2394
|
+
Object.defineProperty(exports, "normalizeSummary", {
|
|
2395
|
+
enumerable: true,
|
|
2396
|
+
get: function () { return chunkMWBFAV3D_cjs.normalizeSummary; }
|
|
2397
|
+
});
|
|
3416
2398
|
Object.defineProperty(exports, "CustomModelMark", {
|
|
3417
2399
|
enumerable: true,
|
|
3418
2400
|
get: function () { return lucideIcons2.Boxes; }
|
|
3419
2401
|
});
|
|
3420
|
-
exports.ACCOUNT_STATUSES = ACCOUNT_STATUSES;
|
|
3421
2402
|
exports.AnimatedLogo = AnimatedLogo;
|
|
3422
2403
|
exports.AppHeader = AppHeader;
|
|
3423
2404
|
exports.BRANDS = BRANDS;
|
|
3424
|
-
exports.BackendStateCard = BackendStateCard;
|
|
3425
2405
|
exports.BarChart = BarChart;
|
|
3426
2406
|
exports.BarRows = BarRows;
|
|
3427
2407
|
exports.BrandMark = BrandMark;
|
|
3428
2408
|
exports.CHART_OTHER = CHART_OTHER;
|
|
3429
2409
|
exports.CHART_PALETTE = CHART_PALETTE;
|
|
3430
|
-
exports.COMPOSE_MODES = COMPOSE_MODES;
|
|
3431
|
-
exports.CampaignCard = CampaignCard;
|
|
3432
|
-
exports.ChannelBadge = ChannelBadge;
|
|
3433
2410
|
exports.ComboBox = ComboBox;
|
|
3434
2411
|
exports.CommerceResource = CommerceResource;
|
|
3435
2412
|
exports.ConfirmDelete = ConfirmDelete;
|
|
3436
2413
|
exports.ContextMenu = ContextMenu;
|
|
3437
|
-
exports.DataTable = DataTable;
|
|
3438
2414
|
exports.Donut = Donut;
|
|
3439
2415
|
exports.DonutRing = Donut2;
|
|
3440
2416
|
exports.DropdownMenu = DropdownMenu;
|
|
3441
|
-
exports.EmptyState = EmptyState;
|
|
3442
2417
|
exports.FadeIn = FadeIn;
|
|
3443
|
-
exports.FieldRow = FieldRow;
|
|
3444
|
-
exports.FieldSelect = FieldSelect;
|
|
3445
|
-
exports.FieldSlider = FieldSlider;
|
|
3446
|
-
exports.FieldSwitch = FieldSwitch;
|
|
3447
|
-
exports.FieldText = FieldText;
|
|
3448
|
-
exports.FieldTextArea = FieldTextArea;
|
|
3449
2418
|
exports.FloatingMenu = FloatingMenu;
|
|
3450
2419
|
exports.GenericLogo = GenericLogo;
|
|
3451
2420
|
exports.HANZO = HANZO;
|
|
3452
2421
|
exports.HANZO_MARK_CONTENT = HANZO_MARK_CONTENT;
|
|
3453
2422
|
exports.HanzoMark = HanzoMark;
|
|
3454
2423
|
exports.HintButton = HintButton;
|
|
3455
|
-
exports.HostProvider = HostProvider;
|
|
3456
2424
|
exports.LUX = LUX;
|
|
3457
2425
|
exports.LegendDot = LegendDot;
|
|
3458
2426
|
exports.LineChart = LineChart;
|
|
@@ -3466,71 +2434,35 @@ exports.MiniBars = MiniBars;
|
|
|
3466
2434
|
exports.OrgMark = OrgMark;
|
|
3467
2435
|
exports.OrgSwitcher = OrgSwitcher;
|
|
3468
2436
|
exports.PARS = PARS;
|
|
3469
|
-
exports.POST_STATUSES = POST_STATUSES;
|
|
3470
|
-
exports.PROVIDERS = PROVIDERS;
|
|
3471
|
-
exports.PageHeader = PageHeader;
|
|
3472
2437
|
exports.Panel = Panel;
|
|
3473
2438
|
exports.PortalTheme = PortalTheme;
|
|
3474
|
-
exports.PostAgenda = PostAgenda;
|
|
3475
|
-
exports.PostCard = PostCard;
|
|
3476
|
-
exports.PostComposer = PostComposer;
|
|
3477
|
-
exports.PrimaryButton = PrimaryButton;
|
|
3478
2439
|
exports.ProductIcon = ProductIcon;
|
|
3479
2440
|
exports.ProviderLogo = ProviderLogo;
|
|
3480
|
-
exports.ProviderReadinessList = ProviderReadinessList;
|
|
3481
2441
|
exports.Reorder = Reorder;
|
|
3482
2442
|
exports.SERIES = SERIES;
|
|
3483
|
-
exports.SLIDEOVER_LG = LG;
|
|
3484
2443
|
exports.SURFACES = SURFACES;
|
|
3485
2444
|
exports.SearchInput = SearchInput;
|
|
3486
2445
|
exports.Segmented = Segmented;
|
|
3487
2446
|
exports.SelectMenu = SelectMenu;
|
|
3488
2447
|
exports.SiteFooter = SiteFooter;
|
|
3489
2448
|
exports.SiteNav = SiteNav;
|
|
3490
|
-
exports.SlideOver = SlideOver;
|
|
3491
|
-
exports.SocialResource = SocialResource;
|
|
3492
|
-
exports.SocialSummaryBar = SocialSummaryBar;
|
|
3493
2449
|
exports.Sparkline = Sparkline;
|
|
3494
|
-
exports.StatusTag = StatusTag;
|
|
3495
2450
|
exports.ToastProvider = ToastProvider;
|
|
3496
2451
|
exports.UtilBar = UtilBar;
|
|
3497
|
-
exports.ViewToggle = ViewToggle;
|
|
3498
2452
|
exports.ZOO = ZOO;
|
|
3499
|
-
exports.accentFor = accentFor;
|
|
3500
|
-
exports.asColor = asColor;
|
|
3501
|
-
exports.classifyBackend = classifyBackend;
|
|
3502
|
-
exports.classifyRead = classifyRead;
|
|
3503
2453
|
exports.colorForIndex = colorForIndex;
|
|
3504
|
-
exports.contrastText = contrastText;
|
|
3505
|
-
exports.createSocialApi = createSocialApi;
|
|
3506
2454
|
exports.filterOptions = filterOptions;
|
|
3507
2455
|
exports.filterOrgs = filterOrgs;
|
|
3508
|
-
exports.formatPostTime = formatPostTime;
|
|
3509
|
-
exports.isHexColor = isHexColor;
|
|
3510
2456
|
exports.isKnownOption = isKnownOption;
|
|
3511
2457
|
exports.monogram = monogram;
|
|
3512
|
-
exports.normalizeAccount = normalizeAccount;
|
|
3513
|
-
exports.normalizeAccounts = normalizeAccounts;
|
|
3514
|
-
exports.normalizePost = normalizePost;
|
|
3515
|
-
exports.normalizePosts = normalizePosts;
|
|
3516
|
-
exports.normalizeProviderCapability = normalizeProviderCapability;
|
|
3517
|
-
exports.normalizeProviders = normalizeProviders;
|
|
3518
|
-
exports.normalizeSummary = normalizeSummary;
|
|
3519
2458
|
exports.orgScope = orgScope;
|
|
3520
2459
|
exports.otherSurfaces = otherSurfaces;
|
|
3521
|
-
exports.parsePostTime = parsePostTime;
|
|
3522
|
-
exports.postDayBucket = postDayBucket;
|
|
3523
|
-
exports.postPreview = postPreview;
|
|
3524
2460
|
exports.providerInitials = providerInitials;
|
|
3525
2461
|
exports.renderMenuItems = renderMenuItems;
|
|
3526
|
-
exports.resolveAccent = resolveAccent;
|
|
3527
2462
|
exports.resolveBrand = resolveBrand;
|
|
3528
2463
|
exports.rowShift = rowShift;
|
|
3529
|
-
exports.setOrgAccent = setOrgAccent;
|
|
3530
2464
|
exports.targetIndex = targetIndex;
|
|
3531
|
-
exports.useAccent = useAccent;
|
|
3532
2465
|
exports.useContainerWidth = useContainerWidth;
|
|
3533
|
-
exports.useHost = useHost;
|
|
3534
2466
|
exports.useToast = useToast;
|
|
3535
2467
|
exports.utilColor = utilColor;
|
|
3536
2468
|
//# sourceMappingURL=index.cjs.map
|