@burdenoff/microfe-billing 2026.614.1 → 2026.623.2
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/billing/BillingAdminRoutes.js +7 -6
- package/dist/billing/BillingAdminRoutes.js.map +1 -1
- package/dist/billing/BillingRoot.js +1 -1
- package/dist/billing/BillingRoot.js.map +1 -1
- package/dist/billing/modules/addons/components/FloatingCartDrawer.js +22 -22
- package/dist/billing/modules/addons/components/FloatingCartDrawer.js.map +1 -1
- package/dist/billing/modules/addons/pages/AddonCreatePage.js +31 -31
- package/dist/billing/modules/addons/pages/AddonCreatePage.js.map +1 -1
- package/dist/billing/modules/addons/pages/AddonDetailPage.js +39 -39
- package/dist/billing/modules/addons/pages/AddonDetailPage.js.map +1 -1
- package/dist/billing/modules/addons/pages/AddonEditPage.js +29 -29
- package/dist/billing/modules/addons/pages/AddonEditPage.js.map +1 -1
- package/dist/billing/modules/addons/pages/AddonsListPage.js +91 -91
- package/dist/billing/modules/addons/pages/AddonsListPage.js.map +1 -1
- package/dist/billing/modules/analytics/pages/AnalyticsPage.js +40 -40
- package/dist/billing/modules/analytics/pages/AnalyticsPage.js.map +1 -1
- package/dist/billing/modules/billing/pages/InvoiceDetailPage.js +115 -115
- package/dist/billing/modules/billing/pages/InvoiceDetailPage.js.map +1 -1
- package/dist/billing/modules/billing/pages/InvoicesListPage.js +75 -72
- package/dist/billing/modules/billing/pages/InvoicesListPage.js.map +1 -1
- package/dist/billing/modules/billing/pages/RefundsPage.js +126 -126
- package/dist/billing/modules/billing/pages/RefundsPage.js.map +1 -1
- package/dist/billing/modules/billing/pages/UserRefundsPage.js +45 -45
- package/dist/billing/modules/billing/pages/UserRefundsPage.js.map +1 -1
- package/dist/billing/modules/checkout/components/BillingAccountSelector.js +25 -25
- package/dist/billing/modules/checkout/components/BillingAccountSelector.js.map +1 -1
- package/dist/billing/modules/checkout/components/CompleteBillingAccountModal.js +31 -35
- package/dist/billing/modules/checkout/components/CompleteBillingAccountModal.js.map +1 -1
- package/dist/billing/modules/checkout/components/CreditsAmountInput.js +9 -9
- package/dist/billing/modules/checkout/components/CreditsAmountInput.js.map +1 -1
- package/dist/billing/modules/checkout/components/OrderSummary.js +31 -31
- package/dist/billing/modules/checkout/components/OrderSummary.js.map +1 -1
- package/dist/billing/modules/checkout/components/PromoCodeInput.js +8 -8
- package/dist/billing/modules/checkout/components/PromoCodeInput.js.map +1 -1
- package/dist/billing/modules/checkout/components/RazorpayPaymentButton.js +5 -5
- package/dist/billing/modules/checkout/components/RazorpayPaymentButton.js.map +1 -1
- package/dist/billing/modules/checkout/components/SimpleAutoPayToggle.js +9 -9
- package/dist/billing/modules/checkout/components/SimpleAutoPayToggle.js.map +1 -1
- package/dist/billing/modules/checkout/components/StripePaymentForm.js +21 -21
- package/dist/billing/modules/checkout/components/StripePaymentForm.js.map +1 -1
- package/dist/billing/modules/checkout/components/SubscriptionSelector.js +11 -11
- package/dist/billing/modules/checkout/components/SubscriptionSelector.js.map +1 -1
- package/dist/billing/modules/checkout/components/UnifiedPaymentMethodSelector.js +31 -31
- package/dist/billing/modules/checkout/components/UnifiedPaymentMethodSelector.js.map +1 -1
- package/dist/billing/modules/checkout/components/WorkspaceQuotaAssignmentModal.js +23 -23
- package/dist/billing/modules/checkout/components/WorkspaceQuotaAssignmentModal.js.map +1 -1
- package/dist/billing/modules/checkout/pages/CheckoutPage.js +91 -91
- package/dist/billing/modules/checkout/pages/CheckoutPage.js.map +1 -1
- package/dist/billing/modules/coupons/pages/CouponDetailPage.js +62 -62
- package/dist/billing/modules/coupons/pages/CouponDetailPage.js.map +1 -1
- package/dist/billing/modules/coupons/pages/CouponsListPage.js +72 -60
- package/dist/billing/modules/coupons/pages/CouponsListPage.js.map +1 -1
- package/dist/billing/modules/coupons/pages/CreateCouponPage.js +66 -66
- package/dist/billing/modules/coupons/pages/CreateCouponPage.js.map +1 -1
- package/dist/billing/modules/coupons/pages/EditCouponPage.js +46 -46
- package/dist/billing/modules/coupons/pages/EditCouponPage.js.map +1 -1
- package/dist/billing/modules/credits/pages/AdminCreditsPage.js +19 -19
- package/dist/billing/modules/credits/pages/AdminCreditsPage.js.map +1 -1
- package/dist/billing/modules/credits/pages/CreditTransactionsPage.js +37 -37
- package/dist/billing/modules/credits/pages/CreditTransactionsPage.js.map +1 -1
- package/dist/billing/modules/credits/pages/CreditWithdrawalPage.js +90 -90
- package/dist/billing/modules/credits/pages/CreditWithdrawalPage.js.map +1 -1
- package/dist/billing/modules/credits/pages/CreditsPage.js +41 -41
- package/dist/billing/modules/credits/pages/CreditsPage.js.map +1 -1
- package/dist/billing/modules/dashboard/components/ActiveSubscriptionCard.js +31 -31
- package/dist/billing/modules/dashboard/components/ActiveSubscriptionCard.js.map +1 -1
- package/dist/billing/modules/dashboard/components/AddPaymentMethodModal.js +35 -35
- package/dist/billing/modules/dashboard/components/AddPaymentMethodModal.js.map +1 -1
- package/dist/billing/modules/dashboard/components/BillingAccountCard.js +24 -24
- package/dist/billing/modules/dashboard/components/BillingAccountCard.js.map +1 -1
- package/dist/billing/modules/dashboard/components/CreateBillingAccountModal.js +99 -99
- package/dist/billing/modules/dashboard/components/CreateBillingAccountModal.js.map +1 -1
- package/dist/billing/modules/dashboard/components/PaymentMethodsSection.js +23 -23
- package/dist/billing/modules/dashboard/components/PaymentMethodsSection.js.map +1 -1
- package/dist/billing/modules/dashboard/components/RecommendedAddonsSection.js +22 -22
- package/dist/billing/modules/dashboard/components/RecommendedAddonsSection.js.map +1 -1
- package/dist/billing/modules/dashboard/pages/OverviewPage.js +58 -58
- package/dist/billing/modules/dashboard/pages/OverviewPage.js.map +1 -1
- package/dist/billing/modules/discounts/pages/DiscountsListPage.js +126 -126
- package/dist/billing/modules/discounts/pages/DiscountsListPage.js.map +1 -1
- package/dist/billing/modules/earnings/pages/PayoutAdminPage.js +83 -79
- package/dist/billing/modules/earnings/pages/PayoutAdminPage.js.map +1 -1
- package/dist/billing/modules/plans/pages/PlanAssignFreePage.js +16 -16
- package/dist/billing/modules/plans/pages/PlanAssignFreePage.js.map +1 -1
- package/dist/billing/modules/plans/pages/PlanBrowseDetailPage.js +40 -40
- package/dist/billing/modules/plans/pages/PlanBrowseDetailPage.js.map +1 -1
- package/dist/billing/modules/plans/pages/PlanCreatePage.js +35 -35
- package/dist/billing/modules/plans/pages/PlanCreatePage.js.map +1 -1
- package/dist/billing/modules/plans/pages/PlanDetailPage.js +57 -57
- package/dist/billing/modules/plans/pages/PlanDetailPage.js.map +1 -1
- package/dist/billing/modules/plans/pages/PlanEditPage.js +35 -35
- package/dist/billing/modules/plans/pages/PlanEditPage.js.map +1 -1
- package/dist/billing/modules/plans/pages/PlansBrowsePage.js +57 -57
- package/dist/billing/modules/plans/pages/PlansBrowsePage.js.map +1 -1
- package/dist/billing/modules/plans/pages/PlansListPage.js +52 -52
- package/dist/billing/modules/plans/pages/PlansListPage.js.map +1 -1
- package/dist/billing/modules/promotions/pages/CreatePromotionPage.js +40 -39
- package/dist/billing/modules/promotions/pages/CreatePromotionPage.js.map +1 -1
- package/dist/billing/modules/promotions/pages/PromotionsListPage.js +22 -19
- package/dist/billing/modules/promotions/pages/PromotionsListPage.js.map +1 -1
- package/dist/billing/modules/quota/pages/QuotaTemplateCreatePage.js +34 -34
- package/dist/billing/modules/quota/pages/QuotaTemplateCreatePage.js.map +1 -1
- package/dist/billing/modules/quota/pages/QuotaTemplateDetailPage.js +47 -47
- package/dist/billing/modules/quota/pages/QuotaTemplateDetailPage.js.map +1 -1
- package/dist/billing/modules/quota/pages/QuotaTemplateEditPage.js +39 -39
- package/dist/billing/modules/quota/pages/QuotaTemplateEditPage.js.map +1 -1
- package/dist/billing/modules/quota/pages/QuotaTemplatesListPage.js +52 -52
- package/dist/billing/modules/quota/pages/QuotaTemplatesListPage.js.map +1 -1
- package/dist/billing/modules/subscriptions/components/ManageSeatsModal.js +23 -23
- package/dist/billing/modules/subscriptions/components/ManageSeatsModal.js.map +1 -1
- package/dist/billing/modules/subscriptions/pages/SubscriptionDetailPage.js +259 -246
- package/dist/billing/modules/subscriptions/pages/SubscriptionDetailPage.js.map +1 -1
- package/dist/billing/modules/subscriptions/pages/SubscriptionsListPage.js +88 -85
- package/dist/billing/modules/subscriptions/pages/SubscriptionsListPage.js.map +1 -1
- package/dist/billing/modules/subscriptions/pages/UpgradeSubscriptionPage.js +51 -51
- package/dist/billing/modules/subscriptions/pages/UpgradeSubscriptionPage.js.map +1 -1
- package/dist/billing/modules/usage/pages/UsagePage.js +206 -196
- package/dist/billing/modules/usage/pages/UsagePage.js.map +1 -1
- package/dist/billing/shared/components/ServerError.js +4 -4
- package/dist/billing/shared/components/ServerError.js.map +1 -1
- package/dist/billing/shared/components/StatCard.js +11 -33
- package/dist/billing/shared/components/StatCard.js.map +1 -1
- package/dist/billing/shared/ui/Card.js +15 -0
- package/dist/billing/shared/ui/Card.js.map +1 -0
- package/dist/billing/shared/ui/MetricCard.js +44 -0
- package/dist/billing/shared/ui/MetricCard.js.map +1 -0
- package/dist/billing/shared/ui/ProgressBar.js +30 -0
- package/dist/billing/shared/ui/ProgressBar.js.map +1 -0
- package/dist/billing/shared/ui/SectionHeader.js +2 -0
- package/dist/billing/shared/ui/StatusPill.js +28 -0
- package/dist/billing/shared/ui/StatusPill.js.map +1 -0
- package/dist/billing/shared/ui/index.js +5 -0
- package/dist/billing/shared/utils/tokens.js +13 -30
- package/dist/billing/shared/utils/tokens.js.map +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"InvoiceDetailPage.js","names":[],"sources":["../../../../../src/billing/modules/billing/pages/InvoiceDetailPage.tsx"],"sourcesContent":["/**\n * Billing Module - Invoice Detail Page\n * Displays detailed information about a single invoice\n */\n\nimport { type FC, useState } from 'react';\nimport { useParams } from 'react-router-dom';\nimport { useBillingNavigate } from '../../../hooks/useBillingNavigate';\nimport { useBilling } from '../../../providers/BillingProvider';\nimport { useBillingAccountSelection } from '../../../hooks/useBillingAccountSelection';\nimport { useInvoice, useInvoiceMutations } from '../hooks/useInvoices';\nimport { useBillingPermissions } from '../../../hooks/useBillingPermissions';\nimport { useGetDefaultBillingAccountDashboardQuery } from '../../../../generated/global-operations';\nimport {\n formatCurrency,\n formatDate,\n formatInvoiceStatus,\n formatInvoiceNumber,\n} from '../../../shared/utils/format';\nimport { withBillingAccountId } from '../../../shared/utils/navigation';\nimport { getInvoiceStatusColor, getStatusBadgeClasses } from '../../../shared/utils/status';\nimport type { InvoiceStatus } from '../../../shared/types';\nimport { useI18n } from '@burdenoff/fe-libs/shared/providers/shell/I18nProvider';\n\nexport const InvoiceDetailPage: FC = () => {\n const { t } = useI18n();\n const tr = (key: string, fallback: string): string => {\n const translated = t(key);\n return translated === key ? fallback : translated;\n };\n const { invoiceId } = useParams<{ invoiceId: string }>();\n const navigateTo = useBillingNavigate();\n const { orgId } = useBilling();\n const permissions = useBillingPermissions();\n const { selectedAccountId } = useBillingAccountSelection({\n orgId,\n syncFromUrl: true,\n urlParamName: 'billingAccountId',\n });\n const { data: defaultBillingAccountData } = useGetDefaultBillingAccountDashboardQuery({\n fetchPolicy: 'cache-first',\n });\n const billingAccountId =\n selectedAccountId ?? defaultBillingAccountData?.getDefaultBillingAccount?.id ?? undefined;\n const { invoice, isLoading, error, refetch } = useInvoice(invoiceId, billingAccountId);\n const { payInvoice, voidInvoice, isPaying, isVoiding } = useInvoiceMutations();\n const defaultPaymentMethodId =\n defaultBillingAccountData?.getDefaultBillingAccount?.defaultPaymentMethod;\n\n // Action error state\n const [actionError, setActionError] = useState<string | null>(null);\n\n // Handle pay invoice\n const handlePayInvoice = async () => {\n if (!invoice) return;\n if (!defaultPaymentMethodId) {\n setActionError('Add and set a default payment method before paying this invoice.');\n return;\n }\n\n if (!billingAccountId) {\n setActionError('No billing account context');\n return;\n }\n setActionError(null);\n try {\n await payInvoice(invoice.id, defaultPaymentMethodId, billingAccountId);\n await refetch();\n } catch (err) {\n setActionError(err instanceof Error ? err.message : 'Failed to pay invoice');\n }\n };\n\n // Handle void invoice\n const handleVoidInvoice = async () => {\n if (!invoice) return;\n if (!billingAccountId) {\n setActionError('No billing account context');\n return;\n }\n\n setActionError(null);\n try {\n await voidInvoice(invoice.id, billingAccountId);\n await refetch();\n } catch (err) {\n setActionError(err instanceof Error ? err.message : 'Failed to void invoice');\n }\n };\n\n // Permission check\n if (!permissions.canViewInvoices) {\n return (\n <div className=\"flex items-center justify-center h-full min-h-[400px]\">\n <div className=\"text-center space-y-2\">\n <div className=\"size-12 mx-auto rounded-full bg-muted flex items-center justify-center\">\n <svg\n className=\"size-6 text-muted-foreground\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M12 15v2m-6 4h12a2 2 0 002-2v-6a2 2 0 00-2-2H6a2 2 0 00-2 2v6a2 2 0 002 2zm10-10V7a4 4 0 00-8 0v4h8z\"\n />\n </svg>\n </div>\n <h2 className=\"text-lg font-semibold text-foreground\">\n {tr('billing.accessDenied.title', 'Access Denied')}\n </h2>\n <p className=\"text-sm text-muted-foreground max-w-sm\">\n {tr('billing.invoices.noViewPermission', \"You don't have permission to view invoices.\")}\n </p>\n </div>\n </div>\n );\n }\n\n // Loading state\n if (isLoading) {\n return (\n <div className=\"space-y-6 p-6\">\n <div className=\"flex items-center gap-4\">\n <div className=\"size-10 bg-muted animate-pulse rounded\" />\n <div className=\"space-y-2\">\n <div className=\"h-8 w-48 bg-muted animate-pulse rounded\" />\n <div className=\"h-4 w-32 bg-muted animate-pulse rounded\" />\n </div>\n </div>\n <div className=\"grid grid-cols-1 lg:grid-cols-3 gap-6\">\n <div className=\"lg:col-span-2 space-y-6\">\n <div className=\"border border-border rounded-lg p-6 space-y-4\">\n <div className=\"h-6 w-32 bg-muted animate-pulse rounded\" />\n <div className=\"h-4 w-full bg-muted animate-pulse rounded\" />\n <div className=\"h-4 w-3/4 bg-muted animate-pulse rounded\" />\n </div>\n <div className=\"border border-border rounded-lg p-6 space-y-4\">\n <div className=\"h-6 w-24 bg-muted animate-pulse rounded\" />\n {[1, 2, 3].map((i) => (\n <div key={i} className=\"flex items-center gap-4\">\n <div className=\"h-4 flex-1 bg-muted animate-pulse rounded\" />\n <div className=\"h-4 w-16 bg-muted animate-pulse rounded\" />\n <div className=\"h-4 w-16 bg-muted animate-pulse rounded\" />\n <div className=\"h-4 w-20 bg-muted animate-pulse rounded\" />\n </div>\n ))}\n </div>\n </div>\n <div className=\"space-y-6\">\n <div className=\"border border-border rounded-lg p-6 space-y-4\">\n <div className=\"h-6 w-24 bg-muted animate-pulse rounded\" />\n {[1, 2, 3, 4].map((i) => (\n <div key={i} className=\"space-y-1\">\n <div className=\"h-3 w-20 bg-muted animate-pulse rounded\" />\n <div className=\"h-4 w-28 bg-muted animate-pulse rounded\" />\n </div>\n ))}\n </div>\n </div>\n </div>\n </div>\n );\n }\n\n // Error state\n if (error || !invoice) {\n return (\n <div className=\"flex items-center justify-center h-full min-h-[400px]\">\n <div className=\"text-center space-y-4\">\n <div className=\"size-12 mx-auto rounded-full bg-destructive/10 flex items-center justify-center\">\n <svg\n className=\"size-6 text-destructive\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z\"\n />\n </svg>\n </div>\n <h2 className=\"text-lg font-semibold text-foreground\">\n {tr('billing.invoices.invoiceNotFound', 'Invoice not found')}\n </h2>\n <p className=\"text-sm text-muted-foreground\">\n {error?.message ||\n tr(\n 'billing.invoices.invoiceNotFoundMessage',\n 'The invoice you are looking for does not exist.'\n )}\n </p>\n <div className=\"flex items-center justify-center gap-3\">\n <button\n type=\"button\"\n onClick={() => refetch()}\n className=\"px-4 py-2 text-sm font-medium bg-primary text-primary-foreground rounded-md hover:bg-primary/90 transition-colors\"\n >\n Try Again\n </button>\n <button\n type=\"button\"\n onClick={() => navigateTo(withBillingAccountId('/invoices', billingAccountId))}\n className=\"px-4 py-2 text-sm font-medium border border-border text-foreground rounded-md hover:bg-muted transition-colors\"\n >\n Back to Invoices\n </button>\n </div>\n </div>\n </div>\n );\n }\n\n const statusColor = getInvoiceStatusColor(invoice.status);\n const isOpen = invoice.status === ('OPEN' as InvoiceStatus);\n const isDraft = invoice.status === ('DRAFT' as InvoiceStatus);\n const items = invoice.items || [];\n const amountDue = invoice.total - invoice.amountPaid;\n\n return (\n <div className=\"space-y-6 p-6\">\n {/* Header */}\n <div className=\"flex flex-col gap-4 sm:flex-row sm:items-start sm:justify-between\">\n <div className=\"flex items-start gap-4\">\n <button\n type=\"button\"\n onClick={() => navigateTo(withBillingAccountId('/invoices', billingAccountId))}\n className=\"p-2 -ml-2 text-muted-foreground hover:text-foreground hover:bg-muted rounded-md transition-colors\"\n >\n <svg className=\"size-5\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\">\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M15 19l-7-7 7-7\"\n />\n </svg>\n </button>\n <div>\n <div className=\"flex items-center gap-3\">\n <h1 className=\"text-2xl font-bold text-foreground\">\n Invoice {formatInvoiceNumber(invoice.invoiceNumber)}\n </h1>\n <span\n className={`px-2 py-1 text-xs font-medium rounded ${getStatusBadgeClasses(statusColor)}`}\n >\n {formatInvoiceStatus(invoice.status)}\n </span>\n </div>\n <p className=\"text-sm text-muted-foreground mt-1\">\n Created {formatDate(invoice.createdAt, 'short')}\n {invoice.dueDate && ` · Due ${formatDate(invoice.dueDate, 'short')}`}\n </p>\n </div>\n </div>\n\n <div className=\"flex items-center gap-2 flex-wrap\">\n {invoice.pdfUrl && (\n <a\n href={invoice.pdfUrl}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"px-4 py-2 text-sm font-medium border border-border text-foreground rounded-md hover:bg-muted transition-colors\"\n >\n Download PDF\n </a>\n )}\n {invoice.invoiceUrl && (\n <a\n href={invoice.invoiceUrl}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"px-4 py-2 text-sm font-medium border border-border text-foreground rounded-md hover:bg-muted transition-colors\"\n >\n View on Portal\n </a>\n )}\n {isOpen && permissions.canPayInvoice && (\n <button\n type=\"button\"\n onClick={handlePayInvoice}\n disabled={isPaying || !defaultPaymentMethodId}\n className=\"px-4 py-2 text-sm font-medium bg-primary text-primary-foreground rounded-md hover:bg-primary/90 transition-colors disabled:opacity-50\"\n >\n {!defaultPaymentMethodId\n ? 'Default Payment Method Required'\n : isPaying\n ? 'Processing...'\n : 'Pay Invoice'}\n </button>\n )}\n {(isOpen || isDraft) && permissions.canVoidInvoice && (\n <button\n type=\"button\"\n onClick={handleVoidInvoice}\n disabled={isVoiding}\n className=\"px-4 py-2 text-sm font-medium border border-border text-destructive rounded-md hover:bg-destructive/10 transition-colors disabled:opacity-50\"\n >\n {isVoiding\n ? tr('billing.invoices.voiding', 'Voiding...')\n : tr('billing.invoices.voidInvoice', 'Void Invoice')}\n </button>\n )}\n </div>\n </div>\n\n {/* Action Error */}\n {actionError && (\n <div className=\"p-3 bg-destructive/10 border border-destructive/20 rounded-md\">\n <p className=\"text-sm text-destructive\">{actionError}</p>\n </div>\n )}\n\n <div className=\"grid grid-cols-1 lg:grid-cols-3 gap-6\">\n {/* Main Content */}\n <div className=\"lg:col-span-2 space-y-6\">\n {/* Line Items */}\n <div className=\"border border-border rounded-lg bg-card overflow-hidden\">\n <div className=\"p-6 border-b border-border bg-muted/30\">\n <h2 className=\"text-lg font-semibold text-foreground\">\n {tr('billing.invoices.lineItems', 'Line Items')} ({items.length})\n </h2>\n </div>\n {items.length === 0 ? (\n <div className=\"p-6\">\n <p className=\"text-sm text-muted-foreground\">\n {tr('billing.invoices.noLineItems', 'No line items on this invoice.')}\n </p>\n </div>\n ) : (\n <div className=\"overflow-x-auto\">\n <table className=\"w-full\">\n <thead className=\"bg-muted/50\">\n <tr>\n <th className=\"text-left px-4 py-3 text-sm font-medium text-muted-foreground\">\n Description\n </th>\n <th className=\"text-right px-4 py-3 text-sm font-medium text-muted-foreground\">\n Qty\n </th>\n <th className=\"text-right px-4 py-3 text-sm font-medium text-muted-foreground\">\n Unit Price\n </th>\n <th className=\"text-right px-4 py-3 text-sm font-medium text-muted-foreground\">\n Amount\n </th>\n </tr>\n </thead>\n <tbody className=\"divide-y divide-border\">\n {items.map((item) => (\n <tr key={item.id} className=\"hover:bg-muted/30 transition-colors\">\n <td className=\"p-4 text-sm text-foreground\">{item.description}</td>\n <td className=\"p-4 text-sm text-muted-foreground text-right\">\n {item.quantity}\n </td>\n <td className=\"p-4 text-sm text-muted-foreground text-right\">\n {formatCurrency(item.unitPrice, invoice.currency)}\n </td>\n <td className=\"p-4 text-sm font-medium text-foreground text-right\">\n {formatCurrency(item.amount, invoice.currency)}\n </td>\n </tr>\n ))}\n </tbody>\n </table>\n </div>\n )}\n\n {/* Totals */}\n <div className=\"border-t border-border p-4\">\n <div className=\"max-w-xs ml-auto space-y-2\">\n <div className=\"flex items-center justify-between text-sm\">\n <span className=\"text-muted-foreground\">\n {tr('billing.invoices.subtotal', 'Subtotal')}\n </span>\n <span className=\"text-foreground\">\n {formatCurrency(invoice.subtotal, invoice.currency)}\n </span>\n </div>\n <div className=\"flex items-center justify-between text-sm\">\n <span className=\"text-muted-foreground\">{tr('billing.invoices.tax', 'Tax')}</span>\n <span className=\"text-foreground\">\n {formatCurrency(invoice.tax, invoice.currency)}\n </span>\n </div>\n <div className=\"flex items-center justify-between text-sm font-semibold border-t border-border pt-2\">\n <span className=\"text-foreground\">{tr('billing.invoices.total', 'Total')}</span>\n <span className=\"text-foreground\">\n {formatCurrency(invoice.total, invoice.currency)}\n </span>\n </div>\n {invoice.amountPaid > 0 && (\n <div className=\"flex items-center justify-between text-sm\">\n <span className=\"text-muted-foreground\">\n {tr('billing.invoices.amountPaid', 'Amount Paid')}\n </span>\n <span className=\"text-status-success-text\">\n -{formatCurrency(invoice.amountPaid, invoice.currency)}\n </span>\n </div>\n )}\n {amountDue > 0 && (\n <div className=\"flex items-center justify-between text-sm font-semibold border-t border-border pt-2\">\n <span className=\"text-foreground\">\n {tr('billing.invoices.amountDue', 'Amount Due')}\n </span>\n <span className=\"text-status-warning-text\">\n {formatCurrency(amountDue, invoice.currency)}\n </span>\n </div>\n )}\n </div>\n </div>\n </div>\n\n {/* Subscription Info */}\n {invoice.subscription && (\n <div className=\"border border-border rounded-lg bg-card overflow-hidden\">\n <div className=\"p-6 border-b border-border bg-muted/30\">\n <h2 className=\"text-lg font-semibold text-foreground\">\n {tr('billing.invoices.subscription', 'Subscription')}\n </h2>\n </div>\n <div className=\"p-6 space-y-4\">\n <div className=\"flex items-center justify-between\">\n <div>\n <p className=\"font-medium text-foreground\">\n {invoice.subscription.plan?.name || 'Unknown Plan'}\n </p>\n <p className=\"text-sm text-muted-foreground mt-0.5\">\n Subscription ID:{' '}\n <span className=\"font-mono text-xs\">{invoice.subscription.id}</span>\n </p>\n </div>\n <button\n type=\"button\"\n onClick={() =>\n navigateTo(\n withBillingAccountId(\n `/subscriptions/${invoice.subscription!.id}`,\n billingAccountId\n )\n )\n }\n className=\"px-3 py-1.5 text-sm font-medium text-foreground hover:bg-muted rounded-md transition-colors\"\n >\n View\n </button>\n </div>\n </div>\n </div>\n )}\n\n {/* Payment Info */}\n {invoice.payment && (\n <div className=\"border border-border rounded-lg bg-card overflow-hidden\">\n <div className=\"p-6 border-b border-border bg-muted/30\">\n <h2 className=\"text-lg font-semibold text-foreground\">\n {tr('billing.invoices.payment', 'Payment')}\n </h2>\n </div>\n <div className=\"p-6\">\n <div className=\"grid grid-cols-2 gap-4\">\n <div>\n <p className=\"text-sm text-muted-foreground\">Payment ID</p>\n <p className=\"font-mono text-sm text-foreground mt-0.5 break-all\">\n {invoice.payment.id}\n </p>\n </div>\n <div>\n <p className=\"text-sm text-muted-foreground\">Amount</p>\n <p className=\"text-sm text-foreground mt-0.5\">\n {formatCurrency(invoice.payment.amount, invoice.payment.currency)}\n </p>\n </div>\n <div>\n <p className=\"text-sm text-muted-foreground\">Status</p>\n <p className=\"text-sm text-foreground mt-0.5 capitalize\">\n {invoice.payment.status.toLowerCase()}\n </p>\n </div>\n <div>\n <p className=\"text-sm text-muted-foreground\">Method</p>\n <p className=\"text-sm text-foreground mt-0.5 capitalize\">\n {invoice.payment.method.toLowerCase().replace(/_/g, ' ')}\n </p>\n </div>\n {invoice.payment.provider && (\n <div>\n <p className=\"text-sm text-muted-foreground\">Provider</p>\n <p className=\"text-sm text-foreground mt-0.5 capitalize\">\n {invoice.payment.provider}\n </p>\n </div>\n )}\n {invoice.payment.paidAt && (\n <div>\n <p className=\"text-sm text-muted-foreground\">Paid At</p>\n <p className=\"text-sm text-foreground mt-0.5\">\n {formatDate(invoice.payment.paidAt, 'short')}\n </p>\n </div>\n )}\n </div>\n </div>\n </div>\n )}\n </div>\n\n {/* Sidebar */}\n <div className=\"space-y-6\">\n {/* Invoice Summary */}\n <div className=\"border border-border rounded-lg bg-card overflow-hidden\">\n <div className=\"p-6 border-b border-border bg-muted/30\">\n <h2 className=\"text-lg font-semibold text-foreground\">\n {tr('billing.invoices.details', 'Details')}\n </h2>\n </div>\n <div className=\"p-6 space-y-4\">\n <div>\n <p className=\"text-sm text-muted-foreground\">Invoice ID</p>\n <p className=\"font-mono text-sm text-foreground mt-0.5 break-all\">{invoice.id}</p>\n </div>\n <div>\n <p className=\"text-sm text-muted-foreground\">Invoice Number</p>\n <p className=\"text-sm text-foreground mt-0.5\">\n {formatInvoiceNumber(invoice.invoiceNumber)}\n </p>\n </div>\n {invoice.itemDescription && (\n <div>\n <p className=\"text-sm text-muted-foreground\">Description</p>\n <p className=\"text-sm text-foreground mt-0.5\">{invoice.itemDescription}</p>\n </div>\n )}\n <div>\n <p className=\"text-sm text-muted-foreground\">Status</p>\n <span\n className={`inline-flex mt-0.5 px-2 py-1 text-xs font-medium rounded ${getStatusBadgeClasses(statusColor)}`}\n >\n {formatInvoiceStatus(invoice.status)}\n </span>\n </div>\n <div>\n <p className=\"text-sm text-muted-foreground\">Currency</p>\n <p className=\"text-sm text-foreground mt-0.5\">{invoice.currency}</p>\n </div>\n <div>\n <p className=\"text-sm text-muted-foreground\">Total</p>\n <p className=\"text-sm font-semibold text-foreground mt-0.5\">\n {formatCurrency(invoice.total, invoice.currency)}\n </p>\n </div>\n <div>\n <p className=\"text-sm text-muted-foreground\">Amount Paid</p>\n <p className=\"text-sm text-status-success-text mt-0.5\">\n {formatCurrency(invoice.amountPaid, invoice.currency)}\n </p>\n </div>\n {amountDue > 0 && (\n <div>\n <p className=\"text-sm text-muted-foreground\">Amount Due</p>\n <p className=\"text-sm font-semibold text-status-warning-text mt-0.5\">\n {formatCurrency(amountDue, invoice.currency)}\n </p>\n </div>\n )}\n </div>\n </div>\n\n {/* Dates */}\n <div className=\"border border-border rounded-lg bg-card overflow-hidden\">\n <div className=\"p-6 border-b border-border bg-muted/30\">\n <h2 className=\"text-lg font-semibold text-foreground\">\n {tr('billing.invoices.dates', 'Dates')}\n </h2>\n </div>\n <div className=\"p-6 space-y-4\">\n <div>\n <p className=\"text-sm text-muted-foreground\">Created</p>\n <p className=\"text-sm text-foreground mt-0.5\">{formatDate(invoice.createdAt)}</p>\n </div>\n {invoice.dueDate && (\n <div>\n <p className=\"text-sm text-muted-foreground\">Due Date</p>\n <p className=\"text-sm text-foreground mt-0.5\">{formatDate(invoice.dueDate)}</p>\n </div>\n )}\n {invoice.paidAt && (\n <div>\n <p className=\"text-sm text-muted-foreground\">Paid At</p>\n <p className=\"text-sm text-foreground mt-0.5\">{formatDate(invoice.paidAt)}</p>\n </div>\n )}\n <div>\n <p className=\"text-sm text-muted-foreground\">Last Updated</p>\n <p className=\"text-sm text-foreground mt-0.5\">{formatDate(invoice.updatedAt)}</p>\n </div>\n </div>\n </div>\n\n {/* Organization */}\n <div className=\"border border-border rounded-lg bg-card overflow-hidden\">\n <div className=\"p-6 border-b border-border bg-muted/30\">\n <h2 className=\"text-lg font-semibold text-foreground\">\n {tr('billing.invoices.organization', 'Organization')}\n </h2>\n </div>\n <div className=\"p-6 space-y-4\">\n <div>\n <p className=\"text-sm text-muted-foreground\">Organization ID</p>\n <p className=\"font-mono text-sm text-foreground mt-0.5 break-all\">\n {invoice.orgId}\n </p>\n </div>\n </div>\n </div>\n </div>\n </div>\n </div>\n );\n};\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"InvoiceDetailPage.js","names":[],"sources":["../../../../../src/billing/modules/billing/pages/InvoiceDetailPage.tsx"],"sourcesContent":["/**\n * Billing Module - Invoice Detail Page\n * Displays detailed information about a single invoice\n */\n\nimport { type FC, useState } from 'react';\nimport { useParams } from 'react-router-dom';\nimport { useBillingNavigate } from '../../../hooks/useBillingNavigate';\nimport { useBilling } from '../../../providers/BillingProvider';\nimport { useBillingAccountSelection } from '../../../hooks/useBillingAccountSelection';\nimport { useInvoice, useInvoiceMutations } from '../hooks/useInvoices';\nimport { useBillingPermissions } from '../../../hooks/useBillingPermissions';\nimport { useGetDefaultBillingAccountDashboardQuery } from '../../../../generated/global-operations';\nimport {\n formatCurrency,\n formatDate,\n formatInvoiceStatus,\n formatInvoiceNumber,\n} from '../../../shared/utils/format';\nimport { withBillingAccountId } from '../../../shared/utils/navigation';\nimport { getInvoiceStatusColor, getStatusBadgeClasses } from '../../../shared/utils/status';\nimport type { InvoiceStatus } from '../../../shared/types';\nimport { useI18n } from '@burdenoff/fe-libs/shared/providers/shell/I18nProvider';\n\nexport const InvoiceDetailPage: FC = () => {\n const { t } = useI18n();\n const tr = (key: string, fallback: string): string => {\n const translated = t(key);\n return translated === key ? fallback : translated;\n };\n const { invoiceId } = useParams<{ invoiceId: string }>();\n const navigateTo = useBillingNavigate();\n const { orgId } = useBilling();\n const permissions = useBillingPermissions();\n const { selectedAccountId } = useBillingAccountSelection({\n orgId,\n syncFromUrl: true,\n urlParamName: 'billingAccountId',\n });\n const { data: defaultBillingAccountData } = useGetDefaultBillingAccountDashboardQuery({\n fetchPolicy: 'cache-first',\n });\n const billingAccountId =\n selectedAccountId ?? defaultBillingAccountData?.getDefaultBillingAccount?.id ?? undefined;\n const { invoice, isLoading, error, refetch } = useInvoice(invoiceId, billingAccountId);\n const { payInvoice, voidInvoice, isPaying, isVoiding } = useInvoiceMutations();\n const defaultPaymentMethodId =\n defaultBillingAccountData?.getDefaultBillingAccount?.defaultPaymentMethod;\n\n // Action error state\n const [actionError, setActionError] = useState<string | null>(null);\n\n // Handle pay invoice\n const handlePayInvoice = async () => {\n if (!invoice) return;\n if (!defaultPaymentMethodId) {\n setActionError('Add and set a default payment method before paying this invoice.');\n return;\n }\n\n if (!billingAccountId) {\n setActionError('No billing account context');\n return;\n }\n setActionError(null);\n try {\n await payInvoice(invoice.id, defaultPaymentMethodId, billingAccountId);\n await refetch();\n } catch (err) {\n setActionError(err instanceof Error ? err.message : 'Failed to pay invoice');\n }\n };\n\n // Handle void invoice\n const handleVoidInvoice = async () => {\n if (!invoice) return;\n if (!billingAccountId) {\n setActionError('No billing account context');\n return;\n }\n\n setActionError(null);\n try {\n await voidInvoice(invoice.id, billingAccountId);\n await refetch();\n } catch (err) {\n setActionError(err instanceof Error ? err.message : 'Failed to void invoice');\n }\n };\n\n // Permission check\n if (!permissions.canViewInvoices) {\n return (\n <div className=\"flex items-center justify-center h-full min-h-[400px]\">\n <div className=\"text-center space-y-2\">\n <div className=\"size-12 mx-auto rounded-full bg-bg-sunken flex items-center justify-center\">\n <svg\n className=\"size-6 text-text-secondary\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M12 15v2m-6 4h12a2 2 0 002-2v-6a2 2 0 00-2-2H6a2 2 0 00-2 2v6a2 2 0 002 2zm10-10V7a4 4 0 00-8 0v4h8z\"\n />\n </svg>\n </div>\n <h2 className=\"text-lg font-semibold text-text-primary\">\n {tr('billing.accessDenied.title', 'Access Denied')}\n </h2>\n <p className=\"text-sm text-text-secondary max-w-sm\">\n {tr('billing.invoices.noViewPermission', \"You don't have permission to view invoices.\")}\n </p>\n </div>\n </div>\n );\n }\n\n // Loading state\n if (isLoading) {\n return (\n <div className=\"space-y-6 px-6 lg:px-8 py-6\">\n <div className=\"flex items-center gap-4\">\n <div className=\"size-10 bg-bg-sunken animate-pulse rounded\" />\n <div className=\"space-y-2\">\n <div className=\"h-8 w-48 bg-bg-sunken animate-pulse rounded\" />\n <div className=\"h-4 w-32 bg-bg-sunken animate-pulse rounded\" />\n </div>\n </div>\n <div className=\"grid grid-cols-1 lg:grid-cols-3 gap-6\">\n <div className=\"lg:col-span-2 space-y-6\">\n <div className=\"border border-border-subtle rounded-lg p-6 space-y-4\">\n <div className=\"h-6 w-32 bg-bg-sunken animate-pulse rounded\" />\n <div className=\"h-4 w-full bg-bg-sunken animate-pulse rounded\" />\n <div className=\"h-4 w-3/4 bg-bg-sunken animate-pulse rounded\" />\n </div>\n <div className=\"border border-border-subtle rounded-lg p-6 space-y-4\">\n <div className=\"h-6 w-24 bg-bg-sunken animate-pulse rounded\" />\n {[1, 2, 3].map((i) => (\n <div key={i} className=\"flex items-center gap-4\">\n <div className=\"h-4 flex-1 bg-bg-sunken animate-pulse rounded\" />\n <div className=\"h-4 w-16 bg-bg-sunken animate-pulse rounded\" />\n <div className=\"h-4 w-16 bg-bg-sunken animate-pulse rounded\" />\n <div className=\"h-4 w-20 bg-bg-sunken animate-pulse rounded\" />\n </div>\n ))}\n </div>\n </div>\n <div className=\"space-y-6\">\n <div className=\"border border-border-subtle rounded-lg p-6 space-y-4\">\n <div className=\"h-6 w-24 bg-bg-sunken animate-pulse rounded\" />\n {[1, 2, 3, 4].map((i) => (\n <div key={i} className=\"space-y-1\">\n <div className=\"h-3 w-20 bg-bg-sunken animate-pulse rounded\" />\n <div className=\"h-4 w-28 bg-bg-sunken animate-pulse rounded\" />\n </div>\n ))}\n </div>\n </div>\n </div>\n </div>\n );\n }\n\n // Error state\n if (error || !invoice) {\n return (\n <div className=\"flex items-center justify-center h-full min-h-[400px]\">\n <div className=\"text-center space-y-4\">\n <div className=\"size-12 mx-auto rounded-full bg-status-error-bg-subtle flex items-center justify-center\">\n <svg\n className=\"size-6 text-status-error-text\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z\"\n />\n </svg>\n </div>\n <h2 className=\"text-lg font-semibold text-text-primary\">\n {tr('billing.invoices.invoiceNotFound', 'Invoice not found')}\n </h2>\n <p className=\"text-sm text-text-secondary\">\n {error?.message ||\n tr(\n 'billing.invoices.invoiceNotFoundMessage',\n 'The invoice you are looking for does not exist.'\n )}\n </p>\n <div className=\"flex items-center justify-center gap-3\">\n <button\n type=\"button\"\n onClick={() => refetch()}\n className=\"px-4 py-2 text-sm font-medium bg-action-primary-bg text-action-primary-text rounded-button hover:bg-action-primary-bgHover transition-colors\"\n >\n Try Again\n </button>\n <button\n type=\"button\"\n onClick={() => navigateTo(withBillingAccountId('/invoices', billingAccountId))}\n className=\"px-4 py-2 text-sm font-medium border border-border-subtle text-text-primary rounded-button hover:bg-bg-sunken transition-colors\"\n >\n Back to Invoices\n </button>\n </div>\n </div>\n </div>\n );\n }\n\n const statusColor = getInvoiceStatusColor(invoice.status);\n const isOpen = invoice.status === ('OPEN' as InvoiceStatus);\n const isDraft = invoice.status === ('DRAFT' as InvoiceStatus);\n const items = invoice.items || [];\n const amountDue = invoice.total - invoice.amountPaid;\n\n return (\n <div className=\"space-y-6 px-6 lg:px-8 py-6\">\n {/* Header */}\n <div className=\"flex flex-col gap-4 sm:flex-row sm:items-start sm:justify-between\">\n <div className=\"flex items-start gap-4\">\n <button\n type=\"button\"\n onClick={() => navigateTo(withBillingAccountId('/invoices', billingAccountId))}\n className=\"p-2 -ml-2 text-text-secondary hover:text-text-primary hover:bg-bg-sunken rounded-button transition-colors\"\n >\n <svg className=\"size-5\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\">\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M15 19l-7-7 7-7\"\n />\n </svg>\n </button>\n <div>\n <div className=\"flex items-center gap-3\">\n <h1 className=\"text-2xl md:text-3xl font-semibold tracking-tight text-text-primary\">\n Invoice {formatInvoiceNumber(invoice.invoiceNumber)}\n </h1>\n <span\n className={`px-2 py-1 text-xs font-medium rounded ${getStatusBadgeClasses(statusColor)}`}\n >\n {formatInvoiceStatus(invoice.status)}\n </span>\n </div>\n <p className=\"text-sm text-text-secondary mt-1\">\n Created {formatDate(invoice.createdAt, 'short')}\n {invoice.dueDate && ` · Due ${formatDate(invoice.dueDate, 'short')}`}\n </p>\n </div>\n </div>\n\n <div className=\"flex items-center gap-2 flex-wrap\">\n {invoice.pdfUrl && (\n <a\n href={invoice.pdfUrl}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"px-4 py-2 text-sm font-medium border border-border-subtle text-text-primary rounded-button hover:bg-bg-sunken transition-colors\"\n >\n Download PDF\n </a>\n )}\n {invoice.invoiceUrl && (\n <a\n href={invoice.invoiceUrl}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"px-4 py-2 text-sm font-medium border border-border-subtle text-text-primary rounded-button hover:bg-bg-sunken transition-colors\"\n >\n View on Portal\n </a>\n )}\n {isOpen && permissions.canPayInvoice && (\n <button\n type=\"button\"\n onClick={handlePayInvoice}\n disabled={isPaying || !defaultPaymentMethodId}\n className=\"px-4 py-2 text-sm font-medium bg-action-primary-bg text-action-primary-text rounded-button hover:bg-action-primary-bgHover transition-colors disabled:opacity-50\"\n >\n {!defaultPaymentMethodId\n ? 'Default Payment Method Required'\n : isPaying\n ? 'Processing...'\n : 'Pay Invoice'}\n </button>\n )}\n {(isOpen || isDraft) && permissions.canVoidInvoice && (\n <button\n type=\"button\"\n onClick={handleVoidInvoice}\n disabled={isVoiding}\n className=\"px-4 py-2 text-sm font-medium border border-border-subtle text-status-error-text rounded-button hover:bg-status-error-bg-subtle transition-colors disabled:opacity-50\"\n >\n {isVoiding\n ? tr('billing.invoices.voiding', 'Voiding...')\n : tr('billing.invoices.voidInvoice', 'Void Invoice')}\n </button>\n )}\n </div>\n </div>\n\n {/* Action Error */}\n {actionError && (\n <div className=\"p-3 bg-status-error-bg-subtle border border-status-error-border rounded-button\">\n <p className=\"text-sm text-status-error-text\">{actionError}</p>\n </div>\n )}\n\n <div className=\"grid grid-cols-1 lg:grid-cols-3 gap-6\">\n {/* Main Content */}\n <div className=\"lg:col-span-2 space-y-6\">\n {/* Line Items */}\n <div className=\"border border-border-subtle rounded-card bg-bg-surface shadow-elevation-1 overflow-hidden\">\n <div className=\"p-6 border-b border-border-subtle bg-bg-sunken\">\n <h2 className=\"text-lg font-semibold text-text-primary\">\n {tr('billing.invoices.lineItems', 'Line Items')} ({items.length})\n </h2>\n </div>\n {items.length === 0 ? (\n <div className=\"p-6\">\n <p className=\"text-sm text-text-secondary\">\n {tr('billing.invoices.noLineItems', 'No line items on this invoice.')}\n </p>\n </div>\n ) : (\n <div className=\"overflow-x-auto\">\n <table className=\"w-full\">\n <thead className=\"bg-bg-sunken\">\n <tr>\n <th className=\"text-left px-4 py-3 text-sm font-medium text-text-secondary\">\n Description\n </th>\n <th className=\"text-right px-4 py-3 text-sm font-medium text-text-secondary\">\n Qty\n </th>\n <th className=\"text-right px-4 py-3 text-sm font-medium text-text-secondary\">\n Unit Price\n </th>\n <th className=\"text-right px-4 py-3 text-sm font-medium text-text-secondary\">\n Amount\n </th>\n </tr>\n </thead>\n <tbody className=\"divide-y divide-border-subtle\">\n {items.map((item) => (\n <tr key={item.id} className=\"hover:bg-bg-sunken transition-colors\">\n <td className=\"p-4 text-sm text-text-primary\">{item.description}</td>\n <td className=\"p-4 text-sm text-text-secondary text-right\">\n {item.quantity}\n </td>\n <td className=\"p-4 text-sm text-text-secondary text-right\">\n {formatCurrency(item.unitPrice, invoice.currency)}\n </td>\n <td className=\"p-4 text-sm font-medium text-text-primary text-right\">\n {formatCurrency(item.amount, invoice.currency)}\n </td>\n </tr>\n ))}\n </tbody>\n </table>\n </div>\n )}\n\n {/* Totals */}\n <div className=\"border-t border-border-subtle p-4\">\n <div className=\"max-w-xs ml-auto space-y-2\">\n <div className=\"flex items-center justify-between text-sm\">\n <span className=\"text-text-secondary\">\n {tr('billing.invoices.subtotal', 'Subtotal')}\n </span>\n <span className=\"text-text-primary\">\n {formatCurrency(invoice.subtotal, invoice.currency)}\n </span>\n </div>\n <div className=\"flex items-center justify-between text-sm\">\n <span className=\"text-text-secondary\">{tr('billing.invoices.tax', 'Tax')}</span>\n <span className=\"text-text-primary\">\n {formatCurrency(invoice.tax, invoice.currency)}\n </span>\n </div>\n <div className=\"flex items-center justify-between text-sm font-semibold border-t border-border-subtle pt-2\">\n <span className=\"text-text-primary\">{tr('billing.invoices.total', 'Total')}</span>\n <span className=\"text-text-primary\">\n {formatCurrency(invoice.total, invoice.currency)}\n </span>\n </div>\n {invoice.amountPaid > 0 && (\n <div className=\"flex items-center justify-between text-sm\">\n <span className=\"text-text-secondary\">\n {tr('billing.invoices.amountPaid', 'Amount Paid')}\n </span>\n <span className=\"text-status-success-text\">\n -{formatCurrency(invoice.amountPaid, invoice.currency)}\n </span>\n </div>\n )}\n {amountDue > 0 && (\n <div className=\"flex items-center justify-between text-sm font-semibold border-t border-border-subtle pt-2\">\n <span className=\"text-text-primary\">\n {tr('billing.invoices.amountDue', 'Amount Due')}\n </span>\n <span className=\"text-status-warning-text\">\n {formatCurrency(amountDue, invoice.currency)}\n </span>\n </div>\n )}\n </div>\n </div>\n </div>\n\n {/* Subscription Info */}\n {invoice.subscription && (\n <div className=\"border border-border-subtle rounded-card bg-bg-surface shadow-elevation-1 overflow-hidden\">\n <div className=\"p-6 border-b border-border-subtle bg-bg-sunken\">\n <h2 className=\"text-lg font-semibold text-text-primary\">\n {tr('billing.invoices.subscription', 'Subscription')}\n </h2>\n </div>\n <div className=\"p-6 space-y-4\">\n <div className=\"flex items-center justify-between\">\n <div>\n <p className=\"font-medium text-text-primary\">\n {invoice.subscription.plan?.name || 'Unknown Plan'}\n </p>\n <p className=\"text-sm text-text-secondary mt-0.5\">\n Subscription ID:{' '}\n <span className=\"font-mono text-xs\">{invoice.subscription.id}</span>\n </p>\n </div>\n <button\n type=\"button\"\n onClick={() =>\n navigateTo(\n withBillingAccountId(\n `/subscriptions/${invoice.subscription!.id}`,\n billingAccountId\n )\n )\n }\n className=\"px-3 py-1.5 text-sm font-medium text-text-primary hover:bg-bg-sunken rounded-button transition-colors\"\n >\n View\n </button>\n </div>\n </div>\n </div>\n )}\n\n {/* Payment Info */}\n {invoice.payment && (\n <div className=\"border border-border-subtle rounded-card bg-bg-surface shadow-elevation-1 overflow-hidden\">\n <div className=\"p-6 border-b border-border-subtle bg-bg-sunken\">\n <h2 className=\"text-lg font-semibold text-text-primary\">\n {tr('billing.invoices.payment', 'Payment')}\n </h2>\n </div>\n <div className=\"p-6\">\n <div className=\"grid grid-cols-2 gap-4\">\n <div>\n <p className=\"text-sm text-text-secondary\">Payment ID</p>\n <p className=\"font-mono text-sm text-text-primary mt-0.5 break-all\">\n {invoice.payment.id}\n </p>\n </div>\n <div>\n <p className=\"text-sm text-text-secondary\">Amount</p>\n <p className=\"text-sm text-text-primary mt-0.5\">\n {formatCurrency(invoice.payment.amount, invoice.payment.currency)}\n </p>\n </div>\n <div>\n <p className=\"text-sm text-text-secondary\">Status</p>\n <p className=\"text-sm text-text-primary mt-0.5 capitalize\">\n {invoice.payment.status.toLowerCase()}\n </p>\n </div>\n <div>\n <p className=\"text-sm text-text-secondary\">Method</p>\n <p className=\"text-sm text-text-primary mt-0.5 capitalize\">\n {invoice.payment.method.toLowerCase().replace(/_/g, ' ')}\n </p>\n </div>\n {invoice.payment.provider && (\n <div>\n <p className=\"text-sm text-text-secondary\">Provider</p>\n <p className=\"text-sm text-text-primary mt-0.5 capitalize\">\n {invoice.payment.provider}\n </p>\n </div>\n )}\n {invoice.payment.paidAt && (\n <div>\n <p className=\"text-sm text-text-secondary\">Paid At</p>\n <p className=\"text-sm text-text-primary mt-0.5\">\n {formatDate(invoice.payment.paidAt, 'short')}\n </p>\n </div>\n )}\n </div>\n </div>\n </div>\n )}\n </div>\n\n {/* Sidebar */}\n <div className=\"space-y-6\">\n {/* Invoice Summary */}\n <div className=\"border border-border-subtle rounded-card bg-bg-surface shadow-elevation-1 overflow-hidden\">\n <div className=\"p-6 border-b border-border-subtle bg-bg-sunken\">\n <h2 className=\"text-lg font-semibold text-text-primary\">\n {tr('billing.invoices.details', 'Details')}\n </h2>\n </div>\n <div className=\"p-6 space-y-4\">\n <div>\n <p className=\"text-sm text-text-secondary\">Invoice ID</p>\n <p className=\"font-mono text-sm text-text-primary mt-0.5 break-all\">{invoice.id}</p>\n </div>\n <div>\n <p className=\"text-sm text-text-secondary\">Invoice Number</p>\n <p className=\"text-sm text-text-primary mt-0.5\">\n {formatInvoiceNumber(invoice.invoiceNumber)}\n </p>\n </div>\n {invoice.itemDescription && (\n <div>\n <p className=\"text-sm text-text-secondary\">Description</p>\n <p className=\"text-sm text-text-primary mt-0.5\">{invoice.itemDescription}</p>\n </div>\n )}\n <div>\n <p className=\"text-sm text-text-secondary\">Status</p>\n <span\n className={`inline-flex mt-0.5 px-2 py-1 text-xs font-medium rounded ${getStatusBadgeClasses(statusColor)}`}\n >\n {formatInvoiceStatus(invoice.status)}\n </span>\n </div>\n <div>\n <p className=\"text-sm text-text-secondary\">Currency</p>\n <p className=\"text-sm text-text-primary mt-0.5\">{invoice.currency}</p>\n </div>\n <div>\n <p className=\"text-sm text-text-secondary\">Total</p>\n <p className=\"text-sm font-semibold text-text-primary mt-0.5\">\n {formatCurrency(invoice.total, invoice.currency)}\n </p>\n </div>\n <div>\n <p className=\"text-sm text-text-secondary\">Amount Paid</p>\n <p className=\"text-sm text-status-success-text mt-0.5\">\n {formatCurrency(invoice.amountPaid, invoice.currency)}\n </p>\n </div>\n {amountDue > 0 && (\n <div>\n <p className=\"text-sm text-text-secondary\">Amount Due</p>\n <p className=\"text-sm font-semibold text-status-warning-text mt-0.5\">\n {formatCurrency(amountDue, invoice.currency)}\n </p>\n </div>\n )}\n </div>\n </div>\n\n {/* Dates */}\n <div className=\"border border-border-subtle rounded-card bg-bg-surface shadow-elevation-1 overflow-hidden\">\n <div className=\"p-6 border-b border-border-subtle bg-bg-sunken\">\n <h2 className=\"text-lg font-semibold text-text-primary\">\n {tr('billing.invoices.dates', 'Dates')}\n </h2>\n </div>\n <div className=\"p-6 space-y-4\">\n <div>\n <p className=\"text-sm text-text-secondary\">Created</p>\n <p className=\"text-sm text-text-primary mt-0.5\">{formatDate(invoice.createdAt)}</p>\n </div>\n {invoice.dueDate && (\n <div>\n <p className=\"text-sm text-text-secondary\">Due Date</p>\n <p className=\"text-sm text-text-primary mt-0.5\">{formatDate(invoice.dueDate)}</p>\n </div>\n )}\n {invoice.paidAt && (\n <div>\n <p className=\"text-sm text-text-secondary\">Paid At</p>\n <p className=\"text-sm text-text-primary mt-0.5\">{formatDate(invoice.paidAt)}</p>\n </div>\n )}\n <div>\n <p className=\"text-sm text-text-secondary\">Last Updated</p>\n <p className=\"text-sm text-text-primary mt-0.5\">{formatDate(invoice.updatedAt)}</p>\n </div>\n </div>\n </div>\n\n {/* Organization */}\n <div className=\"border border-border-subtle rounded-card bg-bg-surface shadow-elevation-1 overflow-hidden\">\n <div className=\"p-6 border-b border-border-subtle bg-bg-sunken\">\n <h2 className=\"text-lg font-semibold text-text-primary\">\n {tr('billing.invoices.organization', 'Organization')}\n </h2>\n </div>\n <div className=\"p-6 space-y-4\">\n <div>\n <p className=\"text-sm text-text-secondary\">Organization ID</p>\n <p className=\"font-mono text-sm text-text-primary mt-0.5 break-all\">\n {invoice.orgId}\n </p>\n </div>\n </div>\n </div>\n </div>\n </div>\n </div>\n );\n};\n"],"mappings":"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"}
|
|
@@ -1,5 +1,7 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import
|
|
1
|
+
import { StatusPill as e } from "../../../shared/ui/StatusPill.js";
|
|
2
|
+
import "../../../shared/ui/index.js";
|
|
3
|
+
import { formatCurrency as t, formatDate as n, formatInvoiceNumber as r, formatInvoiceStatus as i } from "../../../shared/utils/format.js";
|
|
4
|
+
import { getInvoiceStatusColor as a } from "../../../shared/utils/status.js";
|
|
3
5
|
import { useBillingPermissions as o } from "../../../hooks/useBillingPermissions.js";
|
|
4
6
|
import { useGetBillingAccountsByOrgQuery as s } from "../../../../generated/global-operations.js";
|
|
5
7
|
import { useBillingNavigate as c } from "../../../hooks/useBillingNavigate.js";
|
|
@@ -15,7 +17,7 @@ var x = () => {
|
|
|
15
17
|
let { t: e } = b(), t = (t, n) => {
|
|
16
18
|
let r = e(t);
|
|
17
19
|
return r === t ? n : r;
|
|
18
|
-
}, n = c(),
|
|
20
|
+
}, n = c(), r = o(), [a] = g(), x = a.get("billingAccountId") ?? void 0, { data: C } = s({ fetchPolicy: "cache-first" }), w = C?.getBillingAccountsByOrg ?? [], [T, E] = m(x);
|
|
19
21
|
d(() => {
|
|
20
22
|
E(x);
|
|
21
23
|
}, [x]);
|
|
@@ -32,9 +34,9 @@ var x = () => {
|
|
|
32
34
|
page: F,
|
|
33
35
|
pageSize: 20
|
|
34
36
|
});
|
|
35
|
-
return
|
|
37
|
+
return r.canViewInvoices ? B && R.length === 0 ? /* @__PURE__ */ y("div", {
|
|
36
38
|
className: "space-y-6 p-6",
|
|
37
|
-
children: [/* @__PURE__ */ v("div", { className: "h-8 w-48 bg-
|
|
39
|
+
children: [/* @__PURE__ */ v("div", { className: "h-8 w-48 bg-bg-sunken animate-pulse rounded" }), /* @__PURE__ */ v("div", {
|
|
38
40
|
className: "space-y-3",
|
|
39
41
|
children: [
|
|
40
42
|
1,
|
|
@@ -43,12 +45,12 @@ var x = () => {
|
|
|
43
45
|
4,
|
|
44
46
|
5
|
|
45
47
|
].map((e) => /* @__PURE__ */ v("div", {
|
|
46
|
-
className: "border border-border rounded-lg p-4",
|
|
48
|
+
className: "border border-border-subtle rounded-lg p-4",
|
|
47
49
|
children: /* @__PURE__ */ y("div", {
|
|
48
50
|
className: "flex items-center gap-4",
|
|
49
|
-
children: [/* @__PURE__ */ v("div", { className: "size-10 bg-
|
|
51
|
+
children: [/* @__PURE__ */ v("div", { className: "size-10 bg-bg-sunken animate-pulse rounded" }), /* @__PURE__ */ y("div", {
|
|
50
52
|
className: "flex-1 space-y-2",
|
|
51
|
-
children: [/* @__PURE__ */ v("div", { className: "h-4 w-32 bg-
|
|
53
|
+
children: [/* @__PURE__ */ v("div", { className: "h-4 w-32 bg-bg-sunken animate-pulse rounded" }), /* @__PURE__ */ v("div", { className: "h-3 w-48 bg-bg-sunken animate-pulse rounded" })]
|
|
52
54
|
})]
|
|
53
55
|
})
|
|
54
56
|
}, e))
|
|
@@ -59,9 +61,9 @@ var x = () => {
|
|
|
59
61
|
className: "text-center space-y-4",
|
|
60
62
|
children: [
|
|
61
63
|
/* @__PURE__ */ v("div", {
|
|
62
|
-
className: "size-12 mx-auto rounded-full bg-
|
|
64
|
+
className: "size-12 mx-auto rounded-full bg-status-error-bg-subtle flex items-center justify-center",
|
|
63
65
|
children: /* @__PURE__ */ v("svg", {
|
|
64
|
-
className: "size-6 text-
|
|
66
|
+
className: "size-6 text-status-error-text",
|
|
65
67
|
fill: "none",
|
|
66
68
|
viewBox: "0 0 24 24",
|
|
67
69
|
stroke: "currentColor",
|
|
@@ -74,48 +76,48 @@ var x = () => {
|
|
|
74
76
|
})
|
|
75
77
|
}),
|
|
76
78
|
/* @__PURE__ */ v("h2", {
|
|
77
|
-
className: "text-lg font-semibold text-
|
|
79
|
+
className: "text-lg font-semibold text-text-primary",
|
|
78
80
|
children: t("billing.invoices.failedToLoad", "Failed to load invoices")
|
|
79
81
|
}),
|
|
80
82
|
/* @__PURE__ */ v("p", {
|
|
81
|
-
className: "text-sm text-
|
|
83
|
+
className: "text-sm text-text-secondary",
|
|
82
84
|
children: V.message
|
|
83
85
|
}),
|
|
84
86
|
/* @__PURE__ */ v("button", {
|
|
85
87
|
type: "button",
|
|
86
88
|
onClick: () => H(),
|
|
87
|
-
className: "px-4 py-2 text-sm font-medium bg-primary text-primary-
|
|
89
|
+
className: "px-4 py-2 text-sm font-medium bg-action-primary-bg text-action-primary-text rounded-button hover:bg-action-primary-bgHover transition-colors",
|
|
88
90
|
children: "Try Again"
|
|
89
91
|
})
|
|
90
92
|
]
|
|
91
93
|
})
|
|
92
94
|
}) : /* @__PURE__ */ y("div", {
|
|
93
|
-
className: "space-y-6
|
|
95
|
+
className: "space-y-6 px-6 lg:px-8 py-6",
|
|
94
96
|
children: [
|
|
95
97
|
/* @__PURE__ */ y("div", {
|
|
96
98
|
className: "flex flex-col gap-4 sm:flex-row sm:items-center sm:justify-between",
|
|
97
99
|
children: [/* @__PURE__ */ y("div", { children: [/* @__PURE__ */ v("h1", {
|
|
98
|
-
className: "text-2xl font-
|
|
100
|
+
className: "text-2xl md:text-3xl font-semibold tracking-tight text-text-primary",
|
|
99
101
|
children: t("billing.invoices.title", "Invoices")
|
|
100
102
|
}), /* @__PURE__ */ v("p", {
|
|
101
|
-
className: "text-sm text-
|
|
103
|
+
className: "text-sm text-text-secondary mt-1",
|
|
102
104
|
children: t("billing.invoices.subtitle", "View and manage your billing invoices")
|
|
103
105
|
})] }), /* @__PURE__ */ y("div", {
|
|
104
106
|
className: "flex items-center gap-3",
|
|
105
107
|
children: [/* @__PURE__ */ y("button", {
|
|
106
108
|
type: "button",
|
|
107
109
|
onClick: () => n("/refunds"),
|
|
108
|
-
className: "inline-flex items-center gap-2 px-3 py-2 text-sm font-medium border border-border text-
|
|
110
|
+
className: "inline-flex items-center gap-2 px-3 py-2 text-sm font-medium border border-border-subtle text-text-primary rounded-button hover:bg-bg-sunken hover:border-border-strong transition-all duration-200",
|
|
109
111
|
children: [/* @__PURE__ */ v(h, { className: "size-4" }), t("billing.invoices.myRefunds", "My Refunds")]
|
|
110
112
|
}), w.length > 1 && /* @__PURE__ */ y("div", {
|
|
111
113
|
className: "flex items-center gap-2",
|
|
112
114
|
children: [/* @__PURE__ */ v("label", {
|
|
113
|
-
className: "text-sm text-
|
|
115
|
+
className: "text-sm text-text-secondary whitespace-nowrap",
|
|
114
116
|
children: "Billing Account"
|
|
115
117
|
}), /* @__PURE__ */ y("select", {
|
|
116
118
|
value: O ?? "",
|
|
117
119
|
onChange: (e) => E(e.target.value || null),
|
|
118
|
-
className: "text-sm border border-border rounded-
|
|
120
|
+
className: "text-sm border border-border-subtle rounded-button bg-bg-surface text-text-primary px-3 py-2 focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)]",
|
|
119
121
|
children: [/* @__PURE__ */ v("option", {
|
|
120
122
|
value: "",
|
|
121
123
|
children: "All Accounts"
|
|
@@ -128,9 +130,9 @@ var x = () => {
|
|
|
128
130
|
})]
|
|
129
131
|
}),
|
|
130
132
|
/* @__PURE__ */ y("div", {
|
|
131
|
-
className: "flex flex-wrap items-center gap-4 pb-4 border-b border-border",
|
|
133
|
+
className: "flex flex-wrap items-center gap-4 pb-4 border-b border-border-subtle",
|
|
132
134
|
children: [/* @__PURE__ */ v("div", {
|
|
133
|
-
className: "inline-flex rounded-lg border border-border p-1 bg-
|
|
135
|
+
className: "inline-flex rounded-lg border border-border-subtle p-1 bg-bg-sunken flex-wrap",
|
|
134
136
|
children: [
|
|
135
137
|
"all",
|
|
136
138
|
"OPEN",
|
|
@@ -142,13 +144,13 @@ var x = () => {
|
|
|
142
144
|
onClick: () => {
|
|
143
145
|
A(e), I(1);
|
|
144
146
|
},
|
|
145
|
-
className: `px-3 py-1.5 text-sm font-medium rounded-
|
|
146
|
-
children: e === "all" ? "All" :
|
|
147
|
+
className: `px-3 py-1.5 text-sm font-medium rounded-button transition-colors ${k === e ? "bg-bg-surface text-text-primary shadow-sm" : "text-text-secondary hover:text-text-primary"}`,
|
|
148
|
+
children: e === "all" ? "All" : i(e)
|
|
147
149
|
}, e))
|
|
148
150
|
}), /* @__PURE__ */ y("div", {
|
|
149
151
|
className: "relative flex-1 min-w-0 w-full sm:max-w-md",
|
|
150
152
|
children: [/* @__PURE__ */ v("svg", {
|
|
151
|
-
className: "absolute left-3 top-1/2 -translate-y-1/2 size-4 text-
|
|
153
|
+
className: "absolute left-3 top-1/2 -translate-y-1/2 size-4 text-text-secondary",
|
|
152
154
|
fill: "none",
|
|
153
155
|
viewBox: "0 0 24 24",
|
|
154
156
|
stroke: "currentColor",
|
|
@@ -163,17 +165,17 @@ var x = () => {
|
|
|
163
165
|
placeholder: t("billing.invoices.searchPlaceholder", "Search by invoice number..."),
|
|
164
166
|
value: j,
|
|
165
167
|
onChange: (e) => M(e.target.value),
|
|
166
|
-
className: "w-full pl-[3.25rem] pr-4 py-2 text-sm border border-border rounded-
|
|
168
|
+
className: "w-full pl-[3.25rem] pr-4 py-2 text-sm border border-border-subtle rounded-button bg-bg-surface text-text-primary placeholder:text-text-placeholder focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)] focus:border-transparent"
|
|
167
169
|
})]
|
|
168
170
|
})]
|
|
169
171
|
}),
|
|
170
172
|
!B && R.length === 0 ? /* @__PURE__ */ y("div", {
|
|
171
|
-
className: "flex flex-col items-center justify-center py-12 border border-dashed border-border rounded-
|
|
173
|
+
className: "flex flex-col items-center justify-center py-12 border border-dashed border-border-subtle rounded-card",
|
|
172
174
|
children: [
|
|
173
175
|
/* @__PURE__ */ v("div", {
|
|
174
|
-
className: "size-12 rounded-full bg-
|
|
176
|
+
className: "size-12 rounded-full bg-[var(--color-accent-soft)] flex items-center justify-center mb-4",
|
|
175
177
|
children: /* @__PURE__ */ v("svg", {
|
|
176
|
-
className: "size-6 text-
|
|
178
|
+
className: "size-6 text-text-secondary",
|
|
177
179
|
fill: "none",
|
|
178
180
|
viewBox: "0 0 24 24",
|
|
179
181
|
stroke: "currentColor",
|
|
@@ -186,57 +188,57 @@ var x = () => {
|
|
|
186
188
|
})
|
|
187
189
|
}),
|
|
188
190
|
/* @__PURE__ */ v("h3", {
|
|
189
|
-
className: "text-lg font-medium text-
|
|
191
|
+
className: "text-lg font-medium text-text-primary",
|
|
190
192
|
children: t("billing.invoices.noInvoicesFound", "No invoices found")
|
|
191
193
|
}),
|
|
192
194
|
/* @__PURE__ */ v("p", {
|
|
193
|
-
className: "text-sm text-
|
|
195
|
+
className: "text-sm text-text-secondary mt-1",
|
|
194
196
|
children: k !== "all" || N ? t("billing.invoices.noInvoicesFiltered", "No invoices match your filters.") : t("billing.invoices.noInvoicesYet", "You don't have any invoices yet.")
|
|
195
197
|
})
|
|
196
198
|
]
|
|
197
199
|
}) : /* @__PURE__ */ y(_, { children: [/* @__PURE__ */ v("div", {
|
|
198
|
-
className: "border border-border rounded-
|
|
200
|
+
className: "border border-border-subtle rounded-card bg-bg-surface shadow-elevation-1 overflow-hidden",
|
|
199
201
|
children: /* @__PURE__ */ y("table", {
|
|
200
202
|
className: "w-full",
|
|
201
203
|
children: [/* @__PURE__ */ v("thead", {
|
|
202
|
-
className: "bg-
|
|
204
|
+
className: "bg-bg-sunken",
|
|
203
205
|
children: /* @__PURE__ */ y("tr", { children: [
|
|
204
206
|
/* @__PURE__ */ v("th", {
|
|
205
|
-
className: "text-left px-4 py-3 text-
|
|
207
|
+
className: "text-left px-4 py-3 text-xs font-medium uppercase tracking-wide text-text-muted",
|
|
206
208
|
children: "Invoice"
|
|
207
209
|
}),
|
|
208
210
|
/* @__PURE__ */ v("th", {
|
|
209
|
-
className: "text-left px-4 py-3 text-
|
|
211
|
+
className: "text-left px-4 py-3 text-xs font-medium uppercase tracking-wide text-text-muted",
|
|
210
212
|
children: "Status"
|
|
211
213
|
}),
|
|
212
214
|
!O && w.length > 1 && /* @__PURE__ */ v("th", {
|
|
213
|
-
className: "text-left px-4 py-3 text-
|
|
215
|
+
className: "text-left px-4 py-3 text-xs font-medium uppercase tracking-wide text-text-muted hidden lg:table-cell",
|
|
214
216
|
children: "Account"
|
|
215
217
|
}),
|
|
216
218
|
/* @__PURE__ */ v("th", {
|
|
217
|
-
className: "text-left px-4 py-3 text-
|
|
219
|
+
className: "text-left px-4 py-3 text-xs font-medium uppercase tracking-wide text-text-muted hidden sm:table-cell",
|
|
218
220
|
children: "Date"
|
|
219
221
|
}),
|
|
220
222
|
/* @__PURE__ */ v("th", {
|
|
221
|
-
className: "text-left px-4 py-3 text-
|
|
223
|
+
className: "text-left px-4 py-3 text-xs font-medium uppercase tracking-wide text-text-muted hidden md:table-cell",
|
|
222
224
|
children: "Due Date"
|
|
223
225
|
}),
|
|
224
226
|
/* @__PURE__ */ v("th", {
|
|
225
|
-
className: "text-right px-4 py-3 text-
|
|
227
|
+
className: "text-right px-4 py-3 text-xs font-medium uppercase tracking-wide text-text-muted",
|
|
226
228
|
children: "Amount"
|
|
227
229
|
}),
|
|
228
230
|
/* @__PURE__ */ v("th", {
|
|
229
|
-
className: "text-right px-4 py-3 text-
|
|
231
|
+
className: "text-right px-4 py-3 text-xs font-medium uppercase tracking-wide text-text-muted",
|
|
230
232
|
children: "Actions"
|
|
231
233
|
})
|
|
232
234
|
] })
|
|
233
235
|
}), /* @__PURE__ */ v("tbody", {
|
|
234
|
-
className: "divide-y divide-border",
|
|
236
|
+
className: "divide-y divide-border-subtle",
|
|
235
237
|
children: R.map((e) => /* @__PURE__ */ v(S, {
|
|
236
238
|
invoice: e,
|
|
237
239
|
onView: () => n(l(`/invoices/${e.id}`, e.billingAccountId)),
|
|
238
|
-
canPay:
|
|
239
|
-
canVoid:
|
|
240
|
+
canPay: r.canPayInvoice,
|
|
241
|
+
canVoid: r.canVoidInvoice,
|
|
240
242
|
showAccount: !O && w.length > 1,
|
|
241
243
|
accountName: w.find((t) => t.id === e.billingAccountId)?.name ?? null
|
|
242
244
|
}, e.id))
|
|
@@ -245,7 +247,7 @@ var x = () => {
|
|
|
245
247
|
}), z > 1 && /* @__PURE__ */ y("div", {
|
|
246
248
|
className: "flex items-center justify-between pt-2",
|
|
247
249
|
children: [/* @__PURE__ */ y("p", {
|
|
248
|
-
className: "text-sm text-
|
|
250
|
+
className: "text-sm text-text-secondary",
|
|
249
251
|
children: [
|
|
250
252
|
"Page ",
|
|
251
253
|
F,
|
|
@@ -258,13 +260,13 @@ var x = () => {
|
|
|
258
260
|
type: "button",
|
|
259
261
|
onClick: () => I((e) => Math.max(1, e - 1)),
|
|
260
262
|
disabled: F <= 1,
|
|
261
|
-
className: "px-3 py-1.5 text-sm font-medium border border-border rounded-
|
|
263
|
+
className: "px-3 py-1.5 text-sm font-medium border border-border-subtle rounded-button bg-bg-surface text-text-primary hover:bg-bg-sunken disabled:opacity-40 disabled:cursor-not-allowed transition-colors",
|
|
262
264
|
children: "Previous"
|
|
263
265
|
}), /* @__PURE__ */ v("button", {
|
|
264
266
|
type: "button",
|
|
265
267
|
onClick: () => I((e) => Math.min(z, e + 1)),
|
|
266
268
|
disabled: F >= z,
|
|
267
|
-
className: "px-3 py-1.5 text-sm font-medium border border-border rounded-
|
|
269
|
+
className: "px-3 py-1.5 text-sm font-medium border border-border-subtle rounded-button bg-bg-surface text-text-primary hover:bg-bg-sunken disabled:opacity-40 disabled:cursor-not-allowed transition-colors",
|
|
268
270
|
children: "Next"
|
|
269
271
|
})]
|
|
270
272
|
})]
|
|
@@ -276,9 +278,9 @@ var x = () => {
|
|
|
276
278
|
className: "text-center space-y-2",
|
|
277
279
|
children: [
|
|
278
280
|
/* @__PURE__ */ v("div", {
|
|
279
|
-
className: "size-12 mx-auto rounded-full bg-
|
|
281
|
+
className: "size-12 mx-auto rounded-full bg-bg-sunken flex items-center justify-center",
|
|
280
282
|
children: /* @__PURE__ */ v("svg", {
|
|
281
|
-
className: "size-6 text-
|
|
283
|
+
className: "size-6 text-text-secondary",
|
|
282
284
|
fill: "none",
|
|
283
285
|
viewBox: "0 0 24 24",
|
|
284
286
|
stroke: "currentColor",
|
|
@@ -291,20 +293,20 @@ var x = () => {
|
|
|
291
293
|
})
|
|
292
294
|
}),
|
|
293
295
|
/* @__PURE__ */ v("h2", {
|
|
294
|
-
className: "text-lg font-semibold text-
|
|
296
|
+
className: "text-lg font-semibold text-text-primary",
|
|
295
297
|
children: t("billing.accessDenied.title", "Access Denied")
|
|
296
298
|
}),
|
|
297
299
|
/* @__PURE__ */ v("p", {
|
|
298
|
-
className: "text-sm text-
|
|
300
|
+
className: "text-sm text-text-secondary max-w-sm",
|
|
299
301
|
children: t("billing.invoices.noViewPermission", "You don't have permission to view invoices.")
|
|
300
302
|
})
|
|
301
303
|
]
|
|
302
304
|
})
|
|
303
305
|
});
|
|
304
306
|
}, S = ({ invoice: o, onView: s, canPay: c, canVoid: l, showAccount: u = !1, accountName: d }) => {
|
|
305
|
-
let f =
|
|
307
|
+
let f = a(o.status), p = o.status === "OPEN", m = o.status === "DRAFT";
|
|
306
308
|
return /* @__PURE__ */ y("tr", {
|
|
307
|
-
className: "hover:bg-
|
|
309
|
+
className: "hover:bg-bg-sunken transition-colors",
|
|
308
310
|
children: [
|
|
309
311
|
/* @__PURE__ */ y("td", {
|
|
310
312
|
className: "p-4",
|
|
@@ -312,46 +314,47 @@ var x = () => {
|
|
|
312
314
|
href: o.invoiceUrl,
|
|
313
315
|
target: "_blank",
|
|
314
316
|
rel: "noopener noreferrer",
|
|
315
|
-
className: "font-medium text-
|
|
316
|
-
children:
|
|
317
|
+
className: "font-medium text-text-primary hover:text-text-link transition-colors",
|
|
318
|
+
children: r(o.invoiceNumber)
|
|
317
319
|
}) : /* @__PURE__ */ v("button", {
|
|
318
320
|
type: "button",
|
|
319
321
|
onClick: s,
|
|
320
|
-
className: "font-medium text-
|
|
321
|
-
children:
|
|
322
|
+
className: "font-medium text-text-primary hover:text-text-link transition-colors",
|
|
323
|
+
children: r(o.invoiceNumber)
|
|
322
324
|
}), (o.itemDescription ?? o.subscription?.plan?.name) && /* @__PURE__ */ v("p", {
|
|
323
|
-
className: "text-sm text-
|
|
325
|
+
className: "text-sm text-text-secondary mt-0.5",
|
|
324
326
|
children: o.itemDescription ?? o.subscription?.plan?.name
|
|
325
327
|
})]
|
|
326
328
|
}),
|
|
327
329
|
/* @__PURE__ */ v("td", {
|
|
328
330
|
className: "p-4",
|
|
329
|
-
children: /* @__PURE__ */ v(
|
|
330
|
-
|
|
331
|
-
|
|
331
|
+
children: /* @__PURE__ */ v(e, {
|
|
332
|
+
status: f,
|
|
333
|
+
dot: !0,
|
|
334
|
+
children: i(o.status)
|
|
332
335
|
})
|
|
333
336
|
}),
|
|
334
337
|
u && /* @__PURE__ */ v("td", {
|
|
335
338
|
className: "p-4 hidden lg:table-cell",
|
|
336
339
|
children: d ? /* @__PURE__ */ v("span", {
|
|
337
|
-
className: "inline-flex items-center px-2 py-0.5 text-xs font-medium rounded-full bg-
|
|
340
|
+
className: "inline-flex items-center px-2 py-0.5 text-xs font-medium rounded-full bg-bg-sunken text-text-secondary border border-border-subtle",
|
|
338
341
|
children: d
|
|
339
342
|
}) : /* @__PURE__ */ v("span", {
|
|
340
|
-
className: "text-sm text-
|
|
343
|
+
className: "text-sm text-text-secondary",
|
|
341
344
|
children: ", "
|
|
342
345
|
})
|
|
343
346
|
}),
|
|
344
347
|
/* @__PURE__ */ v("td", {
|
|
345
|
-
className: "p-4 text-sm text-
|
|
346
|
-
children:
|
|
348
|
+
className: "p-4 text-sm text-text-secondary hidden sm:table-cell",
|
|
349
|
+
children: n(o.createdAt, "short")
|
|
347
350
|
}),
|
|
348
351
|
/* @__PURE__ */ v("td", {
|
|
349
|
-
className: "p-4 text-sm text-
|
|
350
|
-
children: o.dueDate ?
|
|
352
|
+
className: "p-4 text-sm text-text-secondary hidden md:table-cell",
|
|
353
|
+
children: o.dueDate ? n(o.dueDate, "short") : "—"
|
|
351
354
|
}),
|
|
352
355
|
/* @__PURE__ */ v("td", {
|
|
353
|
-
className: "p-4 text-right font-medium text-
|
|
354
|
-
children:
|
|
356
|
+
className: "p-4 text-right font-medium text-text-primary",
|
|
357
|
+
children: t(o.total, o.currency)
|
|
355
358
|
}),
|
|
356
359
|
/* @__PURE__ */ v("td", {
|
|
357
360
|
className: "p-4 text-right",
|
|
@@ -362,29 +365,29 @@ var x = () => {
|
|
|
362
365
|
href: o.invoiceUrl,
|
|
363
366
|
target: "_blank",
|
|
364
367
|
rel: "noopener noreferrer",
|
|
365
|
-
className: "px-3 py-1.5 text-sm font-medium text-
|
|
368
|
+
className: "px-3 py-1.5 text-sm font-medium text-text-primary hover:bg-bg-sunken rounded-button transition-colors duration-200",
|
|
366
369
|
children: "View"
|
|
367
370
|
}) : /* @__PURE__ */ v("button", {
|
|
368
371
|
type: "button",
|
|
369
372
|
onClick: s,
|
|
370
|
-
className: "px-3 py-1.5 text-sm font-medium text-
|
|
373
|
+
className: "px-3 py-1.5 text-sm font-medium text-text-primary hover:bg-bg-sunken rounded-button transition-colors duration-200",
|
|
371
374
|
children: "View"
|
|
372
375
|
}),
|
|
373
376
|
o.pdfUrl && /* @__PURE__ */ v("a", {
|
|
374
377
|
href: o.pdfUrl,
|
|
375
378
|
target: "_blank",
|
|
376
379
|
rel: "noopener noreferrer",
|
|
377
|
-
className: "px-3 py-1.5 text-sm font-medium text-
|
|
380
|
+
className: "px-3 py-1.5 text-sm font-medium text-text-link hover:bg-[var(--color-accent-softHover)] rounded-button transition-colors duration-200",
|
|
378
381
|
children: "PDF"
|
|
379
382
|
}),
|
|
380
383
|
p && c && /* @__PURE__ */ v("button", {
|
|
381
384
|
type: "button",
|
|
382
|
-
className: "px-3 py-1.5 text-sm font-medium bg-primary text-primary-
|
|
385
|
+
className: "px-3 py-1.5 text-sm font-medium bg-action-primary-bg text-action-primary-text rounded-button hover:bg-action-primary-bgHover transition-colors duration-200",
|
|
383
386
|
children: "Pay"
|
|
384
387
|
}),
|
|
385
388
|
(p || m) && l && /* @__PURE__ */ v("button", {
|
|
386
389
|
type: "button",
|
|
387
|
-
className: "px-3 py-1.5 text-sm font-medium text-
|
|
390
|
+
className: "px-3 py-1.5 text-sm font-medium text-status-error-text hover:bg-status-error-bg-subtle rounded-button transition-colors duration-200",
|
|
388
391
|
children: "Void"
|
|
389
392
|
})
|
|
390
393
|
]
|