fix: complete admin login redirect flow
This commit is contained in:
+14
-16
@@ -1,5 +1,5 @@
|
|||||||
import { useEffect, useState } from "react";
|
import { useEffect, useState } from "react";
|
||||||
import { useLoaderData, useFetcher } from "@remix-run/react";
|
import { useActionData, useLoaderData, useNavigation, useSubmit } from "@remix-run/react";
|
||||||
import { type MetaFunction, type LoaderFunctionArgs, type ActionFunctionArgs } from "@remix-run/node";
|
import { type MetaFunction, type LoaderFunctionArgs, type ActionFunctionArgs } from "@remix-run/node";
|
||||||
import { OAuthClient } from "~/api/login/oauth-client";
|
import { OAuthClient } from "~/api/login/oauth-client";
|
||||||
import { CLIENT_OAUTH_CONFIG } from "~/config/api-config";
|
import { CLIENT_OAUTH_CONFIG } from "~/config/api-config";
|
||||||
@@ -217,7 +217,9 @@ export async function action({ request }: ActionFunctionArgs) {
|
|||||||
export default function Login() {
|
export default function Login() {
|
||||||
// const navigate = useNavigate();
|
// const navigate = useNavigate();
|
||||||
const loaderData = useLoaderData<typeof loader>();
|
const loaderData = useLoaderData<typeof loader>();
|
||||||
const fetcher = useFetcher<{ success: boolean; error?: string }>();
|
const actionData = useActionData<typeof action>();
|
||||||
|
const navigation = useNavigation();
|
||||||
|
const submit = useSubmit();
|
||||||
const [isFlipped, setIsFlipped] = useState(false);
|
const [isFlipped, setIsFlipped] = useState(false);
|
||||||
const [username, setUsername] = useState("");
|
const [username, setUsername] = useState("");
|
||||||
const [password, setPassword] = useState("");
|
const [password, setPassword] = useState("");
|
||||||
@@ -234,8 +236,8 @@ export default function Login() {
|
|||||||
const retryCount = 0;
|
const retryCount = 0;
|
||||||
const remainingAttempts = 5;
|
const remainingAttempts = 5;
|
||||||
|
|
||||||
// 监听 fetcher 的状态
|
// 监听当前登录表单提交状态
|
||||||
const isLoading = fetcher.state === "submitting" || fetcher.state === "loading";
|
const isLoading = navigation.state !== "idle" && navigation.formAction === "/login";
|
||||||
|
|
||||||
// 处理OAuth2.0登录
|
// 处理OAuth2.0登录
|
||||||
const handleOAuthLogin = () => {
|
const handleOAuthLogin = () => {
|
||||||
@@ -298,30 +300,26 @@ export default function Login() {
|
|||||||
|
|
||||||
console.log("📝 [Login] 提交管理员登录表单");
|
console.log("📝 [Login] 提交管理员登录表单");
|
||||||
|
|
||||||
// ✅ 使用 fetcher 提交表单到服务端 action
|
// 使用路由提交而不是 fetcher,确保服务端 redirect 真正触发页面跳转
|
||||||
const formData = new FormData();
|
const formData = new FormData();
|
||||||
formData.append("username", username.trim());
|
formData.append("username", username.trim());
|
||||||
formData.append("password", password.trim());
|
formData.append("password", password.trim());
|
||||||
formData.append("redirectTo", loaderData?.redirectTo || "/");
|
formData.append("redirectTo", loaderData?.redirectTo || "/");
|
||||||
|
|
||||||
fetcher.submit(formData, {
|
submit(formData, {
|
||||||
method: "post",
|
method: "post",
|
||||||
action: "/login"
|
action: "/login"
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
// 处理 fetcher 响应
|
// 处理 action 返回的错误响应
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (fetcher.data) {
|
if (actionData && !actionData.success && actionData.error) {
|
||||||
if (!fetcher.data.success && fetcher.data.error) {
|
console.error("❌ [Login] 登录失败:", actionData.error);
|
||||||
// 登录失败,显示错误
|
setPasswordLoginError(actionData.error);
|
||||||
console.error("❌ [Login] 登录失败:", fetcher.data.error);
|
toastService.error(actionData.error);
|
||||||
setPasswordLoginError(fetcher.data.error);
|
|
||||||
toastService.error(fetcher.data.error);
|
|
||||||
}
|
|
||||||
// 登录成功的情况由 action 中的 redirect 处理,会自动跳转到 callback 页面
|
|
||||||
}
|
}
|
||||||
}, [fetcher.data]);
|
}, [actionData]);
|
||||||
|
|
||||||
// 显示URL错误参数的Toast提示
|
// 显示URL错误参数的Toast提示
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
|||||||
Reference in New Issue
Block a user