From d419322ab71e39cf8de91b9e8d45d0c49e6966a7 Mon Sep 17 00:00:00 2001 From: Usman Baig Date: Thu, 26 Mar 2026 21:22:12 +0100 Subject: [PATCH] refactor: extract shared country list and plan prices --- components/PricingSection.tsx | 39 ++++------------------------------- lib/countries.ts | 35 +++++++++++++++++++++++++++++++ lib/plans.ts | 11 ++++++++++ 3 files changed, 50 insertions(+), 35 deletions(-) create mode 100644 lib/countries.ts diff --git a/components/PricingSection.tsx b/components/PricingSection.tsx index e7c4af4..656b036 100644 --- a/components/PricingSection.tsx +++ b/components/PricingSection.tsx @@ -8,6 +8,7 @@ import { Button, CheckCircleIcon } from '@ciphera-net/ui' import { useAuth } from '@/lib/auth/context' import { initiateOAuthFlow } from '@/lib/api/oauth' import { toast } from '@ciphera-net/ui' +import { COUNTRY_OPTIONS } from '@/lib/countries' import { createCheckoutSession } from '@/lib/api/billing' // 1. Define Plans with IDs and Site Limits @@ -102,40 +103,8 @@ const TRAFFIC_TIERS = [ }, ] -const COUNTRY_OPTIONS = [ - { code: 'BE', label: 'Belgium' }, - { code: 'NL', label: 'Netherlands' }, - { code: 'DE', label: 'Germany' }, - { code: 'FR', label: 'France' }, - { code: 'AT', label: 'Austria' }, - { code: 'IT', label: 'Italy' }, - { code: 'ES', label: 'Spain' }, - { code: 'PT', label: 'Portugal' }, - { code: 'IE', label: 'Ireland' }, - { code: 'LU', label: 'Luxembourg' }, - { code: 'FI', label: 'Finland' }, - { code: 'SE', label: 'Sweden' }, - { code: 'DK', label: 'Denmark' }, - { code: 'PL', label: 'Poland' }, - { code: 'CZ', label: 'Czech Republic' }, - { code: 'RO', label: 'Romania' }, - { code: 'BG', label: 'Bulgaria' }, - { code: 'HR', label: 'Croatia' }, - { code: 'SI', label: 'Slovenia' }, - { code: 'SK', label: 'Slovakia' }, - { code: 'HU', label: 'Hungary' }, - { code: 'LT', label: 'Lithuania' }, - { code: 'LV', label: 'Latvia' }, - { code: 'EE', label: 'Estonia' }, - { code: 'MT', label: 'Malta' }, - { code: 'CY', label: 'Cyprus' }, - { code: 'GR', label: 'Greece' }, - { code: 'US', label: 'United States' }, - { code: 'GB', label: 'United Kingdom' }, - { code: 'CH', label: 'Switzerland' }, - { code: 'NO', label: 'Norway' }, - { code: 'CA', label: 'Canada' }, - { code: 'AU', label: 'Australia' }, +const PRICING_COUNTRY_OPTIONS = [ + ...COUNTRY_OPTIONS.map((c) => ({ code: c.value, label: c.label })), { code: 'OTHER', label: 'Other' }, ] @@ -528,7 +497,7 @@ export default function PricingSection() { className="w-full rounded-lg border border-neutral-700 bg-neutral-800 px-3 py-2.5 text-sm text-white placeholder-neutral-500 focus:border-brand-orange focus:outline-none focus:ring-1 focus:ring-brand-orange transition-colors" > - {COUNTRY_OPTIONS.map((c) => ( + {PRICING_COUNTRY_OPTIONS.map((c) => ( ))} diff --git a/lib/countries.ts b/lib/countries.ts new file mode 100644 index 0000000..33959e1 --- /dev/null +++ b/lib/countries.ts @@ -0,0 +1,35 @@ +export const COUNTRY_OPTIONS = [ + { value: 'BE', label: 'Belgium' }, + { value: 'NL', label: 'Netherlands' }, + { value: 'DE', label: 'Germany' }, + { value: 'FR', label: 'France' }, + { value: 'AT', label: 'Austria' }, + { value: 'IT', label: 'Italy' }, + { value: 'ES', label: 'Spain' }, + { value: 'PT', label: 'Portugal' }, + { value: 'IE', label: 'Ireland' }, + { value: 'LU', label: 'Luxembourg' }, + { value: 'FI', label: 'Finland' }, + { value: 'SE', label: 'Sweden' }, + { value: 'DK', label: 'Denmark' }, + { value: 'PL', label: 'Poland' }, + { value: 'CZ', label: 'Czech Republic' }, + { value: 'RO', label: 'Romania' }, + { value: 'BG', label: 'Bulgaria' }, + { value: 'HR', label: 'Croatia' }, + { value: 'SI', label: 'Slovenia' }, + { value: 'SK', label: 'Slovakia' }, + { value: 'HU', label: 'Hungary' }, + { value: 'LT', label: 'Lithuania' }, + { value: 'LV', label: 'Latvia' }, + { value: 'EE', label: 'Estonia' }, + { value: 'MT', label: 'Malta' }, + { value: 'CY', label: 'Cyprus' }, + { value: 'GR', label: 'Greece' }, + { value: 'US', label: 'United States' }, + { value: 'GB', label: 'United Kingdom' }, + { value: 'CH', label: 'Switzerland' }, + { value: 'NO', label: 'Norway' }, + { value: 'CA', label: 'Canada' }, + { value: 'AU', label: 'Australia' }, +] as const diff --git a/lib/plans.ts b/lib/plans.ts index a2d2ce9..0707111 100644 --- a/lib/plans.ts +++ b/lib/plans.ts @@ -79,3 +79,14 @@ export function formatRetentionMonths(months: number): string { if (Number.isInteger(years)) return years === 1 ? '1 year' : `${years} years` return `${months} months` } + +/** + * Monthly prices in EUR cents per plan and traffic tier. + * IMPORTANT: Must stay in sync with backend GetSubscriptionAmount() in internal/billing/mollie.go + * Yearly = monthly * 11 (1 month free) + */ +export const PLAN_PRICES: Record> = { + solo: { 10000: 700, 50000: 1100, 100000: 1500, 250000: 2500, 500000: 3900, 1000000: 5500, 2500000: 7900, 5000000: 10300, 10000000: 13500 }, + team: { 10000: 1100, 50000: 1900, 100000: 2300, 250000: 3900, 500000: 5900, 1000000: 7900, 2500000: 11900, 5000000: 15500, 10000000: 19900 }, + business: { 10000: 1500, 50000: 2700, 100000: 3100, 250000: 5900, 500000: 7900, 1000000: 11100, 2500000: 16900, 5000000: 20700, 10000000: 26900 }, +}