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:
@@ -308,6 +308,7 @@ Sub2API **v0.1.88** 及以上版本会自动拼接以下参数,无需手动添
|
||||
| `user_id` | Sub2API 用户 ID |
|
||||
| `token` | 用户登录 Token(有 token 才能查看订单历史) |
|
||||
| `theme` | `light`(默认)或 `dark` |
|
||||
| `lang` | 界面语言,`zh`(默认)或 `en` |
|
||||
| `ui_mode` | `standalone`(默认)或 `embedded`(iframe 嵌入) |
|
||||
|
||||
---
|
||||
|
||||
@@ -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>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -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>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -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>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -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>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -134,7 +134,7 @@ export default function MobileOrderList({
|
||||
{locale === 'en' ? 'Loading...' : '加载中...'}
|
||||
</span>
|
||||
) : (
|
||||
<span className={['text-xs', isDark ? 'text-slate-600' : 'text-slate-300'].join(' ')}>
|
||||
<span className={['text-xs', isDark ? 'text-slate-400' : 'text-slate-400'].join(' ')}>
|
||||
{locale === 'en' ? 'Scroll up to load more' : '上滑加载更多'}
|
||||
</span>
|
||||
)}
|
||||
@@ -142,7 +142,7 @@ export default function MobileOrderList({
|
||||
)}
|
||||
|
||||
{!hasMore && orders.length > 0 && (
|
||||
<div className={['py-2 text-center text-xs', isDark ? 'text-slate-600' : 'text-slate-400'].join(' ')}>
|
||||
<div className={['py-2 text-center text-xs', isDark ? 'text-slate-400' : 'text-slate-400'].join(' ')}>
|
||||
{locale === 'en' ? 'All orders loaded' : '已显示全部订单'}
|
||||
</div>
|
||||
)}
|
||||
|
||||
@@ -15,16 +15,16 @@ interface OrderStatusProps {
|
||||
locale?: Locale;
|
||||
}
|
||||
|
||||
function getStatusConfig(order: PublicOrderStatusSnapshot, locale: Locale) {
|
||||
function getStatusConfig(order: PublicOrderStatusSnapshot, locale: Locale, isDark = false) {
|
||||
if (order.rechargeSuccess) {
|
||||
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. Thank you for your payment.',
|
||||
}
|
||||
: { label: '充值成功', color: 'text-green-600', icon: '✓', message: '余额已到账,感谢您的充值!' };
|
||||
: { label: '充值成功', color: isDark ? 'text-green-400' : 'text-green-600', icon: '✓', message: '余额已到账,感谢您的充值!' };
|
||||
}
|
||||
|
||||
if (order.paymentSuccess) {
|
||||
@@ -32,25 +32,25 @@ function getStatusConfig(order: PublicOrderStatusSnapshot, locale: Locale) {
|
||||
return locale === 'en'
|
||||
? {
|
||||
label: 'Recharging',
|
||||
color: 'text-blue-600',
|
||||
color: isDark ? 'text-blue-400' : 'text-blue-600',
|
||||
icon: '⟳',
|
||||
message: 'Payment received. Recharging your balance...',
|
||||
}
|
||||
: { 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 completed, but the balance top-up has not finished yet. The system may retry automatically. Please check the order list later or contact the administrator if it remains unresolved.',
|
||||
}
|
||||
: {
|
||||
label: '支付成功',
|
||||
color: 'text-amber-600',
|
||||
color: isDark ? 'text-amber-400' : 'text-amber-600',
|
||||
icon: '!',
|
||||
message:
|
||||
'支付已完成,但余额充值暂未完成。系统可能会自动重试,请稍后在订单列表查看;如长时间未到账请联系管理员。',
|
||||
@@ -62,14 +62,14 @@ function getStatusConfig(order: PublicOrderStatusSnapshot, locale: Locale) {
|
||||
return locale === 'en'
|
||||
? {
|
||||
label: 'Payment Failed',
|
||||
color: 'text-red-600',
|
||||
color: isDark ? 'text-red-400' : 'text-red-600',
|
||||
icon: '✗',
|
||||
message:
|
||||
'Payment was not completed. Please try again. If funds were deducted but not credited, contact the administrator.',
|
||||
}
|
||||
: {
|
||||
label: '支付失败',
|
||||
color: 'text-red-600',
|
||||
color: isDark ? 'text-red-400' : 'text-red-600',
|
||||
icon: '✗',
|
||||
message: '支付未完成,请重新发起支付;如已扣款未到账,请联系管理员处理。',
|
||||
};
|
||||
@@ -77,35 +77,35 @@ function getStatusConfig(order: PublicOrderStatusSnapshot, 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 one.',
|
||||
}
|
||||
: { 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: 'Cancelled', color: 'text-gray-500', icon: '✗', message: 'The order has been cancelled.' }
|
||||
: { label: '已取消', color: 'text-gray-500', icon: '✗', message: '订单已取消。' };
|
||||
? { label: 'Cancelled', color: isDark ? 'text-slate-400' : 'text-gray-500', icon: '✗', message: 'The 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',
|
||||
color: isDark ? 'text-red-400' : 'text-red-600',
|
||||
icon: '✗',
|
||||
message: 'Payment status is abnormal. Please contact the administrator.',
|
||||
}
|
||||
: { label: '支付异常', color: 'text-red-600', icon: '✗', message: '支付状态异常,请联系管理员处理。' };
|
||||
: { label: '支付异常', color: isDark ? 'text-red-400' : 'text-red-600', icon: '✗', message: '支付状态异常,请联系管理员处理。' };
|
||||
}
|
||||
|
||||
export default function OrderStatus({
|
||||
@@ -156,7 +156,7 @@ export default function OrderStatus({
|
||||
};
|
||||
}, [orderId, currentOrder.paymentSuccess, currentOrder.rechargeSuccess, statusAccessToken]);
|
||||
|
||||
const config = getStatusConfig(currentOrder, locale);
|
||||
const config = getStatusConfig(currentOrder, locale, dark);
|
||||
const doneLabel = locale === 'en' ? 'Done' : '完成';
|
||||
const backLabel = locale === 'en' ? 'Back to Recharge' : '返回充值';
|
||||
|
||||
|
||||
@@ -195,7 +195,9 @@ export default function PaymentForm({
|
||||
onClick={() => handleQuickAmount(val)}
|
||||
className={`rounded-lg border-2 px-4 py-3 text-center font-medium transition-colors ${
|
||||
amount === val
|
||||
? 'border-blue-500 bg-blue-50 text-blue-700'
|
||||
? dark
|
||||
? 'border-blue-500 bg-blue-900/40 text-blue-300'
|
||||
: 'border-blue-500 bg-blue-50 text-blue-700'
|
||||
: dark
|
||||
? 'border-slate-700 bg-slate-900 text-slate-200 hover:border-slate-500'
|
||||
: 'border-gray-200 bg-white text-gray-700 hover:border-gray-300'
|
||||
@@ -373,12 +375,12 @@ export default function PaymentForm({
|
||||
<button
|
||||
type="submit"
|
||||
disabled={!isValid || loading || pendingBlocked}
|
||||
className={`w-full rounded-lg py-3 text-center font-medium text-white transition-colors ${
|
||||
className={`w-full rounded-lg py-3 text-center font-medium transition-colors ${
|
||||
isValid && !loading && !pendingBlocked
|
||||
? getPaymentMeta(effectivePaymentType).buttonClass
|
||||
? `text-white ${getPaymentMeta(effectivePaymentType).buttonClass}`
|
||||
: dark
|
||||
? 'cursor-not-allowed bg-slate-700 text-slate-300'
|
||||
: 'cursor-not-allowed bg-gray-300'
|
||||
? 'cursor-not-allowed bg-slate-700 text-slate-400'
|
||||
: 'cursor-not-allowed bg-gray-300 text-gray-500'
|
||||
}`}
|
||||
>
|
||||
{loading
|
||||
|
||||
@@ -391,14 +391,17 @@ export default function PaymentQRCode({
|
||||
if (cancelBlocked) {
|
||||
return (
|
||||
<div className="flex flex-col items-center space-y-4 py-8">
|
||||
<div className="text-6xl text-green-600">{'✓'}</div>
|
||||
<h2 className="text-xl font-bold text-green-600">{t.paid}</h2>
|
||||
<div className={dark ? 'text-6xl text-green-400' : 'text-6xl text-green-600'}>{'✓'}</div>
|
||||
<h2 className={['text-xl font-bold', dark ? 'text-green-400' : 'text-green-600'].join(' ')}>{t.paid}</h2>
|
||||
<p className={['text-center text-sm', dark ? 'text-slate-400' : 'text-gray-500'].join(' ')}>
|
||||
{t.paidCancelBlocked}
|
||||
</p>
|
||||
<button
|
||||
onClick={onBack}
|
||||
className="mt-4 w-full rounded-lg bg-blue-600 py-3 font-medium text-white hover:bg-blue-700"
|
||||
className={[
|
||||
'mt-4 w-full rounded-lg py-3 font-medium text-white',
|
||||
dark ? 'bg-blue-600/90 hover:bg-blue-600' : 'bg-blue-600 hover:bg-blue-700',
|
||||
].join(' ')}
|
||||
>
|
||||
{t.backToRecharge}
|
||||
</button>
|
||||
@@ -409,7 +412,7 @@ export default function PaymentQRCode({
|
||||
return (
|
||||
<div className="flex flex-col items-center space-y-4">
|
||||
<div className="text-center">
|
||||
<div className="text-4xl font-bold text-blue-600">
|
||||
<div className={['text-4xl font-bold', dark ? 'text-blue-400' : 'text-blue-600'].join(' ')}>
|
||||
{'¥'}
|
||||
{displayAmount.toFixed(2)}
|
||||
</div>
|
||||
@@ -465,13 +468,16 @@ export default function PaymentQRCode({
|
||||
].join(' ')}
|
||||
/>
|
||||
{stripeError && (
|
||||
<div className="rounded-lg border border-red-200 bg-red-50 p-3 text-sm text-red-600">
|
||||
<div className={[
|
||||
'rounded-lg border p-3 text-sm',
|
||||
dark ? 'border-red-700/50 bg-red-900/30 text-red-400' : 'border-red-200 bg-red-50 text-red-600',
|
||||
].join(' ')}>
|
||||
{stripeError}
|
||||
</div>
|
||||
)}
|
||||
{stripeSuccess ? (
|
||||
<div className="text-center">
|
||||
<div className="text-4xl text-green-600">{'✓'}</div>
|
||||
<div className={dark ? 'text-4xl text-green-400' : 'text-4xl text-green-600'}>{'✓'}</div>
|
||||
<p className={['mt-2 text-sm', dark ? 'text-slate-400' : 'text-gray-500'].join(' ')}>
|
||||
{t.successProcessing}
|
||||
</p>
|
||||
|
||||
Reference in New Issue
Block a user