diff --git a/config/subscriptions.php b/config/subscriptions.php index 38cec59e..79ab8593 100644 --- a/config/subscriptions.php +++ b/config/subscriptions.php @@ -47,7 +47,7 @@ return [ 'plans' => [ 'monthly' => [ - 'name' => 'Pro Monthly', + 'name' => 'Standard Monthly', 'price' => 7.80, 'original_price' => null, 'stripe_lookup_key' => env('STRIPE_PRO_MONTHLY_LOOKUP_KEY', 'whisper_pro_monthly'), @@ -63,7 +63,7 @@ return [ ], ], 'yearly' => [ - 'name' => 'Pro Yearly', + 'name' => 'Standard Yearly', 'price' => 46.80, 'original_price' => 93.60, 'stripe_lookup_key' => env('STRIPE_PRO_YEARLY_LOOKUP_KEY', 'whisper_pro_yearly'), @@ -106,7 +106,7 @@ return [ | */ - 'default_plan' => 'monthly', + 'default_plan' => 'yearly', /* |-------------------------------------------------------------------------- diff --git a/lang/es.json b/lang/es.json index 3f73fbf0..26a7ebff 100644 --- a/lang/es.json +++ b/lang/es.json @@ -272,11 +272,13 @@ "Connect your Binance account using your API Key and Secret.": "Conecta tu cuenta de Binance usando tu Clave API y Secreto.", "Connect your Bitpanda account using your API Key.": "Conecta tu cuenta de Bitpanda usando tu Clave API.", "Connect your Indexa Capital account using your API token.": "Conecta tu cuenta de Indexa Capital usando tu token API.", + "Connect bank accounts": "Conectar cuentas bancarias", "Connect your bank and sync transactions automatically.": "Conecta tu banco y sincroniza las transacciones automáticamente.", "Connected": "Conectado", "Connected account": "Cuenta conectada", "Connected Bank Accounts": "Cuentas Bancarias Conectadas", "Connected accounts are a Standard Plan feature. You'll choose a plan at the end of the onboarding.": "Las cuentas conectadas son una función del plan Standard. Elegirás un plan al final del proceso de incorporación.", + "Connected banks": "Bancos conectados", "Connecting...": "Conectando...", "Connecting the dots in your finances...": "Conectando los puntos de tus finanzas...", "Connections": "Conexiones", @@ -477,12 +479,15 @@ "Forgot password": "Olvidé mi contraseña", "Forgot password?": "¿Olvidaste tu contraseña?", "Frequently Asked Questions": "Preguntas Frecuentes", + "Free": "Gratis", "From": "Desde", "Full name": "Nombre completo", "Fully transparent and open source. Review the code yourself.": "Totalmente transparente y de código abierto. Revisa el código tú mismo.", "Gain/loss": "Ganancia/pérdida", "Get Started": "Comenzar", + "Get Started Free": "Empieza Gratis", "Get Started for Free": "Empieza Gratis", + "Get started at no cost. No bank connections included.": "Empieza sin coste. Sin conexiones bancarias incluidas.", "Get notified when you're close to your limit. Never overspend again.": "Recibe notificaciones cuando estés cerca de tu límite. Nunca vuelvas a gastar de más.", "Get help when you need it with priority email support.": "Obtén ayuda cuando la necesites con soporte prioritario por correo electrónico.", "Get a clear picture of where your money goes every month.": "Obtén una imagen clara de a dónde va tu dinero cada mes.", @@ -964,6 +969,7 @@ "Switch to monthly view": "Cambiar a vista mensual", "Sync Now": "Sincronizar Ahora", "Sync now": "Sincronizar ahora", + "Sync transactions and balances automatically. Forget about manually importing CSVs from your bank.": "Sincroniza transacciones y saldos automáticamente. Olvídate de importar CSVs manualmente desde tu banco.", "Sync your encrypted financial data across multiple devices via cloud storage": "Sincroniza tus datos financieros encriptados en múltiples dispositivos a través de almacenamiento en la nube", "Sync your encrypted financial data across\\n multiple devices via cloud storage": "Sincroniza tus datos financieros cifrados en varios dispositivos a través del almacenamiento en la nube", "Syncing": "Sincronizando", @@ -1345,6 +1351,7 @@ "finance app, budgeting, expense tracking, secure finance, personal finance, money management, privacy, privacy-first finance app": "aplicación financiera, presupuesto, seguimiento de gastos, finanzas seguras, finanzas personales, gestión del dinero, privacidad, aplicación financiera centrada en la privacidad", "for the last 12 months": "en los últimos 12 meses", "for the last 30 days": "en los últimos 30 días", + "forever": "siempre", "fuchsia": "fucsia", "gray": "gris", "green": "verde", diff --git a/resources/js/pages/subscription/paywall.tsx b/resources/js/pages/subscription/paywall.tsx index 854ca480..3f75fbe9 100644 --- a/resources/js/pages/subscription/paywall.tsx +++ b/resources/js/pages/subscription/paywall.tsx @@ -13,6 +13,7 @@ import { Head, router, usePage } from '@inertiajs/react'; import { CheckIcon, FolderIcon, + LandmarkIcon, LockIcon, PiggyBankIcon, ReceiptIcon, @@ -43,10 +44,6 @@ function getEquivalentBillingLabel( return t('one-time'); } - if (billingPeriod === 'year') { - return t('/month'); - } - return t('/month'); } @@ -232,6 +229,42 @@ function FinancialSnapshot({ stats }: { stats: PaywallStats }) { ); } +function FeaturesSection({ features }: { features: string[] }) { + return ( +
+
+
+ +
+
+

+ {__('Connected banks')} +

+

+ {__( + 'Sync transactions and balances automatically. Forget about manually importing CSVs from your bank.', + )} +

+
+ +
+ + {features.length > 0 && ( + + )} +
+ ); +} + function CompactPlanCard({ plan, isSelected, @@ -298,18 +331,34 @@ function PricingSection({ planEntries, defaultPlan, currency, + canUseFreePlan, }: { planEntries: [string, Plan][]; defaultPlan: string; currency: string; + canUseFreePlan: boolean; }) { const [selectedPlan, setSelectedPlan] = useState(defaultPlan); + const [freeButtonVisible, setFreeButtonVisible] = useState(false); + const selectedPlanData = planEntries.find( ([key]) => key === selectedPlan, )?.[1]; + useEffect(() => { + if (!canUseFreePlan) { + return; + } + const timer = setTimeout(() => setFreeButtonVisible(true), 5000); + return () => clearTimeout(timer); + }, [canUseFreePlan]); + return (
+ {selectedPlanData && ( + + )} +
{planEntries.map(([key, plan]) => ( - {selectedPlanData && ( -
    - {selectedPlanData.features.slice(0, 4).map((feature) => ( -
  • - - - {__(feature)} - -
  • - ))} -
+ {canUseFreePlan && ( +
+ +
)}
); @@ -370,18 +425,8 @@ export default function Paywall() { planEntries={planEntries} defaultPlan={pricing.defaultPlan} currency={pricing.currency} + canUseFreePlan={canUseFreePlan} /> - - {canUseFreePlan && ( -
- -
- )}
diff --git a/resources/js/pages/welcome.tsx b/resources/js/pages/welcome.tsx index ea1719f7..328ebc5e 100644 --- a/resources/js/pages/welcome.tsx +++ b/resources/js/pages/welcome.tsx @@ -43,7 +43,7 @@ function getBillingLabel(billingPeriod: string | null): string { if (!billingPeriod) { return 'one-time'; } - return `/${billingPeriod}`; + return '/month'; } function FeatureScreenshot({ @@ -99,6 +99,51 @@ function FeatureCard({ ); } +function FreePlanCard({ planFeatures }: { planFeatures: string[] }) { + return ( +
+
+

{__('Free')}

+ +
+ + {__('Free')} + + + {__('forever')} + +
+ +

+ {__( + 'Get started at no cost. No bank connections included.', + )} +

+ +
+ +
    + {planFeatures.map((feature) => ( +
  • + + {__(feature)} +
  • + ))} +
+ + + + +
+
+ ); +} + function LandingPlanCard({ plan, isDefault, @@ -114,6 +159,10 @@ function LandingPlanCard({ currency: string; locale: string; }) { + const { features } = usePage().props; + const monthlyEquivalent = + plan.billing_period === 'year' ? plan.price / 12 : plan.price; + return (
)} -
+

{__(plan.name)}

{plan.original_price && ( {formatCurrency( - plan.original_price * 100, + (plan.billing_period === 'year' + ? plan.original_price / 12 + : plan.original_price) * 100, currency, locale, )} )} - {formatCurrency(plan.price * 100, currency, locale)} + {formatCurrency( + monthlyEquivalent * 100, + currency, + locale, + )} {getBillingLabel(plan.billing_period)}
+ {plan.billing_period === 'year' && ( +

+ {__('Billed annually at')}{' '} + {formatCurrency(plan.price * 100, currency, locale)} +

+ )} +

{__( 'Everything you need to manage your finances securely.', @@ -165,7 +232,10 @@ function LandingPlanCard({

    - {plan.features.map((feature) => ( + {(features['open-banking'] + ? [__('Connect bank accounts'), ...plan.features] + : plan.features + ).map((feature) => (
  • {__(feature)} @@ -284,7 +354,7 @@ export default function Welcome({ canRegister?: boolean; hideAuthButtons?: boolean; }) { - const { appUrl, subscriptionsEnabled, pricing, locale } = + const { appUrl, subscriptionsEnabled, pricing, locale, features } = usePage().props; const planEntries = Object.entries(pricing.plans); const { isMobile } = usePwaInstall(); @@ -900,14 +970,34 @@ export default function Welcome({
    = 3 && + planEntries.length + + (features['open-banking'] + ? 1 + : 0) >= + 3 && 'grid-cols-1 sm:grid-cols-2 lg:grid-cols-3', )} > + {features['open-banking'] && ( + + f !== + 'Priority support', + )} + /> + )} {planEntries.map(([key, plan]) => (