fix(user): satisfy biome check for oauth/payment UI

This commit is contained in:
ppanel-web 2026-02-08 08:49:17 +00:00
parent b32ba55ab8
commit 6e3ef8ab7e
5 changed files with 54 additions and 49 deletions

View File

@ -1,28 +1,29 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>OAuth Redirect</title>
<meta http-equiv="refresh" content="0; url=/#/auth" />
<meta http-equiv="refresh" content="0; url=/#/auth">
<script>
(function () {
try {
// Providers redirect to a path without URL fragments (#). Our app uses hash routing.
// Bridge /oauth/<provider>[/]?... -> /#/oauth/<provider>?...
var path = window.location.pathname || "/";
// Normalize trailing slash so /oauth/google/ and /oauth/google both map to the same route.
path = path.replace(/\/$/, "");
var search = window.location.search || "";
var target = "/#" + path + search;
window.location.replace(target);
} catch (e) {
window.location.replace("/#/auth");
}
})();
"use strict";
// Providers redirect to a path without URL fragments (#). Our app uses hash routing.
// Bridge /oauth/<provider>[/]?... -> /#/oauth/<provider>?...
(() => {
try {
// Normalize trailing slash so /oauth/google/ and /oauth/google both map to the same route.
let path = window.location.pathname || "/";
path = path.replace(/\/$/, "");
const search = window.location.search || "";
const target = `/#${path}${search}`;
window.location.replace(target);
} catch (_e) {
window.location.replace("/#/auth");
}
})();
</script>
</head>
<body>
Redirecting…
</body>
<body>Redirecting…</body>
</html>

View File

@ -1,27 +1,28 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>OAuth Redirect</title>
<meta http-equiv="refresh" content="0; url=/#/auth" />
<meta http-equiv="refresh" content="0; url=/#/auth">
<script>
(function () {
try {
// Providers redirect to a path without URL fragments (#). Our app uses hash routing.
// Bridge /oauth/<provider>[/]?... -> /#/oauth/<provider>?...
var path = window.location.pathname || "/";
path = path.replace(/\/$/, "");
var search = window.location.search || "";
var target = "/#" + path + search;
window.location.replace(target);
} catch (e) {
window.location.replace("/#/auth");
}
})();
"use strict";
// Providers redirect to a path without URL fragments (#). Our app uses hash routing.
// Bridge /oauth/<provider>[/]?... -> /#/oauth/<provider>?...
(() => {
try {
let path = window.location.pathname || "/";
path = path.replace(/\/$/, "");
const search = window.location.search || "";
const target = `/#${path}${search}`;
window.location.replace(target);
} catch (_e) {
window.location.replace("/#/auth");
}
})();
</script>
</head>
<body>
Redirecting…
</body>
<body>Redirecting…</body>
</html>

View File

@ -9,7 +9,7 @@ import {
import { cn } from "@workspace/ui/lib/utils";
import { getAvailablePaymentMethods } from "@workspace/ui/services/user/portal";
import type React from "react";
import React, { memo } from "react";
import { memo, useEffect } from "react";
import { useTranslation } from "react-i18next";
interface PaymentMethodsProps {
@ -37,7 +37,7 @@ const PaymentMethods: React.FC<PaymentMethodsProps> = ({
// Only set a default when the current value is not a valid option.
// This avoids resetting the user's selection on refetch (common on mobile).
// Prefer non-balance methods when possible.
React.useEffect(() => {
useEffect(() => {
if (!data || data.length === 0) return;
const valid = data.some((m) => String(m.id) === String(value));
if (valid) return;

View File

@ -18,6 +18,7 @@ import { useGlobalStore } from "@/stores/global";
export default function Announcement({ type }: { type: "popup" | "pinned" }) {
const { t } = useTranslation("dashboard");
const { user } = useGlobalStore();
const [open, setOpen] = useState(false);
const { data } = useQuery({
queryKey: ["announcement", type],
@ -38,14 +39,12 @@ export default function Announcement({ type }: { type: "popup" | "pinned" }) {
enabled: !!user,
});
if (!data) return null;
const [open, setOpen] = useState(false);
useEffect(() => {
if (type === "popup" && !!data) setOpen(true);
}, [data, type]);
if (!data) return null;
if (type === "popup") {
return (
<Dialog onOpenChange={setOpen} open={open}>

View File

@ -276,7 +276,9 @@ const CheckoutForm: React.FC<Omit<StripePaymentProps, "publishable_key">> = ({
const stripe = useStripe();
const [errorMessage, setErrorMessage] = useState<string | null>(null);
const [qrCodeUrl, setQrCodeUrl] = useState<string | null>(null);
const [qrCodeImageDataUrl, setQrCodeImageDataUrl] = useState<string | null>(null);
const [qrCodeImageDataUrl, setQrCodeImageDataUrl] = useState<string | null>(
null
);
const [isSubmitted, setIsSubmitted] = useState(false);
const { t } = useTranslation("payment");
const qrCodeMap: Record<string, string> = {
@ -342,7 +344,7 @@ const CheckoutForm: React.FC<Omit<StripePaymentProps, "publishable_key">> = ({
const imageDataUrl = wechat?.image_data_url; // data:image/png;base64,...
setQrCodeUrl(data || null);
setQrCodeImageDataUrl(!data ? imageDataUrl || null : null);
setQrCodeImageDataUrl(data ? null : imageDataUrl || null);
}
}
} catch (_error) {
@ -362,11 +364,13 @@ const CheckoutForm: React.FC<Omit<StripePaymentProps, "publishable_key">> = ({
<>
{qrCodeImageDataUrl ? (
<img
alt={qrCodeMap[method] || t(`qrcode.${method}`, `Scan with ${method}`)}
alt={
qrCodeMap[method] || t(`qrcode.${method}`, `Scan with ${method}`)
}
className="mx-auto h-[208px] w-[208px]"
height={208}
src={qrCodeImageDataUrl}
width={208}
height={208}
/>
) : (
<QRCodeCanvas