@burdenoff/microfe-subscriberbot 2026.626.2 → 2026.629.1
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/index.js +4 -4
- package/dist/subscriberbot/SubscriberBotRoot.js +61 -133
- package/dist/subscriberbot/SubscriberBotRoot.js.map +1 -1
- package/dist/subscriberbot/SubscriberBotRoutes.js +56 -187
- package/dist/subscriberbot/SubscriberBotRoutes.js.map +1 -1
- package/dist/subscriberbot/components/StateViews.js +49 -0
- package/dist/subscriberbot/components/StateViews.js.map +1 -0
- package/dist/subscriberbot/components/StatusBadge.js +45 -47
- package/dist/subscriberbot/components/StatusBadge.js.map +1 -1
- package/dist/subscriberbot/context/SubscriberBotContext.js +22 -30
- package/dist/subscriberbot/context/SubscriberBotContext.js.map +1 -1
- package/dist/subscriberbot/hooks/useSubscriberBotApi.js +342 -195
- package/dist/subscriberbot/hooks/useSubscriberBotApi.js.map +1 -1
- package/dist/subscriberbot/index.js +1 -1
- package/dist/subscriberbot/pages/DashboardPage.js +269 -0
- package/dist/subscriberbot/pages/DashboardPage.js.map +1 -0
- package/dist/subscriberbot/pages/InboxPage.js +186 -0
- package/dist/subscriberbot/pages/InboxPage.js.map +1 -0
- package/dist/subscriberbot/pages/InvoicesPage.js +211 -0
- package/dist/subscriberbot/pages/InvoicesPage.js.map +1 -0
- package/dist/subscriberbot/pages/WorkflowsPage.js +236 -0
- package/dist/subscriberbot/pages/WorkflowsPage.js.map +1 -0
- package/dist/subscriberbot/pages/agents/AgentDetailPage.js +160 -0
- package/dist/subscriberbot/pages/agents/AgentDetailPage.js.map +1 -0
- package/dist/subscriberbot/pages/agents/AgentNewPage.js +140 -0
- package/dist/subscriberbot/pages/agents/AgentNewPage.js.map +1 -0
- package/dist/subscriberbot/pages/agents/AgentsListPage.js +178 -0
- package/dist/subscriberbot/pages/agents/AgentsListPage.js.map +1 -0
- package/dist/subscriberbot/pages/providers/ProviderDetailPage.js +179 -0
- package/dist/subscriberbot/pages/providers/ProviderDetailPage.js.map +1 -0
- package/dist/subscriberbot/pages/providers/ProviderNewPage.js +185 -0
- package/dist/subscriberbot/pages/providers/ProviderNewPage.js.map +1 -0
- package/dist/subscriberbot/pages/providers/ProvidersListPage.js +254 -0
- package/dist/subscriberbot/pages/providers/ProvidersListPage.js.map +1 -0
- package/dist/subscriberbot/pages/relationships/RelationshipDetailPage.js +306 -0
- package/dist/subscriberbot/pages/relationships/RelationshipDetailPage.js.map +1 -0
- package/dist/subscriberbot/pages/relationships/RelationshipNewPage.js +253 -0
- package/dist/subscriberbot/pages/relationships/RelationshipNewPage.js.map +1 -0
- package/dist/subscriberbot/pages/relationships/RelationshipsListPage.js +248 -0
- package/dist/subscriberbot/pages/relationships/RelationshipsListPage.js.map +1 -0
- package/dist/subscriberbot/utils/formatters.js +50 -32
- package/dist/subscriberbot/utils/formatters.js.map +1 -1
- package/package.json +1 -1
- package/dist/subscriberbot/components/InvestmentCard.js +0 -97
- package/dist/subscriberbot/components/InvestmentCard.js.map +0 -1
- package/dist/subscriberbot/components/RatingDisplay.js +0 -35
- package/dist/subscriberbot/components/RatingDisplay.js.map +0 -1
- package/dist/subscriberbot/mocks/data.js +0 -1517
- package/dist/subscriberbot/mocks/data.js.map +0 -1
- package/dist/subscriberbot/mocks/users.js +0 -34
- package/dist/subscriberbot/mocks/users.js.map +0 -1
- package/dist/subscriberbot/pages/HomePage.js +0 -930
- package/dist/subscriberbot/pages/HomePage.js.map +0 -1
- package/dist/subscriberbot/pages/admin/AdminAnalyticsPage.js +0 -651
- package/dist/subscriberbot/pages/admin/AdminAnalyticsPage.js.map +0 -1
- package/dist/subscriberbot/pages/admin/AdminDashboard.js +0 -679
- package/dist/subscriberbot/pages/admin/AdminDashboard.js.map +0 -1
- package/dist/subscriberbot/pages/admin/AdminFinancialPage.js +0 -427
- package/dist/subscriberbot/pages/admin/AdminFinancialPage.js.map +0 -1
- package/dist/subscriberbot/pages/admin/AdminOrdersPage.js +0 -665
- package/dist/subscriberbot/pages/admin/AdminOrdersPage.js.map +0 -1
- package/dist/subscriberbot/pages/admin/AdminProfilePage.js +0 -261
- package/dist/subscriberbot/pages/admin/AdminProfilePage.js.map +0 -1
- package/dist/subscriberbot/pages/admin/AdminSettingsPage.js +0 -654
- package/dist/subscriberbot/pages/admin/AdminSettingsPage.js.map +0 -1
- package/dist/subscriberbot/pages/admin/CartManagementPage.js +0 -874
- package/dist/subscriberbot/pages/admin/CartManagementPage.js.map +0 -1
- package/dist/subscriberbot/pages/admin/UserManagementPage.js +0 -898
- package/dist/subscriberbot/pages/admin/UserManagementPage.js.map +0 -1
- package/dist/subscriberbot/pages/cart-owner/AnalyticsDashboard.js +0 -839
- package/dist/subscriberbot/pages/cart-owner/AnalyticsDashboard.js.map +0 -1
- package/dist/subscriberbot/pages/cart-owner/BusinessSettingsPage.js +0 -705
- package/dist/subscriberbot/pages/cart-owner/BusinessSettingsPage.js.map +0 -1
- package/dist/subscriberbot/pages/cart-owner/CartOwnerDashboard.js +0 -802
- package/dist/subscriberbot/pages/cart-owner/CartOwnerDashboard.js.map +0 -1
- package/dist/subscriberbot/pages/cart-owner/CartOwnerProfilePage.js +0 -891
- package/dist/subscriberbot/pages/cart-owner/CartOwnerProfilePage.js.map +0 -1
- package/dist/subscriberbot/pages/cart-owner/CartServiceConfigPage.js +0 -633
- package/dist/subscriberbot/pages/cart-owner/CartServiceConfigPage.js.map +0 -1
- package/dist/subscriberbot/pages/cart-owner/InventoryManagementPage.js +0 -910
- package/dist/subscriberbot/pages/cart-owner/InventoryManagementPage.js.map +0 -1
- package/dist/subscriberbot/pages/cart-owner/OrderManagementPage.js +0 -879
- package/dist/subscriberbot/pages/cart-owner/OrderManagementPage.js.map +0 -1
- package/dist/subscriberbot/pages/cart-owner/StaffManagementPage.js +0 -838
- package/dist/subscriberbot/pages/cart-owner/StaffManagementPage.js.map +0 -1
- package/dist/subscriberbot/pages/common/HelpSupportPage.js +0 -1323
- package/dist/subscriberbot/pages/common/HelpSupportPage.js.map +0 -1
- package/dist/subscriberbot/pages/common/NotificationCenterPage.js +0 -672
- package/dist/subscriberbot/pages/common/NotificationCenterPage.js.map +0 -1
- package/dist/subscriberbot/pages/common/SettingsPage.js +0 -973
- package/dist/subscriberbot/pages/common/SettingsPage.js.map +0 -1
- package/dist/subscriberbot/pages/customer/BookingDetailsPage.js +0 -626
- package/dist/subscriberbot/pages/customer/BookingDetailsPage.js.map +0 -1
- package/dist/subscriberbot/pages/customer/CartDetailPage.js +0 -654
- package/dist/subscriberbot/pages/customer/CartDetailPage.js.map +0 -1
- package/dist/subscriberbot/pages/customer/CartDiscoveryPage.js +0 -555
- package/dist/subscriberbot/pages/customer/CartDiscoveryPage.js.map +0 -1
- package/dist/subscriberbot/pages/customer/CheckoutPage.js +0 -529
- package/dist/subscriberbot/pages/customer/CheckoutPage.js.map +0 -1
- package/dist/subscriberbot/pages/customer/CustomerDashboard.js +0 -532
- package/dist/subscriberbot/pages/customer/CustomerDashboard.js.map +0 -1
- package/dist/subscriberbot/pages/customer/CustomerProfilePage.js +0 -630
- package/dist/subscriberbot/pages/customer/CustomerProfilePage.js.map +0 -1
- package/dist/subscriberbot/pages/customer/DirectServiceBookingPage.js +0 -633
- package/dist/subscriberbot/pages/customer/DirectServiceBookingPage.js.map +0 -1
- package/dist/subscriberbot/pages/customer/FavoritesPage.js +0 -484
- package/dist/subscriberbot/pages/customer/FavoritesPage.js.map +0 -1
- package/dist/subscriberbot/pages/customer/OrderHistoryPage.js +0 -446
- package/dist/subscriberbot/pages/customer/OrderHistoryPage.js.map +0 -1
- package/dist/subscriberbot/pages/customer/OrderTrackingPage.js +0 -394
- package/dist/subscriberbot/pages/customer/OrderTrackingPage.js.map +0 -1
- package/dist/subscriberbot/pages/customer/PaymentMethodsPage.js +0 -495
- package/dist/subscriberbot/pages/customer/PaymentMethodsPage.js.map +0 -1
- package/dist/subscriberbot/pages/customer/ReviewsPage.js +0 -613
- package/dist/subscriberbot/pages/customer/ReviewsPage.js.map +0 -1
- package/dist/subscriberbot/pages/customer/SavedAddressesPage.js +0 -450
- package/dist/subscriberbot/pages/customer/SavedAddressesPage.js.map +0 -1
- package/dist/subscriberbot/pages/investor/InvestmentDetailsPage.js +0 -886
- package/dist/subscriberbot/pages/investor/InvestmentDetailsPage.js.map +0 -1
- package/dist/subscriberbot/pages/investor/InvestmentOpportunitiesPage.js +0 -947
- package/dist/subscriberbot/pages/investor/InvestmentOpportunitiesPage.js.map +0 -1
- package/dist/subscriberbot/pages/investor/InvestorAnalyticsPage.js +0 -687
- package/dist/subscriberbot/pages/investor/InvestorAnalyticsPage.js.map +0 -1
- package/dist/subscriberbot/pages/investor/InvestorDashboard.js +0 -451
- package/dist/subscriberbot/pages/investor/InvestorDashboard.js.map +0 -1
- package/dist/subscriberbot/pages/investor/InvestorInvestmentsPage.js +0 -406
- package/dist/subscriberbot/pages/investor/InvestorInvestmentsPage.js.map +0 -1
- package/dist/subscriberbot/pages/investor/InvestorPortfolioPage.js +0 -575
- package/dist/subscriberbot/pages/investor/InvestorPortfolioPage.js.map +0 -1
- package/dist/subscriberbot/pages/investor/InvestorProfilePage.js +0 -1070
- package/dist/subscriberbot/pages/investor/InvestorProfilePage.js.map +0 -1
- package/dist/subscriberbot/pages/worker/TaskDetailsPage.js +0 -535
- package/dist/subscriberbot/pages/worker/TaskDetailsPage.js.map +0 -1
- package/dist/subscriberbot/pages/worker/WorkerDashboard.js +0 -666
- package/dist/subscriberbot/pages/worker/WorkerDashboard.js.map +0 -1
- package/dist/subscriberbot/pages/worker/WorkerOrdersPage.js +0 -681
- package/dist/subscriberbot/pages/worker/WorkerOrdersPage.js.map +0 -1
- package/dist/subscriberbot/pages/worker/WorkerProfilePage.js +0 -692
- package/dist/subscriberbot/pages/worker/WorkerProfilePage.js.map +0 -1
- package/dist/subscriberbot/pages/worker/WorkerSchedulePage.js +0 -588
- package/dist/subscriberbot/pages/worker/WorkerSchedulePage.js.map +0 -1
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
import { useSubscriberBot as e } from "../../context/SubscriberBotContext.js";
|
|
2
|
+
import { PageLayout as t } from "../../components/PageLayout.js";
|
|
3
|
+
import { formatCurrency as n, formatEnumLabel as r, formatIntervalSuffix as i } from "../../utils/formatters.js";
|
|
4
|
+
import { StatusBadge as a } from "../../components/StatusBadge.js";
|
|
5
|
+
import { EmptyState as o } from "../../components/EmptyState.js";
|
|
6
|
+
import { ErrorView as s, LoadingView as c, Section as l } from "../../components/StateViews.js";
|
|
7
|
+
import { useProvider as u } from "../../hooks/useSubscriberBotApi.js";
|
|
8
|
+
import { ArrowLeft as d, Building2 as f, Globe as p, ShieldCheck as m, Tag as h, TrendingDown as g } from "lucide-react";
|
|
9
|
+
import { useParams as _ } from "react-router-dom";
|
|
10
|
+
import { jsx as v, jsxs as y } from "react/jsx-runtime";
|
|
11
|
+
import { GlassCard as b } from "@burdenoff/fe-libs/ui";
|
|
12
|
+
//#region src/subscriberbot/pages/providers/ProviderDetailPage.tsx
|
|
13
|
+
function x() {
|
|
14
|
+
let { id: x } = _(), { navigateTo: S } = e(), { data: C, isLoading: w, isError: T, refetch: E } = u(x);
|
|
15
|
+
if (w) return /* @__PURE__ */ v(t, {
|
|
16
|
+
title: "Provider",
|
|
17
|
+
children: /* @__PURE__ */ v(c, { label: "Loading provider…" })
|
|
18
|
+
});
|
|
19
|
+
if (T) return /* @__PURE__ */ v(t, {
|
|
20
|
+
title: "Provider",
|
|
21
|
+
children: /* @__PURE__ */ v(s, {
|
|
22
|
+
message: "Could not load this provider.",
|
|
23
|
+
onRetry: () => void E()
|
|
24
|
+
})
|
|
25
|
+
});
|
|
26
|
+
if (!C) return /* @__PURE__ */ v(t, {
|
|
27
|
+
title: "Provider",
|
|
28
|
+
children: /* @__PURE__ */ v(o, {
|
|
29
|
+
illustration: "empty-data",
|
|
30
|
+
title: "Provider not found",
|
|
31
|
+
description: "It may have been removed, or you may not have access to it.",
|
|
32
|
+
action: /* @__PURE__ */ v("button", {
|
|
33
|
+
type: "button",
|
|
34
|
+
onClick: () => S("/providers"),
|
|
35
|
+
className: "rounded-lg bg-action-primary-bg px-4 py-2 text-sm font-medium text-action-primary-text hover:opacity-90",
|
|
36
|
+
children: "Back to providers"
|
|
37
|
+
})
|
|
38
|
+
})
|
|
39
|
+
});
|
|
40
|
+
let D = C;
|
|
41
|
+
return /* @__PURE__ */ y(t, {
|
|
42
|
+
title: D.name,
|
|
43
|
+
description: r(D.category),
|
|
44
|
+
actions: /* @__PURE__ */ y("button", {
|
|
45
|
+
type: "button",
|
|
46
|
+
onClick: () => S("/providers"),
|
|
47
|
+
className: "inline-flex items-center gap-2 rounded-lg border border-border-subtle px-3 py-2 text-sm font-medium text-text-primary hover:bg-bg-sunken",
|
|
48
|
+
children: [/* @__PURE__ */ v(d, { className: "h-4 w-4" }), " Back"]
|
|
49
|
+
}),
|
|
50
|
+
children: [
|
|
51
|
+
/* @__PURE__ */ y("div", {
|
|
52
|
+
className: "flex flex-wrap items-center gap-3",
|
|
53
|
+
children: [
|
|
54
|
+
/* @__PURE__ */ v("span", {
|
|
55
|
+
className: "flex size-10 items-center justify-center rounded-lg bg-[var(--color-accent-soft)] text-text-primary",
|
|
56
|
+
children: /* @__PURE__ */ v(f, { className: "h-5 w-5" })
|
|
57
|
+
}),
|
|
58
|
+
/* @__PURE__ */ v(a, { status: D.status }),
|
|
59
|
+
D.region && /* @__PURE__ */ v("span", {
|
|
60
|
+
className: "text-sm text-text-secondary",
|
|
61
|
+
children: D.region
|
|
62
|
+
}),
|
|
63
|
+
D.websiteUrl && /* @__PURE__ */ y("a", {
|
|
64
|
+
href: D.websiteUrl,
|
|
65
|
+
target: "_blank",
|
|
66
|
+
rel: "noreferrer",
|
|
67
|
+
className: "inline-flex items-center gap-1 text-sm text-text-link hover:underline",
|
|
68
|
+
children: [/* @__PURE__ */ v(p, { className: "h-3.5 w-3.5" }), " Website"]
|
|
69
|
+
})
|
|
70
|
+
]
|
|
71
|
+
}),
|
|
72
|
+
D.description && /* @__PURE__ */ v("p", {
|
|
73
|
+
className: "mt-4 max-w-3xl text-sm text-text-secondary",
|
|
74
|
+
children: D.description
|
|
75
|
+
}),
|
|
76
|
+
/* @__PURE__ */ y("div", {
|
|
77
|
+
className: "mt-6 grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-4",
|
|
78
|
+
children: [
|
|
79
|
+
/* @__PURE__ */ y(b, {
|
|
80
|
+
treatment: "metric",
|
|
81
|
+
className: "p-4",
|
|
82
|
+
children: [/* @__PURE__ */ y("div", {
|
|
83
|
+
className: "flex items-center gap-2 text-xs font-medium text-text-secondary",
|
|
84
|
+
children: [/* @__PURE__ */ v(m, { className: "h-3.5 w-3.5" }), " Vendor health"]
|
|
85
|
+
}), /* @__PURE__ */ v("p", {
|
|
86
|
+
className: "mt-1.5 text-lg font-semibold tabular-nums text-text-primary",
|
|
87
|
+
children: D.vendorHealthScore == null ? "—" : `${D.vendorHealthScore}/100`
|
|
88
|
+
})]
|
|
89
|
+
}),
|
|
90
|
+
/* @__PURE__ */ y(b, {
|
|
91
|
+
treatment: "metric",
|
|
92
|
+
className: "p-4",
|
|
93
|
+
children: [/* @__PURE__ */ y("div", {
|
|
94
|
+
className: "flex items-center gap-2 text-xs font-medium text-text-secondary",
|
|
95
|
+
children: [/* @__PURE__ */ v(g, { className: "h-3.5 w-3.5" }), " Churn risk"]
|
|
96
|
+
}), /* @__PURE__ */ v("p", {
|
|
97
|
+
className: "mt-1.5 text-lg font-semibold tabular-nums text-text-primary",
|
|
98
|
+
children: D.churnRiskScore == null ? "—" : `${D.churnRiskScore}/100`
|
|
99
|
+
})]
|
|
100
|
+
}),
|
|
101
|
+
/* @__PURE__ */ y(b, {
|
|
102
|
+
treatment: "metric",
|
|
103
|
+
className: "p-4",
|
|
104
|
+
children: [/* @__PURE__ */ v("div", {
|
|
105
|
+
className: "flex items-center gap-2 text-xs font-medium text-text-secondary",
|
|
106
|
+
children: "Industry"
|
|
107
|
+
}), /* @__PURE__ */ v("p", {
|
|
108
|
+
className: "mt-1.5 text-sm text-text-primary",
|
|
109
|
+
children: D.industry ?? "—"
|
|
110
|
+
})]
|
|
111
|
+
}),
|
|
112
|
+
/* @__PURE__ */ y(b, {
|
|
113
|
+
treatment: "metric",
|
|
114
|
+
className: "p-4",
|
|
115
|
+
children: [/* @__PURE__ */ v("div", {
|
|
116
|
+
className: "flex items-center gap-2 text-xs font-medium text-text-secondary",
|
|
117
|
+
children: "Language"
|
|
118
|
+
}), /* @__PURE__ */ v("p", {
|
|
119
|
+
className: "mt-1.5 text-sm text-text-primary",
|
|
120
|
+
children: D.language ?? "—"
|
|
121
|
+
})]
|
|
122
|
+
})
|
|
123
|
+
]
|
|
124
|
+
}),
|
|
125
|
+
D.tags.length > 0 && /* @__PURE__ */ y("div", {
|
|
126
|
+
className: "mt-5 flex flex-wrap items-center gap-2",
|
|
127
|
+
children: [/* @__PURE__ */ v(h, { className: "h-3.5 w-3.5 text-text-secondary" }), D.tags.map((e) => /* @__PURE__ */ v("span", {
|
|
128
|
+
className: "rounded-full bg-bg-sunken px-2.5 py-0.5 text-xs text-text-secondary",
|
|
129
|
+
children: e
|
|
130
|
+
}, e))]
|
|
131
|
+
}),
|
|
132
|
+
/* @__PURE__ */ v(l, {
|
|
133
|
+
title: "Plans",
|
|
134
|
+
description: "Pricing this provider publishes",
|
|
135
|
+
children: !D.plans || D.plans.length === 0 ? /* @__PURE__ */ v(o, {
|
|
136
|
+
illustration: "empty-data",
|
|
137
|
+
title: "No published plans",
|
|
138
|
+
description: "When this provider publishes plans, they'll appear here."
|
|
139
|
+
}) : /* @__PURE__ */ v("div", {
|
|
140
|
+
className: "grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-3",
|
|
141
|
+
children: D.plans.map((e) => /* @__PURE__ */ y("div", {
|
|
142
|
+
className: "rounded-lg border border-border-subtle bg-bg-surface p-4",
|
|
143
|
+
children: [
|
|
144
|
+
/* @__PURE__ */ y("div", {
|
|
145
|
+
className: "flex items-start justify-between gap-2",
|
|
146
|
+
children: [/* @__PURE__ */ v("p", {
|
|
147
|
+
className: "text-sm font-semibold text-text-primary",
|
|
148
|
+
children: e.name
|
|
149
|
+
}), /* @__PURE__ */ v(a, { status: e.isActive ? "ACTIVE" : "DISABLED" })]
|
|
150
|
+
}),
|
|
151
|
+
/* @__PURE__ */ y("p", {
|
|
152
|
+
className: "mt-2 text-lg font-bold tabular-nums text-text-primary",
|
|
153
|
+
children: [n(e.amount, e.currency), /* @__PURE__ */ v("span", {
|
|
154
|
+
className: "text-xs font-normal text-text-secondary",
|
|
155
|
+
children: i(e.interval)
|
|
156
|
+
})]
|
|
157
|
+
}),
|
|
158
|
+
e.description && /* @__PURE__ */ v("p", {
|
|
159
|
+
className: "mt-1 text-xs text-text-secondary",
|
|
160
|
+
children: e.description
|
|
161
|
+
}),
|
|
162
|
+
e.features.length > 0 && /* @__PURE__ */ v("ul", {
|
|
163
|
+
className: "mt-3 space-y-1",
|
|
164
|
+
children: e.features.slice(0, 5).map((e) => /* @__PURE__ */ y("li", {
|
|
165
|
+
className: "text-xs text-text-secondary",
|
|
166
|
+
children: ["• ", e]
|
|
167
|
+
}, e))
|
|
168
|
+
})
|
|
169
|
+
]
|
|
170
|
+
}, e.id))
|
|
171
|
+
})
|
|
172
|
+
})
|
|
173
|
+
]
|
|
174
|
+
});
|
|
175
|
+
}
|
|
176
|
+
//#endregion
|
|
177
|
+
export { x as ProviderDetailPage };
|
|
178
|
+
|
|
179
|
+
//# sourceMappingURL=ProviderDetailPage.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ProviderDetailPage.js","names":[],"sources":["../../../../src/subscriberbot/pages/providers/ProviderDetailPage.tsx"],"sourcesContent":["/**\n * Provider detail\n * @module subscriberbot/pages/providers\n *\n * A provider profile from the registry: category, status, region, scores,\n * tags and its published plans. Reads `subProvider(id)`.\n */\n\nimport { ArrowLeft, Building2, Globe, ShieldCheck, TrendingDown, Tag } from 'lucide-react';\nimport { GlassCard } from '@burdenoff/fe-libs/ui';\nimport { PageLayout } from '../../components/PageLayout';\nimport { StatusBadge } from '../../components/StatusBadge';\nimport { EmptyState } from '../../components/EmptyState';\nimport { LoadingView, ErrorView, Section } from '../../components/StateViews';\nimport { useParams } from 'react-router-dom';\nimport { useSubscriberBot } from '../../context/SubscriberBotContext';\nimport { useProvider } from '../../hooks/useSubscriberBotApi';\nimport { formatCurrency, formatEnumLabel, formatIntervalSuffix } from '../../utils/formatters';\n\nexport function ProviderDetailPage() {\n const { id } = useParams<{ id: string }>();\n const { navigateTo } = useSubscriberBot();\n const { data: provider, isLoading, isError, refetch } = useProvider(id);\n\n if (isLoading) {\n return (\n <PageLayout title=\"Provider\">\n <LoadingView label=\"Loading provider…\" />\n </PageLayout>\n );\n }\n\n if (isError) {\n return (\n <PageLayout title=\"Provider\">\n <ErrorView message=\"Could not load this provider.\" onRetry={() => void refetch()} />\n </PageLayout>\n );\n }\n\n if (!provider) {\n return (\n <PageLayout title=\"Provider\">\n <EmptyState\n illustration=\"empty-data\"\n title=\"Provider not found\"\n description=\"It may have been removed, or you may not have access to it.\"\n action={\n <button\n type=\"button\"\n onClick={() => navigateTo('/providers')}\n className=\"rounded-lg bg-action-primary-bg px-4 py-2 text-sm font-medium text-action-primary-text hover:opacity-90\"\n >\n Back to providers\n </button>\n }\n />\n </PageLayout>\n );\n }\n\n const p = provider;\n\n return (\n <PageLayout\n title={p.name}\n description={formatEnumLabel(p.category)}\n actions={\n <button\n type=\"button\"\n onClick={() => navigateTo('/providers')}\n className=\"inline-flex items-center gap-2 rounded-lg border border-border-subtle px-3 py-2 text-sm font-medium text-text-primary hover:bg-bg-sunken\"\n >\n <ArrowLeft className=\"h-4 w-4\" /> Back\n </button>\n }\n >\n <div className=\"flex flex-wrap items-center gap-3\">\n <span className=\"flex size-10 items-center justify-center rounded-lg bg-[var(--color-accent-soft)] text-text-primary\">\n <Building2 className=\"h-5 w-5\" />\n </span>\n <StatusBadge status={p.status} />\n {p.region && <span className=\"text-sm text-text-secondary\">{p.region}</span>}\n {p.websiteUrl && (\n <a\n href={p.websiteUrl}\n target=\"_blank\"\n rel=\"noreferrer\"\n className=\"inline-flex items-center gap-1 text-sm text-text-link hover:underline\"\n >\n <Globe className=\"h-3.5 w-3.5\" /> Website\n </a>\n )}\n </div>\n\n {p.description && (\n <p className=\"mt-4 max-w-3xl text-sm text-text-secondary\">{p.description}</p>\n )}\n\n <div className=\"mt-6 grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-4\">\n <GlassCard treatment=\"metric\" className=\"p-4\">\n <div className=\"flex items-center gap-2 text-xs font-medium text-text-secondary\">\n <ShieldCheck className=\"h-3.5 w-3.5\" /> Vendor health\n </div>\n <p className=\"mt-1.5 text-lg font-semibold tabular-nums text-text-primary\">\n {p.vendorHealthScore != null ? `${p.vendorHealthScore}/100` : '—'}\n </p>\n </GlassCard>\n <GlassCard treatment=\"metric\" className=\"p-4\">\n <div className=\"flex items-center gap-2 text-xs font-medium text-text-secondary\">\n <TrendingDown className=\"h-3.5 w-3.5\" /> Churn risk\n </div>\n <p className=\"mt-1.5 text-lg font-semibold tabular-nums text-text-primary\">\n {p.churnRiskScore != null ? `${p.churnRiskScore}/100` : '—'}\n </p>\n </GlassCard>\n <GlassCard treatment=\"metric\" className=\"p-4\">\n <div className=\"flex items-center gap-2 text-xs font-medium text-text-secondary\">\n Industry\n </div>\n <p className=\"mt-1.5 text-sm text-text-primary\">{p.industry ?? '—'}</p>\n </GlassCard>\n <GlassCard treatment=\"metric\" className=\"p-4\">\n <div className=\"flex items-center gap-2 text-xs font-medium text-text-secondary\">\n Language\n </div>\n <p className=\"mt-1.5 text-sm text-text-primary\">{p.language ?? '—'}</p>\n </GlassCard>\n </div>\n\n {p.tags.length > 0 && (\n <div className=\"mt-5 flex flex-wrap items-center gap-2\">\n <Tag className=\"h-3.5 w-3.5 text-text-secondary\" />\n {p.tags.map((tag) => (\n <span\n key={tag}\n className=\"rounded-full bg-bg-sunken px-2.5 py-0.5 text-xs text-text-secondary\"\n >\n {tag}\n </span>\n ))}\n </div>\n )}\n\n <Section title=\"Plans\" description=\"Pricing this provider publishes\">\n {!p.plans || p.plans.length === 0 ? (\n <EmptyState\n illustration=\"empty-data\"\n title=\"No published plans\"\n description=\"When this provider publishes plans, they'll appear here.\"\n />\n ) : (\n <div className=\"grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-3\">\n {p.plans.map((plan) => (\n <div\n key={plan.id}\n className=\"rounded-lg border border-border-subtle bg-bg-surface p-4\"\n >\n <div className=\"flex items-start justify-between gap-2\">\n <p className=\"text-sm font-semibold text-text-primary\">{plan.name}</p>\n <StatusBadge status={plan.isActive ? 'ACTIVE' : 'DISABLED'} />\n </div>\n <p className=\"mt-2 text-lg font-bold tabular-nums text-text-primary\">\n {formatCurrency(plan.amount, plan.currency)}\n <span className=\"text-xs font-normal text-text-secondary\">\n {formatIntervalSuffix(plan.interval)}\n </span>\n </p>\n {plan.description && (\n <p className=\"mt-1 text-xs text-text-secondary\">{plan.description}</p>\n )}\n {plan.features.length > 0 && (\n <ul className=\"mt-3 space-y-1\">\n {plan.features.slice(0, 5).map((f) => (\n <li key={f} className=\"text-xs text-text-secondary\">\n • {f}\n </li>\n ))}\n </ul>\n )}\n </div>\n ))}\n </div>\n )}\n </Section>\n </PageLayout>\n );\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
import { useSubscriberBot as e } from "../../context/SubscriberBotContext.js";
|
|
2
|
+
import { PageLayout as t } from "../../components/PageLayout.js";
|
|
3
|
+
import { useCreateProvider as n } from "../../hooks/useSubscriberBotApi.js";
|
|
4
|
+
import { useState as r } from "react";
|
|
5
|
+
import { ArrowLeft as i } from "lucide-react";
|
|
6
|
+
import { jsx as a, jsxs as o } from "react/jsx-runtime";
|
|
7
|
+
import { PagePurpose as s } from "@burdenoff/fe-libs/ui";
|
|
8
|
+
//#region src/subscriberbot/pages/providers/ProviderNewPage.tsx
|
|
9
|
+
var c = [
|
|
10
|
+
"SAAS",
|
|
11
|
+
"AI_SERVICE",
|
|
12
|
+
"STREAMING",
|
|
13
|
+
"NEWSLETTER",
|
|
14
|
+
"NEWS_DIGEST",
|
|
15
|
+
"MEMBERSHIP",
|
|
16
|
+
"COMMUNITY",
|
|
17
|
+
"EDUCATION",
|
|
18
|
+
"FINANCIAL",
|
|
19
|
+
"INSURANCE",
|
|
20
|
+
"TELECOM",
|
|
21
|
+
"UTILITY",
|
|
22
|
+
"ASSOCIATION",
|
|
23
|
+
"LICENSE",
|
|
24
|
+
"CONTRACT",
|
|
25
|
+
"OTHER"
|
|
26
|
+
], l = "w-full rounded-lg border border-border-subtle bg-bg-surface px-3 py-2 text-sm text-text-primary placeholder:text-text-secondary focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)]", u = "mb-1 block text-xs font-medium text-text-secondary";
|
|
27
|
+
function d() {
|
|
28
|
+
let { navigateTo: d } = e(), f = n(), [p, m] = r(""), [h, g] = r("SAAS"), [_, v] = r(""), [y, b] = r(""), [x, S] = r(""), [C, w] = r(""), [T, E] = r(""), [D, O] = r(null);
|
|
29
|
+
return /* @__PURE__ */ o(t, {
|
|
30
|
+
title: "Add provider",
|
|
31
|
+
description: "Register a new provider in the registry",
|
|
32
|
+
actions: /* @__PURE__ */ o("button", {
|
|
33
|
+
type: "button",
|
|
34
|
+
onClick: () => d("/providers"),
|
|
35
|
+
className: "inline-flex items-center gap-2 rounded-lg border border-border-subtle px-3 py-2 text-sm font-medium text-text-primary hover:bg-bg-sunken",
|
|
36
|
+
children: [/* @__PURE__ */ a(i, { className: "h-4 w-4" }), " Back"]
|
|
37
|
+
}),
|
|
38
|
+
children: [/* @__PURE__ */ a(s, {
|
|
39
|
+
className: "mb-6",
|
|
40
|
+
children: "Add a provider that isn't in the registry yet so you can attach relationships, plans and assets to it."
|
|
41
|
+
}), /* @__PURE__ */ o("form", {
|
|
42
|
+
onSubmit: (e) => {
|
|
43
|
+
if (e.preventDefault(), O(null), !p.trim()) {
|
|
44
|
+
O("A provider name is required.");
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
let t = T.split(",").map((e) => e.trim()).filter(Boolean), n = {
|
|
48
|
+
name: p.trim(),
|
|
49
|
+
category: h,
|
|
50
|
+
..._.trim() ? { description: _.trim() } : {},
|
|
51
|
+
...y.trim() ? { websiteUrl: y.trim() } : {},
|
|
52
|
+
...x.trim() ? { region: x.trim() } : {},
|
|
53
|
+
...C.trim() ? { industry: C.trim() } : {},
|
|
54
|
+
...t.length ? { tags: t } : {}
|
|
55
|
+
};
|
|
56
|
+
f.mutate(n, {
|
|
57
|
+
onSuccess: (e) => d(`/providers/${e.id}`),
|
|
58
|
+
onError: (e) => O(e instanceof Error ? e.message : "Could not create provider.")
|
|
59
|
+
});
|
|
60
|
+
},
|
|
61
|
+
className: "max-w-2xl space-y-5",
|
|
62
|
+
children: [
|
|
63
|
+
D && /* @__PURE__ */ a("div", {
|
|
64
|
+
className: "rounded-lg border border-status-error-text/30 bg-status-error-bg-subtle px-4 py-2 text-sm text-status-error-text",
|
|
65
|
+
children: D
|
|
66
|
+
}),
|
|
67
|
+
/* @__PURE__ */ o("div", { children: [/* @__PURE__ */ o("label", {
|
|
68
|
+
htmlFor: "prov-name",
|
|
69
|
+
className: u,
|
|
70
|
+
children: ["Name ", /* @__PURE__ */ a("span", {
|
|
71
|
+
className: "text-status-error-text",
|
|
72
|
+
children: "*"
|
|
73
|
+
})]
|
|
74
|
+
}), /* @__PURE__ */ a("input", {
|
|
75
|
+
id: "prov-name",
|
|
76
|
+
type: "text",
|
|
77
|
+
value: p,
|
|
78
|
+
onChange: (e) => m(e.target.value),
|
|
79
|
+
placeholder: "e.g. OpenAI, Netflix, AWS",
|
|
80
|
+
className: l,
|
|
81
|
+
required: !0
|
|
82
|
+
})] }),
|
|
83
|
+
/* @__PURE__ */ o("div", {
|
|
84
|
+
className: "grid grid-cols-1 gap-4 sm:grid-cols-2",
|
|
85
|
+
children: [/* @__PURE__ */ o("div", { children: [/* @__PURE__ */ a("label", {
|
|
86
|
+
htmlFor: "prov-category",
|
|
87
|
+
className: u,
|
|
88
|
+
children: "Category"
|
|
89
|
+
}), /* @__PURE__ */ a("select", {
|
|
90
|
+
id: "prov-category",
|
|
91
|
+
value: h,
|
|
92
|
+
onChange: (e) => g(e.target.value),
|
|
93
|
+
className: l,
|
|
94
|
+
children: c.map((e) => /* @__PURE__ */ a("option", {
|
|
95
|
+
value: e,
|
|
96
|
+
children: e.replace(/_/g, " ")
|
|
97
|
+
}, e))
|
|
98
|
+
})] }), /* @__PURE__ */ o("div", { children: [/* @__PURE__ */ a("label", {
|
|
99
|
+
htmlFor: "prov-website",
|
|
100
|
+
className: u,
|
|
101
|
+
children: "Website"
|
|
102
|
+
}), /* @__PURE__ */ a("input", {
|
|
103
|
+
id: "prov-website",
|
|
104
|
+
type: "url",
|
|
105
|
+
value: y,
|
|
106
|
+
onChange: (e) => b(e.target.value),
|
|
107
|
+
placeholder: "https://…",
|
|
108
|
+
className: l
|
|
109
|
+
})] })]
|
|
110
|
+
}),
|
|
111
|
+
/* @__PURE__ */ o("div", {
|
|
112
|
+
className: "grid grid-cols-1 gap-4 sm:grid-cols-2",
|
|
113
|
+
children: [/* @__PURE__ */ o("div", { children: [/* @__PURE__ */ a("label", {
|
|
114
|
+
htmlFor: "prov-region",
|
|
115
|
+
className: u,
|
|
116
|
+
children: "Region"
|
|
117
|
+
}), /* @__PURE__ */ a("input", {
|
|
118
|
+
id: "prov-region",
|
|
119
|
+
type: "text",
|
|
120
|
+
value: x,
|
|
121
|
+
onChange: (e) => S(e.target.value),
|
|
122
|
+
placeholder: "e.g. Global, US, EU",
|
|
123
|
+
className: l
|
|
124
|
+
})] }), /* @__PURE__ */ o("div", { children: [/* @__PURE__ */ a("label", {
|
|
125
|
+
htmlFor: "prov-industry",
|
|
126
|
+
className: u,
|
|
127
|
+
children: "Industry"
|
|
128
|
+
}), /* @__PURE__ */ a("input", {
|
|
129
|
+
id: "prov-industry",
|
|
130
|
+
type: "text",
|
|
131
|
+
value: C,
|
|
132
|
+
onChange: (e) => w(e.target.value),
|
|
133
|
+
placeholder: "e.g. Cloud, Media",
|
|
134
|
+
className: l
|
|
135
|
+
})] })]
|
|
136
|
+
}),
|
|
137
|
+
/* @__PURE__ */ o("div", { children: [/* @__PURE__ */ a("label", {
|
|
138
|
+
htmlFor: "prov-desc",
|
|
139
|
+
className: u,
|
|
140
|
+
children: "Description"
|
|
141
|
+
}), /* @__PURE__ */ a("textarea", {
|
|
142
|
+
id: "prov-desc",
|
|
143
|
+
value: _,
|
|
144
|
+
onChange: (e) => v(e.target.value),
|
|
145
|
+
rows: 3,
|
|
146
|
+
placeholder: "What does this provider offer?",
|
|
147
|
+
className: l
|
|
148
|
+
})] }),
|
|
149
|
+
/* @__PURE__ */ o("div", { children: [/* @__PURE__ */ o("label", {
|
|
150
|
+
htmlFor: "prov-tags",
|
|
151
|
+
className: u,
|
|
152
|
+
children: ["Tags ", /* @__PURE__ */ a("span", {
|
|
153
|
+
className: "text-text-secondary",
|
|
154
|
+
children: "(comma-separated)"
|
|
155
|
+
})]
|
|
156
|
+
}), /* @__PURE__ */ a("input", {
|
|
157
|
+
id: "prov-tags",
|
|
158
|
+
type: "text",
|
|
159
|
+
value: T,
|
|
160
|
+
onChange: (e) => E(e.target.value),
|
|
161
|
+
placeholder: "ai, productivity, enterprise",
|
|
162
|
+
className: l
|
|
163
|
+
})] }),
|
|
164
|
+
/* @__PURE__ */ o("div", {
|
|
165
|
+
className: "flex gap-3",
|
|
166
|
+
children: [/* @__PURE__ */ a("button", {
|
|
167
|
+
type: "submit",
|
|
168
|
+
disabled: f.isPending,
|
|
169
|
+
className: "rounded-lg bg-action-primary-bg px-5 py-2.5 text-sm font-medium text-action-primary-text hover:opacity-90 disabled:opacity-50",
|
|
170
|
+
children: f.isPending ? "Creating…" : "Create provider"
|
|
171
|
+
}), /* @__PURE__ */ a("button", {
|
|
172
|
+
type: "button",
|
|
173
|
+
onClick: () => d("/providers"),
|
|
174
|
+
className: "rounded-lg border border-border-subtle px-5 py-2.5 text-sm font-medium text-text-primary hover:bg-bg-sunken",
|
|
175
|
+
children: "Cancel"
|
|
176
|
+
})]
|
|
177
|
+
})
|
|
178
|
+
]
|
|
179
|
+
})]
|
|
180
|
+
});
|
|
181
|
+
}
|
|
182
|
+
//#endregion
|
|
183
|
+
export { d as ProviderNewPage };
|
|
184
|
+
|
|
185
|
+
//# sourceMappingURL=ProviderNewPage.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ProviderNewPage.js","names":[],"sources":["../../../../src/subscriberbot/pages/providers/ProviderNewPage.tsx"],"sourcesContent":["/**\n * Create provider\n * @module subscriberbot/pages/providers\n *\n * Add a provider to the registry. Writes `subCreateProvider`.\n */\n\nimport { useState } from 'react';\nimport { ArrowLeft } from 'lucide-react';\nimport { PagePurpose } from '@burdenoff/fe-libs/ui';\nimport { PageLayout } from '../../components/PageLayout';\nimport { useSubscriberBot } from '../../context/SubscriberBotContext';\nimport { useCreateProvider } from '../../hooks/useSubscriberBotApi';\nimport type { SubCreateProviderInput, SubProviderCategory } from '../../types';\n\nconst CATEGORIES: SubProviderCategory[] = [\n 'SAAS',\n 'AI_SERVICE',\n 'STREAMING',\n 'NEWSLETTER',\n 'NEWS_DIGEST',\n 'MEMBERSHIP',\n 'COMMUNITY',\n 'EDUCATION',\n 'FINANCIAL',\n 'INSURANCE',\n 'TELECOM',\n 'UTILITY',\n 'ASSOCIATION',\n 'LICENSE',\n 'CONTRACT',\n 'OTHER',\n];\n\nconst inputCls =\n 'w-full rounded-lg border border-border-subtle bg-bg-surface px-3 py-2 text-sm text-text-primary placeholder:text-text-secondary focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)]';\nconst labelCls = 'mb-1 block text-xs font-medium text-text-secondary';\n\nexport function ProviderNewPage() {\n const { navigateTo } = useSubscriberBot();\n const create = useCreateProvider();\n\n const [name, setName] = useState('');\n const [category, setCategory] = useState<SubProviderCategory>('SAAS');\n const [description, setDescription] = useState('');\n const [websiteUrl, setWebsiteUrl] = useState('');\n const [region, setRegion] = useState('');\n const [industry, setIndustry] = useState('');\n const [tags, setTags] = useState('');\n const [formError, setFormError] = useState<string | null>(null);\n\n const handleSubmit = (e: React.FormEvent) => {\n e.preventDefault();\n setFormError(null);\n if (!name.trim()) {\n setFormError('A provider name is required.');\n return;\n }\n const parsedTags = tags\n .split(',')\n .map((t) => t.trim())\n .filter(Boolean);\n const input: SubCreateProviderInput = {\n name: name.trim(),\n category,\n ...(description.trim() ? { description: description.trim() } : {}),\n ...(websiteUrl.trim() ? { websiteUrl: websiteUrl.trim() } : {}),\n ...(region.trim() ? { region: region.trim() } : {}),\n ...(industry.trim() ? { industry: industry.trim() } : {}),\n ...(parsedTags.length ? { tags: parsedTags } : {}),\n };\n create.mutate(input, {\n onSuccess: (provider) => navigateTo(`/providers/${provider.id}`),\n onError: (err) =>\n setFormError(err instanceof Error ? err.message : 'Could not create provider.'),\n });\n };\n\n return (\n <PageLayout\n title=\"Add provider\"\n description=\"Register a new provider in the registry\"\n actions={\n <button\n type=\"button\"\n onClick={() => navigateTo('/providers')}\n className=\"inline-flex items-center gap-2 rounded-lg border border-border-subtle px-3 py-2 text-sm font-medium text-text-primary hover:bg-bg-sunken\"\n >\n <ArrowLeft className=\"h-4 w-4\" /> Back\n </button>\n }\n >\n <PagePurpose className=\"mb-6\">\n Add a provider that isn't in the registry yet so you can attach relationships, plans and\n assets to it.\n </PagePurpose>\n\n <form onSubmit={handleSubmit} className=\"max-w-2xl space-y-5\">\n {formError && (\n <div className=\"rounded-lg border border-status-error-text/30 bg-status-error-bg-subtle px-4 py-2 text-sm text-status-error-text\">\n {formError}\n </div>\n )}\n\n <div>\n <label htmlFor=\"prov-name\" className={labelCls}>\n Name <span className=\"text-status-error-text\">*</span>\n </label>\n <input\n id=\"prov-name\"\n type=\"text\"\n value={name}\n onChange={(e) => setName(e.target.value)}\n placeholder=\"e.g. OpenAI, Netflix, AWS\"\n className={inputCls}\n required\n />\n </div>\n\n <div className=\"grid grid-cols-1 gap-4 sm:grid-cols-2\">\n <div>\n <label htmlFor=\"prov-category\" className={labelCls}>\n Category\n </label>\n <select\n id=\"prov-category\"\n value={category}\n onChange={(e) => setCategory(e.target.value as SubProviderCategory)}\n className={inputCls}\n >\n {CATEGORIES.map((c) => (\n <option key={c} value={c}>\n {c.replace(/_/g, ' ')}\n </option>\n ))}\n </select>\n </div>\n <div>\n <label htmlFor=\"prov-website\" className={labelCls}>\n Website\n </label>\n <input\n id=\"prov-website\"\n type=\"url\"\n value={websiteUrl}\n onChange={(e) => setWebsiteUrl(e.target.value)}\n placeholder=\"https://…\"\n className={inputCls}\n />\n </div>\n </div>\n\n <div className=\"grid grid-cols-1 gap-4 sm:grid-cols-2\">\n <div>\n <label htmlFor=\"prov-region\" className={labelCls}>\n Region\n </label>\n <input\n id=\"prov-region\"\n type=\"text\"\n value={region}\n onChange={(e) => setRegion(e.target.value)}\n placeholder=\"e.g. Global, US, EU\"\n className={inputCls}\n />\n </div>\n <div>\n <label htmlFor=\"prov-industry\" className={labelCls}>\n Industry\n </label>\n <input\n id=\"prov-industry\"\n type=\"text\"\n value={industry}\n onChange={(e) => setIndustry(e.target.value)}\n placeholder=\"e.g. Cloud, Media\"\n className={inputCls}\n />\n </div>\n </div>\n\n <div>\n <label htmlFor=\"prov-desc\" className={labelCls}>\n Description\n </label>\n <textarea\n id=\"prov-desc\"\n value={description}\n onChange={(e) => setDescription(e.target.value)}\n rows={3}\n placeholder=\"What does this provider offer?\"\n className={inputCls}\n />\n </div>\n\n <div>\n <label htmlFor=\"prov-tags\" className={labelCls}>\n Tags <span className=\"text-text-secondary\">(comma-separated)</span>\n </label>\n <input\n id=\"prov-tags\"\n type=\"text\"\n value={tags}\n onChange={(e) => setTags(e.target.value)}\n placeholder=\"ai, productivity, enterprise\"\n className={inputCls}\n />\n </div>\n\n <div className=\"flex gap-3\">\n <button\n type=\"submit\"\n disabled={create.isPending}\n className=\"rounded-lg bg-action-primary-bg px-5 py-2.5 text-sm font-medium text-action-primary-text hover:opacity-90 disabled:opacity-50\"\n >\n {create.isPending ? 'Creating…' : 'Create provider'}\n </button>\n <button\n type=\"button\"\n onClick={() => navigateTo('/providers')}\n className=\"rounded-lg border border-border-subtle px-5 py-2.5 text-sm font-medium text-text-primary hover:bg-bg-sunken\"\n >\n Cancel\n </button>\n </div>\n </form>\n </PageLayout>\n );\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,254 @@
|
|
|
1
|
+
import { useSubscriberBot as e } from "../../context/SubscriberBotContext.js";
|
|
2
|
+
import { cn as t } from "../../utils/cn.js";
|
|
3
|
+
import { PageLayout as n } from "../../components/PageLayout.js";
|
|
4
|
+
import { formatEnumLabel as r } from "../../utils/formatters.js";
|
|
5
|
+
import { StatusBadge as i } from "../../components/StatusBadge.js";
|
|
6
|
+
import { EmptyState as a } from "../../components/EmptyState.js";
|
|
7
|
+
import { ErrorView as o, LoadingView as s } from "../../components/StateViews.js";
|
|
8
|
+
import { useProviders as c } from "../../hooks/useSubscriberBotApi.js";
|
|
9
|
+
import { useState as l } from "react";
|
|
10
|
+
import { Building2 as u, Plus as d, Search as f, ShieldCheck as p } from "lucide-react";
|
|
11
|
+
import { Fragment as m, jsx as h, jsxs as g } from "react/jsx-runtime";
|
|
12
|
+
import { EmphasisPanel as _, PagePurpose as v } from "@burdenoff/fe-libs/ui";
|
|
13
|
+
//#region src/subscriberbot/pages/providers/ProvidersListPage.tsx
|
|
14
|
+
var y = 24, b = [
|
|
15
|
+
{
|
|
16
|
+
value: "",
|
|
17
|
+
label: "All categories"
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
value: "SAAS",
|
|
21
|
+
label: "SaaS"
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
value: "AI_SERVICE",
|
|
25
|
+
label: "AI service"
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
value: "STREAMING",
|
|
29
|
+
label: "Streaming"
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
value: "NEWSLETTER",
|
|
33
|
+
label: "Newsletter"
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
value: "NEWS_DIGEST",
|
|
37
|
+
label: "News digest"
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
value: "MEMBERSHIP",
|
|
41
|
+
label: "Membership"
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
value: "COMMUNITY",
|
|
45
|
+
label: "Community"
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
value: "EDUCATION",
|
|
49
|
+
label: "Education"
|
|
50
|
+
},
|
|
51
|
+
{
|
|
52
|
+
value: "FINANCIAL",
|
|
53
|
+
label: "Financial"
|
|
54
|
+
},
|
|
55
|
+
{
|
|
56
|
+
value: "INSURANCE",
|
|
57
|
+
label: "Insurance"
|
|
58
|
+
},
|
|
59
|
+
{
|
|
60
|
+
value: "TELECOM",
|
|
61
|
+
label: "Telecom"
|
|
62
|
+
},
|
|
63
|
+
{
|
|
64
|
+
value: "UTILITY",
|
|
65
|
+
label: "Utility"
|
|
66
|
+
},
|
|
67
|
+
{
|
|
68
|
+
value: "ASSOCIATION",
|
|
69
|
+
label: "Association"
|
|
70
|
+
},
|
|
71
|
+
{
|
|
72
|
+
value: "LICENSE",
|
|
73
|
+
label: "License"
|
|
74
|
+
},
|
|
75
|
+
{
|
|
76
|
+
value: "CONTRACT",
|
|
77
|
+
label: "Contract"
|
|
78
|
+
},
|
|
79
|
+
{
|
|
80
|
+
value: "OTHER",
|
|
81
|
+
label: "Other"
|
|
82
|
+
}
|
|
83
|
+
], x = [
|
|
84
|
+
{
|
|
85
|
+
value: "",
|
|
86
|
+
label: "Any status"
|
|
87
|
+
},
|
|
88
|
+
{
|
|
89
|
+
value: "VERIFIED",
|
|
90
|
+
label: "Verified"
|
|
91
|
+
},
|
|
92
|
+
{
|
|
93
|
+
value: "CLAIMED",
|
|
94
|
+
label: "Claimed"
|
|
95
|
+
},
|
|
96
|
+
{
|
|
97
|
+
value: "UNVERIFIED",
|
|
98
|
+
label: "Unverified"
|
|
99
|
+
},
|
|
100
|
+
{
|
|
101
|
+
value: "DEPRECATED",
|
|
102
|
+
label: "Deprecated"
|
|
103
|
+
}
|
|
104
|
+
];
|
|
105
|
+
function S() {
|
|
106
|
+
let { navigateTo: S } = e(), [C, w] = l(0), [T, E] = l(""), [D, O] = l(""), [k, A] = l(""), [j, M] = l(""), { data: N, isLoading: P, isError: F, refetch: I, isFetching: L } = c({
|
|
107
|
+
search: T || void 0,
|
|
108
|
+
category: k || void 0,
|
|
109
|
+
status: j || void 0,
|
|
110
|
+
pagination: {
|
|
111
|
+
limit: y,
|
|
112
|
+
offset: C * y
|
|
113
|
+
}
|
|
114
|
+
}), R = N?.items ?? [], z = N?.pageInfo.hasMore ?? !1;
|
|
115
|
+
return /* @__PURE__ */ g(n, {
|
|
116
|
+
title: "Providers",
|
|
117
|
+
description: "Discover and browse the global provider registry",
|
|
118
|
+
actions: /* @__PURE__ */ g("button", {
|
|
119
|
+
type: "button",
|
|
120
|
+
onClick: () => S("/providers/new"),
|
|
121
|
+
className: "inline-flex items-center gap-2 rounded-lg bg-action-primary-bg px-4 py-2 text-sm font-medium text-action-primary-text hover:opacity-90",
|
|
122
|
+
children: [/* @__PURE__ */ h(d, { className: "h-4 w-4" }), " Add provider"]
|
|
123
|
+
}),
|
|
124
|
+
children: [
|
|
125
|
+
/* @__PURE__ */ h(v, {
|
|
126
|
+
className: "mb-4",
|
|
127
|
+
children: "The registry is the public face of the Subscription Knowledge Graph — every provider exists here whether or not it integrates. Search and filter to find the ones you have relationships with, or add a new one."
|
|
128
|
+
}),
|
|
129
|
+
/* @__PURE__ */ h(_, { children: /* @__PURE__ */ g("form", {
|
|
130
|
+
onSubmit: (e) => {
|
|
131
|
+
e.preventDefault(), E(D.trim()), w(0);
|
|
132
|
+
},
|
|
133
|
+
className: "relative",
|
|
134
|
+
children: [/* @__PURE__ */ h(f, { className: "absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-text-secondary" }), /* @__PURE__ */ h("input", {
|
|
135
|
+
type: "text",
|
|
136
|
+
placeholder: "Search providers by name…",
|
|
137
|
+
value: D,
|
|
138
|
+
onChange: (e) => O(e.target.value),
|
|
139
|
+
className: "w-full rounded-lg border border-border-subtle bg-bg-surface py-2.5 pl-10 pr-3 text-sm text-text-primary placeholder:text-text-secondary focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)]"
|
|
140
|
+
})]
|
|
141
|
+
}) }),
|
|
142
|
+
/* @__PURE__ */ g("div", {
|
|
143
|
+
className: "mt-4 flex flex-wrap items-center gap-3",
|
|
144
|
+
children: [/* @__PURE__ */ h("select", {
|
|
145
|
+
value: k,
|
|
146
|
+
onChange: (e) => {
|
|
147
|
+
A(e.target.value), w(0);
|
|
148
|
+
},
|
|
149
|
+
className: "rounded-lg border border-border-subtle bg-bg-surface px-3 py-2 text-xs text-text-primary focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)]",
|
|
150
|
+
children: b.map((e) => /* @__PURE__ */ h("option", {
|
|
151
|
+
value: e.value,
|
|
152
|
+
children: e.label
|
|
153
|
+
}, e.value))
|
|
154
|
+
}), /* @__PURE__ */ h("select", {
|
|
155
|
+
value: j,
|
|
156
|
+
onChange: (e) => {
|
|
157
|
+
M(e.target.value), w(0);
|
|
158
|
+
},
|
|
159
|
+
className: "rounded-lg border border-border-subtle bg-bg-surface px-3 py-2 text-xs text-text-primary focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)]",
|
|
160
|
+
children: x.map((e) => /* @__PURE__ */ h("option", {
|
|
161
|
+
value: e.value,
|
|
162
|
+
children: e.label
|
|
163
|
+
}, e.value))
|
|
164
|
+
})]
|
|
165
|
+
}),
|
|
166
|
+
P ? /* @__PURE__ */ h(s, { label: "Loading providers…" }) : F ? /* @__PURE__ */ h(o, {
|
|
167
|
+
message: "Could not load the provider registry.",
|
|
168
|
+
onRetry: () => void I()
|
|
169
|
+
}) : R.length === 0 ? /* @__PURE__ */ h("div", {
|
|
170
|
+
className: "mt-6",
|
|
171
|
+
children: /* @__PURE__ */ h(a, {
|
|
172
|
+
illustration: "empty-search",
|
|
173
|
+
icon: /* @__PURE__ */ h(u, { className: "h-12 w-12" }),
|
|
174
|
+
title: "No providers found",
|
|
175
|
+
description: T ? `No providers match "${T}".` : "No providers in the registry with these filters yet.",
|
|
176
|
+
action: /* @__PURE__ */ h("button", {
|
|
177
|
+
type: "button",
|
|
178
|
+
onClick: () => S("/providers/new"),
|
|
179
|
+
className: "rounded-lg bg-action-primary-bg px-4 py-2 text-sm font-medium text-action-primary-text hover:opacity-90",
|
|
180
|
+
children: "Add provider"
|
|
181
|
+
})
|
|
182
|
+
})
|
|
183
|
+
}) : /* @__PURE__ */ g(m, { children: [/* @__PURE__ */ h("div", {
|
|
184
|
+
className: "mt-6 grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-3",
|
|
185
|
+
children: R.map((e) => /* @__PURE__ */ g("button", {
|
|
186
|
+
type: "button",
|
|
187
|
+
onClick: () => S(`/providers/${e.id}`),
|
|
188
|
+
className: "flex flex-col rounded-lg border border-border-subtle bg-bg-surface p-4 text-left transition-shadow hover:shadow-md",
|
|
189
|
+
children: [
|
|
190
|
+
/* @__PURE__ */ g("div", {
|
|
191
|
+
className: "flex items-start justify-between gap-2",
|
|
192
|
+
children: [/* @__PURE__ */ h("span", {
|
|
193
|
+
className: "flex size-9 items-center justify-center rounded-lg bg-[var(--color-accent-soft)] text-text-primary",
|
|
194
|
+
children: /* @__PURE__ */ h(u, { className: "h-4 w-4" })
|
|
195
|
+
}), /* @__PURE__ */ h(i, { status: e.status })]
|
|
196
|
+
}),
|
|
197
|
+
/* @__PURE__ */ h("p", {
|
|
198
|
+
className: "mt-3 truncate text-sm font-semibold text-text-primary",
|
|
199
|
+
children: e.name
|
|
200
|
+
}),
|
|
201
|
+
/* @__PURE__ */ h("p", {
|
|
202
|
+
className: "text-xs text-text-secondary",
|
|
203
|
+
children: r(e.category)
|
|
204
|
+
}),
|
|
205
|
+
e.description && /* @__PURE__ */ h("p", {
|
|
206
|
+
className: "mt-2 line-clamp-2 text-xs text-text-secondary",
|
|
207
|
+
children: e.description
|
|
208
|
+
}),
|
|
209
|
+
/* @__PURE__ */ g("div", {
|
|
210
|
+
className: "mt-3 flex flex-wrap items-center gap-2 text-xs text-text-secondary",
|
|
211
|
+
children: [e.region && /* @__PURE__ */ h("span", { children: e.region }), e.vendorHealthScore != null && /* @__PURE__ */ g("span", {
|
|
212
|
+
className: "inline-flex items-center gap-1",
|
|
213
|
+
children: [
|
|
214
|
+
/* @__PURE__ */ h(p, { className: "h-3 w-3" }),
|
|
215
|
+
e.vendorHealthScore,
|
|
216
|
+
"/100"
|
|
217
|
+
]
|
|
218
|
+
})]
|
|
219
|
+
})
|
|
220
|
+
]
|
|
221
|
+
}, e.id))
|
|
222
|
+
}), /* @__PURE__ */ g("div", {
|
|
223
|
+
className: "mt-4 flex items-center justify-between",
|
|
224
|
+
children: [/* @__PURE__ */ g("p", {
|
|
225
|
+
className: "text-xs text-text-secondary",
|
|
226
|
+
children: [
|
|
227
|
+
"Page ",
|
|
228
|
+
C + 1,
|
|
229
|
+
L ? " · refreshing…" : ""
|
|
230
|
+
]
|
|
231
|
+
}), /* @__PURE__ */ g("div", {
|
|
232
|
+
className: "flex gap-2",
|
|
233
|
+
children: [/* @__PURE__ */ h("button", {
|
|
234
|
+
type: "button",
|
|
235
|
+
disabled: C === 0,
|
|
236
|
+
onClick: () => w((e) => Math.max(0, e - 1)),
|
|
237
|
+
className: t("rounded-lg border border-border-subtle px-3 py-1.5 text-xs font-medium", C === 0 ? "cursor-not-allowed text-text-secondary opacity-50" : "text-text-primary hover:bg-bg-sunken"),
|
|
238
|
+
children: "Previous"
|
|
239
|
+
}), /* @__PURE__ */ h("button", {
|
|
240
|
+
type: "button",
|
|
241
|
+
disabled: !z,
|
|
242
|
+
onClick: () => w((e) => e + 1),
|
|
243
|
+
className: t("rounded-lg border border-border-subtle px-3 py-1.5 text-xs font-medium", z ? "text-text-primary hover:bg-bg-sunken" : "cursor-not-allowed text-text-secondary opacity-50"),
|
|
244
|
+
children: "Next"
|
|
245
|
+
})]
|
|
246
|
+
})]
|
|
247
|
+
})] })
|
|
248
|
+
]
|
|
249
|
+
});
|
|
250
|
+
}
|
|
251
|
+
//#endregion
|
|
252
|
+
export { S as ProvidersListPage };
|
|
253
|
+
|
|
254
|
+
//# sourceMappingURL=ProvidersListPage.js.map
|