From f71eef0ebae26deb6d80bad70fc555b1915c1606 Mon Sep 17 00:00:00 2001 From: "Logan.Li" Date: Mon, 14 Sep 2026 22:08:44 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E4=B8=93=E4=B8=9A=E7=89=88=E5=8D=95?= =?UTF-8?q?=E8=AE=BE=E5=A4=87=E6=97=B6=E9=9A=90=E8=97=8F=E5=B8=AD=E4=BD=8D?= =?UTF-8?q?=E6=96=87=E6=A1=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/pro/UpgradeView.tsx | 124 +++++++++++------------------ 1 file changed, 46 insertions(+), 78 deletions(-) diff --git a/src/components/pro/UpgradeView.tsx b/src/components/pro/UpgradeView.tsx index 5ece996..4cb7781 100644 --- a/src/components/pro/UpgradeView.tsx +++ b/src/components/pro/UpgradeView.tsx @@ -4,18 +4,8 @@ import { useCallback, useEffect, useState } from 'react' import { useTranslation } from 'react-i18next' -import { - Check, - Crown, - ExternalLink, - Loader2, - Shield, -} from 'lucide-react' -import { - proFeatureLabel, - useEntitlementStore, - type ProFeature, -} from '../../stores/entitlementStore' +import { Check, Crown, ExternalLink, Loader2, Shield } from 'lucide-react' +import { proFeatureLabel, useEntitlementStore, type ProFeature } from '../../stores/entitlementStore' import { checkout as licenseCheckout } from '../../platform/licenseApi' import { createLogger } from '../../utils/logger' @@ -38,10 +28,7 @@ function looksLikeValidLicenseKey(value: string): boolean { return trimmed.startsWith('LIC-') || trimmed.startsWith('LICOFF-') || trimmed.length >= 8 } -function activatedLabel( - t: (key: string) => string, - planType: string | null -): string { +function activatedLabel(t: (key: string) => string, planType: string | null): string { switch (planType) { case 'yearly': return t('pro.activatedYearly') @@ -97,38 +84,39 @@ export default function UpgradeView({ feature, comingSoon }: UpgradeViewProps) { const highlight = feature ? proFeatureLabel(feature) : null - const startCheckout = useCallback(async (planChoice: 'yearly' | 'perpetual') => { - setSelectedPlan(planChoice) - setCheckoutLoading(true) - setCheckoutError(null) - const trimmedEmail = emailInput.trim() - if (!trimmedEmail || !trimmedEmail.includes('@')) { - setCheckoutError(t('pro.emailRequired')) - setCheckoutLoading(false) - return - } - try { - await setEmail(trimmedEmail) - const id = - deviceId || - (await window.opsxApi.licenseDeviceId().catch(() => '')) - const result = await licenseCheckout({ - customerEmail: trimmedEmail, - deviceId: id, - planType: planChoice, - }) - if (!result.checkoutUrl) { - throw new Error(t('pro.checkoutUnavailable', { status: 'no-url' })) + const startCheckout = useCallback( + async (planChoice: 'yearly' | 'perpetual') => { + setSelectedPlan(planChoice) + setCheckoutLoading(true) + setCheckoutError(null) + const trimmedEmail = emailInput.trim() + if (!trimmedEmail || !trimmedEmail.includes('@')) { + setCheckoutError(t('pro.emailRequired')) + setCheckoutLoading(false) + return } - await window.opsxApi.openExternal(result.checkoutUrl) - } catch (error) { - const message = error instanceof Error ? error.message : String(error) - logger.warn('checkout failed', message) - setCheckoutError(message) - } finally { - setCheckoutLoading(false) - } - }, [deviceId, emailInput, setEmail, t]) + try { + await setEmail(trimmedEmail) + const id = deviceId || (await window.opsxApi.licenseDeviceId().catch(() => '')) + const result = await licenseCheckout({ + customerEmail: trimmedEmail, + deviceId: id, + planType: planChoice, + }) + if (!result.checkoutUrl) { + throw new Error(t('pro.checkoutUnavailable', { status: 'no-url' })) + } + await window.opsxApi.openExternal(result.checkoutUrl) + } catch (error) { + const message = error instanceof Error ? error.message : String(error) + logger.warn('checkout failed', message) + setCheckoutError(message) + } finally { + setCheckoutLoading(false) + } + }, + [deviceId, emailInput, setEmail, t] + ) const handleActivate = useCallback(async () => { setActivateError(null) @@ -162,14 +150,12 @@ export default function UpgradeView({ feature, comingSoon }: UpgradeViewProps) { return (
-
+
-

- {t('pro.title')} -

+

{t('pro.title')}

{comingSoon && highlight ? t('pro.subtitleComingSoon', { feature: highlight }) @@ -189,7 +175,7 @@ export default function UpgradeView({ feature, comingSoon }: UpgradeViewProps) { ? t('pro.expiresAt', { date: new Date(expiresAt * 1000).toLocaleDateString() }) : t('pro.lifetime') : null} - {plan === 'pro' && maxDevices + {plan === 'pro' && maxDevices && maxDevices > 1 ? ` · ${t('pro.devices', { count: maxDevices })}` : null}

@@ -213,23 +199,15 @@ export default function UpgradeView({ feature, comingSoon }: UpgradeViewProps) { placeholder="you@example.com" className="w-full rounded-lg border border-dark-600 bg-dark-900 px-3 py-2 text-sm text-content-primary outline-none focus:border-accent-blue" /> - {checkoutError && ( -

{checkoutError}

- )} + {checkoutError &&

{checkoutError}

}
)}
{/* Free */}
- @@ -248,14 +226,8 @@ export default function UpgradeView({ feature, comingSoon }: UpgradeViewProps) { {/* Yearly */}
- @@ -292,11 +264,7 @@ export default function UpgradeView({ feature, comingSoon }: UpgradeViewProps) { {/* Perpetual */}
- {showActivate && ( -
+
@@ -384,7 +352,7 @@ export default function UpgradeView({ feature, comingSoon }: UpgradeViewProps) { )} -