@carlonicora/nextjs-jsonapi 1.129.1 → 1.131.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/dist/{BlockNoteEditor-RG2YQDMQ.js → BlockNoteEditor-MCHL63TJ.js} +11 -11
- package/dist/BlockNoteEditor-MCHL63TJ.js.map +1 -0
- package/dist/{BlockNoteEditor-WIAQJ5HM.mjs → BlockNoteEditor-Q2GLKMFU.mjs} +4 -4
- package/dist/BlockNoteEditor-Q2GLKMFU.mjs.map +1 -0
- package/dist/billing/index.js +398 -389
- package/dist/billing/index.js.map +1 -1
- package/dist/billing/index.mjs +131 -122
- package/dist/billing/index.mjs.map +1 -1
- package/dist/{chunk-F54XZKPY.mjs → chunk-4TM6GOT3.mjs} +2135 -2063
- package/dist/chunk-4TM6GOT3.mjs.map +1 -0
- package/dist/{chunk-YQTMNZQB.js → chunk-PE6DSRTQ.js} +188 -116
- package/dist/chunk-PE6DSRTQ.js.map +1 -0
- package/dist/client/index.js +2 -2
- package/dist/client/index.mjs +1 -1
- package/dist/components/index.d.mts +20 -2
- package/dist/components/index.d.ts +20 -2
- package/dist/components/index.js +8 -2
- package/dist/components/index.js.map +1 -1
- package/dist/components/index.mjs +7 -1
- package/dist/contexts/index.d.mts +2 -0
- package/dist/contexts/index.d.ts +2 -0
- package/dist/contexts/index.js +2 -2
- package/dist/contexts/index.mjs +1 -1
- package/dist/features/help/index.js +32 -31
- package/dist/features/help/index.js.map +1 -1
- package/dist/features/help/index.mjs +3 -2
- package/dist/features/help/index.mjs.map +1 -1
- package/package.json +1 -1
- package/src/components/containers/ReactMarkdownContainer.tsx +2 -2
- package/src/components/containers/RoundPageContainerTitle.tsx +47 -40
- package/src/components/editors/BlockNoteDiffInlineContent.tsx +10 -10
- package/src/components/editors/BlockNoteEditor.tsx +2 -2
- package/src/components/forms/FormCheckbox.tsx +2 -2
- package/src/components/forms/FormFieldWrapper.tsx +1 -1
- package/src/components/forms/FormSlider.tsx +1 -1
- package/src/components/forms/GdprConsentCheckbox.tsx +1 -1
- package/src/components/hero/EntitySection.tsx +2 -1
- package/src/components/index.ts +1 -0
- package/src/components/typography/DetailField.tsx +35 -0
- package/src/components/typography/MicroLabel.tsx +21 -0
- package/src/components/typography/SectionHeader.tsx +18 -0
- package/src/components/typography/index.ts +6 -0
- package/src/contexts/SharedContext.tsx +2 -0
- package/src/features/assistant/components/parts/AssistantEmptyState.tsx +2 -1
- package/src/features/assistant/components/parts/AssistantSidebar.tsx +2 -1
- package/src/features/auth/components/buttons/GoogleSignInButton.tsx +1 -1
- package/src/features/auth/components/forms/Register.tsx +1 -1
- package/src/features/auth/components/forms/TwoFactorChallenge.tsx +3 -3
- package/src/features/auth/components/two-factor/BackupCodesDialog.tsx +1 -1
- package/src/features/auth/components/two-factor/TotpInput.tsx +2 -2
- package/src/features/auth/components/two-factor/TwoFactorSettings.tsx +3 -3
- package/src/features/billing/components/cards/BillingUsageSummaryCard.tsx +4 -4
- package/src/features/billing/components/cards/CustomerInfoCard.tsx +6 -6
- package/src/features/billing/components/cards/InvoicesSummaryCard.tsx +5 -5
- package/src/features/billing/components/cards/PaymentMethodSummaryCard.tsx +4 -4
- package/src/features/billing/components/cards/SubscriptionSummaryCard.tsx +4 -4
- package/src/features/billing/components/containers/BillingDashboardContainer.tsx +2 -2
- package/src/features/billing/components/widgets/BillingAlertBanner.tsx +8 -8
- package/src/features/billing/stripe-customer/components/containers/PaymentMethodsContainer.tsx +2 -2
- package/src/features/billing/stripe-customer/components/details/PaymentMethodCard.tsx +8 -2
- package/src/features/billing/stripe-customer/components/forms/PaymentMethodForm.tsx +1 -1
- package/src/features/billing/stripe-invoice/components/details/InvoiceDetails.tsx +16 -18
- package/src/features/billing/stripe-invoice/components/lists/InvoicesList.tsx +2 -2
- package/src/features/billing/stripe-invoice/components/widgets/InvoiceStatusBadge.tsx +8 -7
- package/src/features/billing/stripe-price/components/lists/PricesList.tsx +6 -13
- package/src/features/billing/stripe-product/components/containers/ProductsAdminContainer.tsx +3 -3
- package/src/features/billing/stripe-product/components/lists/ProductsList.tsx +4 -7
- package/src/features/billing/stripe-promotion-code/components/PromoCodeInput.tsx +6 -6
- package/src/features/billing/stripe-subscription/components/containers/SubscriptionsContainer.tsx +2 -2
- package/src/features/billing/stripe-subscription/components/details/SubscriptionDetails.tsx +10 -10
- package/src/features/billing/stripe-subscription/components/widgets/PricingCard.tsx +2 -2
- package/src/features/billing/stripe-subscription/components/widgets/ProductPricingRow.tsx +2 -1
- package/src/features/billing/stripe-subscription/components/widgets/ProrationPreview.tsx +1 -1
- package/src/features/billing/stripe-subscription/components/widgets/SubscriptionStatusBadge.tsx +12 -11
- package/src/features/billing/stripe-subscription/components/wizards/WizardStepPaymentMethod.tsx +2 -1
- package/src/features/billing/stripe-subscription/components/wizards/WizardStepReview.tsx +10 -13
- package/src/features/billing/stripe-usage/components/containers/UsageContainer.tsx +2 -2
- package/src/features/billing/stripe-usage/components/details/UsageSummaryCard.tsx +6 -6
- package/src/features/billing/stripe-usage/components/lists/UsageHistoryTable.tsx +3 -2
- package/src/features/company/components/details/CompanyContent.tsx +4 -7
- package/src/features/company/components/details/TokenStatusIndicator.tsx +5 -5
- package/src/features/company/components/forms/CompanyDeleter.tsx +1 -1
- package/src/features/company/components/forms/CompanyEditor.tsx +3 -2
- package/src/features/content/components/lists/ContentsList.tsx +2 -1
- package/src/features/feature/components/forms/FormFeatures.tsx +6 -1
- package/src/features/help/components/HelpTOC.tsx +2 -3
- package/src/features/how-to/components/containers/HowToCommand.tsx +3 -3
- package/src/features/how-to/components/containers/HowToCommandViewer.tsx +4 -1
- package/src/features/notification/components/containers/NotificationsListContainer.tsx +1 -1
- package/src/features/notification/components/modals/NotificationModal.tsx +2 -2
- package/src/features/oauth/components/OAuthClientCard.tsx +1 -1
- package/src/features/oauth/components/OAuthClientDetail.tsx +5 -9
- package/src/features/oauth/components/OAuthClientForm.tsx +3 -3
- package/src/features/oauth/components/OAuthClientList.tsx +5 -4
- package/src/features/oauth/components/OAuthClientSecretDisplay.tsx +3 -3
- package/src/features/oauth/components/OAuthRedirectUriInput.tsx +1 -1
- package/src/features/oauth/components/OAuthScopeSelector.tsx +2 -2
- package/src/features/oauth/components/consent/OAuthConsentHeader.tsx +1 -1
- package/src/features/oauth/components/consent/OAuthConsentScreen.tsx +1 -1
- package/src/features/oauth/components/consent/OAuthScopeList.tsx +2 -3
- package/src/features/rbac/components/RbacContainer.tsx +1 -1
- package/src/features/rbac/components/RbacPermissionCell.tsx +2 -2
- package/src/features/rbac/components/RbacPermissionPicker.tsx +3 -3
- package/src/features/referral/components/ReferralWidget.tsx +7 -6
- package/src/features/waitlist/components/forms/WaitlistForm.tsx +3 -2
- package/src/features/waitlist/components/forms/WaitlistQuestionnaireRenderer.tsx +1 -1
- package/src/features/waitlist/components/lists/WaitlistList.tsx +2 -1
- package/src/features/waitlist/components/sections/WaitlistConfirmation.tsx +3 -2
- package/src/features/waitlist/components/sections/WaitlistSuccessState.tsx +2 -1
- package/src/features/waitlist/hooks/useWaitlistTableStructure.tsx +1 -1
- package/src/shadcnui/custom/link.tsx +7 -1
- package/src/shadcnui/ui/alert.tsx +1 -1
- package/src/shadcnui/ui/badge.tsx +7 -0
- package/src/shadcnui/ui/button.tsx +1 -1
- package/src/shadcnui/ui/chart.tsx +1 -3
- package/dist/BlockNoteEditor-RG2YQDMQ.js.map +0 -1
- package/dist/BlockNoteEditor-WIAQJ5HM.mjs.map +0 -1
- package/dist/chunk-F54XZKPY.mjs.map +0 -1
- package/dist/chunk-YQTMNZQB.js.map +0 -1
package/src/features/billing/stripe-subscription/components/widgets/SubscriptionStatusBadge.tsx
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
|
|
3
|
+
import { Badge, type BadgeProps } from "../../../../../shadcnui";
|
|
3
4
|
import { SubscriptionStatus } from "../../data";
|
|
4
5
|
|
|
5
6
|
type SubscriptionStatusBadgeProps = {
|
|
@@ -9,47 +10,47 @@ type SubscriptionStatusBadgeProps = {
|
|
|
9
10
|
|
|
10
11
|
type StatusConfig = {
|
|
11
12
|
label: string;
|
|
12
|
-
|
|
13
|
+
variant: BadgeProps["variant"];
|
|
13
14
|
};
|
|
14
15
|
|
|
15
16
|
const statusConfig: Record<SubscriptionStatus, StatusConfig> = {
|
|
16
17
|
[SubscriptionStatus.ACTIVE]: {
|
|
17
18
|
label: "Active",
|
|
18
|
-
|
|
19
|
+
variant: "softGreen",
|
|
19
20
|
},
|
|
20
21
|
[SubscriptionStatus.TRIALING]: {
|
|
21
22
|
label: "Trial",
|
|
22
|
-
|
|
23
|
+
variant: "softBlue",
|
|
23
24
|
},
|
|
24
25
|
[SubscriptionStatus.PAST_DUE]: {
|
|
25
26
|
label: "Past Due",
|
|
26
|
-
|
|
27
|
+
variant: "softRed",
|
|
27
28
|
},
|
|
28
29
|
[SubscriptionStatus.CANCELED]: {
|
|
29
30
|
label: "Canceled",
|
|
30
|
-
|
|
31
|
+
variant: "softGray",
|
|
31
32
|
},
|
|
32
33
|
[SubscriptionStatus.PAUSED]: {
|
|
33
34
|
label: "Paused",
|
|
34
|
-
|
|
35
|
+
variant: "softYellow",
|
|
35
36
|
},
|
|
36
37
|
[SubscriptionStatus.UNPAID]: {
|
|
37
38
|
label: "Unpaid",
|
|
38
|
-
|
|
39
|
+
variant: "softOrange",
|
|
39
40
|
},
|
|
40
41
|
[SubscriptionStatus.INCOMPLETE]: {
|
|
41
42
|
label: "Incomplete",
|
|
42
|
-
|
|
43
|
+
variant: "softGray",
|
|
43
44
|
},
|
|
44
45
|
[SubscriptionStatus.INCOMPLETE_EXPIRED]: {
|
|
45
46
|
label: "Expired",
|
|
46
|
-
|
|
47
|
+
variant: "softGray",
|
|
47
48
|
},
|
|
48
49
|
};
|
|
49
50
|
|
|
50
51
|
const cancelingConfig: StatusConfig = {
|
|
51
52
|
label: "Canceling",
|
|
52
|
-
|
|
53
|
+
variant: "softAmber",
|
|
53
54
|
};
|
|
54
55
|
|
|
55
56
|
export function SubscriptionStatusBadge({ status, cancelAtPeriodEnd }: SubscriptionStatusBadgeProps) {
|
|
@@ -58,5 +59,5 @@ export function SubscriptionStatusBadge({ status, cancelAtPeriodEnd }: Subscript
|
|
|
58
59
|
? cancelingConfig
|
|
59
60
|
: statusConfig[status] || statusConfig[SubscriptionStatus.CANCELED];
|
|
60
61
|
|
|
61
|
-
return <
|
|
62
|
+
return <Badge variant={config.variant}>{config.label}</Badge>;
|
|
62
63
|
}
|
package/src/features/billing/stripe-subscription/components/wizards/WizardStepPaymentMethod.tsx
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
|
|
3
3
|
import { PaymentMethodForm } from "../../../stripe-customer/components/forms/PaymentMethodForm";
|
|
4
|
+
import { SectionHeader } from "../../../../../components/typography";
|
|
4
5
|
|
|
5
6
|
type WizardStepPaymentMethodProps = {
|
|
6
7
|
onBack: () => void;
|
|
@@ -12,7 +13,7 @@ export function WizardStepPaymentMethod({ onBack, onSuccess, isProcessing }: Wiz
|
|
|
12
13
|
return (
|
|
13
14
|
<div className="space-y-6">
|
|
14
15
|
<div className="text-center">
|
|
15
|
-
<
|
|
16
|
+
<SectionHeader>Add Payment Method</SectionHeader>
|
|
16
17
|
<p className="text-sm text-muted-foreground">Enter your card details to complete your subscription</p>
|
|
17
18
|
</div>
|
|
18
19
|
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
|
|
3
3
|
import { AlertCircle } from "lucide-react";
|
|
4
|
-
import { Alert, AlertDescription, Button } from "../../../../../shadcnui";
|
|
4
|
+
import { Alert, AlertDescription, Badge, Button } from "../../../../../shadcnui";
|
|
5
|
+
import { SectionHeader } from "../../../../../components/typography";
|
|
5
6
|
import { formatCurrency } from "../../../components/utils/currency";
|
|
6
7
|
import { StripePriceInterface } from "../../../stripe-price/data/stripe-price.interface";
|
|
7
8
|
import { ProrationPreviewInterface } from "../../../stripe-invoice/data/stripe-invoice.interface";
|
|
@@ -120,7 +121,7 @@ export function WizardStepReview({
|
|
|
120
121
|
<div className="space-y-6">
|
|
121
122
|
{/* Selected Plan Summary */}
|
|
122
123
|
<div className="bg-muted/50 rounded-lg p-4 space-y-3">
|
|
123
|
-
<
|
|
124
|
+
<SectionHeader>Selected Plan</SectionHeader>
|
|
124
125
|
<div className="flex justify-between items-center">
|
|
125
126
|
<div>
|
|
126
127
|
<p className="font-medium">{selectedPrice.product?.name}</p>
|
|
@@ -132,14 +133,10 @@ export function WizardStepReview({
|
|
|
132
133
|
<p className="text-sm text-muted-foreground line-through">
|
|
133
134
|
{formatCurrency(selectedPrice.unitAmount || 0, selectedPrice.currency)}
|
|
134
135
|
</p>
|
|
135
|
-
<p className="
|
|
136
|
+
<p className="text-success text-lg font-semibold">
|
|
136
137
|
{formatCurrency(discountedPrice, selectedPrice.currency)}
|
|
137
138
|
</p>
|
|
138
|
-
{discountDescription &&
|
|
139
|
-
<span className="inline-block text-xs bg-green-100 text-green-700 px-2 py-0.5 rounded-full">
|
|
140
|
-
{discountDescription}
|
|
141
|
-
</span>
|
|
142
|
-
)}
|
|
139
|
+
{discountDescription && <Badge variant="softGreen">{discountDescription}</Badge>}
|
|
143
140
|
</>
|
|
144
141
|
) : (
|
|
145
142
|
<p className="font-semibold text-lg">
|
|
@@ -156,25 +153,25 @@ export function WizardStepReview({
|
|
|
156
153
|
<div
|
|
157
154
|
className={`${isTrialUpgrade ? "bg-amber-50 border-amber-200" : "bg-blue-50 border-blue-200"} border rounded-lg p-4 space-y-2`}
|
|
158
155
|
>
|
|
159
|
-
<h4 className={`font-medium ${isTrialUpgrade ? "text-
|
|
156
|
+
<h4 className={`font-medium ${isTrialUpgrade ? "text-warning" : "text-blue-800"}`}>
|
|
160
157
|
{isTrialUpgrade ? "Trial Upgrade" : "Proration Summary"}
|
|
161
158
|
</h4>
|
|
162
|
-
<p className={`text-sm ${isTrialUpgrade ? "text-
|
|
159
|
+
<p className={`text-sm ${isTrialUpgrade ? "text-warning" : "text-blue-700"}`}>
|
|
163
160
|
{isTrialUpgrade
|
|
164
161
|
? "Your trial will end immediately and you will be charged the full price."
|
|
165
162
|
: "Your next charge will be adjusted to account for the plan change."}
|
|
166
163
|
</p>
|
|
167
164
|
<div className="flex justify-between text-sm">
|
|
168
|
-
<span className={`${isTrialUpgrade ? "text-
|
|
165
|
+
<span className={`${isTrialUpgrade ? "text-warning" : "text-blue-600"}`}>
|
|
169
166
|
{isTrialUpgrade ? "Amount to charge now:" : "Amount due now:"}
|
|
170
167
|
</span>
|
|
171
|
-
<span className={`font-medium ${isTrialUpgrade ? "text-
|
|
168
|
+
<span className={`font-medium ${isTrialUpgrade ? "text-warning" : "text-blue-800"}`}>
|
|
172
169
|
{discountedImmediateCharge !== null ? (
|
|
173
170
|
<>
|
|
174
171
|
<span className="line-through text-muted-foreground mr-2">
|
|
175
172
|
{formatCurrency(prorationPreview.immediateCharge, prorationPreview.currency)}
|
|
176
173
|
</span>
|
|
177
|
-
<span className="text-
|
|
174
|
+
<span className="text-success">
|
|
178
175
|
{formatCurrency(discountedImmediateCharge, prorationPreview.currency)}
|
|
179
176
|
</span>
|
|
180
177
|
</>
|
|
@@ -86,7 +86,7 @@ export function UsageContainer() {
|
|
|
86
86
|
{/* Header */}
|
|
87
87
|
<div className="flex items-center gap-x-3">
|
|
88
88
|
<Activity className="h-8 w-8" />
|
|
89
|
-
<h1 className="text-3xl font-
|
|
89
|
+
<h1 className="text-primary text-3xl font-semibold">Usage Tracking</h1>
|
|
90
90
|
</div>
|
|
91
91
|
|
|
92
92
|
{/* Empty State */}
|
|
@@ -94,7 +94,7 @@ export function UsageContainer() {
|
|
|
94
94
|
<div className="bg-muted/50 flex flex-col items-center justify-center gap-y-4 rounded-lg border-2 border-dashed border-gray-300 p-12">
|
|
95
95
|
<Activity className="text-muted-foreground h-16 w-16" />
|
|
96
96
|
<div className="text-center">
|
|
97
|
-
<h3 className="mb-2 text-
|
|
97
|
+
<h3 className="mb-2 text-sm font-medium">No usage meters configured</h3>
|
|
98
98
|
<p className="text-muted-foreground">
|
|
99
99
|
Usage tracking will appear here when you have metered subscriptions with configured meters.
|
|
100
100
|
</p>
|
|
@@ -52,8 +52,8 @@ export function UsageSummaryCard({ meter, summary }: UsageSummaryCardProps) {
|
|
|
52
52
|
<Activity className="h-5 w-5" />
|
|
53
53
|
</div>
|
|
54
54
|
<div className="flex flex-col">
|
|
55
|
-
<h3 className="font-
|
|
56
|
-
<p className="text-
|
|
55
|
+
<h3 className="text-sm font-medium">{displayName}</h3>
|
|
56
|
+
<p className="text-muted-foreground text-xs">{meter.id}</p>
|
|
57
57
|
</div>
|
|
58
58
|
</CardHeader>
|
|
59
59
|
|
|
@@ -61,7 +61,7 @@ export function UsageSummaryCard({ meter, summary }: UsageSummaryCardProps) {
|
|
|
61
61
|
{/* Current Usage */}
|
|
62
62
|
<div>
|
|
63
63
|
<p className="text-3xl font-bold">{currentUsage.toLocaleString()}</p>
|
|
64
|
-
{hasLimit && <p className="text-
|
|
64
|
+
{hasLimit && <p className="text-muted-foreground text-sm">of {limit.toLocaleString()} used</p>}
|
|
65
65
|
</div>
|
|
66
66
|
|
|
67
67
|
{/* Progress Bar */}
|
|
@@ -70,16 +70,16 @@ export function UsageSummaryCard({ meter, summary }: UsageSummaryCardProps) {
|
|
|
70
70
|
<div className="h-2 w-full overflow-hidden rounded-full bg-gray-200">
|
|
71
71
|
<div className={`h-full transition-all ${progressColor}`} style={{ width: `${progressWidth}%` }} />
|
|
72
72
|
</div>
|
|
73
|
-
<p className="text-
|
|
73
|
+
<p className="text-muted-foreground text-sm">{percentage?.toFixed(1)}% used</p>
|
|
74
74
|
</div>
|
|
75
75
|
) : (
|
|
76
|
-
<p className="text-
|
|
76
|
+
<p className="text-muted-foreground text-sm">No limit set</p>
|
|
77
77
|
)}
|
|
78
78
|
|
|
79
79
|
{/* Period Information */}
|
|
80
80
|
{summary && summary.start && summary.end && (
|
|
81
81
|
<div className="border-t pt-3">
|
|
82
|
-
<p className="text-
|
|
82
|
+
<p className="text-muted-foreground text-xs">
|
|
83
83
|
Period: {formatDate(summary.start)} - {formatDate(summary.end)}
|
|
84
84
|
</p>
|
|
85
85
|
</div>
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
|
|
3
3
|
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "../../../../../shadcnui";
|
|
4
|
+
import { SectionHeader } from "../../../../../components/typography";
|
|
4
5
|
import { StripeUsageInterface } from "../../data/stripe-usage.interface";
|
|
5
6
|
|
|
6
7
|
type UsageHistoryTableProps = {
|
|
@@ -39,7 +40,7 @@ export function UsageHistoryTable({ usageRecords }: UsageHistoryTableProps) {
|
|
|
39
40
|
|
|
40
41
|
return (
|
|
41
42
|
<div className="flex w-full flex-col gap-y-4">
|
|
42
|
-
<
|
|
43
|
+
<SectionHeader level={2}>Usage History</SectionHeader>
|
|
43
44
|
<div className="overflow-clip rounded-lg border">
|
|
44
45
|
<Table>
|
|
45
46
|
<TableHeader className="bg-muted">
|
|
@@ -60,7 +61,7 @@ export function UsageHistoryTable({ usageRecords }: UsageHistoryTableProps) {
|
|
|
60
61
|
<TableCell className="font-medium">{dateTime}</TableCell>
|
|
61
62
|
<TableCell className="text-muted-foreground">{record.meterEventName}</TableCell>
|
|
62
63
|
<TableCell className="text-right font-medium">{quantity}</TableCell>
|
|
63
|
-
<TableCell className="text-muted-foreground text-sm
|
|
64
|
+
<TableCell className="text-muted-foreground text-sm tabular-nums">{record.stripeEventId}</TableCell>
|
|
64
65
|
</TableRow>
|
|
65
66
|
);
|
|
66
67
|
})}
|
|
@@ -5,6 +5,7 @@ import { useTranslations } from "next-intl";
|
|
|
5
5
|
import Image from "next/image";
|
|
6
6
|
import { ReactNode } from "react";
|
|
7
7
|
import { AttributeElement } from "../../../../components";
|
|
8
|
+
import { SectionHeader, MicroLabel } from "../../../../components/typography";
|
|
8
9
|
import { FiscalDataDisplay } from "../../../../components/fiscal/FiscalDataDisplay";
|
|
9
10
|
import { CompanyInterface } from "../../data";
|
|
10
11
|
|
|
@@ -34,7 +35,7 @@ export function CompanyContent({ company, actions }: CompanyContentProps) {
|
|
|
34
35
|
<div className="flex flex-col gap-y-8">
|
|
35
36
|
{/* Title Row */}
|
|
36
37
|
<div className="flex w-full items-center justify-between">
|
|
37
|
-
<
|
|
38
|
+
<SectionHeader level={2}>{company.name}</SectionHeader>
|
|
38
39
|
{actions && <div className="flex items-center gap-x-2">{actions}</div>}
|
|
39
40
|
</div>
|
|
40
41
|
|
|
@@ -70,9 +71,7 @@ export function CompanyContent({ company, actions }: CompanyContentProps) {
|
|
|
70
71
|
{/* Fiscal Data Section */}
|
|
71
72
|
{company.fiscal_data && (
|
|
72
73
|
<div className="flex flex-col gap-y-3">
|
|
73
|
-
<
|
|
74
|
-
{t("company.sections.fiscal_data")}
|
|
75
|
-
</h3>
|
|
74
|
+
<MicroLabel>{t("company.sections.fiscal_data")}</MicroLabel>
|
|
76
75
|
<FiscalDataDisplay fiscalData={company.fiscal_data} />
|
|
77
76
|
</div>
|
|
78
77
|
)}
|
|
@@ -80,9 +79,7 @@ export function CompanyContent({ company, actions }: CompanyContentProps) {
|
|
|
80
79
|
{/* Address Details Section */}
|
|
81
80
|
{hasAddressDetails(company) && (
|
|
82
81
|
<div className="flex flex-col gap-y-3">
|
|
83
|
-
<
|
|
84
|
-
{t("company.sections.address_details")}
|
|
85
|
-
</h3>
|
|
82
|
+
<MicroLabel>{t("company.sections.address_details")}</MicroLabel>
|
|
86
83
|
<div className="grid grid-cols-1 gap-4 md:grid-cols-3">
|
|
87
84
|
{company.street && <AttributeElement title={t("company.fields.street.label")} value={company.street} />}
|
|
88
85
|
{company.street_number && (
|
|
@@ -62,11 +62,11 @@ export function TokenStatusIndicator({ className, size = "md", showExtraPages =
|
|
|
62
62
|
|
|
63
63
|
const getBatteryIcon = () => {
|
|
64
64
|
if (percentage > 75) {
|
|
65
|
-
return <BatteryFull className={cn(iconSize, "text-
|
|
65
|
+
return <BatteryFull className={cn(iconSize, "text-success")} />;
|
|
66
66
|
} else if (percentage > 50) {
|
|
67
|
-
return <BatteryMedium className={cn(iconSize, "text-
|
|
67
|
+
return <BatteryMedium className={cn(iconSize, "text-success")} />;
|
|
68
68
|
} else if (percentage >= 25) {
|
|
69
|
-
return <BatteryLow className={cn(iconSize, "text-
|
|
69
|
+
return <BatteryLow className={cn(iconSize, "text-warning")} />;
|
|
70
70
|
} else {
|
|
71
71
|
return <Battery className={cn(iconSize, "text-destructive")} />;
|
|
72
72
|
}
|
|
@@ -74,9 +74,9 @@ export function TokenStatusIndicator({ className, size = "md", showExtraPages =
|
|
|
74
74
|
|
|
75
75
|
const getStatusColor = () => {
|
|
76
76
|
if (percentage > 50) {
|
|
77
|
-
return "text-
|
|
77
|
+
return "text-success";
|
|
78
78
|
} else if (percentage >= 25) {
|
|
79
|
-
return "text-
|
|
79
|
+
return "text-warning";
|
|
80
80
|
} else {
|
|
81
81
|
return "text-destructive";
|
|
82
82
|
}
|
|
@@ -99,7 +99,7 @@ function CompanyDeleterInternal({ company, isAdministrator }: CompanyDeleterInte
|
|
|
99
99
|
<div className="flex w-full flex-col">
|
|
100
100
|
<Label className="flex items-center">
|
|
101
101
|
{t(`company.fields.name.label`)}
|
|
102
|
-
<span className="
|
|
102
|
+
<span className="ml-1 text-destructive">*</span>
|
|
103
103
|
</Label>
|
|
104
104
|
<Input
|
|
105
105
|
className={`w-full`}
|
|
@@ -20,6 +20,7 @@ import {
|
|
|
20
20
|
parseFiscalData,
|
|
21
21
|
} from "../../../../components";
|
|
22
22
|
import type { FiscalDataHandle } from "../../../../components";
|
|
23
|
+
import { SectionHeader } from "../../../../components/typography";
|
|
23
24
|
import { Modules } from "../../../../core";
|
|
24
25
|
import { useI18nRouter } from "../../../../i18n";
|
|
25
26
|
import { getRoleId } from "../../../../roles";
|
|
@@ -223,7 +224,7 @@ function CompanyEditorInternal({
|
|
|
223
224
|
<div className="flex w-full items-start justify-between gap-x-4">
|
|
224
225
|
<div className="flex w-96 flex-col justify-start gap-y-4">
|
|
225
226
|
<FileUploader value={files} onValueChange={setFiles} dropzoneOptions={dropzone} className="w-full p-4">
|
|
226
|
-
<FileInput className="text-
|
|
227
|
+
<FileInput className="text-muted-foreground/50 outline-dashed">
|
|
227
228
|
<div className="flex w-full flex-col items-center justify-center pt-3 pb-4">
|
|
228
229
|
<div className="flex w-full flex-col items-center justify-center pt-3 pb-4">
|
|
229
230
|
{file || company?.logo ? (
|
|
@@ -262,7 +263,7 @@ function CompanyEditorInternal({
|
|
|
262
263
|
}
|
|
263
264
|
}}
|
|
264
265
|
/>
|
|
265
|
-
<
|
|
266
|
+
<SectionHeader className="mt-2">{t(`company.sections.fiscal_data`)}</SectionHeader>
|
|
266
267
|
<ItalianFiscalData ref={fiscalRef} initialData={parseFiscalData(company?.fiscal_data)} />
|
|
267
268
|
</div>
|
|
268
269
|
{canAccessFeatures && (
|
|
@@ -5,6 +5,7 @@ import { Modules } from "../../../../core";
|
|
|
5
5
|
import { usePageUrlGenerator } from "../../../../hooks";
|
|
6
6
|
import { HoverCard, HoverCardContent, HoverCardTrigger, Link } from "../../../../shadcnui";
|
|
7
7
|
import { getIconByModule } from "../../../../utils";
|
|
8
|
+
import { SectionHeader } from "../../../../components/typography";
|
|
8
9
|
import { ContributorsList } from "../../../user/components";
|
|
9
10
|
import { ContentInterface } from "../../data";
|
|
10
11
|
|
|
@@ -17,7 +18,7 @@ export function ContentsList({ contentList }: ContentsListProps) {
|
|
|
17
18
|
|
|
18
19
|
return (
|
|
19
20
|
<div className="flex min-h-0 w-full flex-col overflow-y-auto">
|
|
20
|
-
<
|
|
21
|
+
<SectionHeader level={2}>{t(`content.news`)}</SectionHeader>
|
|
21
22
|
<div className="flex flex-col">
|
|
22
23
|
{contentList.map((content) => (
|
|
23
24
|
<ContentsListElement content={content} key={content.id} />
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
|
|
3
3
|
import { Checkbox, Label, ScrollArea } from "../../../../shadcnui";
|
|
4
|
+
import { SectionHeader } from "../../../../components/typography";
|
|
4
5
|
import { FeatureInterface } from "../../data";
|
|
5
6
|
|
|
6
7
|
type FormFeaturesProps = {
|
|
@@ -30,7 +31,11 @@ export function FormFeatures({ form, name, features, featureField = "featureIds"
|
|
|
30
31
|
|
|
31
32
|
return (
|
|
32
33
|
<div className="flex w-full flex-col">
|
|
33
|
-
{name &&
|
|
34
|
+
{name && (
|
|
35
|
+
<SectionHeader level={2} className="mb-4 border-b">
|
|
36
|
+
{name}
|
|
37
|
+
</SectionHeader>
|
|
38
|
+
)}
|
|
34
39
|
<ScrollArea className="h-[40vh]">
|
|
35
40
|
<div className="flex flex-col gap-y-2 pr-4">
|
|
36
41
|
{features
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
import { useEffect, useState } from "react";
|
|
3
3
|
import { useTranslations } from "next-intl";
|
|
4
4
|
import type { HelpHeading } from "../types/help-article.types";
|
|
5
|
+
import { MicroLabel } from "../../../components/typography";
|
|
5
6
|
|
|
6
7
|
export function HelpTOC({ headings }: { headings: readonly HelpHeading[] }) {
|
|
7
8
|
const t = useTranslations();
|
|
@@ -26,9 +27,7 @@ export function HelpTOC({ headings }: { headings: readonly HelpHeading[] }) {
|
|
|
26
27
|
if (headings.length === 0) return null;
|
|
27
28
|
return (
|
|
28
29
|
<nav aria-label={t("help.toc.title")} className="hidden lg:block">
|
|
29
|
-
<
|
|
30
|
-
{t("help.toc.title")}
|
|
31
|
-
</div>
|
|
30
|
+
<MicroLabel className="mb-2">{t("help.toc.title")}</MicroLabel>
|
|
32
31
|
<ul className="space-y-1 text-sm">
|
|
33
32
|
{headings.map((h) => (
|
|
34
33
|
<li key={h.slug} style={{ paddingLeft: `${(h.depth - 2) * 0.75}rem` }}>
|
|
@@ -207,15 +207,15 @@ export default function HowToCommand({ pathname, extraGroups, onStartChat }: How
|
|
|
207
207
|
{/* Keyboard hints footer */}
|
|
208
208
|
<div className="text-muted-foreground flex items-center justify-center gap-4 border-t px-3 py-2 text-xs">
|
|
209
209
|
<span className="flex items-center gap-1">
|
|
210
|
-
<kbd className="bg-muted rounded border px-1.5 py-0.5
|
|
210
|
+
<kbd className="bg-muted rounded border px-1.5 py-0.5 tabular-nums text-xs">⏎</kbd>
|
|
211
211
|
{t(`howto.command.keyboard.select`)}
|
|
212
212
|
</span>
|
|
213
213
|
<span className="flex items-center gap-1">
|
|
214
|
-
<kbd className="bg-muted rounded border px-1.5 py-0.5
|
|
214
|
+
<kbd className="bg-muted rounded border px-1.5 py-0.5 tabular-nums text-xs">↑↓</kbd>
|
|
215
215
|
{t(`howto.command.keyboard.navigate`)}
|
|
216
216
|
</span>
|
|
217
217
|
<span className="flex items-center gap-1">
|
|
218
|
-
<kbd className="bg-muted rounded border px-1.5 py-0.5
|
|
218
|
+
<kbd className="bg-muted rounded border px-1.5 py-0.5 tabular-nums text-xs">
|
|
219
219
|
{t(`howto.keyboard.esc`)}
|
|
220
220
|
</kbd>
|
|
221
221
|
{t(`howto.command.keyboard.close`)}
|
|
@@ -6,6 +6,7 @@ import { useMemo } from "react";
|
|
|
6
6
|
|
|
7
7
|
import { BlockNoteEditorContainer } from "../../../../components";
|
|
8
8
|
import { Button } from "../../../../shadcnui";
|
|
9
|
+
import { SectionHeader } from "../../../../components/typography";
|
|
9
10
|
import { HowToInterface } from "../../data/HowToInterface";
|
|
10
11
|
import { calculateReadingTime, extractHeadings } from "../../utils/blocknote";
|
|
11
12
|
|
|
@@ -29,7 +30,9 @@ export default function HowToCommandViewer({ howTo, onBack, onStartChat }: HowTo
|
|
|
29
30
|
<ArrowLeft className="h-4 w-4" />
|
|
30
31
|
<span className="ml-1">{t("howto.command.back")}</span>
|
|
31
32
|
</Button>
|
|
32
|
-
<
|
|
33
|
+
<SectionHeader level={2} className="flex-1 truncate">
|
|
34
|
+
{howTo.name}
|
|
35
|
+
</SectionHeader>
|
|
33
36
|
<div className="text-muted-foreground flex items-center gap-1.5 text-sm">
|
|
34
37
|
<BookOpen className="h-4 w-4" />
|
|
35
38
|
<span>{t("howto.reading_time.label", { minutes: readingTime })}</span>
|
|
@@ -13,7 +13,7 @@ function NotificationsListContainerContent() {
|
|
|
13
13
|
if (error) {
|
|
14
14
|
return (
|
|
15
15
|
<div className="flex items-center justify-center p-8 text-center">
|
|
16
|
-
<div className="text-destructive text-
|
|
16
|
+
<div className="text-destructive text-xs/relaxed">
|
|
17
17
|
<p>Error loading notifications: {error}</p>
|
|
18
18
|
<p className="text-muted-foreground mt-2">Please try refreshing the page.</p>
|
|
19
19
|
</div>
|
|
@@ -205,7 +205,7 @@ function NotificationModalContent({ isOpen, setIsOpen }: NotificationModalProps)
|
|
|
205
205
|
<CardHeader className="p-4">
|
|
206
206
|
<CardTitle>{t(`entities.notifications`, { count: 2 })}</CardTitle>
|
|
207
207
|
{isLoading && <div className="text-muted-foreground text-xs">Loading...</div>}
|
|
208
|
-
{error && <div className="text-destructive text-xs">Error: {error}</div>}
|
|
208
|
+
{error && <div className="text-destructive text-xs/relaxed">Error: {error}</div>}
|
|
209
209
|
</CardHeader>
|
|
210
210
|
<Separator />
|
|
211
211
|
<ScrollArea className="h-96">
|
|
@@ -214,7 +214,7 @@ function NotificationModalContent({ isOpen, setIsOpen }: NotificationModalProps)
|
|
|
214
214
|
<Fragment key={notification.id}>{generateNotification(notification, () => setIsOpen(false))}</Fragment>
|
|
215
215
|
))
|
|
216
216
|
) : (
|
|
217
|
-
<div className="p-4 text-center text-sm
|
|
217
|
+
<div className="text-muted-foreground p-4 text-center text-sm">{t(`notification.empty`)}</div>
|
|
218
218
|
)}
|
|
219
219
|
</ScrollArea>
|
|
220
220
|
</Card>
|
|
@@ -93,7 +93,7 @@ export function OAuthClientCard({ client, onClick, onEdit, onDelete }: OAuthClie
|
|
|
93
93
|
</CardHeader>
|
|
94
94
|
<CardContent>
|
|
95
95
|
<div className="flex flex-wrap gap-x-4 gap-y-1 text-sm text-muted-foreground">
|
|
96
|
-
<span className="
|
|
96
|
+
<span className="tabular-nums">{truncatedId}</span>
|
|
97
97
|
<span>Created {createdAgo}</span>
|
|
98
98
|
<span>{client.isConfidential ? "Confidential" : "Public"}</span>
|
|
99
99
|
</div>
|
|
@@ -94,7 +94,7 @@ export function OAuthClientDetail({
|
|
|
94
94
|
<CardHeader>
|
|
95
95
|
<div className="flex items-start justify-between">
|
|
96
96
|
<div>
|
|
97
|
-
<CardTitle
|
|
97
|
+
<CardTitle>{client.name}</CardTitle>
|
|
98
98
|
{client.description && <CardDescription className="mt-1">{client.description}</CardDescription>}
|
|
99
99
|
</div>
|
|
100
100
|
<div className="flex items-center gap-2">
|
|
@@ -110,18 +110,14 @@ export function OAuthClientDetail({
|
|
|
110
110
|
<div className="space-y-2">
|
|
111
111
|
<Label>Client ID</Label>
|
|
112
112
|
<div className="flex gap-2">
|
|
113
|
-
<Input value={client.clientId} readOnly className="
|
|
113
|
+
<Input value={client.clientId} readOnly className="tabular-nums" />
|
|
114
114
|
<Button
|
|
115
115
|
variant="outline"
|
|
116
116
|
size="icon"
|
|
117
117
|
onClick={() => copyToClipboard(client.clientId, "clientId")}
|
|
118
118
|
title="Copy Client ID"
|
|
119
119
|
>
|
|
120
|
-
{copiedField === "clientId" ?
|
|
121
|
-
<Check className="h-4 w-4 text-green-600" />
|
|
122
|
-
) : (
|
|
123
|
-
<Copy className="h-4 w-4" />
|
|
124
|
-
)}
|
|
120
|
+
{copiedField === "clientId" ? <Check className="text-success h-4 w-4" /> : <Copy className="h-4 w-4" />}
|
|
125
121
|
</Button>
|
|
126
122
|
</div>
|
|
127
123
|
</div>
|
|
@@ -130,7 +126,7 @@ export function OAuthClientDetail({
|
|
|
130
126
|
<div className="space-y-2">
|
|
131
127
|
<Label>Client Secret</Label>
|
|
132
128
|
<div className="flex gap-2">
|
|
133
|
-
<Input value="••••••••••••••••••••••••••••••••" readOnly className="
|
|
129
|
+
<Input value="••••••••••••••••••••••••••••••••" readOnly className="tabular-nums" />
|
|
134
130
|
{onRegenerateSecret && (
|
|
135
131
|
<Button
|
|
136
132
|
variant="outline"
|
|
@@ -155,7 +151,7 @@ export function OAuthClientDetail({
|
|
|
155
151
|
<Label>Redirect URIs</Label>
|
|
156
152
|
<ul className="space-y-1">
|
|
157
153
|
{client.redirectUris.map((uri, index) => (
|
|
158
|
-
<li key={index} className="flex items-center gap-2 text-sm
|
|
154
|
+
<li key={index} className="flex items-center gap-2 text-sm tabular-nums">
|
|
159
155
|
<ExternalLink className="h-3 w-3 text-muted-foreground" />
|
|
160
156
|
{uri}
|
|
161
157
|
</li>
|
|
@@ -121,7 +121,7 @@ export function OAuthClientForm({ client, onSubmit, onCancel, isLoading = false
|
|
|
121
121
|
disabled={isLoading}
|
|
122
122
|
className={errors.name ? "border-destructive" : ""}
|
|
123
123
|
/>
|
|
124
|
-
{errors.name && <p className="text-
|
|
124
|
+
{errors.name && <p className="text-destructive text-xs/relaxed">{errors.name}</p>}
|
|
125
125
|
</div>
|
|
126
126
|
|
|
127
127
|
{/* Description */}
|
|
@@ -164,7 +164,7 @@ export function OAuthClientForm({ client, onSubmit, onCancel, isLoading = false
|
|
|
164
164
|
<div className="flex items-start space-x-3 p-3 rounded-md border">
|
|
165
165
|
<RadioGroupItem value="confidential" id="confidential" className="mt-1" />
|
|
166
166
|
<div>
|
|
167
|
-
<Label htmlFor="confidential" className="
|
|
167
|
+
<Label htmlFor="confidential" className="cursor-pointer">
|
|
168
168
|
Confidential
|
|
169
169
|
</Label>
|
|
170
170
|
<p className="text-sm text-muted-foreground">
|
|
@@ -175,7 +175,7 @@ export function OAuthClientForm({ client, onSubmit, onCancel, isLoading = false
|
|
|
175
175
|
<div className="flex items-start space-x-3 p-3 rounded-md border">
|
|
176
176
|
<RadioGroupItem value="public" id="public" className="mt-1" />
|
|
177
177
|
<div>
|
|
178
|
-
<Label htmlFor="public" className="
|
|
178
|
+
<Label htmlFor="public" className="cursor-pointer">
|
|
179
179
|
Public
|
|
180
180
|
</Label>
|
|
181
181
|
<p className="text-sm text-muted-foreground">
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
import { Plus, Key } from "lucide-react";
|
|
4
4
|
import { Button, Skeleton } from "../../../shadcnui";
|
|
5
|
+
import { SectionHeader } from "../../../components/typography";
|
|
5
6
|
import { OAuthClientCard } from "./OAuthClientCard";
|
|
6
7
|
import { OAuthClientInterface } from "../interfaces/oauth.interface";
|
|
7
8
|
|
|
@@ -45,7 +46,7 @@ export function OAuthClientList({
|
|
|
45
46
|
return (
|
|
46
47
|
<div className="space-y-4">
|
|
47
48
|
<div className="flex items-center justify-between">
|
|
48
|
-
<
|
|
49
|
+
<SectionHeader level={2}>{title}</SectionHeader>
|
|
49
50
|
<Skeleton className="h-10 w-32" />
|
|
50
51
|
</div>
|
|
51
52
|
<div className="space-y-3">
|
|
@@ -62,7 +63,7 @@ export function OAuthClientList({
|
|
|
62
63
|
return (
|
|
63
64
|
<div className="space-y-4">
|
|
64
65
|
<div className="flex items-center justify-between">
|
|
65
|
-
<
|
|
66
|
+
<SectionHeader level={2}>{title}</SectionHeader>
|
|
66
67
|
</div>
|
|
67
68
|
<div className="rounded-lg border border-destructive/50 bg-destructive/10 p-6 text-center">
|
|
68
69
|
<p className="text-destructive">{error.message}</p>
|
|
@@ -76,7 +77,7 @@ export function OAuthClientList({
|
|
|
76
77
|
return (
|
|
77
78
|
<div className="space-y-4">
|
|
78
79
|
<div className="flex items-center justify-between">
|
|
79
|
-
<
|
|
80
|
+
<SectionHeader level={2}>{title}</SectionHeader>
|
|
80
81
|
{onCreateClick && (
|
|
81
82
|
<Button onClick={onCreateClick}>
|
|
82
83
|
<Plus className="h-4 w-4 mr-2" />
|
|
@@ -103,7 +104,7 @@ export function OAuthClientList({
|
|
|
103
104
|
return (
|
|
104
105
|
<div className="space-y-4">
|
|
105
106
|
<div className="flex items-center justify-between">
|
|
106
|
-
<
|
|
107
|
+
<SectionHeader level={2}>{title}</SectionHeader>
|
|
107
108
|
{onCreateClick && (
|
|
108
109
|
<Button onClick={onCreateClick}>
|
|
109
110
|
<Plus className="h-4 w-4 mr-2" />
|
|
@@ -85,7 +85,7 @@ export function OAuthClientSecretDisplay({ secret, onDismiss, open, clientName }
|
|
|
85
85
|
|
|
86
86
|
<div className="flex items-center space-x-2">
|
|
87
87
|
<div className="flex-1">
|
|
88
|
-
<Input value={secret} readOnly className="
|
|
88
|
+
<Input value={secret} readOnly className="tabular-nums text-sm" onClick={(e) => e.currentTarget.select()} />
|
|
89
89
|
</div>
|
|
90
90
|
<Button
|
|
91
91
|
type="button"
|
|
@@ -94,11 +94,11 @@ export function OAuthClientSecretDisplay({ secret, onDismiss, open, clientName }
|
|
|
94
94
|
onClick={handleCopy}
|
|
95
95
|
title={copied ? "Copied!" : "Copy to clipboard"}
|
|
96
96
|
>
|
|
97
|
-
{copied ? <Check className="h-4 w-4
|
|
97
|
+
{copied ? <Check className="text-success h-4 w-4" /> : <Copy className="h-4 w-4" />}
|
|
98
98
|
</Button>
|
|
99
99
|
</div>
|
|
100
100
|
|
|
101
|
-
{copied && <p className="text-
|
|
101
|
+
{copied && <p className="text-success text-center text-sm">Copied to clipboard!</p>}
|
|
102
102
|
|
|
103
103
|
<DialogFooter className="mt-4">
|
|
104
104
|
<Button onClick={handleDismiss} className="w-full">
|