@openrails/billing-ui 0.242.0 → 0.243.0
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/CHANGELOG.md +27 -11
- package/README.md +41 -8
- package/dist/admin/billing-admin.d.ts +3 -0
- package/dist/admin/components/app-sidebar.d.ts +1 -0
- package/dist/admin/components/confirm.d.ts +4 -0
- package/dist/admin/components/cursor-pager.d.ts +8 -0
- package/dist/admin/components/data-table.d.ts +14 -0
- package/dist/admin/components/fact-card.d.ts +5 -0
- package/dist/admin/components/form-field-errors.d.ts +3 -0
- package/dist/admin/components/linked-table-row.d.ts +5 -0
- package/dist/admin/components/logo.d.ts +3 -0
- package/dist/admin/components/no-access.d.ts +3 -0
- package/dist/admin/components/no-merchants.d.ts +1 -0
- package/dist/admin/components/notification-bell.d.ts +2 -0
- package/dist/admin/components/route-error.d.ts +3 -0
- package/dist/admin/components/site-header.d.ts +9 -0
- package/dist/admin/components/status-badge.d.ts +3 -0
- package/dist/admin/components/typed-confirm-dialog.d.ts +11 -0
- package/dist/admin/components/ui/alert-dialog.d.ts +18 -0
- package/dist/admin/components/ui/avatar.d.ts +11 -0
- package/dist/admin/components/ui/badge.d.ts +7 -0
- package/dist/admin/components/ui/breadcrumb.d.ts +10 -0
- package/dist/admin/components/ui/button.d.ts +8 -0
- package/dist/admin/components/ui/card.d.ts +11 -0
- package/dist/admin/components/ui/chart.d.ts +44 -0
- package/dist/admin/components/ui/dialog.d.ts +17 -0
- package/dist/admin/components/ui/dropdown-menu.d.ts +29 -0
- package/dist/admin/components/ui/input.d.ts +3 -0
- package/dist/admin/components/ui/label.d.ts +3 -0
- package/dist/admin/components/ui/select.d.ts +15 -0
- package/dist/admin/components/ui/separator.d.ts +3 -0
- package/dist/admin/components/ui/sheet.d.ts +14 -0
- package/dist/admin/components/ui/sidebar.d.ts +63 -0
- package/dist/admin/components/ui/skeleton.d.ts +2 -0
- package/dist/admin/components/ui/sonner.d.ts +3 -0
- package/dist/admin/components/ui/switch.d.ts +5 -0
- package/dist/admin/components/ui/table.d.ts +10 -0
- package/dist/admin/components/ui/tabs.d.ts +10 -0
- package/dist/admin/components/ui/textarea.d.ts +3 -0
- package/dist/admin/components/ui/tooltip.d.ts +6 -0
- package/dist/admin/context.d.ts +1193 -0
- package/dist/admin/hooks/use-mobile.d.ts +1 -0
- package/dist/admin/index.d.ts +5 -0
- package/dist/admin/layouts/app-layout.d.ts +4 -0
- package/dist/admin/lib/api/client.d.ts +64 -0
- package/dist/admin/lib/api/copilot.d.ts +6 -0
- package/dist/admin/lib/api/credit-endpoints.d.ts +8 -0
- package/dist/admin/lib/api/credit-types.d.ts +9 -0
- package/dist/admin/lib/api/endpoints.d.ts +133 -0
- package/dist/admin/lib/api/index.d.ts +89 -0
- package/dist/admin/lib/api/invoice-profile-endpoints.d.ts +6 -0
- package/dist/admin/lib/api/metrics.d.ts +68 -0
- package/dist/admin/lib/api/order-endpoints.d.ts +21 -0
- package/dist/admin/lib/api/types.d.ts +122 -0
- package/dist/admin/lib/auth.d.ts +6 -0
- package/dist/admin/lib/capabilities.d.ts +13 -0
- package/dist/admin/lib/chunk-error.d.ts +1 -0
- package/dist/admin/lib/confirm.d.ts +11 -0
- package/dist/admin/lib/credit-queries.d.ts +23 -0
- package/dist/admin/lib/csv.d.ts +3 -0
- package/dist/admin/lib/cursor-pages.d.ts +13 -0
- package/dist/admin/lib/dialog-width.d.ts +6 -0
- package/dist/admin/lib/dom.d.ts +1 -0
- package/dist/admin/lib/duration.d.ts +3 -0
- package/dist/admin/lib/format.d.ts +23 -0
- package/dist/admin/lib/mount.d.ts +6 -0
- package/dist/admin/lib/mutations.d.ts +125 -0
- package/dist/admin/lib/order-queries.d.ts +29 -0
- package/dist/admin/lib/queries.d.ts +369 -0
- package/dist/admin/lib/query-client.d.ts +3 -0
- package/dist/admin/lib/toast.d.ts +10 -0
- package/dist/admin/lib/utils.d.ts +2 -0
- package/dist/admin/messages.d.ts +670 -0
- package/dist/admin/navigation.d.ts +14 -0
- package/dist/admin/pages/catalog/application-dialog.d.ts +2 -0
- package/dist/admin/pages/catalog/copilot-panel.d.ts +4 -0
- package/dist/admin/pages/catalog/index.d.ts +4 -0
- package/dist/admin/pages/catalog/meter-form.d.ts +6 -0
- package/dist/admin/pages/catalog/metering-model.d.ts +67 -0
- package/dist/admin/pages/catalog/metering.d.ts +3 -0
- package/dist/admin/pages/catalog/price-detail.d.ts +2 -0
- package/dist/admin/pages/catalog/price-format.d.ts +3 -0
- package/dist/admin/pages/catalog/price-wizard-logic.d.ts +20 -0
- package/dist/admin/pages/catalog/price-wizard.d.ts +10 -0
- package/dist/admin/pages/catalog/psp-links.d.ts +10 -0
- package/dist/admin/pages/catalog/rate-card-editor.d.ts +10 -0
- package/dist/admin/pages/customers/credit-form.d.ts +14 -0
- package/dist/admin/pages/customers/credits.d.ts +5 -0
- package/dist/admin/pages/customers/default-card-badges.d.ts +3 -0
- package/dist/admin/pages/customers/detail.d.ts +5 -0
- package/dist/admin/pages/customers/grant-duration.d.ts +32 -0
- package/dist/admin/pages/customers/index.d.ts +2 -0
- package/dist/admin/pages/customers/invoice-profile-model.d.ts +18 -0
- package/dist/admin/pages/customers/invoice-profile.d.ts +9 -0
- package/dist/admin/pages/dashboard/index.d.ts +2 -0
- package/dist/admin/pages/dashboard/lib.d.ts +48 -0
- package/dist/admin/pages/dashboard/range-picker.d.ts +1 -0
- package/dist/admin/pages/dashboard/range.d.ts +34 -0
- package/dist/admin/pages/dashboard/reports-model.d.ts +29 -0
- package/dist/admin/pages/dashboard/reports.d.ts +2 -0
- package/dist/admin/pages/dashboard/use-range.d.ts +5 -0
- package/dist/admin/pages/dashboard/widget-editor.d.ts +8 -0
- package/dist/admin/pages/dashboard/widget-tile.d.ts +9 -0
- package/dist/admin/pages/dashboard/widget-viz.d.ts +12 -0
- package/dist/admin/pages/ops/index.d.ts +2 -0
- package/dist/admin/pages/orders/detail.d.ts +5 -0
- package/dist/admin/pages/orders/index.d.ts +1 -0
- package/dist/admin/pages/orders/model.d.ts +7 -0
- package/dist/admin/pages/payments/attempts.d.ts +7 -0
- package/dist/admin/pages/payments/detail.d.ts +2 -0
- package/dist/admin/pages/payments/health-model.d.ts +149 -0
- package/dist/admin/pages/payments/health.d.ts +2 -0
- package/dist/admin/pages/payments/index.d.ts +2 -0
- package/dist/admin/pages/settings/configuration-edit.d.ts +9 -0
- package/dist/admin/pages/settings/index.d.ts +9 -0
- package/dist/admin/pages/settings/notifications.d.ts +2 -0
- package/dist/admin/pages/settings/setting-fields.d.ts +20 -0
- package/dist/admin/pages/subscriptions/change-subscription-dialog.d.ts +16 -0
- package/dist/admin/pages/subscriptions/detail.d.ts +2 -0
- package/dist/admin/pages/subscriptions/dunning.d.ts +2 -0
- package/dist/admin/pages/subscriptions/index.d.ts +2 -0
- package/dist/admin/pages/subscriptions/subscription-change-options.d.ts +23 -0
- package/dist/admin/pages/subscriptions/views.d.ts +15 -0
- package/dist/admin/router.d.ts +32 -0
- package/dist/admin/routes.d.ts +5 -0
- package/dist/admin/summary.d.ts +27 -0
- package/dist/admin/theme.d.ts +2 -0
- package/dist/admin/types.d.ts +56 -0
- package/dist/admin/ui-context.d.ts +14 -0
- package/dist/admin-attempts-lAoW-Urd.js +419 -0
- package/dist/admin-attempts-lAoW-Urd.js.map +1 -0
- package/dist/admin-auth-DQGHtt0j.js +14 -0
- package/dist/admin-auth-DQGHtt0j.js.map +1 -0
- package/dist/admin-badge-DR5-1qd8.js +31 -0
- package/dist/admin-badge-DR5-1qd8.js.map +1 -0
- package/dist/admin-button-CTL3DgOt.js +46 -0
- package/dist/admin-button-CTL3DgOt.js.map +1 -0
- package/dist/admin-capabilities-BuigAgtm.js +59 -0
- package/dist/admin-capabilities-BuigAgtm.js.map +1 -0
- package/dist/admin-card-bzAks3-3.js +51 -0
- package/dist/admin-card-bzAks3-3.js.map +1 -0
- package/dist/admin-catalog-CC7I4n0_.js +1189 -0
- package/dist/admin-catalog-CC7I4n0_.js.map +1 -0
- package/dist/admin-confirm-katGq0Qo.js +12 -0
- package/dist/admin-confirm-katGq0Qo.js.map +1 -0
- package/dist/admin-csv-CPoNZj2D.js +16 -0
- package/dist/admin-csv-CPoNZj2D.js.map +1 -0
- package/dist/admin-customers-D8u5gq3M.js +160 -0
- package/dist/admin-customers-D8u5gq3M.js.map +1 -0
- package/dist/admin-dashboard-DqqFjOzq.js +420 -0
- package/dist/admin-dashboard-DqqFjOzq.js.map +1 -0
- package/dist/admin-data-table-qfXLOFmN.js +96 -0
- package/dist/admin-data-table-qfXLOFmN.js.map +1 -0
- package/dist/admin-detail-5aNNvrc0.js +324 -0
- package/dist/admin-detail-5aNNvrc0.js.map +1 -0
- package/dist/admin-detail-7p684Uyc.js +342 -0
- package/dist/admin-detail-7p684Uyc.js.map +1 -0
- package/dist/admin-detail-CGOyqs7s.js +1312 -0
- package/dist/admin-detail-CGOyqs7s.js.map +1 -0
- package/dist/admin-detail-DUAJQg8G.js +710 -0
- package/dist/admin-detail-DUAJQg8G.js.map +1 -0
- package/dist/admin-dialog-BjuKI5Hp.js +88 -0
- package/dist/admin-dialog-BjuKI5Hp.js.map +1 -0
- package/dist/admin-dialog-width-BPrgdYlj.js +6 -0
- package/dist/admin-dialog-width-BPrgdYlj.js.map +1 -0
- package/dist/admin-dom-uMmZzRvU.js +149 -0
- package/dist/admin-dom-uMmZzRvU.js.map +1 -0
- package/dist/admin-dropdown-menu-BW1D_h6s.js +69 -0
- package/dist/admin-dropdown-menu-BW1D_h6s.js.map +1 -0
- package/dist/admin-dunning-B2zgtrOo.js +10 -0
- package/dist/admin-dunning-B2zgtrOo.js.map +1 -0
- package/dist/admin-fact-card-DO_fHosg.js +20 -0
- package/dist/admin-fact-card-DO_fHosg.js.map +1 -0
- package/dist/admin-form-field-errors-hbUMIriS.js +14 -0
- package/dist/admin-form-field-errors-hbUMIriS.js.map +1 -0
- package/dist/admin-format-DoohJ7Fg.js +136 -0
- package/dist/admin-format-DoohJ7Fg.js.map +1 -0
- package/dist/admin-health-B4jN2LwR.js +983 -0
- package/dist/admin-health-B4jN2LwR.js.map +1 -0
- package/dist/admin-input-CcfQfJFN.js +17 -0
- package/dist/admin-input-CcfQfJFN.js.map +1 -0
- package/dist/admin-invoice-profile-model-Cgjy3zV8.js +53 -0
- package/dist/admin-invoice-profile-model-Cgjy3zV8.js.map +1 -0
- package/dist/admin-label-BiEN5cjb.js +15 -0
- package/dist/admin-label-BiEN5cjb.js.map +1 -0
- package/dist/admin-linked-table-row-BsaUruCN.js +26 -0
- package/dist/admin-linked-table-row-BsaUruCN.js.map +1 -0
- package/dist/admin-metering-BGAXbT23.js +1702 -0
- package/dist/admin-metering-BGAXbT23.js.map +1 -0
- package/dist/admin-ops-B3mcr76u.js +217 -0
- package/dist/admin-ops-B3mcr76u.js.map +1 -0
- package/dist/admin-orders-dxC99Idl.js +192 -0
- package/dist/admin-orders-dxC99Idl.js.map +1 -0
- package/dist/admin-payments-Bs7HSfP0.js +246 -0
- package/dist/admin-payments-Bs7HSfP0.js.map +1 -0
- package/dist/admin-price-detail-DRquxpA9.js +482 -0
- package/dist/admin-price-detail-DRquxpA9.js.map +1 -0
- package/dist/admin-price-format-DM1qORWI.js +44 -0
- package/dist/admin-price-format-DM1qORWI.js.map +1 -0
- package/dist/admin-price-wizard-CI7K-2Nz.js +357 -0
- package/dist/admin-price-wizard-CI7K-2Nz.js.map +1 -0
- package/dist/admin-range-picker-Dr2M1EZr.js +192 -0
- package/dist/admin-range-picker-Dr2M1EZr.js.map +1 -0
- package/dist/admin-reports-CywKLiSA.js +320 -0
- package/dist/admin-reports-CywKLiSA.js.map +1 -0
- package/dist/admin-select-DBgprVW6.js +81 -0
- package/dist/admin-select-DBgprVW6.js.map +1 -0
- package/dist/admin-settings-Bmoy95uO.js +1434 -0
- package/dist/admin-settings-Bmoy95uO.js.map +1 -0
- package/dist/admin-skeleton-DsM7crYi.js +14 -0
- package/dist/admin-skeleton-DsM7crYi.js.map +1 -0
- package/dist/admin-status-badge-BFPgo71d.js +38 -0
- package/dist/admin-status-badge-BFPgo71d.js.map +1 -0
- package/dist/admin-subscriptions-CLYc_HEV.js +301 -0
- package/dist/admin-subscriptions-CLYc_HEV.js.map +1 -0
- package/dist/admin-switch-BJUxLCsa.js +20 -0
- package/dist/admin-switch-BJUxLCsa.js.map +1 -0
- package/dist/admin-table-CH9TrXJf.js +61 -0
- package/dist/admin-table-CH9TrXJf.js.map +1 -0
- package/dist/admin-tabs-528FJMjt.js +46 -0
- package/dist/admin-tabs-528FJMjt.js.map +1 -0
- package/dist/admin-textarea-DEz38RaI.js +15 -0
- package/dist/admin-textarea-DEz38RaI.js.map +1 -0
- package/dist/admin-typed-confirm-dialog-DU7m9-O7.js +66 -0
- package/dist/admin-typed-confirm-dialog-DU7m9-O7.js.map +1 -0
- package/dist/admin-utils-BK4Vh1o_.js +1809 -0
- package/dist/admin-utils-BK4Vh1o_.js.map +1 -0
- package/dist/admin-widget-viz-Da48c-Zf.js +581 -0
- package/dist/admin-widget-viz-Da48c-Zf.js.map +1 -0
- package/dist/admin.css +3 -0
- package/dist/admin.js +2164 -0
- package/dist/admin.js.map +1 -0
- package/dist/appearance.d.ts +1 -1
- package/dist/client/generated/error-codes.d.ts +1 -1
- package/dist/client/generated/routes.d.ts +2171 -176
- package/dist/client/generated/wire.d.ts +1273 -0
- package/dist/{hooks-Uiw-zW3H.js → hooks-Ckd8F2JF.js} +7 -7
- package/dist/hooks-Ckd8F2JF.js.map +1 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.js +11 -11
- package/dist/index.js.map +1 -1
- package/dist/lib/{offer-label.d.ts → price-label.d.ts} +1 -1
- package/dist/locales/de.js +1 -1
- package/dist/locales/de.js.map +1 -1
- package/dist/locales/en.d.ts +1 -1
- package/dist/locales/en.js +1 -1
- package/dist/locales/en.js.map +1 -1
- package/dist/locales/es.js +1 -1
- package/dist/locales/es.js.map +1 -1
- package/dist/locales/ja.js +1 -1
- package/dist/locales/ja.js.map +1 -1
- package/dist/locales/ko.js +1 -1
- package/dist/locales/ko.js.map +1 -1
- package/dist/locales/zh.js +1 -1
- package/dist/locales/zh.js.map +1 -1
- package/dist/{offers.d.ts → product-list.d.ts} +5 -5
- package/dist/react.js +1 -1
- package/dist/styles.css +1 -1
- package/package.json +28 -6
- package/dist/hooks-Uiw-zW3H.js.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"admin-range-picker-Dr2M1EZr.js","names":[],"sources":["../src/admin/pages/dashboard/range.ts","../src/admin/pages/dashboard/use-range.ts","../src/admin/pages/dashboard/range-picker.tsx"],"sourcesContent":["// The dashboard's range, kept in the URL: a preset (?range=7d) or a custom\n// span of UTC dates (?from=2026-09-01&to=2026-09-30, both inclusive). Every\n// widget runs over it except one that keeps its own (fixed_range).\nimport type {\n MetricsQuery,\n MetricsRange,\n Widget,\n} from \"#orck/admin/lib/api/metrics\"\n\nexport const RANGE_PRESETS = [\n { value: \"7d\", label: \"Last 7 days\" },\n { value: \"30d\", label: \"Last 30 days\" },\n { value: \"90d\", label: \"Last 3 months\" },\n { value: \"6m\", label: \"Last 6 months\" },\n { value: \"1y\", label: \"Last year\" },\n] as const\n\nexport const DEFAULT_PRESET = \"30d\"\n\nexport type DashboardRange = { preset: string } | { from: string; to: string }\n\nconst DATE = /^\\d{4}-\\d{2}-\\d{2}$/\n\nconst validDate = (s: string | null): s is string =>\n !!s && DATE.test(s) && !Number.isNaN(Date.parse(`${s}T00:00:00Z`))\n\nexport function rangeFromParams(params: URLSearchParams): DashboardRange {\n const from = params.get(\"from\")\n const to = params.get(\"to\")\n if (validDate(from) && validDate(to)) {\n return from <= to ? { from, to } : { from: to, to: from }\n }\n const preset = params.get(\"range\")\n return {\n preset: RANGE_PRESETS.some((p) => p.value === preset)\n ? preset!\n : DEFAULT_PRESET,\n }\n}\n\n// withRange is params showing range; the default preset leaves no trace.\nexport function withRange(\n params: URLSearchParams,\n range: DashboardRange\n): URLSearchParams {\n const p = new URLSearchParams(params)\n p.delete(\"range\")\n p.delete(\"from\")\n p.delete(\"to\")\n if (\"from\" in range) {\n p.set(\"from\", range.from)\n p.set(\"to\", range.to)\n } else if (range.preset !== DEFAULT_PRESET) {\n p.set(\"range\", range.preset)\n }\n return p\n}\n\nexport function metricsRange(range: DashboardRange): MetricsRange {\n return \"from\" in range\n ? { from: range.from, to: range.to }\n : { last: range.preset }\n}\n\nconst dayMs = 86_400_000\n\nconst utcDate = (d: Date) => d.toISOString().slice(0, 10)\n\n// rangeDates is the range as inclusive UTC dates. A preset ends today and\n// counts back as the API resolves \"last\": \"6m\" is six calendar months.\nexport function rangeDates(\n range: DashboardRange,\n now = new Date()\n): { from: string; to: string } {\n if (\"from\" in range) return range\n const [, n, unit] = /^(\\d+)([dwmy])$/.exec(range.preset) ?? [\"\", \"30\", \"d\"]\n const count = Number(n)\n const start = new Date(\n Date.UTC(now.getUTCFullYear(), now.getUTCMonth(), now.getUTCDate() + 1)\n )\n if (unit === \"d\") start.setUTCDate(start.getUTCDate() - count)\n if (unit === \"w\") start.setUTCDate(start.getUTCDate() - 7 * count)\n if (unit === \"m\") start.setUTCMonth(start.getUTCMonth() - count)\n if (unit === \"y\") start.setUTCFullYear(start.getUTCFullYear() - count)\n return { from: utcDate(start), to: utcDate(now) }\n}\n\nexport function rangeLabel(range: DashboardRange, now = new Date()): string {\n const { from, to } = rangeDates(range, now)\n const fmt = (s: string) =>\n new Date(`${s}T00:00:00Z`).toLocaleDateString(undefined, {\n month: \"short\",\n day: \"numeric\",\n year: s.slice(0, 4) === utcDate(now).slice(0, 4) ? undefined : \"numeric\",\n timeZone: \"UTC\",\n })\n return from === to ? fmt(from) : `${fmt(from)} – ${fmt(to)}`\n}\n\n// MAX_BUCKETS is the metrics API's limit on a time series.\nconst MAX_BUCKETS = 400\nconst GRAINS = [\"day\", \"week\", \"month\", \"quarter\", \"year\"]\nconst GRAIN_DAYS: Record<string, number> = {\n day: 1,\n week: 7,\n month: 28,\n quarter: 89,\n year: 365,\n}\n\n// fitGrain coarsens grain until the range fits the bucket limit, so a long\n// custom range never turns a daily chart into an error.\nexport function fitGrain(\n grain: string,\n range: DashboardRange,\n now = new Date()\n): string {\n const { from, to } = rangeDates(range, now)\n const days = (Date.parse(to) - Date.parse(from)) / dayMs + 1\n let i = Math.max(GRAINS.indexOf(grain), 0)\n while (\n i < GRAINS.length - 1 &&\n days / GRAIN_DAYS[GRAINS[i]] > MAX_BUCKETS - 2\n )\n i++\n return GRAINS[i]\n}\n\n// widgetQuery is the query a widget runs on a dashboard showing range.\nexport function widgetQuery(\n widget: Widget,\n range: DashboardRange\n): MetricsQuery {\n if (widget.fixed_range) return widget.query\n const query: MetricsQuery = { ...widget.query, range: metricsRange(range) }\n if (query.grain) query.grain = fitGrain(query.grain, range)\n return query\n}\n","import { useSearchParams } from \"#orck/admin/router\"\n\nimport { rangeFromParams, withRange, type DashboardRange } from \"./range\"\n\n// useDashboardRange reads the range from the URL and replaces it there.\nexport function useDashboardRange(): [\n DashboardRange,\n (range: DashboardRange) => void,\n] {\n const [params, setParams] = useSearchParams()\n return [\n rangeFromParams(params),\n (range) => setParams(withRange(params, range), { replace: true }),\n ]\n}\n","import { AdminMessage, useAdminUI } from \"#orck/admin/ui-context\"\nimport { useRef } from \"react\"\n// Range picker for the dashboard and its reports: the presets, or a custom\n// start and end date. The choice lives in the URL, so a link shows the same\n// range.\nimport { Button } from \"#orck/admin/components/ui/button\"\nimport { Input } from \"#orck/admin/components/ui/input\"\nimport {\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from \"#orck/admin/components/ui/select\"\n\nimport { DEFAULT_PRESET, RANGE_PRESETS, rangeDates, rangeLabel } from \"./range\"\nimport { useDashboardRange } from \"./use-range\"\n\nconst CUSTOM = \"custom\"\n\nexport function RangePicker() {\n const { text: adminText } = useAdminUI()\n\n const [range, setRange] = useDashboardRange()\n // A host router can publish its new URL after the next input edit. Read\n // both live fields; the committed URL key resets them on back/forward.\n const startInput = useRef<HTMLInputElement>(null)\n const endInput = useRef<HTMLInputElement>(null)\n const custom = \"from\" in range\n const items = [\n ...RANGE_PRESETS.map((p) => ({ value: p.value, label: p.label })),\n { value: CUSTOM, label: \"Custom range\" },\n ]\n return (\n <div className=\"flex flex-wrap items-center gap-2\">\n <span\n className=\"hidden text-sm text-muted-foreground tabular-nums sm:inline\"\n aria-live=\"polite\"\n >\n {rangeLabel(range)}\n </span>\n <Select\n items={items}\n value={custom ? CUSTOM : range.preset}\n onValueChange={(next) => {\n if (!next) return\n setRange(next === CUSTOM ? rangeDates(range) : { preset: next })\n }}\n >\n <SelectTrigger\n size=\"sm\"\n className=\"w-[150px]\"\n aria-label={adminText(\"Date range\")}\n >\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n {items.map((item) => (\n <SelectItem key={item.value} value={item.value}>\n {item.label}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n {custom && (\n <div key={`${range.from}/${range.to}`} className=\"contents\">\n <label className=\"flex items-center gap-1.5 text-xs font-medium\">\n <AdminMessage id={\"Start\"} />\n <Input\n ref={startInput}\n type=\"date\"\n className=\"h-8 w-auto\"\n defaultValue={range.from}\n max={range.to}\n onChange={(e) => {\n const from = e.target.value\n const to = endInput.current?.value || range.to\n if (from) setRange({ from, to: from > to ? from : to })\n }}\n />\n </label>\n <label className=\"flex items-center gap-1.5 text-xs font-medium\">\n <AdminMessage id={\"End\"} />\n <Input\n ref={endInput}\n type=\"date\"\n className=\"h-8 w-auto\"\n defaultValue={range.to}\n min={range.from}\n onChange={(e) => {\n const to = e.target.value\n const from = startInput.current?.value || range.from\n if (to) setRange({ from: to < from ? to : from, to })\n }}\n />\n </label>\n <Button\n variant=\"ghost\"\n size=\"sm\"\n onClick={() => setRange({ preset: DEFAULT_PRESET })}\n >\n <AdminMessage id={\"Reset\"} />\n </Button>\n </div>\n )}\n </div>\n )\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,320 @@
|
|
|
1
|
+
import { E as e, S as t, i as n, p as r, w as i } from "./admin-utils-BK4Vh1o_.js";
|
|
2
|
+
import { t as a } from "./admin-button-CTL3DgOt.js";
|
|
3
|
+
import { t as o } from "./admin-skeleton-DsM7crYi.js";
|
|
4
|
+
import { r as s } from "./admin-capabilities-BuigAgtm.js";
|
|
5
|
+
import { a as c, i as l, n as u, o as d, r as f, s as p, t as m } from "./admin-table-CH9TrXJf.js";
|
|
6
|
+
import { a as h, i as g, n as _, o as v, r as y, t as b } from "./admin-card-bzAks3-3.js";
|
|
7
|
+
import { t as x } from "./admin-csv-CPoNZj2D.js";
|
|
8
|
+
import { i as S, n as C, r as w, t as T } from "./admin-range-picker-Dr2M1EZr.js";
|
|
9
|
+
import { useQuery as E } from "@tanstack/react-query";
|
|
10
|
+
import { jsx as D, jsxs as O } from "react/jsx-runtime";
|
|
11
|
+
import { HugeiconsIcon as k } from "@hugeicons/react";
|
|
12
|
+
import { Download01Icon as A } from "@hugeicons/core-free-icons";
|
|
13
|
+
//#region src/admin/pages/dashboard/reports-model.ts
|
|
14
|
+
function j(e, t = /* @__PURE__ */ new Date()) {
|
|
15
|
+
let { from: n, to: r } = S(e, t);
|
|
16
|
+
return (Date.parse(r) - Date.parse(n)) / 864e5 + 1;
|
|
17
|
+
}
|
|
18
|
+
function M(e) {
|
|
19
|
+
return {
|
|
20
|
+
measures: [
|
|
21
|
+
"new_subscriptions",
|
|
22
|
+
"cancellations",
|
|
23
|
+
"net_new_subscriptions"
|
|
24
|
+
],
|
|
25
|
+
by: ["time"],
|
|
26
|
+
grain: "day",
|
|
27
|
+
range: w(e)
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
function N(e) {
|
|
31
|
+
return {
|
|
32
|
+
measures: ["payment_count"],
|
|
33
|
+
by: ["time"],
|
|
34
|
+
grain: "month",
|
|
35
|
+
range: w(e),
|
|
36
|
+
filters: { attempt_kind: ["renewal"] }
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
function P(e) {
|
|
40
|
+
return {
|
|
41
|
+
measures: ["cancellations", "churn_rate"],
|
|
42
|
+
by: ["time"],
|
|
43
|
+
grain: "month",
|
|
44
|
+
range: w(e)
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
var F = (e) => Number(e ?? 0);
|
|
48
|
+
function I(e) {
|
|
49
|
+
let t = e.columns.findIndex((e) => e.kind === "time"), n = /* @__PURE__ */ new Map();
|
|
50
|
+
for (let r of e.rows) {
|
|
51
|
+
let i = {};
|
|
52
|
+
e.columns.forEach((e, t) => {
|
|
53
|
+
i[e.name] = r[t];
|
|
54
|
+
}), n.set(String(r[t]), i);
|
|
55
|
+
}
|
|
56
|
+
return n;
|
|
57
|
+
}
|
|
58
|
+
function L(e) {
|
|
59
|
+
return [...I(e)].sort(([e], [t]) => e < t ? -1 : 1).map(([e, t]) => ({
|
|
60
|
+
date: e.slice(0, 10),
|
|
61
|
+
started: F(t.new_subscriptions),
|
|
62
|
+
canceled: F(t.cancellations),
|
|
63
|
+
net: F(t.net_new_subscriptions)
|
|
64
|
+
}));
|
|
65
|
+
}
|
|
66
|
+
function R(e, t) {
|
|
67
|
+
let n = I(e), r = I(t);
|
|
68
|
+
return [.../* @__PURE__ */ new Set([...n.keys(), ...r.keys()])].sort().map((e) => {
|
|
69
|
+
let t = r.get(e)?.churn_rate;
|
|
70
|
+
return {
|
|
71
|
+
month: e.slice(0, 7),
|
|
72
|
+
renewals: F(n.get(e)?.payment_count),
|
|
73
|
+
canceled: F(r.get(e)?.cancellations),
|
|
74
|
+
churn: t == null ? null : Number(t)
|
|
75
|
+
};
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
var z = (e) => ({
|
|
79
|
+
header: [
|
|
80
|
+
"date",
|
|
81
|
+
"new_subscriptions",
|
|
82
|
+
"cancellations",
|
|
83
|
+
"net_change"
|
|
84
|
+
],
|
|
85
|
+
rows: e.map((e) => [
|
|
86
|
+
e.date,
|
|
87
|
+
e.started,
|
|
88
|
+
e.canceled,
|
|
89
|
+
e.net
|
|
90
|
+
])
|
|
91
|
+
}), B = (e) => ({
|
|
92
|
+
header: [
|
|
93
|
+
"month",
|
|
94
|
+
"renewals",
|
|
95
|
+
"cancellations",
|
|
96
|
+
"churn_rate"
|
|
97
|
+
],
|
|
98
|
+
rows: e.map((e) => [
|
|
99
|
+
e.month,
|
|
100
|
+
e.renewals,
|
|
101
|
+
e.canceled,
|
|
102
|
+
e.churn ?? ""
|
|
103
|
+
])
|
|
104
|
+
}), V = (e) => (/* @__PURE__ */ new Date(`${e}T00:00:00Z`)).toLocaleDateString(void 0, {
|
|
105
|
+
month: "short",
|
|
106
|
+
day: "numeric",
|
|
107
|
+
year: "numeric",
|
|
108
|
+
timeZone: "UTC"
|
|
109
|
+
}), H = (e) => (/* @__PURE__ */ new Date(`${e}-01T00:00:00Z`)).toLocaleDateString(void 0, {
|
|
110
|
+
month: "short",
|
|
111
|
+
year: "numeric",
|
|
112
|
+
timeZone: "UTC"
|
|
113
|
+
}), U = (e) => e > 0 ? `+${e.toLocaleString()}` : e.toLocaleString(), W = (e) => e === null ? "—" : `${(e * 100).toLocaleString(void 0, { maximumFractionDigits: 2 })}%`, G = (e) => {
|
|
114
|
+
let { from: t, to: n } = S(e);
|
|
115
|
+
return `${t}-to-${n}`;
|
|
116
|
+
};
|
|
117
|
+
function K() {
|
|
118
|
+
let e = s(), [t] = C();
|
|
119
|
+
return e ? e.metrics ? /* @__PURE__ */ O("div", {
|
|
120
|
+
className: "flex flex-col gap-4",
|
|
121
|
+
children: [
|
|
122
|
+
/* @__PURE__ */ O("div", {
|
|
123
|
+
className: "flex flex-wrap items-center justify-between gap-3",
|
|
124
|
+
children: [/* @__PURE__ */ D("h1", {
|
|
125
|
+
className: "text-2xl font-semibold tracking-tight",
|
|
126
|
+
children: /* @__PURE__ */ D(i, { id: "Reports" })
|
|
127
|
+
}), /* @__PURE__ */ D(T, {})]
|
|
128
|
+
}),
|
|
129
|
+
/* @__PURE__ */ D(X, { range: t }),
|
|
130
|
+
/* @__PURE__ */ D(Z, { range: t })
|
|
131
|
+
]
|
|
132
|
+
}) : /* @__PURE__ */ D(n, {
|
|
133
|
+
to: "/",
|
|
134
|
+
replace: !0
|
|
135
|
+
}) : null;
|
|
136
|
+
}
|
|
137
|
+
function q(e) {
|
|
138
|
+
return e instanceof t && e.isPermissionDenied ? "Your role cannot read metrics." : e instanceof Error ? e.message : "The report failed to load.";
|
|
139
|
+
}
|
|
140
|
+
function J({ title: e, description: t, onDownload: n, canDownload: r, children: o }) {
|
|
141
|
+
return /* @__PURE__ */ O(b, { children: [/* @__PURE__ */ O(h, { children: [
|
|
142
|
+
/* @__PURE__ */ D(v, { children: e }),
|
|
143
|
+
/* @__PURE__ */ D(g, { children: t }),
|
|
144
|
+
/* @__PURE__ */ D(_, { children: /* @__PURE__ */ O(a, {
|
|
145
|
+
size: "sm",
|
|
146
|
+
variant: "outline",
|
|
147
|
+
onClick: n,
|
|
148
|
+
disabled: !r,
|
|
149
|
+
children: [/* @__PURE__ */ D(k, {
|
|
150
|
+
icon: A,
|
|
151
|
+
className: "size-4"
|
|
152
|
+
}), /* @__PURE__ */ D(i, { id: "Download CSV" })]
|
|
153
|
+
}) })
|
|
154
|
+
] }), /* @__PURE__ */ D(y, {
|
|
155
|
+
className: "overflow-x-auto",
|
|
156
|
+
children: o
|
|
157
|
+
})] });
|
|
158
|
+
}
|
|
159
|
+
function Y({ loading: e, error: t, retry: n, empty: r }) {
|
|
160
|
+
return e ? /* @__PURE__ */ D("div", {
|
|
161
|
+
className: "grid gap-2",
|
|
162
|
+
"aria-busy": !0,
|
|
163
|
+
children: Array.from({ length: 5 }).map((e, t) => /* @__PURE__ */ D(o, { className: "h-6 w-full" }, t))
|
|
164
|
+
}) : t ? /* @__PURE__ */ O("div", {
|
|
165
|
+
role: "alert",
|
|
166
|
+
className: "flex flex-wrap items-center gap-3 text-sm text-destructive",
|
|
167
|
+
children: [q(t), /* @__PURE__ */ D(a, {
|
|
168
|
+
size: "sm",
|
|
169
|
+
variant: "outline",
|
|
170
|
+
onClick: n,
|
|
171
|
+
children: /* @__PURE__ */ D(i, { id: "Retry" })
|
|
172
|
+
})]
|
|
173
|
+
}) : r ? /* @__PURE__ */ D("p", {
|
|
174
|
+
className: "py-6 text-center text-sm text-muted-foreground",
|
|
175
|
+
children: /* @__PURE__ */ D(i, { id: "Nothing in this range. Pick a wider range." })
|
|
176
|
+
}) : null;
|
|
177
|
+
}
|
|
178
|
+
function X({ range: t }) {
|
|
179
|
+
let { text: n } = e(), { adminQueries: a } = r(), o = j(t) > 400, s = E({
|
|
180
|
+
...a.widgetMetrics(M(t)),
|
|
181
|
+
enabled: !o
|
|
182
|
+
}), h = s.data ? L(s.data) : [], g = h.reduce((e, t) => ({
|
|
183
|
+
started: e.started + t.started,
|
|
184
|
+
canceled: e.canceled + t.canceled,
|
|
185
|
+
net: e.net + t.net
|
|
186
|
+
}), {
|
|
187
|
+
started: 0,
|
|
188
|
+
canceled: 0,
|
|
189
|
+
net: 0
|
|
190
|
+
});
|
|
191
|
+
return /* @__PURE__ */ D(J, {
|
|
192
|
+
title: n("Daily subscriptions"),
|
|
193
|
+
description: n("Subscriptions started and canceled each day (UTC), newest first."),
|
|
194
|
+
canDownload: h.length > 0,
|
|
195
|
+
onDownload: () => {
|
|
196
|
+
let e = z(h);
|
|
197
|
+
x(`daily-subscriptions-${G(t)}.csv`, e.header, e.rows);
|
|
198
|
+
},
|
|
199
|
+
children: o ? /* @__PURE__ */ O("p", {
|
|
200
|
+
className: "py-6 text-center text-sm text-muted-foreground",
|
|
201
|
+
children: [
|
|
202
|
+
/* @__PURE__ */ D(i, { id: "The daily report covers at most " }),
|
|
203
|
+
400,
|
|
204
|
+
/* @__PURE__ */ D(i, { id: " days. Pick a shorter range." })
|
|
205
|
+
]
|
|
206
|
+
}) : h.length === 0 || s.error ? /* @__PURE__ */ D(Y, {
|
|
207
|
+
loading: s.isPending,
|
|
208
|
+
error: s.error,
|
|
209
|
+
retry: () => void s.refetch(),
|
|
210
|
+
empty: h.length === 0
|
|
211
|
+
}) : /* @__PURE__ */ O(m, { children: [
|
|
212
|
+
/* @__PURE__ */ D(d, { children: /* @__PURE__ */ O(p, {
|
|
213
|
+
className: "hover:bg-transparent",
|
|
214
|
+
children: [
|
|
215
|
+
/* @__PURE__ */ D(c, { children: /* @__PURE__ */ D(i, { id: "Date" }) }),
|
|
216
|
+
/* @__PURE__ */ D(c, {
|
|
217
|
+
className: "text-right",
|
|
218
|
+
children: /* @__PURE__ */ D(i, { id: "New" })
|
|
219
|
+
}),
|
|
220
|
+
/* @__PURE__ */ D(c, {
|
|
221
|
+
className: "text-right",
|
|
222
|
+
children: /* @__PURE__ */ D(i, { id: "Canceled" })
|
|
223
|
+
}),
|
|
224
|
+
/* @__PURE__ */ D(c, {
|
|
225
|
+
className: "text-right",
|
|
226
|
+
children: /* @__PURE__ */ D(i, { id: "Net change" })
|
|
227
|
+
})
|
|
228
|
+
]
|
|
229
|
+
}) }),
|
|
230
|
+
/* @__PURE__ */ D(u, { children: [...h].reverse().map((e) => /* @__PURE__ */ O(p, { children: [
|
|
231
|
+
/* @__PURE__ */ D(f, {
|
|
232
|
+
className: "tabular-nums",
|
|
233
|
+
children: V(e.date)
|
|
234
|
+
}),
|
|
235
|
+
/* @__PURE__ */ D(f, {
|
|
236
|
+
className: "text-right tabular-nums",
|
|
237
|
+
children: e.started.toLocaleString()
|
|
238
|
+
}),
|
|
239
|
+
/* @__PURE__ */ D(f, {
|
|
240
|
+
className: "text-right tabular-nums",
|
|
241
|
+
children: e.canceled.toLocaleString()
|
|
242
|
+
}),
|
|
243
|
+
/* @__PURE__ */ D(f, {
|
|
244
|
+
className: "text-right tabular-nums",
|
|
245
|
+
children: U(e.net)
|
|
246
|
+
})
|
|
247
|
+
] }, e.date)) }),
|
|
248
|
+
/* @__PURE__ */ D(l, { children: /* @__PURE__ */ O(p, { children: [
|
|
249
|
+
/* @__PURE__ */ D(f, { children: /* @__PURE__ */ D(i, { id: "Total" }) }),
|
|
250
|
+
/* @__PURE__ */ D(f, {
|
|
251
|
+
className: "text-right tabular-nums",
|
|
252
|
+
children: g.started.toLocaleString()
|
|
253
|
+
}),
|
|
254
|
+
/* @__PURE__ */ D(f, {
|
|
255
|
+
className: "text-right tabular-nums",
|
|
256
|
+
children: g.canceled.toLocaleString()
|
|
257
|
+
}),
|
|
258
|
+
/* @__PURE__ */ D(f, {
|
|
259
|
+
className: "text-right tabular-nums",
|
|
260
|
+
children: U(g.net)
|
|
261
|
+
})
|
|
262
|
+
] }) })
|
|
263
|
+
] })
|
|
264
|
+
});
|
|
265
|
+
}
|
|
266
|
+
function Z({ range: t }) {
|
|
267
|
+
let { text: n } = e(), { adminQueries: a } = r(), o = E(a.widgetMetrics(N(t))), s = E(a.widgetMetrics(P(t))), l = o.data && s.data ? R(o.data, s.data) : [], h = o.error ?? s.error;
|
|
268
|
+
return /* @__PURE__ */ D(J, {
|
|
269
|
+
title: n("Monthly renewals"),
|
|
270
|
+
description: n("Renewal payments, cancellations and churn each calendar month (UTC); churn is the month's cancellations over the subscriptions it began with."),
|
|
271
|
+
canDownload: l.length > 0,
|
|
272
|
+
onDownload: () => {
|
|
273
|
+
let e = B(l);
|
|
274
|
+
x(`monthly-renewals-${G(t)}.csv`, e.header, e.rows);
|
|
275
|
+
},
|
|
276
|
+
children: l.length === 0 || h ? /* @__PURE__ */ D(Y, {
|
|
277
|
+
loading: o.isPending || s.isPending,
|
|
278
|
+
error: h,
|
|
279
|
+
retry: () => {
|
|
280
|
+
o.refetch(), s.refetch();
|
|
281
|
+
},
|
|
282
|
+
empty: l.length === 0
|
|
283
|
+
}) : /* @__PURE__ */ O(m, { children: [/* @__PURE__ */ D(d, { children: /* @__PURE__ */ O(p, {
|
|
284
|
+
className: "hover:bg-transparent",
|
|
285
|
+
children: [
|
|
286
|
+
/* @__PURE__ */ D(c, { children: /* @__PURE__ */ D(i, { id: "Month" }) }),
|
|
287
|
+
/* @__PURE__ */ D(c, {
|
|
288
|
+
className: "text-right",
|
|
289
|
+
children: /* @__PURE__ */ D(i, { id: "Renewals" })
|
|
290
|
+
}),
|
|
291
|
+
/* @__PURE__ */ D(c, {
|
|
292
|
+
className: "text-right",
|
|
293
|
+
children: /* @__PURE__ */ D(i, { id: "Canceled" })
|
|
294
|
+
}),
|
|
295
|
+
/* @__PURE__ */ D(c, {
|
|
296
|
+
className: "text-right",
|
|
297
|
+
children: /* @__PURE__ */ D(i, { id: "Churn" })
|
|
298
|
+
})
|
|
299
|
+
]
|
|
300
|
+
}) }), /* @__PURE__ */ D(u, { children: [...l].reverse().map((e) => /* @__PURE__ */ O(p, { children: [
|
|
301
|
+
/* @__PURE__ */ D(f, { children: H(e.month) }),
|
|
302
|
+
/* @__PURE__ */ D(f, {
|
|
303
|
+
className: "text-right tabular-nums",
|
|
304
|
+
children: e.renewals.toLocaleString()
|
|
305
|
+
}),
|
|
306
|
+
/* @__PURE__ */ D(f, {
|
|
307
|
+
className: "text-right tabular-nums",
|
|
308
|
+
children: e.canceled.toLocaleString()
|
|
309
|
+
}),
|
|
310
|
+
/* @__PURE__ */ D(f, {
|
|
311
|
+
className: "text-right tabular-nums",
|
|
312
|
+
children: W(e.churn)
|
|
313
|
+
})
|
|
314
|
+
] }, e.month)) })] })
|
|
315
|
+
});
|
|
316
|
+
}
|
|
317
|
+
//#endregion
|
|
318
|
+
export { K as ReportsPage };
|
|
319
|
+
|
|
320
|
+
//# sourceMappingURL=admin-reports-CywKLiSA.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"admin-reports-CywKLiSA.js","names":[],"sources":["../src/admin/pages/dashboard/reports-model.ts","../src/admin/pages/dashboard/reports.tsx"],"sourcesContent":["// The Reports page's tables, built from metrics queries over the dashboard's\n// range: subscriptions by UTC day, renewals and churn by UTC month.\nimport type {\n MetricsCell,\n MetricsQuery,\n MetricsResult,\n} from \"#orck/admin/lib/api/metrics\"\n\nimport { metricsRange, rangeDates, type DashboardRange } from \"./range\"\n\n// MAX_DAYS is the most days the daily report covers (the API's bucket limit).\nexport const MAX_DAYS = 400\n\nexport function rangeDays(range: DashboardRange, now = new Date()): number {\n const { from, to } = rangeDates(range, now)\n return (Date.parse(to) - Date.parse(from)) / 86_400_000 + 1\n}\n\nexport function dailyQuery(range: DashboardRange): MetricsQuery {\n return {\n measures: [\"new_subscriptions\", \"cancellations\", \"net_new_subscriptions\"],\n by: [\"time\"],\n grain: \"day\",\n range: metricsRange(range),\n }\n}\n\nexport function renewalsQuery(range: DashboardRange): MetricsQuery {\n return {\n measures: [\"payment_count\"],\n by: [\"time\"],\n grain: \"month\",\n range: metricsRange(range),\n filters: { attempt_kind: [\"renewal\"] },\n }\n}\n\nexport function churnQuery(range: DashboardRange): MetricsQuery {\n return {\n measures: [\"cancellations\", \"churn_rate\"],\n by: [\"time\"],\n grain: \"month\",\n range: metricsRange(range),\n }\n}\n\nexport interface DailyRow {\n // date is the UTC day, YYYY-MM-DD.\n date: string\n started: number\n canceled: number\n net: number\n}\n\nexport interface MonthlyRow {\n // month is the UTC month, YYYY-MM.\n month: string\n renewals: number\n canceled: number\n // churn is null for a month that began with no subscriptions.\n churn: number | null\n}\n\nconst count = (cell: MetricsCell | undefined) => Number(cell ?? 0)\n\n// cellsByBucket keys each row's measures by its time bucket.\nfunction cellsByBucket(\n result: MetricsResult\n): Map<string, Record<string, MetricsCell>> {\n const time = result.columns.findIndex((c) => c.kind === \"time\")\n const out = new Map<string, Record<string, MetricsCell>>()\n for (const row of result.rows) {\n const cells: Record<string, MetricsCell> = {}\n result.columns.forEach((c, i) => {\n cells[c.name] = row[i]\n })\n out.set(String(row[time]), cells)\n }\n return out\n}\n\n// dailyRows is the daily report, oldest day first.\nexport function dailyRows(result: MetricsResult): DailyRow[] {\n return [...cellsByBucket(result)]\n .sort(([a], [b]) => (a < b ? -1 : 1))\n .map(([bucket, cells]) => ({\n date: bucket.slice(0, 10),\n started: count(cells.new_subscriptions),\n canceled: count(cells.cancellations),\n net: count(cells.net_new_subscriptions),\n }))\n}\n\n// monthlyRows joins renewals with cancellations and churn, oldest month first.\nexport function monthlyRows(\n renewals: MetricsResult,\n churn: MetricsResult\n): MonthlyRow[] {\n const paid = cellsByBucket(renewals)\n const lost = cellsByBucket(churn)\n const buckets = [...new Set([...paid.keys(), ...lost.keys()])].sort()\n return buckets.map((bucket) => {\n const rate = lost.get(bucket)?.churn_rate\n return {\n month: bucket.slice(0, 7),\n renewals: count(paid.get(bucket)?.payment_count),\n canceled: count(lost.get(bucket)?.cancellations),\n churn: rate === null || rate === undefined ? null : Number(rate),\n }\n })\n}\n\nexport const dailyCsv = (rows: DailyRow[]) => ({\n header: [\"date\", \"new_subscriptions\", \"cancellations\", \"net_change\"],\n rows: rows.map((r) => [r.date, r.started, r.canceled, r.net]),\n})\n\nexport const monthlyCsv = (rows: MonthlyRow[]) => ({\n header: [\"month\", \"renewals\", \"cancellations\", \"churn_rate\"],\n rows: rows.map((r) => [r.month, r.renewals, r.canceled, r.churn ?? \"\"]),\n})\n","import { AdminMessage, useAdminUI } from \"#orck/admin/ui-context\"\nimport { useAdminServices } from \"#orck/admin/context\"\n// Dashboard › Reports: the daily subscription report and the monthly renewal\n// report over the dashboard's range, each a table with a CSV download.\nimport { HugeiconsIcon } from \"@hugeicons/react\"\nimport { Download01Icon } from \"@hugeicons/core-free-icons\"\nimport type * as React from \"react\"\nimport { Navigate } from \"#orck/admin/router\"\nimport { useQuery } from \"@tanstack/react-query\"\n\nimport { Button } from \"#orck/admin/components/ui/button\"\nimport {\n Card,\n CardAction,\n CardContent,\n CardDescription,\n CardHeader,\n CardTitle,\n} from \"#orck/admin/components/ui/card\"\nimport { Skeleton } from \"#orck/admin/components/ui/skeleton\"\nimport {\n Table,\n TableBody,\n TableCell,\n TableFooter,\n TableHead,\n TableHeader,\n TableRow,\n} from \"#orck/admin/components/ui/table\"\nimport { ApiError } from \"#orck/admin/lib/api/client\"\nimport { useAccess } from \"#orck/admin/lib/capabilities\"\nimport { downloadCsv } from \"#orck/admin/lib/csv\"\n\nimport { rangeDates, type DashboardRange } from \"./range\"\nimport { RangePicker } from \"./range-picker\"\nimport { useDashboardRange } from \"./use-range\"\nimport {\n MAX_DAYS,\n churnQuery,\n dailyCsv,\n dailyQuery,\n dailyRows,\n monthlyCsv,\n monthlyRows,\n rangeDays,\n renewalsQuery,\n} from \"./reports-model\"\n\nconst utcDay = (date: string) =>\n new Date(`${date}T00:00:00Z`).toLocaleDateString(undefined, {\n month: \"short\",\n day: \"numeric\",\n year: \"numeric\",\n timeZone: \"UTC\",\n })\n\nconst utcMonth = (month: string) =>\n new Date(`${month}-01T00:00:00Z`).toLocaleDateString(undefined, {\n month: \"short\",\n year: \"numeric\",\n timeZone: \"UTC\",\n })\n\nconst signed = (n: number) =>\n n > 0 ? `+${n.toLocaleString()}` : n.toLocaleString()\n\nconst percent = (ratio: number | null) =>\n ratio === null\n ? \"—\"\n : `${(ratio * 100).toLocaleString(undefined, { maximumFractionDigits: 2 })}%`\n\nconst suffix = (range: DashboardRange) => {\n const { from, to } = rangeDates(range)\n return `${from}-to-${to}`\n}\n\nexport function ReportsPage() {\n const access = useAccess()\n const [range] = useDashboardRange()\n if (!access) return null\n if (!access.metrics) return <Navigate to=\"/\" replace />\n return (\n <div className=\"flex flex-col gap-4\">\n <div className=\"flex flex-wrap items-center justify-between gap-3\">\n <h1 className=\"text-2xl font-semibold tracking-tight\">\n <AdminMessage id={\"Reports\"} />\n </h1>\n <RangePicker />\n </div>\n <DailyReport range={range} />\n <MonthlyReport range={range} />\n </div>\n )\n}\n\nfunction failure(error: unknown) {\n if (error instanceof ApiError && error.isPermissionDenied)\n return \"Your role cannot read metrics.\"\n return error instanceof Error ? error.message : \"The report failed to load.\"\n}\n\nfunction ReportCard({\n title,\n description,\n onDownload,\n canDownload,\n children,\n}: {\n title: string\n description: string\n onDownload: () => void\n canDownload: boolean\n children: React.ReactNode\n}) {\n return (\n <Card>\n <CardHeader>\n <CardTitle>{title}</CardTitle>\n <CardDescription>{description}</CardDescription>\n <CardAction>\n <Button\n size=\"sm\"\n variant=\"outline\"\n onClick={onDownload}\n disabled={!canDownload}\n >\n <HugeiconsIcon icon={Download01Icon} className=\"size-4\" />\n <AdminMessage id={\"Download CSV\"} />\n </Button>\n </CardAction>\n </CardHeader>\n <CardContent className=\"overflow-x-auto\">{children}</CardContent>\n </Card>\n )\n}\n\nfunction ReportState({\n loading,\n error,\n retry,\n empty,\n}: {\n loading: boolean\n error: unknown\n retry: () => void\n empty: boolean\n}) {\n if (loading)\n return (\n <div className=\"grid gap-2\" aria-busy>\n {Array.from({ length: 5 }).map((_, i) => (\n <Skeleton key={i} className=\"h-6 w-full\" />\n ))}\n </div>\n )\n if (error)\n return (\n <div\n role=\"alert\"\n className=\"flex flex-wrap items-center gap-3 text-sm text-destructive\"\n >\n {failure(error)}\n <Button size=\"sm\" variant=\"outline\" onClick={retry}>\n <AdminMessage id={\"Retry\"} />\n </Button>\n </div>\n )\n if (empty)\n return (\n <p className=\"py-6 text-center text-sm text-muted-foreground\">\n <AdminMessage id={\"Nothing in this range. Pick a wider range.\"} />\n </p>\n )\n return null\n}\n\nfunction DailyReport({ range }: { range: DashboardRange }) {\n const { text: adminText } = useAdminUI()\n\n const { adminQueries } = useAdminServices()\n\n const tooLong = rangeDays(range) > MAX_DAYS\n const query = useQuery({\n ...adminQueries.widgetMetrics(dailyQuery(range)),\n enabled: !tooLong,\n })\n const rows = query.data ? dailyRows(query.data) : []\n const totals = rows.reduce(\n (t, r) => ({\n started: t.started + r.started,\n canceled: t.canceled + r.canceled,\n net: t.net + r.net,\n }),\n { started: 0, canceled: 0, net: 0 }\n )\n return (\n <ReportCard\n title={adminText(\"Daily subscriptions\")}\n description={adminText(\n \"Subscriptions started and canceled each day (UTC), newest first.\"\n )}\n canDownload={rows.length > 0}\n onDownload={() => {\n const csv = dailyCsv(rows)\n downloadCsv(\n `daily-subscriptions-${suffix(range)}.csv`,\n csv.header,\n csv.rows\n )\n }}\n >\n {tooLong ? (\n <p className=\"py-6 text-center text-sm text-muted-foreground\">\n <AdminMessage id={\"The daily report covers at most \"} />\n {MAX_DAYS}\n <AdminMessage id={\" days. Pick a shorter range.\"} />\n </p>\n ) : rows.length === 0 || query.error ? (\n <ReportState\n loading={query.isPending}\n error={query.error}\n retry={() => void query.refetch()}\n empty={rows.length === 0}\n />\n ) : (\n <Table>\n <TableHeader>\n <TableRow className=\"hover:bg-transparent\">\n <TableHead>\n <AdminMessage id={\"Date\"} />\n </TableHead>\n <TableHead className=\"text-right\">\n <AdminMessage id={\"New\"} />\n </TableHead>\n <TableHead className=\"text-right\">\n <AdminMessage id={\"Canceled\"} />\n </TableHead>\n <TableHead className=\"text-right\">\n <AdminMessage id={\"Net change\"} />\n </TableHead>\n </TableRow>\n </TableHeader>\n <TableBody>\n {[...rows].reverse().map((r) => (\n <TableRow key={r.date}>\n <TableCell className=\"tabular-nums\">{utcDay(r.date)}</TableCell>\n <TableCell className=\"text-right tabular-nums\">\n {r.started.toLocaleString()}\n </TableCell>\n <TableCell className=\"text-right tabular-nums\">\n {r.canceled.toLocaleString()}\n </TableCell>\n <TableCell className=\"text-right tabular-nums\">\n {signed(r.net)}\n </TableCell>\n </TableRow>\n ))}\n </TableBody>\n <TableFooter>\n <TableRow>\n <TableCell>\n <AdminMessage id={\"Total\"} />\n </TableCell>\n <TableCell className=\"text-right tabular-nums\">\n {totals.started.toLocaleString()}\n </TableCell>\n <TableCell className=\"text-right tabular-nums\">\n {totals.canceled.toLocaleString()}\n </TableCell>\n <TableCell className=\"text-right tabular-nums\">\n {signed(totals.net)}\n </TableCell>\n </TableRow>\n </TableFooter>\n </Table>\n )}\n </ReportCard>\n )\n}\n\nfunction MonthlyReport({ range }: { range: DashboardRange }) {\n const { text: adminText } = useAdminUI()\n\n const { adminQueries } = useAdminServices()\n\n const renewals = useQuery(adminQueries.widgetMetrics(renewalsQuery(range)))\n const churn = useQuery(adminQueries.widgetMetrics(churnQuery(range)))\n const rows =\n renewals.data && churn.data ? monthlyRows(renewals.data, churn.data) : []\n const error = renewals.error ?? churn.error\n return (\n <ReportCard\n title={adminText(\"Monthly renewals\")}\n description={adminText(\n \"Renewal payments, cancellations and churn each calendar month (UTC); churn is the month's cancellations over the subscriptions it began with.\"\n )}\n canDownload={rows.length > 0}\n onDownload={() => {\n const csv = monthlyCsv(rows)\n downloadCsv(\n `monthly-renewals-${suffix(range)}.csv`,\n csv.header,\n csv.rows\n )\n }}\n >\n {rows.length === 0 || error ? (\n <ReportState\n loading={renewals.isPending || churn.isPending}\n error={error}\n retry={() => {\n void renewals.refetch()\n void churn.refetch()\n }}\n empty={rows.length === 0}\n />\n ) : (\n <Table>\n <TableHeader>\n <TableRow className=\"hover:bg-transparent\">\n <TableHead>\n <AdminMessage id={\"Month\"} />\n </TableHead>\n <TableHead className=\"text-right\">\n <AdminMessage id={\"Renewals\"} />\n </TableHead>\n <TableHead className=\"text-right\">\n <AdminMessage id={\"Canceled\"} />\n </TableHead>\n <TableHead className=\"text-right\">\n <AdminMessage id={\"Churn\"} />\n </TableHead>\n </TableRow>\n </TableHeader>\n <TableBody>\n {[...rows].reverse().map((r) => (\n <TableRow key={r.month}>\n <TableCell>{utcMonth(r.month)}</TableCell>\n <TableCell className=\"text-right tabular-nums\">\n {r.renewals.toLocaleString()}\n </TableCell>\n <TableCell className=\"text-right tabular-nums\">\n {r.canceled.toLocaleString()}\n </TableCell>\n <TableCell className=\"text-right tabular-nums\">\n {percent(r.churn)}\n </TableCell>\n </TableRow>\n ))}\n </TableBody>\n </Table>\n )}\n </ReportCard>\n )\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import { f as e, t } from "./admin-utils-BK4Vh1o_.js";
|
|
2
|
+
import "react";
|
|
3
|
+
import { jsx as n, jsxs as r } from "react/jsx-runtime";
|
|
4
|
+
import { CheckIcon as i, ChevronDownIcon as a, ChevronUpIcon as o } from "lucide-react";
|
|
5
|
+
import { Select as s } from "@base-ui/react/select";
|
|
6
|
+
//#region src/admin/components/ui/select.tsx
|
|
7
|
+
var c = s.Root;
|
|
8
|
+
function l({ className: e, ...r }) {
|
|
9
|
+
return /* @__PURE__ */ n(s.Value, {
|
|
10
|
+
"data-slot": "select-value",
|
|
11
|
+
className: t("flex flex-1 text-left", e),
|
|
12
|
+
...r
|
|
13
|
+
});
|
|
14
|
+
}
|
|
15
|
+
function u({ className: e, size: i = "default", children: o, ...c }) {
|
|
16
|
+
return /* @__PURE__ */ r(s.Trigger, {
|
|
17
|
+
"data-slot": "select-trigger",
|
|
18
|
+
"data-size": i,
|
|
19
|
+
className: t("flex w-fit items-center justify-between gap-1.5 rounded-lg border border-input bg-transparent py-2 pr-2 pl-2.5 text-sm whitespace-nowrap transition-colors outline-none select-none focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 disabled:cursor-not-allowed disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 data-placeholder:text-muted-foreground data-[size=default]:h-8 data-[size=sm]:h-7 data-[size=sm]:rounded-[min(var(--radius-md),10px)] *:data-[slot=select-value]:line-clamp-1 *:data-[slot=select-value]:flex *:data-[slot=select-value]:items-center *:data-[slot=select-value]:gap-1.5 dark:bg-input/30 dark:hover:bg-input/50 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4", e),
|
|
20
|
+
...c,
|
|
21
|
+
children: [o, /* @__PURE__ */ n(s.Icon, { render: /* @__PURE__ */ n(a, { className: "pointer-events-none size-4 text-muted-foreground" }) })]
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
function d({ className: i, children: a, side: o = "bottom", sideOffset: c = 4, align: l = "center", alignOffset: u = 0, alignItemWithTrigger: d = !0, ...f }) {
|
|
25
|
+
return /* @__PURE__ */ n(s.Portal, {
|
|
26
|
+
container: e().portal,
|
|
27
|
+
children: /* @__PURE__ */ n(s.Positioner, {
|
|
28
|
+
side: o,
|
|
29
|
+
sideOffset: c,
|
|
30
|
+
align: l,
|
|
31
|
+
alignOffset: u,
|
|
32
|
+
alignItemWithTrigger: d,
|
|
33
|
+
className: "isolate z-50",
|
|
34
|
+
children: /* @__PURE__ */ r(s.Popup, {
|
|
35
|
+
"data-slot": "select-content",
|
|
36
|
+
"data-align-trigger": d,
|
|
37
|
+
className: t("relative isolate z-50 max-h-(--available-height) w-(--anchor-width) min-w-36 origin-(--transform-origin) overflow-x-hidden overflow-y-auto rounded-lg bg-popover text-popover-foreground shadow-md ring-1 ring-foreground/10 duration-100 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95 data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-[align-trigger=true]:animate-none data-[side=bottom]:slide-in-from-top-2 data-[side=inline-end]:slide-in-from-left-2 data-[side=inline-start]:slide-in-from-right-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2", i),
|
|
38
|
+
...f,
|
|
39
|
+
children: [
|
|
40
|
+
/* @__PURE__ */ n(p, {}),
|
|
41
|
+
/* @__PURE__ */ n(s.List, { children: a }),
|
|
42
|
+
/* @__PURE__ */ n(m, {})
|
|
43
|
+
]
|
|
44
|
+
})
|
|
45
|
+
})
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
function f({ className: e, children: a, ...o }) {
|
|
49
|
+
return /* @__PURE__ */ r(s.Item, {
|
|
50
|
+
"data-slot": "select-item",
|
|
51
|
+
className: t("relative flex w-full cursor-default items-center gap-1.5 rounded-md py-1 pr-8 pl-1.5 text-sm outline-hidden select-none focus:bg-accent focus:text-accent-foreground not-data-[variant=destructive]:focus:**:text-accent-foreground data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 *:[span]:last:flex *:[span]:last:items-center *:[span]:last:gap-2", e),
|
|
52
|
+
...o,
|
|
53
|
+
children: [/* @__PURE__ */ n(s.ItemText, {
|
|
54
|
+
className: "flex flex-1 shrink-0 gap-2 whitespace-nowrap",
|
|
55
|
+
children: a
|
|
56
|
+
}), /* @__PURE__ */ n(s.ItemIndicator, {
|
|
57
|
+
render: /* @__PURE__ */ n("span", { className: "pointer-events-none absolute right-2 flex size-4 items-center justify-center" }),
|
|
58
|
+
children: /* @__PURE__ */ n(i, { className: "pointer-events-none" })
|
|
59
|
+
})]
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
function p({ className: e, ...r }) {
|
|
63
|
+
return /* @__PURE__ */ n(s.ScrollUpArrow, {
|
|
64
|
+
"data-slot": "select-scroll-up-button",
|
|
65
|
+
className: t("top-0 z-10 flex w-full cursor-default items-center justify-center bg-popover py-1 [&_svg:not([class*='size-'])]:size-4", e),
|
|
66
|
+
...r,
|
|
67
|
+
children: /* @__PURE__ */ n(o, {})
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
function m({ className: e, ...r }) {
|
|
71
|
+
return /* @__PURE__ */ n(s.ScrollDownArrow, {
|
|
72
|
+
"data-slot": "select-scroll-down-button",
|
|
73
|
+
className: t("bottom-0 z-10 flex w-full cursor-default items-center justify-center bg-popover py-1 [&_svg:not([class*='size-'])]:size-4", e),
|
|
74
|
+
...r,
|
|
75
|
+
children: /* @__PURE__ */ n(a, {})
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
//#endregion
|
|
79
|
+
export { l as a, u as i, d as n, f as r, c as t };
|
|
80
|
+
|
|
81
|
+
//# sourceMappingURL=admin-select-DBgprVW6.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"admin-select-DBgprVW6.js","names":[],"sources":["../src/admin/components/ui/select.tsx"],"sourcesContent":["\"use client\"\nimport { useAdminContext } from \"#orck/admin/context\"\n\nimport * as React from \"react\"\nimport { Select as SelectPrimitive } from \"@base-ui/react/select\"\n\nimport { cn } from \"#orck/admin/lib/utils\"\nimport { ChevronDownIcon, CheckIcon, ChevronUpIcon } from \"lucide-react\"\n\nconst Select = SelectPrimitive.Root\n\nfunction SelectGroup({ className, ...props }: SelectPrimitive.Group.Props) {\n return (\n <SelectPrimitive.Group\n data-slot=\"select-group\"\n className={cn(\"scroll-my-1 p-1\", className)}\n {...props}\n />\n )\n}\n\nfunction SelectValue({ className, ...props }: SelectPrimitive.Value.Props) {\n return (\n <SelectPrimitive.Value\n data-slot=\"select-value\"\n className={cn(\"flex flex-1 text-left\", className)}\n {...props}\n />\n )\n}\n\nfunction SelectTrigger({\n className,\n size = \"default\",\n children,\n ...props\n}: SelectPrimitive.Trigger.Props & {\n size?: \"sm\" | \"default\"\n}) {\n return (\n <SelectPrimitive.Trigger\n data-slot=\"select-trigger\"\n data-size={size}\n className={cn(\n \"flex w-fit items-center justify-between gap-1.5 rounded-lg border border-input bg-transparent py-2 pr-2 pl-2.5 text-sm whitespace-nowrap transition-colors outline-none select-none focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 disabled:cursor-not-allowed disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 data-placeholder:text-muted-foreground data-[size=default]:h-8 data-[size=sm]:h-7 data-[size=sm]:rounded-[min(var(--radius-md),10px)] *:data-[slot=select-value]:line-clamp-1 *:data-[slot=select-value]:flex *:data-[slot=select-value]:items-center *:data-[slot=select-value]:gap-1.5 dark:bg-input/30 dark:hover:bg-input/50 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\n className\n )}\n {...props}\n >\n {children}\n <SelectPrimitive.Icon\n render={\n <ChevronDownIcon className=\"pointer-events-none size-4 text-muted-foreground\" />\n }\n />\n </SelectPrimitive.Trigger>\n )\n}\n\nfunction SelectContent({\n className,\n children,\n side = \"bottom\",\n sideOffset = 4,\n align = \"center\",\n alignOffset = 0,\n alignItemWithTrigger = true,\n ...props\n}: SelectPrimitive.Popup.Props &\n Pick<\n SelectPrimitive.Positioner.Props,\n \"align\" | \"alignOffset\" | \"side\" | \"sideOffset\" | \"alignItemWithTrigger\"\n >) {\n return (\n <SelectPrimitive.Portal container={useAdminContext().portal}>\n <SelectPrimitive.Positioner\n side={side}\n sideOffset={sideOffset}\n align={align}\n alignOffset={alignOffset}\n alignItemWithTrigger={alignItemWithTrigger}\n className=\"isolate z-50\"\n >\n <SelectPrimitive.Popup\n data-slot=\"select-content\"\n data-align-trigger={alignItemWithTrigger}\n className={cn(\n \"relative isolate z-50 max-h-(--available-height) w-(--anchor-width) min-w-36 origin-(--transform-origin) overflow-x-hidden overflow-y-auto rounded-lg bg-popover text-popover-foreground shadow-md ring-1 ring-foreground/10 duration-100 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95 data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-[align-trigger=true]:animate-none data-[side=bottom]:slide-in-from-top-2 data-[side=inline-end]:slide-in-from-left-2 data-[side=inline-start]:slide-in-from-right-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2\",\n className\n )}\n {...props}\n >\n <SelectScrollUpButton />\n <SelectPrimitive.List>{children}</SelectPrimitive.List>\n <SelectScrollDownButton />\n </SelectPrimitive.Popup>\n </SelectPrimitive.Positioner>\n </SelectPrimitive.Portal>\n )\n}\n\nfunction SelectLabel({\n className,\n ...props\n}: SelectPrimitive.GroupLabel.Props) {\n return (\n <SelectPrimitive.GroupLabel\n data-slot=\"select-label\"\n className={cn(\"px-1.5 py-1 text-xs text-muted-foreground\", className)}\n {...props}\n />\n )\n}\n\nfunction SelectItem({\n className,\n children,\n ...props\n}: SelectPrimitive.Item.Props) {\n return (\n <SelectPrimitive.Item\n data-slot=\"select-item\"\n className={cn(\n \"relative flex w-full cursor-default items-center gap-1.5 rounded-md py-1 pr-8 pl-1.5 text-sm outline-hidden select-none focus:bg-accent focus:text-accent-foreground not-data-[variant=destructive]:focus:**:text-accent-foreground data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 *:[span]:last:flex *:[span]:last:items-center *:[span]:last:gap-2\",\n className\n )}\n {...props}\n >\n <SelectPrimitive.ItemText className=\"flex flex-1 shrink-0 gap-2 whitespace-nowrap\">\n {children}\n </SelectPrimitive.ItemText>\n <SelectPrimitive.ItemIndicator\n render={\n <span className=\"pointer-events-none absolute right-2 flex size-4 items-center justify-center\" />\n }\n >\n <CheckIcon className=\"pointer-events-none\" />\n </SelectPrimitive.ItemIndicator>\n </SelectPrimitive.Item>\n )\n}\n\nfunction SelectSeparator({\n className,\n ...props\n}: SelectPrimitive.Separator.Props) {\n return (\n <SelectPrimitive.Separator\n data-slot=\"select-separator\"\n className={cn(\"pointer-events-none -mx-1 my-1 h-px bg-border\", className)}\n {...props}\n />\n )\n}\n\nfunction SelectScrollUpButton({\n className,\n ...props\n}: React.ComponentProps<typeof SelectPrimitive.ScrollUpArrow>) {\n return (\n <SelectPrimitive.ScrollUpArrow\n data-slot=\"select-scroll-up-button\"\n className={cn(\n \"top-0 z-10 flex w-full cursor-default items-center justify-center bg-popover py-1 [&_svg:not([class*='size-'])]:size-4\",\n className\n )}\n {...props}\n >\n <ChevronUpIcon />\n </SelectPrimitive.ScrollUpArrow>\n )\n}\n\nfunction SelectScrollDownButton({\n className,\n ...props\n}: React.ComponentProps<typeof SelectPrimitive.ScrollDownArrow>) {\n return (\n <SelectPrimitive.ScrollDownArrow\n data-slot=\"select-scroll-down-button\"\n className={cn(\n \"bottom-0 z-10 flex w-full cursor-default items-center justify-center bg-popover py-1 [&_svg:not([class*='size-'])]:size-4\",\n className\n )}\n {...props}\n >\n <ChevronDownIcon />\n </SelectPrimitive.ScrollDownArrow>\n )\n}\n\nexport {\n Select,\n SelectContent,\n SelectGroup,\n SelectItem,\n SelectLabel,\n SelectScrollDownButton,\n SelectScrollUpButton,\n SelectSeparator,\n SelectTrigger,\n SelectValue,\n}\n"],"mappings":";;;;;;AASA,IAAM,IAAS,EAAgB;AAY/B,SAAS,EAAY,EAAE,cAAW,GAAG,KAAsC;CACzE,OACE,kBAAC,EAAgB,OAAjB;EACE,aAAU;EACV,WAAW,EAAG,yBAAyB,CAAS;EAChD,GAAI;CACL,CAAA;AAEL;AAEA,SAAS,EAAc,EACrB,cACA,UAAO,WACP,aACA,GAAG,KAGF;CACD,OACE,kBAAC,EAAgB,SAAjB;EACE,aAAU;EACV,aAAW;EACX,WAAW,EACT,u2BACA,CACF;EACA,GAAI;EAPN,UAAA,CASG,GACD,kBAAC,EAAgB,MAAjB,EACE,QACE,kBAAC,GAAD,EAAiB,WAAU,mDAAoD,CAAA,EAElF,CAAA,CACsB;;AAE7B;AAEA,SAAS,EAAc,EACrB,cACA,aACA,UAAO,UACP,gBAAa,GACb,WAAQ,UACR,iBAAc,GACd,0BAAuB,IACvB,GAAG,KAKA;CACH,OACE,kBAAC,EAAgB,QAAjB;EAAwB,WAAW,EAAgB,CAAC,CAAC;EACnD,UAAA,kBAAC,EAAgB,YAAjB;GACQ;GACM;GACL;GACM;GACS;GACtB,WAAU;GAEV,UAAA,kBAAC,EAAgB,OAAjB;IACE,aAAU;IACV,sBAAoB;IACpB,WAAW,EACT,gpBACA,CACF;IACA,GAAI;IAPN,UAAA;KASE,kBAAC,GAAD,CAAuB,CAAA;KACvB,kBAAC,EAAgB,MAAjB,EAAuB,YAA+B,CAAA;KACtD,kBAAC,GAAD,CAAyB,CAAA;IACJ;;EACG,CAAA;CACN,CAAA;AAE5B;AAeA,SAAS,EAAW,EAClB,cACA,aACA,GAAG,KAC0B;CAC7B,OACE,kBAAC,EAAgB,MAAjB;EACE,aAAU;EACV,WAAW,EACT,sbACA,CACF;EACA,GAAI;EANN,UAAA,CAQE,kBAAC,EAAgB,UAAjB;GAA0B,WAAU;GACjC;EACuB,CAAA,GAC1B,kBAAC,EAAgB,eAAjB;GACE,QACE,kBAAC,QAAD,EAAM,WAAU,+EAAgF,CAAA;GAGlG,UAAA,kBAAC,GAAD,EAAW,WAAU,sBAAuB,CAAA;EACf,CAAA,CACX;;AAE1B;AAeA,SAAS,EAAqB,EAC5B,cACA,GAAG,KAC0D;CAC7D,OACE,kBAAC,EAAgB,eAAjB;EACE,aAAU;EACV,WAAW,EACT,0HACA,CACF;EACA,GAAI;EAEJ,UAAA,kBAAC,GAAD,CAAgB,CAAA;CACa,CAAA;AAEnC;AAEA,SAAS,EAAuB,EAC9B,cACA,GAAG,KAC4D;CAC/D,OACE,kBAAC,EAAgB,iBAAjB;EACE,aAAU;EACV,WAAW,EACT,6HACA,CACF;EACA,GAAI;EAEJ,UAAA,kBAAC,GAAD,CAAkB,CAAA;CACa,CAAA;AAErC"}
|