27b88426e2
* fix(entitlements): show paid features as gated upsells instead of dead ends Post-cutover, non-payers still saw fully interactive UI for paid features (bank picker, agent-build hero, SKV VAT submission) that silently failed or 403'd on the server gate. Every surface now stays visible as a conversion surface but is explicitly gated: - new shared components/billing/UpgradeNote (lock icon + billing link) - agent-build hero (dashboard + new-user checklist): routes to /settings/billing with upgrade copy when the ai capability is missing - bank connect: BankingSettingsPanel and the import-page PSD2 wizard swap the bank list for an upgrade note; the import selection card swaps the "Rekommenderat" chip for "Kräver abonnemang" - VAT report SkatteverketPanel: gated state renders before the connection check, so trial-connected companies see the upsell instead of action buttons that would 403; manual-filing framing kept - SkatteverketConnectPanel: skahmst consent note hidden while gated (irrelevant until the consent page is reachable) Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * test(ne-bilaga): fix time-of-day flake in SRU field-code assertion The bare substrings '7310'/'7350' also match the #SKAPAD HHMMSS timestamp when CI runs at 07:31/07:35, so the assertion now requires the full '#UPPGIFT <code>' prefix. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
29 lines
996 B
TypeScript
29 lines
996 B
TypeScript
import Link from 'next/link'
|
|
import { Lock } from 'lucide-react'
|
|
import { cn } from '@/lib/utils'
|
|
|
|
/**
|
|
* Inline paywall note for a feature that is visible but not entitled.
|
|
* The feature stays on screen (conversion surface: never hide, disable
|
|
* with an upsell), this note explains why it's disabled and links to
|
|
* /settings/billing. Copy mirrors CAPABILITY_BLOCKED_MESSAGE_SV.
|
|
*/
|
|
export function UpgradeNote({ children, className }: { children?: React.ReactNode; className?: string }) {
|
|
return (
|
|
<div
|
|
className={cn(
|
|
'flex items-start gap-2.5 rounded-lg border border-border bg-secondary/40 px-3 py-2.5 text-sm text-muted-foreground',
|
|
className,
|
|
)}
|
|
>
|
|
<Lock className="h-4 w-4 mt-0.5 shrink-0" />
|
|
<span>
|
|
{children ?? 'Den här funktionen kräver ett abonnemang.'}{' '}
|
|
<Link href="/settings/billing" className="underline underline-offset-2 text-foreground">
|
|
Uppgradera
|
|
</Link>
|
|
</span>
|
|
</div>
|
|
)
|
|
}
|