feat: Add QR code card component with download functionality and a new pricing page with internationalization.

This commit is contained in:
Timo 2026-01-07 19:59:04 +01:00
parent e7478a4af7
commit d04e7a1f70
4 changed files with 263 additions and 261 deletions

View File

@ -141,13 +141,13 @@ export default function PricingPage() {
'50 dynamic QR codes', '50 dynamic QR codes',
'Unlimited static QR codes', 'Unlimited static QR codes',
'Advanced analytics (scans, devices, locations)', 'Advanced analytics (scans, devices, locations)',
'Custom branding (colors)', 'Custom branding (colors & logos)',
], ],
buttonText: isCurrentPlanWithInterval('PRO', selectedInterval) buttonText: isCurrentPlanWithInterval('PRO', selectedInterval)
? 'Current Plan' ? 'Current Plan'
: hasPlanDifferentInterval('PRO') : hasPlanDifferentInterval('PRO')
? `Switch to ${billingPeriod === 'month' ? 'Monthly' : 'Yearly'}` ? `Switch to ${billingPeriod === 'month' ? 'Monthly' : 'Yearly'}`
: 'Upgrade to Pro', : 'Upgrade to Pro',
buttonVariant: 'primary' as const, buttonVariant: 'primary' as const,
disabled: isCurrentPlanWithInterval('PRO', selectedInterval), disabled: isCurrentPlanWithInterval('PRO', selectedInterval),
popular: true, popular: true,
@ -170,8 +170,8 @@ export default function PricingPage() {
buttonText: isCurrentPlanWithInterval('BUSINESS', selectedInterval) buttonText: isCurrentPlanWithInterval('BUSINESS', selectedInterval)
? 'Current Plan' ? 'Current Plan'
: hasPlanDifferentInterval('BUSINESS') : hasPlanDifferentInterval('BUSINESS')
? `Switch to ${billingPeriod === 'month' ? 'Monthly' : 'Yearly'}` ? `Switch to ${billingPeriod === 'month' ? 'Monthly' : 'Yearly'}`
: 'Upgrade to Business', : 'Upgrade to Business',
buttonVariant: 'primary' as const, buttonVariant: 'primary' as const,
disabled: isCurrentPlanWithInterval('BUSINESS', selectedInterval), disabled: isCurrentPlanWithInterval('BUSINESS', selectedInterval),
popular: false, popular: false,

View File

@ -69,17 +69,17 @@ export const Pricing: React.FC<PricingProps> = ({ t }) => {
{plan.key === 'free' {plan.key === 'free'
? t.pricing[plan.key].price ? t.pricing[plan.key].price
: billingPeriod === 'month' : billingPeriod === 'month'
? t.pricing[plan.key].price ? t.pricing[plan.key].price
: plan.key === 'pro' : plan.key === 'pro'
? '€90' ? '€90'
: '€290'} : '€290'}
</span> </span>
<span className="text-gray-600 ml-2"> <span className="text-gray-600 ml-2">
{plan.key === 'free' {plan.key === 'free'
? t.pricing[plan.key].period ? t.pricing[plan.key].period
: billingPeriod === 'month' : billingPeriod === 'month'
? t.pricing[plan.key].period ? t.pricing[plan.key].period
: 'per year'} : 'per year'}
</span> </span>
</div> </div>
{billingPeriod === 'year' && plan.key !== 'free' && ( {billingPeriod === 'year' && plan.key !== 'free' && (
@ -90,7 +90,7 @@ export const Pricing: React.FC<PricingProps> = ({ t }) => {
</div> </div>
</CardHeader> </CardHeader>
<CardContent className="space-y-4"> <CardContent className="space-y-8">
<ul className="space-y-3"> <ul className="space-y-3">
{t.pricing[plan.key].features.map((feature: string, index: number) => ( {t.pricing[plan.key].features.map((feature: string, index: number) => (
<li key={index} className="flex items-start space-x-3"> <li key={index} className="flex items-start space-x-3">
@ -102,15 +102,17 @@ export const Pricing: React.FC<PricingProps> = ({ t }) => {
))} ))}
</ul> </ul>
<Link href="/signup"> <div className="mt-8">
<Button <Link href="/signup">
variant={plan.popular ? 'primary' : 'outline'} <Button
className="w-full" variant={plan.popular ? 'primary' : 'outline'}
size="lg" className="w-full"
> size="lg"
Get Started >
</Button> Get Started
</Link> </Button>
</Link>
</div>
</CardContent> </CardContent>
</Card> </Card>
))} ))}

View File

@ -149,7 +149,7 @@
"50 dynamic QR codes", "50 dynamic QR codes",
"Unlimited static QR codes", "Unlimited static QR codes",
"Advanced analytics (scans, devices, locations)", "Advanced analytics (scans, devices, locations)",
"Custom branding (colors)" "Custom branding (colors & logos)"
] ]
}, },
"business": { "business": {