@burdenoff/microfe-store 2026.625.3 → 2026.625.5
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/StoreRoutes.js +3 -3
- package/dist/StoreRoutes.js.map +1 -1
- package/dist/components/AccessDenied.js +3 -3
- package/dist/components/AccessDenied.js.map +1 -1
- package/dist/components/InstallAppModal.js +255 -175
- package/dist/components/InstallAppModal.js.map +1 -1
- package/dist/components/cart/CartDrawer.js +10 -10
- package/dist/components/cart/CartDrawer.js.map +1 -1
- package/dist/node_modules/{@apollo → .bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo}/client/errors/CombinedGraphQLErrors.js +1 -1
- package/dist/node_modules/.bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo/client/errors/CombinedGraphQLErrors.js.map +1 -0
- package/dist/node_modules/{@apollo → .bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo}/client/errors/utils.js +1 -1
- package/dist/node_modules/.bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo/client/errors/utils.js.map +1 -0
- package/dist/node_modules/{@apollo → .bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo}/client/link/core/ApolloLink.js +2 -2
- package/dist/node_modules/.bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo/client/link/core/ApolloLink.js.map +1 -0
- package/dist/node_modules/{@apollo → .bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo}/client/link/subscriptions/index.js +2 -2
- package/dist/node_modules/.bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo/client/link/subscriptions/index.js.map +1 -0
- package/dist/node_modules/{@apollo → .bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo}/client/link/utils/createOperation.js +1 -1
- package/dist/node_modules/.bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo/client/link/utils/createOperation.js.map +1 -0
- package/dist/node_modules/.bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo/client/utilities/caching/sizes.js.map +1 -0
- package/dist/node_modules/{@apollo → .bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo}/client/utilities/graphql/print.js +1 -1
- package/dist/node_modules/.bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo/client/utilities/graphql/print.js.map +1 -0
- package/dist/node_modules/{@apollo → .bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo}/client/utilities/internal/caches.js +2 -2
- package/dist/node_modules/.bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo/client/utilities/internal/caches.js.map +1 -0
- package/dist/node_modules/{@apollo → .bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo}/client/utilities/internal/checkDocument.js +1 -1
- package/dist/node_modules/.bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo/client/utilities/internal/checkDocument.js.map +1 -0
- package/dist/node_modules/{@apollo → .bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo}/client/utilities/internal/getMainDefinition.js +1 -1
- package/dist/node_modules/.bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo/client/utilities/internal/getMainDefinition.js.map +1 -0
- package/dist/node_modules/.bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo/client/utilities/internal/getMemoryInternals.js +9 -0
- package/dist/node_modules/.bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo/client/utilities/internal/getMemoryInternals.js.map +1 -0
- package/dist/node_modules/{@apollo → .bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo}/client/utilities/internal/getOperationDefinition.js +1 -1
- package/dist/node_modules/.bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo/client/utilities/internal/getOperationDefinition.js.map +1 -0
- package/dist/node_modules/.bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo/client/utilities/internal/getOperationName.js +8 -0
- package/dist/node_modules/.bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo/client/utilities/internal/getOperationName.js.map +1 -0
- package/dist/node_modules/{@apollo → .bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo}/client/utilities/internal/globals/global.js +1 -1
- package/dist/node_modules/.bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo/client/utilities/internal/globals/global.js.map +1 -0
- package/dist/node_modules/.bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo/client/utilities/internal/globals/maybe.js +10 -0
- package/dist/node_modules/.bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo/client/utilities/internal/globals/maybe.js.map +1 -0
- package/dist/node_modules/.bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo/client/utilities/internal/isNonNullObject.js +8 -0
- package/dist/node_modules/.bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo/client/utilities/internal/isNonNullObject.js.map +1 -0
- package/dist/node_modules/{@apollo → .bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo}/client/utilities/internal/makeUniqueId.js +1 -1
- package/dist/node_modules/.bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo/client/utilities/internal/makeUniqueId.js.map +1 -0
- package/dist/node_modules/{@apollo → .bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo}/client/utilities/internal/memoize.js +2 -2
- package/dist/node_modules/.bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo/client/utilities/internal/memoize.js.map +1 -0
- package/dist/node_modules/{@apollo → .bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo}/client/utilities/internal/stringifyForDisplay.js +1 -1
- package/dist/node_modules/.bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo/client/utilities/internal/stringifyForDisplay.js.map +1 -0
- package/dist/node_modules/{@apollo → .bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo}/client/utilities/invariant/index.js +1 -1
- package/dist/node_modules/.bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo/client/utilities/invariant/index.js.map +1 -0
- package/dist/node_modules/.bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo/client/version.js +6 -0
- package/dist/node_modules/.bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo/client/version.js.map +1 -0
- package/dist/node_modules/{@wry → .bun/@wry_caches@1.0.1/node_modules/@wry}/caches/lib/weak.js +1 -1
- package/dist/node_modules/.bun/@wry_caches@1.0.1/node_modules/@wry/caches/lib/weak.js.map +1 -0
- package/dist/node_modules/{@wry → .bun/@wry_trie@0.5.0/node_modules/@wry}/trie/lib/index.js +1 -1
- package/dist/node_modules/.bun/@wry_trie@0.5.0/node_modules/@wry/trie/lib/index.js.map +1 -0
- package/dist/node_modules/{graphql-ws → .bun/graphql-ws@6.0.8_796ebe57c2b0ffe0/node_modules/graphql-ws}/dist/client.js +1 -1
- package/dist/node_modules/.bun/graphql-ws@6.0.8_796ebe57c2b0ffe0/node_modules/graphql-ws/dist/client.js.map +1 -0
- package/dist/node_modules/{graphql-ws → .bun/graphql-ws@6.0.8_796ebe57c2b0ffe0/node_modules/graphql-ws}/dist/common-CGW11Fyb.js +1 -1
- package/dist/node_modules/.bun/graphql-ws@6.0.8_796ebe57c2b0ffe0/node_modules/graphql-ws/dist/common-CGW11Fyb.js.map +1 -0
- package/dist/node_modules/{rxjs → .bun/rxjs@7.8.2/node_modules/rxjs}/dist/esm5/internal/NotificationFactories.js +1 -1
- package/dist/node_modules/.bun/rxjs@7.8.2/node_modules/rxjs/dist/esm5/internal/NotificationFactories.js.map +1 -0
- package/dist/node_modules/{rxjs → .bun/rxjs@7.8.2/node_modules/rxjs}/dist/esm5/internal/Observable.js +1 -1
- package/dist/node_modules/.bun/rxjs@7.8.2/node_modules/rxjs/dist/esm5/internal/Observable.js.map +1 -0
- package/dist/node_modules/{rxjs → .bun/rxjs@7.8.2/node_modules/rxjs}/dist/esm5/internal/Subscriber.js +2 -2
- package/dist/node_modules/.bun/rxjs@7.8.2/node_modules/rxjs/dist/esm5/internal/Subscriber.js.map +1 -0
- package/dist/node_modules/{rxjs → .bun/rxjs@7.8.2/node_modules/rxjs}/dist/esm5/internal/Subscription.js +2 -2
- package/dist/node_modules/.bun/rxjs@7.8.2/node_modules/rxjs/dist/esm5/internal/Subscription.js.map +1 -0
- package/dist/node_modules/{rxjs → .bun/rxjs@7.8.2/node_modules/rxjs}/dist/esm5/internal/config.js +1 -1
- package/dist/node_modules/.bun/rxjs@7.8.2/node_modules/rxjs/dist/esm5/internal/config.js.map +1 -0
- package/dist/node_modules/{rxjs → .bun/rxjs@7.8.2/node_modules/rxjs}/dist/esm5/internal/observable/empty.js +1 -1
- package/dist/node_modules/.bun/rxjs@7.8.2/node_modules/rxjs/dist/esm5/internal/observable/empty.js.map +1 -0
- package/dist/node_modules/{rxjs → .bun/rxjs@7.8.2/node_modules/rxjs}/dist/esm5/internal/scheduler/timeoutProvider.js +2 -2
- package/dist/node_modules/.bun/rxjs@7.8.2/node_modules/rxjs/dist/esm5/internal/scheduler/timeoutProvider.js.map +1 -0
- package/dist/node_modules/{rxjs → .bun/rxjs@7.8.2/node_modules/rxjs}/dist/esm5/internal/symbol/observable.js +1 -1
- package/dist/node_modules/.bun/rxjs@7.8.2/node_modules/rxjs/dist/esm5/internal/symbol/observable.js.map +1 -0
- package/dist/node_modules/{rxjs → .bun/rxjs@7.8.2/node_modules/rxjs}/dist/esm5/internal/util/UnsubscriptionError.js +1 -1
- package/dist/node_modules/.bun/rxjs@7.8.2/node_modules/rxjs/dist/esm5/internal/util/UnsubscriptionError.js.map +1 -0
- package/dist/node_modules/.bun/rxjs@7.8.2/node_modules/rxjs/dist/esm5/internal/util/arrRemove.js +11 -0
- package/dist/node_modules/.bun/rxjs@7.8.2/node_modules/rxjs/dist/esm5/internal/util/arrRemove.js.map +1 -0
- package/dist/node_modules/{rxjs → .bun/rxjs@7.8.2/node_modules/rxjs}/dist/esm5/internal/util/createErrorClass.js +1 -1
- package/dist/node_modules/.bun/rxjs@7.8.2/node_modules/rxjs/dist/esm5/internal/util/createErrorClass.js.map +1 -0
- package/dist/node_modules/{rxjs → .bun/rxjs@7.8.2/node_modules/rxjs}/dist/esm5/internal/util/errorContext.js +1 -1
- package/dist/node_modules/.bun/rxjs@7.8.2/node_modules/rxjs/dist/esm5/internal/util/errorContext.js.map +1 -0
- package/dist/node_modules/.bun/rxjs@7.8.2/node_modules/rxjs/dist/esm5/internal/util/identity.js +8 -0
- package/dist/node_modules/.bun/rxjs@7.8.2/node_modules/rxjs/dist/esm5/internal/util/identity.js.map +1 -0
- package/dist/node_modules/.bun/rxjs@7.8.2/node_modules/rxjs/dist/esm5/internal/util/isFunction.js +8 -0
- package/dist/node_modules/.bun/rxjs@7.8.2/node_modules/rxjs/dist/esm5/internal/util/isFunction.js.map +1 -0
- package/dist/node_modules/.bun/rxjs@7.8.2/node_modules/rxjs/dist/esm5/internal/util/noop.js +6 -0
- package/dist/node_modules/.bun/rxjs@7.8.2/node_modules/rxjs/dist/esm5/internal/util/noop.js.map +1 -0
- package/dist/node_modules/{rxjs → .bun/rxjs@7.8.2/node_modules/rxjs}/dist/esm5/internal/util/pipe.js +1 -1
- package/dist/node_modules/.bun/rxjs@7.8.2/node_modules/rxjs/dist/esm5/internal/util/pipe.js.map +1 -0
- package/dist/node_modules/{rxjs → .bun/rxjs@7.8.2/node_modules/rxjs}/dist/esm5/internal/util/reportUnhandledError.js +1 -1
- package/dist/node_modules/.bun/rxjs@7.8.2/node_modules/rxjs/dist/esm5/internal/util/reportUnhandledError.js.map +1 -0
- package/dist/node_modules/{rxjs → .bun/tslib@2.8.1}/node_modules/tslib/tslib.es6.js +1 -1
- package/dist/node_modules/.bun/tslib@2.8.1/node_modules/tslib/tslib.es6.js.map +1 -0
- package/dist/pages/AdminDashboardPage.js +89 -90
- package/dist/pages/AdminDashboardPage.js.map +1 -1
- package/dist/pages/AdminReviewModerationPage.js +56 -58
- package/dist/pages/AdminReviewModerationPage.js.map +1 -1
- package/dist/pages/AdminStoresPage.js +372 -391
- package/dist/pages/AdminStoresPage.js.map +1 -1
- package/dist/pages/AdminSubmissionsQueuePage.js +148 -134
- package/dist/pages/AdminSubmissionsQueuePage.js.map +1 -1
- package/dist/pages/AppDetailPage.js +120 -123
- package/dist/pages/AppDetailPage.js.map +1 -1
- package/dist/pages/AppSettingsPage.js +297 -70
- package/dist/pages/AppSettingsPage.js.map +1 -1
- package/dist/pages/CartPage.js +76 -65
- package/dist/pages/CartPage.js.map +1 -1
- package/dist/pages/InstalledAppsPage.js +315 -106
- package/dist/pages/InstalledAppsPage.js.map +1 -1
- package/dist/pages/MarketplaceHomePage.js +378 -368
- package/dist/pages/MarketplaceHomePage.js.map +1 -1
- package/dist/pages/MyLicensesPage.js +75 -67
- package/dist/pages/MyLicensesPage.js.map +1 -1
- package/dist/pages/OrderConfirmationPage.js +37 -38
- package/dist/pages/OrderConfirmationPage.js.map +1 -1
- package/dist/pages/OrdersPage.js +64 -53
- package/dist/pages/OrdersPage.js.map +1 -1
- package/dist/pages/ProductDetailPage.js +213 -215
- package/dist/pages/ProductDetailPage.js.map +1 -1
- package/dist/pages/ProductReviewsPage.js +2 -2
- package/dist/pages/ProductReviewsPage.js.map +1 -1
- package/dist/pages/PublisherDashboardPage.js +92 -93
- package/dist/pages/PublisherDashboardPage.js.map +1 -1
- package/dist/pages/PublisherRevenuePage.js +60 -61
- package/dist/pages/PublisherRevenuePage.js.map +1 -1
- package/dist/pages/PublisherSubmissionsPage.js +96 -97
- package/dist/pages/PublisherSubmissionsPage.js.map +1 -1
- package/dist/pages/PublisherSubmitPage.js +184 -189
- package/dist/pages/PublisherSubmitPage.js.map +1 -1
- package/dist/providers/StoreProvider.js +3 -3
- package/package.json +2 -2
- package/dist/node_modules/@apollo/client/errors/CombinedGraphQLErrors.js.map +0 -1
- package/dist/node_modules/@apollo/client/errors/utils.js.map +0 -1
- package/dist/node_modules/@apollo/client/link/core/ApolloLink.js.map +0 -1
- package/dist/node_modules/@apollo/client/link/subscriptions/index.js.map +0 -1
- package/dist/node_modules/@apollo/client/link/utils/createOperation.js.map +0 -1
- package/dist/node_modules/@apollo/client/utilities/caching/sizes.js.map +0 -1
- package/dist/node_modules/@apollo/client/utilities/graphql/print.js.map +0 -1
- package/dist/node_modules/@apollo/client/utilities/internal/caches.js.map +0 -1
- package/dist/node_modules/@apollo/client/utilities/internal/checkDocument.js.map +0 -1
- package/dist/node_modules/@apollo/client/utilities/internal/getMainDefinition.js.map +0 -1
- package/dist/node_modules/@apollo/client/utilities/internal/getMemoryInternals.js +0 -9
- package/dist/node_modules/@apollo/client/utilities/internal/getMemoryInternals.js.map +0 -1
- package/dist/node_modules/@apollo/client/utilities/internal/getOperationDefinition.js.map +0 -1
- package/dist/node_modules/@apollo/client/utilities/internal/getOperationName.js +0 -8
- package/dist/node_modules/@apollo/client/utilities/internal/getOperationName.js.map +0 -1
- package/dist/node_modules/@apollo/client/utilities/internal/globals/global.js.map +0 -1
- package/dist/node_modules/@apollo/client/utilities/internal/globals/maybe.js +0 -10
- package/dist/node_modules/@apollo/client/utilities/internal/globals/maybe.js.map +0 -1
- package/dist/node_modules/@apollo/client/utilities/internal/isNonNullObject.js +0 -8
- package/dist/node_modules/@apollo/client/utilities/internal/isNonNullObject.js.map +0 -1
- package/dist/node_modules/@apollo/client/utilities/internal/makeUniqueId.js.map +0 -1
- package/dist/node_modules/@apollo/client/utilities/internal/memoize.js.map +0 -1
- package/dist/node_modules/@apollo/client/utilities/internal/stringifyForDisplay.js.map +0 -1
- package/dist/node_modules/@apollo/client/utilities/invariant/index.js.map +0 -1
- package/dist/node_modules/@apollo/client/version.js +0 -6
- package/dist/node_modules/@apollo/client/version.js.map +0 -1
- package/dist/node_modules/@wry/caches/lib/weak.js.map +0 -1
- package/dist/node_modules/@wry/trie/lib/index.js.map +0 -1
- package/dist/node_modules/graphql-ws/dist/client.js.map +0 -1
- package/dist/node_modules/graphql-ws/dist/common-CGW11Fyb.js.map +0 -1
- package/dist/node_modules/rxjs/dist/esm5/internal/NotificationFactories.js.map +0 -1
- package/dist/node_modules/rxjs/dist/esm5/internal/Observable.js.map +0 -1
- package/dist/node_modules/rxjs/dist/esm5/internal/Subscriber.js.map +0 -1
- package/dist/node_modules/rxjs/dist/esm5/internal/Subscription.js.map +0 -1
- package/dist/node_modules/rxjs/dist/esm5/internal/config.js.map +0 -1
- package/dist/node_modules/rxjs/dist/esm5/internal/observable/empty.js.map +0 -1
- package/dist/node_modules/rxjs/dist/esm5/internal/scheduler/timeoutProvider.js.map +0 -1
- package/dist/node_modules/rxjs/dist/esm5/internal/symbol/observable.js.map +0 -1
- package/dist/node_modules/rxjs/dist/esm5/internal/util/UnsubscriptionError.js.map +0 -1
- package/dist/node_modules/rxjs/dist/esm5/internal/util/arrRemove.js +0 -11
- package/dist/node_modules/rxjs/dist/esm5/internal/util/arrRemove.js.map +0 -1
- package/dist/node_modules/rxjs/dist/esm5/internal/util/createErrorClass.js.map +0 -1
- package/dist/node_modules/rxjs/dist/esm5/internal/util/errorContext.js.map +0 -1
- package/dist/node_modules/rxjs/dist/esm5/internal/util/identity.js +0 -8
- package/dist/node_modules/rxjs/dist/esm5/internal/util/identity.js.map +0 -1
- package/dist/node_modules/rxjs/dist/esm5/internal/util/isFunction.js +0 -8
- package/dist/node_modules/rxjs/dist/esm5/internal/util/isFunction.js.map +0 -1
- package/dist/node_modules/rxjs/dist/esm5/internal/util/noop.js +0 -6
- package/dist/node_modules/rxjs/dist/esm5/internal/util/noop.js.map +0 -1
- package/dist/node_modules/rxjs/dist/esm5/internal/util/pipe.js.map +0 -1
- package/dist/node_modules/rxjs/dist/esm5/internal/util/reportUnhandledError.js.map +0 -1
- package/dist/node_modules/rxjs/node_modules/tslib/tslib.es6.js.map +0 -1
- /package/dist/node_modules/{@apollo → .bun/@apollo_client@4.1.9_e571b0b00fd00a97/node_modules/@apollo}/client/utilities/caching/sizes.js +0 -0
|
@@ -3,130 +3,138 @@ import { useMyEntitlements as t } from "../hooks/useStoreGraphQL.js";
|
|
|
3
3
|
import { useMemo as n } from "react";
|
|
4
4
|
import { QuotaMeter as r } from "@burdenoff/fe-libs/shared/components";
|
|
5
5
|
import { useI18n as i } from "@burdenoff/fe-libs/shared/providers/shell/I18nProvider";
|
|
6
|
-
import { AlertCircle as a, ArrowLeft as o,
|
|
7
|
-
import { Fragment as
|
|
8
|
-
import { useNavigate as
|
|
9
|
-
import { EmphasisPanel as p, IllustratedEmptyState as m } from "@burdenoff/fe-libs/ui";
|
|
6
|
+
import { AlertCircle as a, ArrowLeft as o, KeyRound as s, Loader2 as c, ShieldCheck as l } from "lucide-react";
|
|
7
|
+
import { Fragment as u, jsx as d, jsxs as f } from "react/jsx-runtime";
|
|
8
|
+
import { useNavigate as p } from "react-router-dom";
|
|
10
9
|
//#region src/pages/MyLicensesPage.tsx
|
|
11
|
-
var
|
|
12
|
-
let
|
|
13
|
-
return /* @__PURE__ */
|
|
10
|
+
var m = (e) => e === "ACTIVE" ? "bg-status-success-bg-subtle text-status-success-text" : e === "SUSPENDED" || e === "PENDING" ? "bg-status-warning-bg-subtle text-status-warning-text" : e === "EXPIRED" || e === "REVOKED" ? "bg-status-error-bg-subtle text-status-error-text" : "bg-bg-sunken text-text-muted", h = () => {
|
|
11
|
+
let h = p(), { basePath: g } = e(), { t: _ } = i(), { entitlements: v, hasMore: y, loading: b, error: x, refetch: S, loadMore: C } = t(), w = n(() => v.slice().sort((e, t) => e.id.localeCompare(t.id)), [v]);
|
|
12
|
+
return /* @__PURE__ */ f("div", {
|
|
14
13
|
className: "flex h-full flex-col",
|
|
15
|
-
children: [/* @__PURE__ */
|
|
16
|
-
className: "sticky top-0 z-10 border-b border-border-
|
|
17
|
-
children: /* @__PURE__ */
|
|
14
|
+
children: [/* @__PURE__ */ d("header", {
|
|
15
|
+
className: "sticky top-0 z-10 border-b border-border-default bg-bg-surface px-6 py-4",
|
|
16
|
+
children: /* @__PURE__ */ f("div", {
|
|
18
17
|
className: "mx-auto flex max-w-5xl items-center gap-4",
|
|
19
|
-
children: [/* @__PURE__ */
|
|
18
|
+
children: [/* @__PURE__ */ d("button", {
|
|
20
19
|
type: "button",
|
|
21
|
-
onClick: () =>
|
|
20
|
+
onClick: () => h(-1),
|
|
22
21
|
"aria-label": "Go back",
|
|
23
22
|
className: "cursor-pointer rounded-lg p-2 text-text-muted transition-colors hover:bg-bg-sunken hover:text-text-primary",
|
|
24
|
-
children: /* @__PURE__ */
|
|
25
|
-
}), /* @__PURE__ */
|
|
23
|
+
children: /* @__PURE__ */ d(o, { className: "size-5" })
|
|
24
|
+
}), /* @__PURE__ */ f("div", { children: [/* @__PURE__ */ d("h1", {
|
|
26
25
|
className: "text-2xl font-bold text-text-primary",
|
|
27
|
-
children:
|
|
28
|
-
}), /* @__PURE__ */
|
|
26
|
+
children: _("pages.licenses.title", { defaultValue: "My Licenses" })
|
|
27
|
+
}), /* @__PURE__ */ d("p", {
|
|
29
28
|
className: "text-sm text-text-muted",
|
|
30
|
-
children:
|
|
29
|
+
children: _("pages.licenses.subtitle", { defaultValue: "Review and manage your product entitlements" })
|
|
31
30
|
})] })]
|
|
32
31
|
})
|
|
33
|
-
}), /* @__PURE__ */
|
|
32
|
+
}), /* @__PURE__ */ d("main", {
|
|
34
33
|
className: "flex-1 overflow-y-auto p-6",
|
|
35
|
-
children: /* @__PURE__ */
|
|
34
|
+
children: /* @__PURE__ */ d("div", {
|
|
36
35
|
className: "mx-auto max-w-5xl",
|
|
37
|
-
children:
|
|
36
|
+
children: b ? /* @__PURE__ */ d("output", {
|
|
38
37
|
"aria-label": "Loading licenses",
|
|
39
38
|
className: "flex items-center justify-center py-16",
|
|
40
|
-
children: /* @__PURE__ */
|
|
39
|
+
children: /* @__PURE__ */ d(c, {
|
|
41
40
|
className: "size-8 animate-spin text-text-muted",
|
|
42
41
|
"aria-hidden": "true"
|
|
43
42
|
})
|
|
44
|
-
}) :
|
|
43
|
+
}) : x ? /* @__PURE__ */ f("div", {
|
|
45
44
|
role: "alert",
|
|
46
45
|
className: "rounded-xl border border-status-error-border bg-status-error-bg-subtle p-8 text-center",
|
|
47
46
|
children: [
|
|
48
|
-
/* @__PURE__ */
|
|
49
|
-
/* @__PURE__ */
|
|
47
|
+
/* @__PURE__ */ d(a, { className: "mx-auto mb-3 size-10 text-status-error-text" }),
|
|
48
|
+
/* @__PURE__ */ d("h3", {
|
|
50
49
|
className: "text-lg font-semibold text-status-error-text",
|
|
51
|
-
children:
|
|
50
|
+
children: _("pages.licenses.failedToLoad", { defaultValue: "Failed to load licenses" })
|
|
52
51
|
}),
|
|
53
|
-
/* @__PURE__ */
|
|
52
|
+
/* @__PURE__ */ d("p", {
|
|
54
53
|
className: "mt-2 text-sm text-text-muted",
|
|
55
|
-
children:
|
|
54
|
+
children: x.message
|
|
56
55
|
}),
|
|
57
|
-
/* @__PURE__ */
|
|
56
|
+
/* @__PURE__ */ d("button", {
|
|
58
57
|
type: "button",
|
|
59
|
-
onClick: () =>
|
|
58
|
+
onClick: () => S(),
|
|
60
59
|
className: "mt-4 cursor-pointer rounded-lg bg-action-primary-bg px-4 py-2 text-sm font-medium text-action-primary-text",
|
|
61
|
-
children:
|
|
60
|
+
children: _("common.tryAgain", { defaultValue: "Try Again" })
|
|
62
61
|
})
|
|
63
62
|
]
|
|
64
|
-
}) :
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
63
|
+
}) : w.length === 0 ? /* @__PURE__ */ f("div", {
|
|
64
|
+
className: "rounded-xl border border-border-default bg-bg-surface p-12 text-center",
|
|
65
|
+
children: [
|
|
66
|
+
/* @__PURE__ */ d(s, { className: "mx-auto mb-3 size-12 text-text-muted" }),
|
|
67
|
+
/* @__PURE__ */ d("h3", {
|
|
68
|
+
className: "text-lg font-semibold text-text-primary",
|
|
69
|
+
children: _("pages.licenses.emptyTitle", { defaultValue: "No licenses yet" })
|
|
70
|
+
}),
|
|
71
|
+
/* @__PURE__ */ d("p", {
|
|
72
|
+
className: "mt-2 text-sm text-text-muted",
|
|
73
|
+
children: _("pages.licenses.emptyDescription", { defaultValue: "Purchase apps from the marketplace to see your licenses here." })
|
|
74
|
+
}),
|
|
75
|
+
/* @__PURE__ */ d("button", {
|
|
76
|
+
type: "button",
|
|
77
|
+
onClick: () => h(`${g}/marketplace`),
|
|
78
|
+
className: "mt-4 cursor-pointer rounded-lg bg-action-primary-bg px-4 py-2 text-sm font-medium text-action-primary-text",
|
|
79
|
+
children: _("pages.licenses.browseMarketplace", { defaultValue: "Browse Marketplace" })
|
|
80
|
+
})
|
|
81
|
+
]
|
|
82
|
+
}) : /* @__PURE__ */ f(u, { children: [/* @__PURE__ */ d("div", {
|
|
83
|
+
className: "mb-6 rounded-xl border border-border-default bg-bg-surface p-4",
|
|
84
|
+
children: /* @__PURE__ */ d(r, {
|
|
85
|
+
label: _("pages.licenses.activeLicenses", { defaultValue: "Active licenses" }),
|
|
86
|
+
used: w.filter((e) => e.status === "ACTIVE").length,
|
|
79
87
|
limit: null,
|
|
80
|
-
unit:
|
|
88
|
+
unit: _("pages.licenses.licensesUnit", { defaultValue: "licenses" })
|
|
81
89
|
})
|
|
82
|
-
}), /* @__PURE__ */
|
|
90
|
+
}), /* @__PURE__ */ f("ul", {
|
|
83
91
|
className: "flex flex-col gap-y-4",
|
|
84
|
-
children: [
|
|
85
|
-
className: "rounded-xl border border-border-
|
|
86
|
-
children: /* @__PURE__ */
|
|
92
|
+
children: [w.map((e) => /* @__PURE__ */ d("li", {
|
|
93
|
+
className: "rounded-xl border border-border-default bg-bg-surface p-4",
|
|
94
|
+
children: /* @__PURE__ */ f("div", {
|
|
87
95
|
className: "flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between",
|
|
88
|
-
children: [/* @__PURE__ */
|
|
89
|
-
/* @__PURE__ */
|
|
96
|
+
children: [/* @__PURE__ */ f("div", { children: [
|
|
97
|
+
/* @__PURE__ */ f("div", {
|
|
90
98
|
className: "flex items-center gap-2",
|
|
91
|
-
children: [/* @__PURE__ */
|
|
99
|
+
children: [/* @__PURE__ */ d(l, { className: "size-4 text-status-success-text" }), /* @__PURE__ */ f("h3", {
|
|
92
100
|
className: "font-semibold text-text-primary",
|
|
93
101
|
children: ["Product ", e.productId]
|
|
94
102
|
})]
|
|
95
103
|
}),
|
|
96
|
-
/* @__PURE__ */
|
|
104
|
+
/* @__PURE__ */ d("p", {
|
|
97
105
|
className: "mt-1 text-sm text-text-muted",
|
|
98
|
-
children:
|
|
106
|
+
children: _("pages.licenses.entitlementId", {
|
|
99
107
|
defaultValue: `Entitlement ID: ${e.id}`,
|
|
100
108
|
id: e.id
|
|
101
109
|
})
|
|
102
110
|
}),
|
|
103
|
-
e.licenseKey && /* @__PURE__ */
|
|
111
|
+
e.licenseKey && /* @__PURE__ */ d("p", {
|
|
104
112
|
className: "mt-1 text-sm text-text-muted",
|
|
105
|
-
children:
|
|
113
|
+
children: _("pages.licenses.licenseKey", {
|
|
106
114
|
defaultValue: `License key: ${e.licenseKey}`,
|
|
107
115
|
key: e.licenseKey
|
|
108
116
|
})
|
|
109
117
|
}),
|
|
110
|
-
e.expiresAt && /* @__PURE__ */
|
|
118
|
+
e.expiresAt && /* @__PURE__ */ d("p", {
|
|
111
119
|
className: "mt-1 text-sm text-text-muted",
|
|
112
|
-
children:
|
|
120
|
+
children: _("pages.licenses.expiresOn", {
|
|
113
121
|
defaultValue: `Expires on ${new Date(e.expiresAt).toLocaleDateString()}`,
|
|
114
122
|
date: new Date(e.expiresAt).toLocaleDateString()
|
|
115
123
|
})
|
|
116
124
|
})
|
|
117
|
-
] }), /* @__PURE__ */
|
|
118
|
-
className: `rounded-full px-3 py-1 text-xs font-semibold ${
|
|
125
|
+
] }), /* @__PURE__ */ d("span", {
|
|
126
|
+
className: `rounded-full px-3 py-1 text-xs font-semibold ${m(e.status)}`,
|
|
119
127
|
children: e.status
|
|
120
128
|
})]
|
|
121
129
|
})
|
|
122
|
-
}, e.id)),
|
|
130
|
+
}, e.id)), y && /* @__PURE__ */ d("li", {
|
|
123
131
|
className: "flex justify-center pt-4 list-none",
|
|
124
|
-
children: /* @__PURE__ */
|
|
132
|
+
children: /* @__PURE__ */ d("button", {
|
|
125
133
|
type: "button",
|
|
126
|
-
onClick:
|
|
127
|
-
disabled:
|
|
134
|
+
onClick: C,
|
|
135
|
+
disabled: b,
|
|
128
136
|
className: "rounded-lg border border-border-default px-6 py-2.5 text-sm font-medium text-text-primary hover:bg-bg-subtle disabled:opacity-50",
|
|
129
|
-
children:
|
|
137
|
+
children: b ? "Loading…" : "Load more"
|
|
130
138
|
})
|
|
131
139
|
})]
|
|
132
140
|
})] })
|
|
@@ -135,6 +143,6 @@ var h = (e) => e === "ACTIVE" ? "bg-status-success-bg-subtle text-status-success
|
|
|
135
143
|
});
|
|
136
144
|
};
|
|
137
145
|
//#endregion
|
|
138
|
-
export {
|
|
146
|
+
export { h as MyLicensesPage };
|
|
139
147
|
|
|
140
148
|
//# sourceMappingURL=MyLicensesPage.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MyLicensesPage.js","names":[],"sources":["../../src/pages/MyLicensesPage.tsx"],"sourcesContent":["import type { FC } from 'react';\nimport { useMemo } from 'react';\nimport { useNavigate } from 'react-router-dom';\nimport { ArrowLeft, ShieldCheck, AlertCircle, Loader2 } from 'lucide-react';\nimport { useI18n } from '@burdenoff/fe-libs/shared/providers/shell/I18nProvider';\nimport { QuotaMeter } from '@burdenoff/fe-libs/shared/components';\nimport { EmphasisPanel, IllustratedEmptyState } from '@burdenoff/fe-libs/ui';\nimport { useStore } from '../providers/StoreProvider';\nimport { useMyEntitlements } from '../hooks/useStoreGraphQL';\n\ninterface LicenseItem {\n id: string;\n productId: string;\n status: string;\n licenseKey?: string | null;\n expiresAt?: string | null;\n}\n\nconst statusClass = (status: string): string => {\n if (status === 'ACTIVE') return 'bg-status-success-bg-subtle text-status-success-text';\n if (status === 'SUSPENDED' || status === 'PENDING') {\n return 'bg-status-warning-bg-subtle text-status-warning-text';\n }\n if (status === 'EXPIRED' || status === 'REVOKED') {\n return 'bg-status-error-bg-subtle text-status-error-text';\n }\n return 'bg-bg-sunken text-text-muted';\n};\n\nexport const MyLicensesPage: FC = () => {\n const navigate = useNavigate();\n const { basePath } = useStore();\n const { t } = useI18n();\n const { entitlements, hasMore, loading, error, refetch, loadMore } = useMyEntitlements();\n\n const licenses = useMemo(\n () => (entitlements as LicenseItem[]).slice().sort((a, b) => a.id.localeCompare(b.id)),\n [entitlements]\n );\n\n return (\n <div className=\"flex h-full flex-col\">\n <header className=\"sticky top-0 z-10 border-b border-border-seam bg-bg-surface px-6 py-4\">\n <div className=\"mx-auto flex max-w-5xl items-center gap-4\">\n <button\n type=\"button\"\n onClick={() => navigate(-1)}\n aria-label=\"Go back\"\n className=\"cursor-pointer rounded-lg p-2 text-text-muted transition-colors hover:bg-bg-sunken hover:text-text-primary\"\n >\n <ArrowLeft className=\"size-5\" />\n </button>\n <div>\n <h1 className=\"text-2xl font-bold text-text-primary\">\n {t('pages.licenses.title', { defaultValue: 'My Licenses' })}\n </h1>\n <p className=\"text-sm text-text-muted\">\n {t('pages.licenses.subtitle', {\n defaultValue: 'Review and manage your product entitlements',\n })}\n </p>\n </div>\n </div>\n </header>\n\n <main className=\"flex-1 overflow-y-auto p-6\">\n <div className=\"mx-auto max-w-5xl\">\n {loading ? (\n <output\n aria-label=\"Loading licenses\"\n className=\"flex items-center justify-center py-16\"\n >\n <Loader2 className=\"size-8 animate-spin text-text-muted\" aria-hidden=\"true\" />\n </output>\n ) : error ? (\n <div\n role=\"alert\"\n className=\"rounded-xl border border-status-error-border bg-status-error-bg-subtle p-8 text-center\"\n >\n <AlertCircle className=\"mx-auto mb-3 size-10 text-status-error-text\" />\n <h3 className=\"text-lg font-semibold text-status-error-text\">\n {t('pages.licenses.failedToLoad', { defaultValue: 'Failed to load licenses' })}\n </h3>\n <p className=\"mt-2 text-sm text-text-muted\">{error.message}</p>\n <button\n type=\"button\"\n onClick={() => refetch()}\n className=\"mt-4 cursor-pointer rounded-lg bg-action-primary-bg px-4 py-2 text-sm font-medium text-action-primary-text\"\n >\n {t('common.tryAgain', { defaultValue: 'Try Again' })}\n </button>\n </div>\n ) : licenses.length === 0 ? (\n <IllustratedEmptyState\n illustration=\"empty-data\"\n title={t('pages.licenses.emptyTitle', { defaultValue: 'No licenses yet' })}\n description={t('pages.licenses.emptyDescription', {\n defaultValue: 'Purchase apps from the marketplace to see your licenses here.',\n })}\n action={\n <button\n type=\"button\"\n onClick={() => navigate(`${basePath}/marketplace`)}\n className=\"cursor-pointer rounded-lg bg-action-primary-bg px-4 py-2 text-sm font-medium text-action-primary-text\"\n >\n {t('pages.licenses.browseMarketplace', { defaultValue: 'Browse Marketplace' })}\n </button>\n }\n />\n ) : (\n <>\n {/*\n Inline quota meter showing active-license consumption vs the\n workspace plan limit. The limit is sourced from the billing\n summary when available; passing `null` renders an\n \"Unlimited\" indicator instead of misleading 0/0 progress.\n */}\n <EmphasisPanel className=\"mb-6\">\n <QuotaMeter\n label={t('pages.licenses.activeLicenses', {\n defaultValue: 'Active licenses',\n })}\n used={licenses.filter((l) => l.status === 'ACTIVE').length}\n limit={null}\n unit={t('pages.licenses.licensesUnit', {\n defaultValue: 'licenses',\n })}\n />\n </EmphasisPanel>\n <ul className=\"flex flex-col gap-y-4\">\n {licenses.map((license) => (\n <li\n key={license.id}\n className=\"rounded-xl border border-border-seam bg-bg-surface p-4 transition-[box-shadow,border-color] hover:border-border-strong hover:shadow-[var(--shadow-pop)]\"\n >\n <div className=\"flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between\">\n <div>\n <div className=\"flex items-center gap-2\">\n <ShieldCheck className=\"size-4 text-status-success-text\" />\n <h3 className=\"font-semibold text-text-primary\">\n Product {license.productId}\n </h3>\n </div>\n <p className=\"mt-1 text-sm text-text-muted\">\n {t('pages.licenses.entitlementId', {\n defaultValue: `Entitlement ID: ${license.id}`,\n id: license.id,\n })}\n </p>\n {license.licenseKey && (\n <p className=\"mt-1 text-sm text-text-muted\">\n {t('pages.licenses.licenseKey', {\n defaultValue: `License key: ${license.licenseKey}`,\n key: license.licenseKey,\n })}\n </p>\n )}\n {license.expiresAt && (\n <p className=\"mt-1 text-sm text-text-muted\">\n {t('pages.licenses.expiresOn', {\n defaultValue: `Expires on ${new Date(license.expiresAt).toLocaleDateString()}`,\n date: new Date(license.expiresAt).toLocaleDateString(),\n })}\n </p>\n )}\n </div>\n <span\n className={`rounded-full px-3 py-1 text-xs font-semibold ${statusClass(license.status)} ${\n license.status === 'ACTIVE'\n ? 'motion-safe:animate-vc-glow-pulse'\n : ''\n }`}\n >\n {license.status}\n </span>\n </div>\n </li>\n ))}\n {hasMore && (\n <li className=\"flex justify-center pt-4 list-none\">\n <button\n type=\"button\"\n onClick={loadMore}\n disabled={loading}\n className=\"rounded-lg border border-border-default px-6 py-2.5 text-sm font-medium text-text-primary hover:bg-bg-subtle disabled:opacity-50\"\n >\n {loading ? 'Loading…' : 'Load more'}\n </button>\n </li>\n )}\n </ul>\n </>\n )}\n </div>\n </main>\n </div>\n );\n};\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"MyLicensesPage.js","names":[],"sources":["../../src/pages/MyLicensesPage.tsx"],"sourcesContent":["import type { FC } from 'react';\nimport { useMemo } from 'react';\nimport { useNavigate } from 'react-router-dom';\nimport { KeyRound, ArrowLeft, ShieldCheck, AlertCircle, Loader2 } from 'lucide-react';\nimport { useI18n } from '@burdenoff/fe-libs/shared/providers/shell/I18nProvider';\nimport { QuotaMeter } from '@burdenoff/fe-libs/shared/components';\nimport { useStore } from '../providers/StoreProvider';\nimport { useMyEntitlements } from '../hooks/useStoreGraphQL';\n\ninterface LicenseItem {\n id: string;\n productId: string;\n status: string;\n licenseKey?: string | null;\n expiresAt?: string | null;\n}\n\nconst statusClass = (status: string): string => {\n if (status === 'ACTIVE') return 'bg-status-success-bg-subtle text-status-success-text';\n if (status === 'SUSPENDED' || status === 'PENDING') {\n return 'bg-status-warning-bg-subtle text-status-warning-text';\n }\n if (status === 'EXPIRED' || status === 'REVOKED') {\n return 'bg-status-error-bg-subtle text-status-error-text';\n }\n return 'bg-bg-sunken text-text-muted';\n};\n\nexport const MyLicensesPage: FC = () => {\n const navigate = useNavigate();\n const { basePath } = useStore();\n const { t } = useI18n();\n const { entitlements, hasMore, loading, error, refetch, loadMore } = useMyEntitlements();\n\n const licenses = useMemo(\n () => (entitlements as LicenseItem[]).slice().sort((a, b) => a.id.localeCompare(b.id)),\n [entitlements]\n );\n\n return (\n <div className=\"flex h-full flex-col\">\n <header className=\"sticky top-0 z-10 border-b border-border-default bg-bg-surface px-6 py-4\">\n <div className=\"mx-auto flex max-w-5xl items-center gap-4\">\n <button\n type=\"button\"\n onClick={() => navigate(-1)}\n aria-label=\"Go back\"\n className=\"cursor-pointer rounded-lg p-2 text-text-muted transition-colors hover:bg-bg-sunken hover:text-text-primary\"\n >\n <ArrowLeft className=\"size-5\" />\n </button>\n <div>\n <h1 className=\"text-2xl font-bold text-text-primary\">\n {t('pages.licenses.title', { defaultValue: 'My Licenses' })}\n </h1>\n <p className=\"text-sm text-text-muted\">\n {t('pages.licenses.subtitle', {\n defaultValue: 'Review and manage your product entitlements',\n })}\n </p>\n </div>\n </div>\n </header>\n\n <main className=\"flex-1 overflow-y-auto p-6\">\n <div className=\"mx-auto max-w-5xl\">\n {loading ? (\n <output\n aria-label=\"Loading licenses\"\n className=\"flex items-center justify-center py-16\"\n >\n <Loader2 className=\"size-8 animate-spin text-text-muted\" aria-hidden=\"true\" />\n </output>\n ) : error ? (\n <div\n role=\"alert\"\n className=\"rounded-xl border border-status-error-border bg-status-error-bg-subtle p-8 text-center\"\n >\n <AlertCircle className=\"mx-auto mb-3 size-10 text-status-error-text\" />\n <h3 className=\"text-lg font-semibold text-status-error-text\">\n {t('pages.licenses.failedToLoad', { defaultValue: 'Failed to load licenses' })}\n </h3>\n <p className=\"mt-2 text-sm text-text-muted\">{error.message}</p>\n <button\n type=\"button\"\n onClick={() => refetch()}\n className=\"mt-4 cursor-pointer rounded-lg bg-action-primary-bg px-4 py-2 text-sm font-medium text-action-primary-text\"\n >\n {t('common.tryAgain', { defaultValue: 'Try Again' })}\n </button>\n </div>\n ) : licenses.length === 0 ? (\n <div className=\"rounded-xl border border-border-default bg-bg-surface p-12 text-center\">\n <KeyRound className=\"mx-auto mb-3 size-12 text-text-muted\" />\n <h3 className=\"text-lg font-semibold text-text-primary\">\n {t('pages.licenses.emptyTitle', { defaultValue: 'No licenses yet' })}\n </h3>\n <p className=\"mt-2 text-sm text-text-muted\">\n {t('pages.licenses.emptyDescription', {\n defaultValue: 'Purchase apps from the marketplace to see your licenses here.',\n })}\n </p>\n <button\n type=\"button\"\n onClick={() => navigate(`${basePath}/marketplace`)}\n className=\"mt-4 cursor-pointer rounded-lg bg-action-primary-bg px-4 py-2 text-sm font-medium text-action-primary-text\"\n >\n {t('pages.licenses.browseMarketplace', { defaultValue: 'Browse Marketplace' })}\n </button>\n </div>\n ) : (\n <>\n {/*\n Inline quota meter showing active-license consumption vs the\n workspace plan limit. The limit is sourced from the billing\n summary when available; passing `null` renders an\n \"Unlimited\" indicator instead of misleading 0/0 progress.\n */}\n <div className=\"mb-6 rounded-xl border border-border-default bg-bg-surface p-4\">\n <QuotaMeter\n label={t('pages.licenses.activeLicenses', {\n defaultValue: 'Active licenses',\n })}\n used={licenses.filter((l) => l.status === 'ACTIVE').length}\n limit={null}\n unit={t('pages.licenses.licensesUnit', {\n defaultValue: 'licenses',\n })}\n />\n </div>\n <ul className=\"flex flex-col gap-y-4\">\n {licenses.map((license) => (\n <li\n key={license.id}\n className=\"rounded-xl border border-border-default bg-bg-surface p-4\"\n >\n <div className=\"flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between\">\n <div>\n <div className=\"flex items-center gap-2\">\n <ShieldCheck className=\"size-4 text-status-success-text\" />\n <h3 className=\"font-semibold text-text-primary\">\n Product {license.productId}\n </h3>\n </div>\n <p className=\"mt-1 text-sm text-text-muted\">\n {t('pages.licenses.entitlementId', {\n defaultValue: `Entitlement ID: ${license.id}`,\n id: license.id,\n })}\n </p>\n {license.licenseKey && (\n <p className=\"mt-1 text-sm text-text-muted\">\n {t('pages.licenses.licenseKey', {\n defaultValue: `License key: ${license.licenseKey}`,\n key: license.licenseKey,\n })}\n </p>\n )}\n {license.expiresAt && (\n <p className=\"mt-1 text-sm text-text-muted\">\n {t('pages.licenses.expiresOn', {\n defaultValue: `Expires on ${new Date(license.expiresAt).toLocaleDateString()}`,\n date: new Date(license.expiresAt).toLocaleDateString(),\n })}\n </p>\n )}\n </div>\n <span\n className={`rounded-full px-3 py-1 text-xs font-semibold ${statusClass(license.status)}`}\n >\n {license.status}\n </span>\n </div>\n </li>\n ))}\n {hasMore && (\n <li className=\"flex justify-center pt-4 list-none\">\n <button\n type=\"button\"\n onClick={loadMore}\n disabled={loading}\n className=\"rounded-lg border border-border-default px-6 py-2.5 text-sm font-medium text-text-primary hover:bg-bg-subtle disabled:opacity-50\"\n >\n {loading ? 'Loading…' : 'Load more'}\n </button>\n </li>\n )}\n </ul>\n </>\n )}\n </div>\n </main>\n </div>\n );\n};\n"],"mappings":"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"}
|
|
@@ -6,101 +6,100 @@ import { ArrowRight as s, CheckCircle2 as c, Copy as l, Download as u, KeyRound
|
|
|
6
6
|
import { jsx as p, jsxs as m } from "react/jsx-runtime";
|
|
7
7
|
import { useNavigate as h, useParams as g } from "react-router-dom";
|
|
8
8
|
import { graphqlFetch as _ } from "@burdenoff/fe-libs/shared/graphql";
|
|
9
|
-
import { EmphasisPanel as v } from "@burdenoff/fe-libs/ui";
|
|
10
9
|
//#region src/pages/OrderConfirmationPage.tsx
|
|
11
|
-
var
|
|
12
|
-
let
|
|
10
|
+
var v = "\n query OrderConfirmation($id: ID!) {\n getStoreOrder(id: $id) {\n id\n status\n total\n currency\n purchasedAt\n lineItems\n context\n }\n myEntitlements {\n id\n productId\n licenseKey\n expiresAt\n features\n product {\n id\n name\n slug\n icon\n manifest\n }\n }\n }\n", y = () => {
|
|
11
|
+
let y = h(), { basePath: b, authToken: x } = e(), { orderId: S } = g(), [C, w] = o(null), [T, E] = o([]), [D, O] = o(!0), [k, A] = o(null), [j, M] = o(null);
|
|
13
12
|
a(() => {
|
|
14
|
-
if (!
|
|
13
|
+
if (!S) return;
|
|
15
14
|
let e = !1;
|
|
16
15
|
return (async () => {
|
|
17
|
-
|
|
16
|
+
O(!0), A(null);
|
|
18
17
|
try {
|
|
19
18
|
let t = await _({
|
|
20
19
|
gateway: "global",
|
|
21
|
-
query:
|
|
22
|
-
variables: { id:
|
|
23
|
-
authToken:
|
|
20
|
+
query: v,
|
|
21
|
+
variables: { id: S },
|
|
22
|
+
authToken: x || void 0
|
|
24
23
|
});
|
|
25
24
|
if (e) return;
|
|
26
25
|
if (t.errors?.length) throw Error(t.errors[0]?.message ?? "Failed to load order");
|
|
27
|
-
|
|
26
|
+
w(t.data?.getStoreOrder ?? null);
|
|
28
27
|
let n = new Set((t.data?.getStoreOrder?.lineItems ?? []).map((e) => e.productId));
|
|
29
|
-
|
|
28
|
+
E((t.data?.myEntitlements ?? []).filter((e) => n.has(e.productId)));
|
|
30
29
|
} catch (t) {
|
|
31
30
|
if (e) return;
|
|
32
|
-
|
|
31
|
+
A(t instanceof Error ? t.message : "Failed to load order");
|
|
33
32
|
} finally {
|
|
34
|
-
e ||
|
|
33
|
+
e || O(!1);
|
|
35
34
|
}
|
|
36
35
|
})(), () => {
|
|
37
36
|
e = !0;
|
|
38
37
|
};
|
|
39
|
-
}, [
|
|
40
|
-
let
|
|
38
|
+
}, [S, x]);
|
|
39
|
+
let N = async (e) => {
|
|
41
40
|
r("light");
|
|
42
41
|
try {
|
|
43
|
-
await n(e) ? (
|
|
42
|
+
await n(e) ? (M(e), i("success"), setTimeout(() => M(null), 1500)) : i("error");
|
|
44
43
|
} catch {
|
|
45
44
|
i("error");
|
|
46
45
|
}
|
|
47
|
-
},
|
|
46
|
+
}, P = (e, t) => {
|
|
48
47
|
let n = new URLSearchParams();
|
|
49
48
|
n.set("install", e), t && n.set("licenseKey", t), window.location.href = `/vibecontrols/agents?${n.toString()}`;
|
|
50
49
|
};
|
|
51
50
|
return /* @__PURE__ */ m("main", {
|
|
52
51
|
className: "mx-auto max-w-3xl p-6",
|
|
53
52
|
children: [
|
|
54
|
-
/* @__PURE__ */ m(
|
|
55
|
-
className: "rounded-2xl p-6 text-center",
|
|
53
|
+
/* @__PURE__ */ m("div", {
|
|
54
|
+
className: "rounded-2xl border border-border-default bg-surface-raised p-6 text-center",
|
|
56
55
|
children: [
|
|
57
56
|
/* @__PURE__ */ p(c, { className: "mx-auto size-12 text-status-success-text" }),
|
|
58
57
|
/* @__PURE__ */ p("h1", {
|
|
59
58
|
className: "mt-3 text-2xl font-bold text-text-primary",
|
|
60
59
|
children: "Order placed successfully"
|
|
61
60
|
}),
|
|
62
|
-
|
|
63
|
-
className: "mt-1 text-sm
|
|
61
|
+
C && /* @__PURE__ */ m("p", {
|
|
62
|
+
className: "mt-1 text-sm text-text-secondary",
|
|
64
63
|
children: [
|
|
65
64
|
"Total: ",
|
|
66
|
-
((e, n) => t(e, n || "USD"))(
|
|
67
|
-
|
|
65
|
+
((e, n) => t(e, n || "USD"))(C.total, C.currency),
|
|
66
|
+
C.purchasedAt && ` • ${new Date(C.purchasedAt).toLocaleString()}`
|
|
68
67
|
]
|
|
69
68
|
}),
|
|
70
|
-
|
|
71
|
-
className: "mx-auto mt-4 max-w-sm rounded-lg border border-border-
|
|
69
|
+
S && /* @__PURE__ */ m("div", {
|
|
70
|
+
className: "mx-auto mt-4 max-w-sm rounded-lg border border-border-default bg-surface-default px-4 py-2 text-left",
|
|
72
71
|
children: [/* @__PURE__ */ p("p", {
|
|
73
72
|
className: "text-xs uppercase tracking-wide text-text-tertiary",
|
|
74
73
|
children: "Order ID"
|
|
75
74
|
}), /* @__PURE__ */ p("p", {
|
|
76
75
|
className: "mt-0.5 break-all font-mono text-xs text-text-primary",
|
|
77
|
-
children:
|
|
76
|
+
children: S
|
|
78
77
|
})]
|
|
79
78
|
})
|
|
80
79
|
]
|
|
81
80
|
}),
|
|
82
|
-
|
|
81
|
+
k && /* @__PURE__ */ p("div", {
|
|
83
82
|
role: "alert",
|
|
84
83
|
className: "mt-4 rounded-md border border-border-danger bg-surface-danger-muted px-4 py-3 text-sm text-text-danger",
|
|
85
|
-
children:
|
|
84
|
+
children: k
|
|
86
85
|
}),
|
|
87
|
-
|
|
86
|
+
D ? /* @__PURE__ */ p("output", {
|
|
88
87
|
className: "mt-6 block py-12 text-center text-text-secondary",
|
|
89
88
|
children: "Loading licenses…"
|
|
90
|
-
}) :
|
|
89
|
+
}) : T.length > 0 ? /* @__PURE__ */ m("div", {
|
|
91
90
|
className: "mt-6",
|
|
92
91
|
children: [/* @__PURE__ */ m("h2", {
|
|
93
92
|
className: "mb-3 flex items-center gap-2 text-sm font-semibold text-text-primary",
|
|
94
93
|
children: [
|
|
95
94
|
/* @__PURE__ */ p(d, { className: "size-4" }),
|
|
96
95
|
"Your licenses (",
|
|
97
|
-
|
|
96
|
+
T.length,
|
|
98
97
|
")"
|
|
99
98
|
]
|
|
100
99
|
}), /* @__PURE__ */ p("ul", {
|
|
101
100
|
className: "space-y-3",
|
|
102
|
-
children:
|
|
103
|
-
className: "rounded-lg border border-border-
|
|
101
|
+
children: T.map((e) => /* @__PURE__ */ p("li", {
|
|
102
|
+
className: "rounded-lg border border-border-default bg-surface-raised p-4",
|
|
104
103
|
children: /* @__PURE__ */ m("div", {
|
|
105
104
|
className: "flex items-start gap-3",
|
|
106
105
|
children: [
|
|
@@ -130,13 +129,13 @@ var y = "\n query OrderConfirmation($id: ID!) {\n getStoreOrder(id: $id) {\n
|
|
|
130
129
|
children: e.licenseKey
|
|
131
130
|
}), /* @__PURE__ */ p("button", {
|
|
132
131
|
type: "button",
|
|
133
|
-
onClick: () => void
|
|
132
|
+
onClick: () => void N(e.licenseKey),
|
|
134
133
|
className: "rounded-md border border-border-default bg-surface-default p-1 text-text-primary hover:bg-surface-hover",
|
|
135
134
|
title: "Copy license key",
|
|
136
135
|
children: /* @__PURE__ */ p(l, { className: "size-3.5" })
|
|
137
136
|
})]
|
|
138
137
|
}),
|
|
139
|
-
|
|
138
|
+
j === e.licenseKey && /* @__PURE__ */ p("p", {
|
|
140
139
|
className: "mt-1 text-xs text-status-success-text",
|
|
141
140
|
children: "Copied to clipboard"
|
|
142
141
|
})
|
|
@@ -144,7 +143,7 @@ var y = "\n query OrderConfirmation($id: ID!) {\n getStoreOrder(id: $id) {\n
|
|
|
144
143
|
}),
|
|
145
144
|
/* @__PURE__ */ m("button", {
|
|
146
145
|
type: "button",
|
|
147
|
-
onClick: () =>
|
|
146
|
+
onClick: () => P(e.productId, e.licenseKey),
|
|
148
147
|
className: "inline-flex items-center gap-1 rounded-md bg-action-primary-bg px-3 py-1.5 text-xs font-semibold text-action-primary-text hover:opacity-90",
|
|
149
148
|
children: [/* @__PURE__ */ p(u, { className: "size-3.5" }), "Install to workspace"]
|
|
150
149
|
})
|
|
@@ -157,12 +156,12 @@ var y = "\n query OrderConfirmation($id: ID!) {\n getStoreOrder(id: $id) {\n
|
|
|
157
156
|
className: "mt-6 flex flex-col gap-2 sm:flex-row sm:justify-center",
|
|
158
157
|
children: [/* @__PURE__ */ m("button", {
|
|
159
158
|
type: "button",
|
|
160
|
-
onClick: () =>
|
|
159
|
+
onClick: () => y(`${b}/orders`),
|
|
161
160
|
className: "cursor-pointer inline-flex items-center justify-center gap-2 rounded-lg bg-action-primary-bg px-4 py-2 text-sm font-semibold text-action-primary-text",
|
|
162
161
|
children: [/* @__PURE__ */ p(f, { className: "size-4" }), "View My Orders"]
|
|
163
162
|
}), /* @__PURE__ */ m("button", {
|
|
164
163
|
type: "button",
|
|
165
|
-
onClick: () =>
|
|
164
|
+
onClick: () => y(`${b}/marketplace`),
|
|
166
165
|
className: "cursor-pointer inline-flex items-center justify-center gap-2 rounded-lg border border-border-default px-4 py-2 text-sm font-semibold text-text-primary hover:bg-surface-hover",
|
|
167
166
|
children: ["Continue Shopping", /* @__PURE__ */ p(s, { className: "size-4" })]
|
|
168
167
|
})]
|
|
@@ -171,6 +170,6 @@ var y = "\n query OrderConfirmation($id: ID!) {\n getStoreOrder(id: $id) {\n
|
|
|
171
170
|
});
|
|
172
171
|
};
|
|
173
172
|
//#endregion
|
|
174
|
-
export {
|
|
173
|
+
export { y as OrderConfirmationPage };
|
|
175
174
|
|
|
176
175
|
//# sourceMappingURL=OrderConfirmationPage.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"OrderConfirmationPage.js","names":[],"sources":["../../src/pages/OrderConfirmationPage.tsx"],"sourcesContent":["import type { FC } from 'react';\nimport { useEffect, useState } from 'react';\nimport { useNavigate, useParams } from 'react-router-dom';\nimport { CheckCircle2, Receipt, ArrowRight, Copy, Download, KeyRound } from 'lucide-react';\nimport { graphqlFetch } from '@burdenoff/fe-libs/shared/graphql';\nimport { EmphasisPanel } from '@burdenoff/fe-libs/ui';\nimport { useStore } from '../providers/StoreProvider';\nimport { nativeCopyText, nativeImpact, nativeNotify } from '../utils/nativeBridge';\nimport { formatPrice as formatCurrency } from '../utils';\n\ntype LineItem = {\n productId: string;\n name: string;\n quantity: number;\n unitPrice: number;\n subtotal: number;\n itemType?: string;\n};\n\ntype OrderDetails = {\n id: string;\n status: string;\n total: number;\n currency: string;\n purchasedAt?: string | null;\n lineItems: LineItem[];\n context?: Record<string, unknown> | null;\n};\n\ntype Entitlement = {\n id: string;\n productId: string;\n licenseKey: string | null;\n expiresAt: string | null;\n features: string[];\n product: {\n id: string;\n name: string;\n slug: string;\n icon: string | null;\n manifest: Record<string, unknown> | null;\n } | null;\n};\n\nconst ORDER_QUERY = /* GraphQL */ `\n query OrderConfirmation($id: ID!) {\n getStoreOrder(id: $id) {\n id\n status\n total\n currency\n purchasedAt\n lineItems\n context\n }\n myEntitlements {\n id\n productId\n licenseKey\n expiresAt\n features\n product {\n id\n name\n slug\n icon\n manifest\n }\n }\n }\n`;\n\nexport const OrderConfirmationPage: FC = () => {\n const navigate = useNavigate();\n const { basePath, authToken } = useStore();\n const { orderId } = useParams<{ orderId: string }>();\n const [order, setOrder] = useState<OrderDetails | null>(null);\n const [entitlements, setEntitlements] = useState<Entitlement[]>([]);\n const [loading, setLoading] = useState(true);\n const [error, setError] = useState<string | null>(null);\n const [copiedKey, setCopiedKey] = useState<string | null>(null);\n\n useEffect(() => {\n if (!orderId) return;\n let cancelled = false;\n const load = async () => {\n setLoading(true);\n setError(null);\n try {\n const result = await graphqlFetch<{\n getStoreOrder: OrderDetails | null;\n myEntitlements: Entitlement[];\n }>({\n gateway: 'global',\n query: ORDER_QUERY,\n variables: { id: orderId },\n authToken: authToken || undefined,\n });\n if (cancelled) return;\n if (result.errors?.length) {\n throw new Error(result.errors[0]?.message ?? 'Failed to load order');\n }\n setOrder(result.data?.getStoreOrder ?? null);\n // Filter entitlements to only those matching products in this order\n const productIds = new Set(\n (result.data?.getStoreOrder?.lineItems ?? []).map((item) => item.productId)\n );\n const orderEntitlements = (result.data?.myEntitlements ?? []).filter((e) =>\n productIds.has(e.productId)\n );\n setEntitlements(orderEntitlements);\n } catch (err) {\n if (cancelled) return;\n setError(err instanceof Error ? err.message : 'Failed to load order');\n } finally {\n if (!cancelled) setLoading(false);\n }\n };\n void load();\n return () => {\n cancelled = true;\n };\n }, [orderId, authToken]);\n\n const copyKey = async (key: string) => {\n void nativeImpact('light');\n try {\n const ok = await nativeCopyText(key);\n if (ok) {\n setCopiedKey(key);\n void nativeNotify('success');\n setTimeout(() => setCopiedKey(null), 1500);\n } else {\n void nativeNotify('error');\n }\n } catch {\n void nativeNotify('error');\n }\n };\n\n const installInWorkspace = (productId: string, licenseKey: string | null) => {\n const params = new URLSearchParams();\n params.set('install', productId);\n if (licenseKey) params.set('licenseKey', licenseKey);\n // Navigate to the vibecontrols plugin install page via the top-level router.\n // Uses a plain anchor to avoid cross-MFE router imports.\n window.location.href = `/vibecontrols/agents?${params.toString()}`;\n };\n\n const formatPrice = (amount: number, currency: string) =>\n formatCurrency(amount, currency || 'USD');\n\n return (\n <main className=\"mx-auto max-w-3xl p-6\">\n <EmphasisPanel className=\"rounded-2xl p-6 text-center\">\n <CheckCircle2 className=\"mx-auto size-12 text-status-success-text\" />\n <h1 className=\"mt-3 text-2xl font-bold text-text-primary\">Order placed successfully</h1>\n {order && (\n <p className=\"mt-1 text-sm tabular-nums text-text-secondary\">\n Total: {formatPrice(order.total, order.currency)}\n {order.purchasedAt && ` • ${new Date(order.purchasedAt).toLocaleString()}`}\n </p>\n )}\n {orderId && (\n <div className=\"mx-auto mt-4 max-w-sm rounded-lg border border-border-seam bg-surface-default px-4 py-2 text-left\">\n <p className=\"text-xs uppercase tracking-wide text-text-tertiary\">Order ID</p>\n <p className=\"mt-0.5 break-all font-mono text-xs text-text-primary\">{orderId}</p>\n </div>\n )}\n </EmphasisPanel>\n\n {error && (\n <div\n role=\"alert\"\n className=\"mt-4 rounded-md border border-border-danger bg-surface-danger-muted px-4 py-3 text-sm text-text-danger\"\n >\n {error}\n </div>\n )}\n\n {loading ? (\n <output className=\"mt-6 block py-12 text-center text-text-secondary\">\n Loading licenses…\n </output>\n ) : entitlements.length > 0 ? (\n <div className=\"mt-6\">\n <h2 className=\"mb-3 flex items-center gap-2 text-sm font-semibold text-text-primary\">\n <KeyRound className=\"size-4\" />\n Your licenses ({entitlements.length})\n </h2>\n <ul className=\"space-y-3\">\n {entitlements.map((ent) => (\n <li\n key={ent.id}\n className=\"rounded-lg border border-border-seam bg-surface-raised p-4 transition-[box-shadow,border-color] hover:border-border-strong hover:shadow-[var(--shadow-pop)]\"\n >\n <div className=\"flex items-start gap-3\">\n {ent.product?.icon ? (\n <img\n src={ent.product.icon}\n alt=\"\"\n className=\"size-12 flex-shrink-0 rounded-md object-cover\"\n />\n ) : (\n <div className=\"flex size-12 flex-shrink-0 items-center justify-center rounded-md bg-surface-muted text-xs text-text-secondary\">\n {ent.product?.name.slice(0, 2).toUpperCase() ?? '?'}\n </div>\n )}\n <div className=\"min-w-0 flex-1\">\n <h3 className=\"text-base font-semibold text-text-primary\">\n {ent.product?.name ?? 'Unknown product'}\n </h3>\n {ent.expiresAt && (\n <p className=\"text-xs text-text-secondary\">\n Expires: {new Date(ent.expiresAt).toLocaleDateString()}\n </p>\n )}\n {ent.licenseKey && (\n <div className=\"mt-2 flex items-center gap-2\">\n <code className=\"flex-1 truncate rounded bg-surface-muted px-2 py-1 font-mono text-[11px] text-text-primary\">\n {ent.licenseKey}\n </code>\n <button\n type=\"button\"\n onClick={() => void copyKey(ent.licenseKey!)}\n className=\"rounded-md border border-border-default bg-surface-default p-1 text-text-primary hover:bg-surface-hover\"\n title=\"Copy license key\"\n >\n <Copy className=\"size-3.5\" />\n </button>\n </div>\n )}\n {copiedKey === ent.licenseKey && (\n <p className=\"mt-1 text-xs text-status-success-text\">Copied to clipboard</p>\n )}\n </div>\n <button\n type=\"button\"\n onClick={() => installInWorkspace(ent.productId, ent.licenseKey)}\n className=\"inline-flex items-center gap-1 rounded-md bg-action-primary-bg px-3 py-1.5 text-xs font-semibold text-action-primary-text hover:opacity-90\"\n >\n <Download className=\"size-3.5\" />\n Install to workspace\n </button>\n </div>\n </li>\n ))}\n </ul>\n </div>\n ) : null}\n\n <div className=\"mt-6 flex flex-col gap-2 sm:flex-row sm:justify-center\">\n <button\n type=\"button\"\n onClick={() => navigate(`${basePath}/orders`)}\n className=\"cursor-pointer inline-flex items-center justify-center gap-2 rounded-lg bg-action-primary-bg px-4 py-2 text-sm font-semibold text-action-primary-text\"\n >\n <Receipt className=\"size-4\" />\n View My Orders\n </button>\n <button\n type=\"button\"\n onClick={() => navigate(`${basePath}/marketplace`)}\n className=\"cursor-pointer inline-flex items-center justify-center gap-2 rounded-lg border border-border-default px-4 py-2 text-sm font-semibold text-text-primary hover:bg-surface-hover\"\n >\n Continue Shopping\n <ArrowRight className=\"size-4\" />\n </button>\n </div>\n </main>\n );\n};\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"OrderConfirmationPage.js","names":[],"sources":["../../src/pages/OrderConfirmationPage.tsx"],"sourcesContent":["import type { FC } from 'react';\nimport { useEffect, useState } from 'react';\nimport { useNavigate, useParams } from 'react-router-dom';\nimport { CheckCircle2, Receipt, ArrowRight, Copy, Download, KeyRound } from 'lucide-react';\nimport { graphqlFetch } from '@burdenoff/fe-libs/shared/graphql';\nimport { useStore } from '../providers/StoreProvider';\nimport { nativeCopyText, nativeImpact, nativeNotify } from '../utils/nativeBridge';\nimport { formatPrice as formatCurrency } from '../utils';\n\ntype LineItem = {\n productId: string;\n name: string;\n quantity: number;\n unitPrice: number;\n subtotal: number;\n itemType?: string;\n};\n\ntype OrderDetails = {\n id: string;\n status: string;\n total: number;\n currency: string;\n purchasedAt?: string | null;\n lineItems: LineItem[];\n context?: Record<string, unknown> | null;\n};\n\ntype Entitlement = {\n id: string;\n productId: string;\n licenseKey: string | null;\n expiresAt: string | null;\n features: string[];\n product: {\n id: string;\n name: string;\n slug: string;\n icon: string | null;\n manifest: Record<string, unknown> | null;\n } | null;\n};\n\nconst ORDER_QUERY = /* GraphQL */ `\n query OrderConfirmation($id: ID!) {\n getStoreOrder(id: $id) {\n id\n status\n total\n currency\n purchasedAt\n lineItems\n context\n }\n myEntitlements {\n id\n productId\n licenseKey\n expiresAt\n features\n product {\n id\n name\n slug\n icon\n manifest\n }\n }\n }\n`;\n\nexport const OrderConfirmationPage: FC = () => {\n const navigate = useNavigate();\n const { basePath, authToken } = useStore();\n const { orderId } = useParams<{ orderId: string }>();\n const [order, setOrder] = useState<OrderDetails | null>(null);\n const [entitlements, setEntitlements] = useState<Entitlement[]>([]);\n const [loading, setLoading] = useState(true);\n const [error, setError] = useState<string | null>(null);\n const [copiedKey, setCopiedKey] = useState<string | null>(null);\n\n useEffect(() => {\n if (!orderId) return;\n let cancelled = false;\n const load = async () => {\n setLoading(true);\n setError(null);\n try {\n const result = await graphqlFetch<{\n getStoreOrder: OrderDetails | null;\n myEntitlements: Entitlement[];\n }>({\n gateway: 'global',\n query: ORDER_QUERY,\n variables: { id: orderId },\n authToken: authToken || undefined,\n });\n if (cancelled) return;\n if (result.errors?.length) {\n throw new Error(result.errors[0]?.message ?? 'Failed to load order');\n }\n setOrder(result.data?.getStoreOrder ?? null);\n // Filter entitlements to only those matching products in this order\n const productIds = new Set(\n (result.data?.getStoreOrder?.lineItems ?? []).map((item) => item.productId)\n );\n const orderEntitlements = (result.data?.myEntitlements ?? []).filter((e) =>\n productIds.has(e.productId)\n );\n setEntitlements(orderEntitlements);\n } catch (err) {\n if (cancelled) return;\n setError(err instanceof Error ? err.message : 'Failed to load order');\n } finally {\n if (!cancelled) setLoading(false);\n }\n };\n void load();\n return () => {\n cancelled = true;\n };\n }, [orderId, authToken]);\n\n const copyKey = async (key: string) => {\n void nativeImpact('light');\n try {\n const ok = await nativeCopyText(key);\n if (ok) {\n setCopiedKey(key);\n void nativeNotify('success');\n setTimeout(() => setCopiedKey(null), 1500);\n } else {\n void nativeNotify('error');\n }\n } catch {\n void nativeNotify('error');\n }\n };\n\n const installInWorkspace = (productId: string, licenseKey: string | null) => {\n const params = new URLSearchParams();\n params.set('install', productId);\n if (licenseKey) params.set('licenseKey', licenseKey);\n // Navigate to the vibecontrols plugin install page via the top-level router.\n // Uses a plain anchor to avoid cross-MFE router imports.\n window.location.href = `/vibecontrols/agents?${params.toString()}`;\n };\n\n const formatPrice = (amount: number, currency: string) =>\n formatCurrency(amount, currency || 'USD');\n\n return (\n <main className=\"mx-auto max-w-3xl p-6\">\n <div className=\"rounded-2xl border border-border-default bg-surface-raised p-6 text-center\">\n <CheckCircle2 className=\"mx-auto size-12 text-status-success-text\" />\n <h1 className=\"mt-3 text-2xl font-bold text-text-primary\">Order placed successfully</h1>\n {order && (\n <p className=\"mt-1 text-sm text-text-secondary\">\n Total: {formatPrice(order.total, order.currency)}\n {order.purchasedAt && ` • ${new Date(order.purchasedAt).toLocaleString()}`}\n </p>\n )}\n {orderId && (\n <div className=\"mx-auto mt-4 max-w-sm rounded-lg border border-border-default bg-surface-default px-4 py-2 text-left\">\n <p className=\"text-xs uppercase tracking-wide text-text-tertiary\">Order ID</p>\n <p className=\"mt-0.5 break-all font-mono text-xs text-text-primary\">{orderId}</p>\n </div>\n )}\n </div>\n\n {error && (\n <div\n role=\"alert\"\n className=\"mt-4 rounded-md border border-border-danger bg-surface-danger-muted px-4 py-3 text-sm text-text-danger\"\n >\n {error}\n </div>\n )}\n\n {loading ? (\n <output className=\"mt-6 block py-12 text-center text-text-secondary\">\n Loading licenses…\n </output>\n ) : entitlements.length > 0 ? (\n <div className=\"mt-6\">\n <h2 className=\"mb-3 flex items-center gap-2 text-sm font-semibold text-text-primary\">\n <KeyRound className=\"size-4\" />\n Your licenses ({entitlements.length})\n </h2>\n <ul className=\"space-y-3\">\n {entitlements.map((ent) => (\n <li\n key={ent.id}\n className=\"rounded-lg border border-border-default bg-surface-raised p-4\"\n >\n <div className=\"flex items-start gap-3\">\n {ent.product?.icon ? (\n <img\n src={ent.product.icon}\n alt=\"\"\n className=\"size-12 flex-shrink-0 rounded-md object-cover\"\n />\n ) : (\n <div className=\"flex size-12 flex-shrink-0 items-center justify-center rounded-md bg-surface-muted text-xs text-text-secondary\">\n {ent.product?.name.slice(0, 2).toUpperCase() ?? '?'}\n </div>\n )}\n <div className=\"min-w-0 flex-1\">\n <h3 className=\"text-base font-semibold text-text-primary\">\n {ent.product?.name ?? 'Unknown product'}\n </h3>\n {ent.expiresAt && (\n <p className=\"text-xs text-text-secondary\">\n Expires: {new Date(ent.expiresAt).toLocaleDateString()}\n </p>\n )}\n {ent.licenseKey && (\n <div className=\"mt-2 flex items-center gap-2\">\n <code className=\"flex-1 truncate rounded bg-surface-muted px-2 py-1 font-mono text-[11px] text-text-primary\">\n {ent.licenseKey}\n </code>\n <button\n type=\"button\"\n onClick={() => void copyKey(ent.licenseKey!)}\n className=\"rounded-md border border-border-default bg-surface-default p-1 text-text-primary hover:bg-surface-hover\"\n title=\"Copy license key\"\n >\n <Copy className=\"size-3.5\" />\n </button>\n </div>\n )}\n {copiedKey === ent.licenseKey && (\n <p className=\"mt-1 text-xs text-status-success-text\">Copied to clipboard</p>\n )}\n </div>\n <button\n type=\"button\"\n onClick={() => installInWorkspace(ent.productId, ent.licenseKey)}\n className=\"inline-flex items-center gap-1 rounded-md bg-action-primary-bg px-3 py-1.5 text-xs font-semibold text-action-primary-text hover:opacity-90\"\n >\n <Download className=\"size-3.5\" />\n Install to workspace\n </button>\n </div>\n </li>\n ))}\n </ul>\n </div>\n ) : null}\n\n <div className=\"mt-6 flex flex-col gap-2 sm:flex-row sm:justify-center\">\n <button\n type=\"button\"\n onClick={() => navigate(`${basePath}/orders`)}\n className=\"cursor-pointer inline-flex items-center justify-center gap-2 rounded-lg bg-action-primary-bg px-4 py-2 text-sm font-semibold text-action-primary-text\"\n >\n <Receipt className=\"size-4\" />\n View My Orders\n </button>\n <button\n type=\"button\"\n onClick={() => navigate(`${basePath}/marketplace`)}\n className=\"cursor-pointer inline-flex items-center justify-center gap-2 rounded-lg border border-border-default px-4 py-2 text-sm font-semibold text-text-primary hover:bg-surface-hover\"\n >\n Continue Shopping\n <ArrowRight className=\"size-4\" />\n </button>\n </div>\n </main>\n );\n};\n"],"mappings":"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"}
|