public: new page and copy improvements

This commit is contained in:
Carl-Gerhard Lindesvärd
2026-02-17 00:16:08 +01:00
parent 0ebe2768be
commit e3faab7588
22 changed files with 1026 additions and 352 deletions

View File

@@ -1,16 +1,14 @@
'use client';
import NumberFlow from '@number-flow/react';
import { PRICING } from '@openpanel/payments/prices';
import { CheckIcon, ServerIcon, StarIcon } from 'lucide-react';
import Link from 'next/link';
import { useState } from 'react';
import { GetStartedButton } from '@/components/get-started-button';
import { Section, SectionHeader } from '@/components/section';
import { Button } from '@/components/ui/button';
import { cn } from '@/lib/utils';
import NumberFlow from '@number-flow/react';
import { PRICING } from '@openpanel/payments/prices';
import { CheckIcon, StarIcon } from 'lucide-react';
import { useState } from 'react';
import { formatEventsCount } from '@/lib/utils';
import { cn, formatEventsCount } from '@/lib/utils';
const features = [
'Unlimited websites or apps',
@@ -28,51 +26,56 @@ export function Pricing() {
return (
<Section className="container">
<div className="col md:row gap-16">
<div className="w-full md:w-1/3 min-w-sm col gap-4 border rounded-3xl p-6 bg-linear-to-b from-card to-background">
<p className="text-sm text-muted-foreground">
<div className="col w-full min-w-sm gap-4 rounded-3xl border bg-linear-to-b from-card to-background p-6 md:w-1/3">
<p className="text-muted-foreground text-sm">
Choose how many events you'll track this month
</p>
<div className="row flex-wrap gap-2">
{PRICING.map((tier, index) => (
<Button
className={cn('relative h-8 rounded-full border px-4')}
key={tier.price}
variant={selectedIndex === index ? 'default' : 'outline'}
size="sm"
className={cn('h-8 rounded-full relative px-4 border')}
onClick={() => setSelectedIndex(index)}
size="sm"
variant={selectedIndex === index ? 'default' : 'outline'}
>
{tier.popular && <StarIcon className="size-4" />}
{formatEventsCount(tier.events)}
</Button>
))}
<Button
variant={selectedIndex === -1 ? 'default' : 'outline'}
size="sm"
className={cn('h-8 rounded-full relative px-4 border')}
className={cn('relative h-8 rounded-full border px-4')}
onClick={() => setSelectedIndex(-1)}
size="sm"
variant={selectedIndex === -1 ? 'default' : 'outline'}
>
Custom
</Button>
</div>
<div className="col items-baseline mt-8 md:mt-auto w-full">
<div className="col mt-8 w-full items-baseline md:mt-auto">
{selected ? (
<>
<NumberFlow
className="text-5xl font-bold"
value={selected.price}
format={{
style: 'currency',
currency: 'USD',
minimumFractionDigits: 0,
maximumFractionDigits: 1,
}}
locales={'en-US'}
/>
<div className="row justify-between w-full">
<span className="text-muted-foreground/80 text-sm -mt-2">
<div className="row items-end gap-3">
<NumberFlow
className="font-bold text-5xl"
format={{
style: 'currency',
currency: 'USD',
minimumFractionDigits: 0,
maximumFractionDigits: 1,
}}
locales={'en-US'}
value={selected.price}
/>
<span className="mb-2 rounded-full bg-primary/10 px-2.5 py-0.5 font-medium text-primary text-xs">
30-day free trial
</span>
</div>
<div className="row w-full justify-between">
<span className="-mt-2 text-muted-foreground/80 text-sm">
Per month
</span>
<span className="text-muted-foreground/80 text-sm -mt-2">
<span className="-mt-2 text-muted-foreground/80 text-sm">
+ VAT if applicable
</span>
</div>
@@ -89,18 +92,18 @@ export function Pricing() {
</div>
</div>
<div className="col gap-8 justify-center flex-1 shrink-0">
<div className="col flex-1 shrink-0 justify-center gap-8">
<div className="col gap-4">
<SectionHeader
title="Simple, transparent pricing"
description="Pay only for what you use. Choose your event volume - everything else is unlimited. No surprises, no hidden fees."
title="Simple, transparent pricing"
/>
</div>
<ul className="col gap-2">
{features.map((feature) => (
<li key={feature} className="row gap-2 items-start text-sm">
<CheckIcon className="size-4 shrink-0 mt-0.5" />
<li className="row items-start gap-2 text-sm" key={feature}>
<CheckIcon className="mt-0.5 size-4 shrink-0" />
<span>{feature}</span>
</li>
))}
@@ -108,9 +111,16 @@ export function Pricing() {
<GetStartedButton className="w-fit" />
<p className="text-sm text-muted-foreground">
All features are included upfront - no hidden costs. You choose how
many events to track each month.
<p className="row items-center gap-2 text-muted-foreground text-sm">
<ServerIcon className="size-4 shrink-0" />
Prefer to self-host?{' '}
<Link
className="text-primary hover:underline"
href="/docs/self-hosting/self-hosting"
>
Deploy for free
</Link>{' '}
with unlimited events.
</p>
</div>
</div>