fix: 暗色主题二轮修复 - 支付页面、订单状态、Stripe弹窗、Fallback组件

- PaymentForm: 快速金额选中暗色态、禁用按钮暗色态
- PaymentQRCode: Stripe错误框、成功图标、取消按钮暗色适配
- MobileOrderList: 底部文字对比度修复(slate-600→slate-400)
- OrderStatus: getStatusConfig增加isDark参数,所有状态色适配暗色
- result/page: getStatusConfig传isDark、链接按钮暗色、Fallback暗色背景
- stripe-popup/page: 金额/成功图标/链接/禁用按钮/Fallback暗色适配
- pay/page: 帮助图片容器、错误提示、Fallback暗色背景
- orders/page: 错误提示、Fallback暗色背景
- README: 补充lang参数说明
This commit is contained in:
erio
2026-03-14 03:27:24 +08:00
parent 3b5a3ba5df
commit 48e94c205a
9 changed files with 85 additions and 70 deletions

View File

@@ -177,7 +177,7 @@ function OrdersContent() {
<div className={`flex min-h-screen items-center justify-center p-4 ${isDark ? 'bg-slate-950' : 'bg-slate-50'}`}>
<div className="text-center text-red-500">
<p className="text-lg font-medium">{text.missingAuth}</p>
<p className="mt-2 text-sm text-gray-500">{text.visitOrders}</p>
<p className={`mt-2 text-sm ${isDark ? 'text-slate-400' : 'text-gray-500'}`}>{text.visitOrders}</p>
</div>
</div>
);
@@ -238,10 +238,11 @@ function OrdersContent() {
function OrdersPageFallback() {
const searchParams = useSearchParams();
const locale = resolveLocale(searchParams.get('lang'));
const isDark = searchParams.get('theme') === 'dark';
return (
<div className="flex min-h-screen items-center justify-center">
<div className="text-gray-500">{pickLocaleText(locale, '加载中...', 'Loading...')}</div>
<div className={`flex min-h-screen items-center justify-center ${isDark ? 'bg-slate-950' : 'bg-slate-50'}`}>
<div className={isDark ? 'text-slate-400' : 'text-gray-500'}>{pickLocaleText(locale, '加载中...', 'Loading...')}</div>
</div>
);
}

View File

@@ -110,7 +110,7 @@ function PayContent() {
{pickLocaleText(locale, '帮助', 'Support')}
</div>
{helpImageUrl && (
<img src={helpImageUrl} alt="help" onClick={() => setHelpImageOpen(true)} className="mt-3 max-h-40 w-full cursor-zoom-in rounded-lg object-contain bg-white/70 p-2" />
<img src={helpImageUrl} alt="help" onClick={() => setHelpImageOpen(true)} className={`mt-3 max-h-40 w-full cursor-zoom-in rounded-lg object-contain p-2 ${isDark ? 'bg-slate-700/50' : 'bg-white/70'}`} />
)}
{helpText && (
<div className={['mt-3 space-y-1 text-sm leading-6', isDark ? 'text-slate-300' : 'text-slate-600'].join(' ')}>
@@ -301,7 +301,7 @@ function PayContent() {
<div className={`flex min-h-screen items-center justify-center p-4 ${isDark ? 'bg-slate-950' : 'bg-slate-50'}`}>
<div className="text-center text-red-500">
<p className="text-lg font-medium">{pickLocaleText(locale, '缺少认证信息', 'Missing authentication info')}</p>
<p className="mt-2 text-sm text-gray-500">
<p className={`mt-2 text-sm ${isDark ? 'text-slate-400' : 'text-gray-500'}`}>
{pickLocaleText(locale, '请从 Sub2API 平台正确访问充值页面', 'Please open the recharge page from the Sub2API platform')}
</p>
</div>
@@ -314,7 +314,7 @@ function PayContent() {
<div className={`flex min-h-screen items-center justify-center p-4 ${isDark ? 'bg-slate-950' : 'bg-slate-50'}`}>
<div className="text-center text-red-500">
<p className="text-lg font-medium">{pickLocaleText(locale, '用户不存在', 'User not found')}</p>
<p className="mt-2 text-sm text-gray-500">
<p className={`mt-2 text-sm ${isDark ? 'text-slate-400' : 'text-gray-500'}`}>
{pickLocaleText(locale, '请检查链接是否正确,或联系管理员', 'Please check whether the link is correct or contact the administrator')}
</p>
</div>
@@ -852,7 +852,7 @@ function PayContent() {
{pickLocaleText(locale, '帮助', 'Support')}
</div>
{helpImageUrl && (
<img src={helpImageUrl} alt="help" onClick={() => setHelpImageOpen(true)} className="mt-3 max-h-40 w-full cursor-zoom-in rounded-lg object-contain bg-white/70 p-2" />
<img src={helpImageUrl} alt="help" onClick={() => setHelpImageOpen(true)} className={`mt-3 max-h-40 w-full cursor-zoom-in rounded-lg object-contain p-2 ${isDark ? 'bg-slate-700/50' : 'bg-white/70'}`} />
)}
{helpText && (
<div className={['mt-3 space-y-1 text-sm leading-6', isDark ? 'text-slate-300' : 'text-slate-600'].join(' ')}>
@@ -935,9 +935,10 @@ function PayContent() {
function PayPageFallback() {
const searchParams = useSearchParams();
const locale = resolveLocale(searchParams.get('lang'));
const isDark = searchParams.get('theme') === 'dark';
return (
<div className="flex min-h-screen items-center justify-center">
<div className="text-gray-500">{pickLocaleText(locale, '加载中...', 'Loading...')}</div>
<div className={`flex min-h-screen items-center justify-center ${isDark ? 'bg-slate-950' : 'bg-slate-50'}`}>
<div className={isDark ? 'text-slate-400' : 'text-gray-500'}>{pickLocaleText(locale, '加载中...', 'Loading...')}</div>
</div>
);
}

View File

@@ -54,12 +54,12 @@ function closeCurrentWindow() {
}, 250);
}
function getStatusConfig(order: PublicOrderStatusSnapshot | null, locale: Locale, hasAccessToken: boolean) {
function getStatusConfig(order: PublicOrderStatusSnapshot | null, locale: Locale, hasAccessToken: boolean, isDark = false) {
if (!order) {
return locale === 'en'
? {
label: 'Payment Error',
color: 'text-red-600',
color: isDark ? 'text-red-400' : 'text-red-600',
icon: '✗',
message: hasAccessToken
? 'Unable to load the order status. Please try again later.'
@@ -67,7 +67,7 @@ function getStatusConfig(order: PublicOrderStatusSnapshot | null, locale: Locale
}
: {
label: '支付异常',
color: 'text-red-600',
color: isDark ? 'text-red-400' : 'text-red-600',
icon: '✗',
message: hasAccessToken ? '未查询到订单状态,请稍后重试。' : '订单访问凭证缺失,请返回原充值页查看订单结果。',
};
@@ -77,11 +77,11 @@ function getStatusConfig(order: PublicOrderStatusSnapshot | null, locale: Locale
return locale === 'en'
? {
label: 'Recharge Successful',
color: 'text-green-600',
color: isDark ? 'text-green-400' : 'text-green-600',
icon: '✓',
message: 'Your balance has been credited successfully.',
}
: { label: '充值成功', color: 'text-green-600', icon: '✓', message: '余额已成功到账!' };
: { label: '充值成功', color: isDark ? 'text-green-400' : 'text-green-600', icon: '✓', message: '余额已成功到账!' };
}
if (order.paymentSuccess) {
@@ -89,25 +89,25 @@ function getStatusConfig(order: PublicOrderStatusSnapshot | null, locale: Locale
return locale === 'en'
? {
label: 'Top-up Processing',
color: 'text-blue-600',
color: isDark ? 'text-blue-400' : 'text-blue-600',
icon: '⟳',
message: 'Payment succeeded, and the balance top-up is being processed.',
}
: { label: '充值处理中', color: 'text-blue-600', icon: '⟳', message: '支付成功,余额正在充值中...' };
: { label: '充值处理中', color: isDark ? 'text-blue-400' : 'text-blue-600', icon: '⟳', message: '支付成功,余额正在充值中...' };
}
if (order.rechargeStatus === 'failed') {
return locale === 'en'
? {
label: 'Payment Successful',
color: 'text-amber-600',
color: isDark ? 'text-amber-400' : 'text-amber-600',
icon: '!',
message:
'Payment succeeded, but the balance top-up has not completed yet. Please check again later or contact the administrator.',
}
: {
label: '支付成功',
color: 'text-amber-600',
color: isDark ? 'text-amber-400' : 'text-amber-600',
icon: '!',
message: '支付成功,但余额充值暂未完成,请稍后查看订单结果或联系管理员。',
};
@@ -116,30 +116,30 @@ function getStatusConfig(order: PublicOrderStatusSnapshot | null, locale: Locale
if (order.status === 'PENDING') {
return locale === 'en'
? { label: 'Awaiting Payment', color: 'text-yellow-600', icon: '⏳', message: 'The order has not been paid yet.' }
: { label: '等待支付', color: 'text-yellow-600', icon: '⏳', message: '订单尚未完成支付。' };
? { label: 'Awaiting Payment', color: isDark ? 'text-yellow-400' : 'text-yellow-600', icon: '⏳', message: 'The order has not been paid yet.' }
: { label: '等待支付', color: isDark ? 'text-yellow-400' : 'text-yellow-600', icon: '⏳', message: '订单尚未完成支付。' };
}
if (order.status === 'EXPIRED') {
return locale === 'en'
? {
label: 'Order Expired',
color: 'text-gray-500',
color: isDark ? 'text-slate-400' : 'text-gray-500',
icon: '⏰',
message: 'This order has expired. Please create a new order.',
}
: { label: '订单已超时', color: 'text-gray-500', icon: '⏰', message: '订单已超时,请重新充值。' };
: { label: '订单已超时', color: isDark ? 'text-slate-400' : 'text-gray-500', icon: '⏰', message: '订单已超时,请重新充值。' };
}
if (order.status === 'CANCELLED') {
return locale === 'en'
? { label: 'Order Cancelled', color: 'text-gray-500', icon: '✗', message: 'This order has been cancelled.' }
: { label: '订单已取消', color: 'text-gray-500', icon: '✗', message: '订单已被取消。' };
? { label: 'Order Cancelled', color: isDark ? 'text-slate-400' : 'text-gray-500', icon: '✗', message: 'This order has been cancelled.' }
: { label: '订单已取消', color: isDark ? 'text-slate-400' : 'text-gray-500', icon: '✗', message: '订单已被取消。' };
}
return locale === 'en'
? { label: 'Payment Error', color: 'text-red-600', icon: '✗', message: 'Please contact the administrator.' }
: { label: '支付异常', color: 'text-red-600', icon: '✗', message: '请联系管理员处理。' };
? { label: 'Payment Error', color: isDark ? 'text-red-400' : 'text-red-600', icon: '✗', message: 'Please contact the administrator.' }
: { label: '支付异常', color: isDark ? 'text-red-400' : 'text-red-600', icon: '✗', message: '请联系管理员处理。' };
}
function ResultContent() {
@@ -233,7 +233,7 @@ function ResultContent() {
);
}
const display = getStatusConfig(orderState, locale, Boolean(accessToken));
const display = getStatusConfig(orderState, locale, Boolean(accessToken), isDark);
return (
<div className={`flex min-h-screen items-center justify-center p-4 ${isDark ? 'bg-slate-950' : 'bg-slate-50'}`}>
@@ -254,14 +254,14 @@ function ResultContent() {
<button
type="button"
onClick={closeCurrentWindow}
className="text-sm text-blue-600 underline hover:text-blue-700"
className={`text-sm underline ${isDark ? 'text-blue-400 hover:text-blue-300' : 'text-blue-600 hover:text-blue-700'}`}
>
{text.closeNow}
</button>
</div>
)
) : (
<button type="button" onClick={goBack} className="mt-4 text-sm text-blue-600 underline hover:text-blue-700">
<button type="button" onClick={goBack} className={`mt-4 text-sm underline ${isDark ? 'text-blue-400 hover:text-blue-300' : 'text-blue-600 hover:text-blue-700'}`}>
{text.back}
</button>
)}
@@ -277,10 +277,11 @@ function ResultContent() {
function ResultPageFallback() {
const searchParams = useSearchParams();
const locale = resolveLocale(searchParams.get('lang'));
const isDark = searchParams.get('theme') === 'dark';
return (
<div className="flex min-h-screen items-center justify-center bg-slate-50">
<div className="text-gray-500">{pickLocaleText(locale, '加载中...', 'Loading...')}</div>
<div className={`flex min-h-screen items-center justify-center ${isDark ? 'bg-slate-950' : 'bg-slate-50'}`}>
<div className={isDark ? 'text-slate-400' : 'text-gray-500'}>{pickLocaleText(locale, '加载中...', 'Loading...')}</div>
</div>
);
}

View File

@@ -195,7 +195,7 @@ function StripePopupContent() {
className={`w-full max-w-md space-y-4 rounded-2xl border p-6 ${isDark ? 'border-slate-700 bg-slate-900' : 'border-slate-200 bg-white'} shadow-lg`}
>
<div className="text-center">
<div className="text-3xl font-bold text-blue-600">
<div className={`text-3xl font-bold ${isDark ? 'text-blue-400' : 'text-blue-600'}`}>
{'¥'}
{amount.toFixed(2)}
</div>
@@ -213,7 +213,7 @@ function StripePopupContent() {
<button
type="button"
onClick={() => window.close()}
className="w-full text-sm text-blue-600 underline hover:text-blue-700"
className={`w-full text-sm underline ${isDark ? 'text-blue-400 hover:text-blue-300' : 'text-blue-600 hover:text-blue-700'}`}
>
{text.closeWindow}
</button>
@@ -235,7 +235,7 @@ function StripePopupContent() {
className={`w-full max-w-md space-y-4 rounded-2xl border p-6 ${isDark ? 'border-slate-700 bg-slate-900' : 'border-slate-200 bg-white'} shadow-lg`}
>
<div className="text-center">
<div className="text-3xl font-bold text-blue-600">
<div className={`text-3xl font-bold ${isDark ? 'text-blue-400' : 'text-blue-600'}`}>
{'¥'}
{amount.toFixed(2)}
</div>
@@ -251,12 +251,12 @@ function StripePopupContent() {
</div>
) : stripeSuccess ? (
<div className="py-6 text-center">
<div className="text-5xl text-green-600">{'✓'}</div>
<div className={`text-5xl ${isDark ? 'text-green-400' : 'text-green-600'}`}>{'✓'}</div>
<p className={`mt-3 text-sm ${isDark ? 'text-slate-400' : 'text-gray-500'}`}>{text.successClosing}</p>
<button
type="button"
onClick={() => window.close()}
className="mt-4 text-sm text-blue-600 underline hover:text-blue-700"
className={`mt-4 text-sm underline ${isDark ? 'text-blue-400 hover:text-blue-300' : 'text-blue-600 hover:text-blue-700'}`}
>
{text.closeWindowManually}
</button>
@@ -280,7 +280,9 @@ function StripePopupContent() {
onClick={handleSubmit}
className={[
'w-full rounded-lg py-3 font-medium text-white shadow-md transition-colors',
stripeSubmitting ? 'bg-gray-400 cursor-not-allowed' : getPaymentMeta('stripe').buttonClass,
stripeSubmitting
? isDark ? 'bg-slate-700 text-slate-400 cursor-not-allowed' : 'bg-gray-400 cursor-not-allowed'
: getPaymentMeta('stripe').buttonClass,
].join(' ')}
>
{stripeSubmitting ? (
@@ -302,10 +304,11 @@ function StripePopupContent() {
function StripePopupFallback() {
const searchParams = useSearchParams();
const locale = resolveLocale(searchParams.get('lang'));
const isDark = searchParams.get('theme') === 'dark';
return (
<div className="flex min-h-screen items-center justify-center">
<div className="text-gray-500">{pickLocaleText(locale, '加载中...', 'Loading...')}</div>
<div className={`flex min-h-screen items-center justify-center ${isDark ? 'bg-slate-950' : 'bg-slate-50'}`}>
<div className={isDark ? 'text-slate-400' : 'text-gray-500'}>{pickLocaleText(locale, '加载中...', 'Loading...')}</div>
</div>
);
}