fix: 修复登录后跳转被立即重定向回登录页的问题

所有页面改用 useAuth hook,先检查 localStorage 再判断是否跳转
This commit is contained in:
chen guanjun 2026-06-22 09:21:40 +08:00
parent fb1951783c
commit 44688d7387
7 changed files with 57 additions and 26 deletions

View File

@ -6,11 +6,13 @@ import { useDropzone } from "react-dropzone";
import toast from "react-hot-toast";
import api from "@/lib/api";
import { useAuthStore } from "@/lib/store";
import { useAuth } from "@/hooks/useAuth";
import { SUBJECTS } from "@/types";
import type { MistakeOCRResponse } from "@/types";
export default function CollectPage() {
const router = useRouter();
const { ready } = useAuth();
const isLoggedIn = useAuthStore((s) => s.isLoggedIn);
const [subject, setSubject] = useState<string>("");
const [uploading, setUploading] = useState(false);
@ -27,9 +29,9 @@ export default function CollectPage() {
const onDrop = useCallback(
async (acceptedFiles: File[]) => {
if (!isLoggedIn) {
if (!ready) return null;
// isLoggedIn check removed
router.push("/login");
return;
}
const file = acceptedFiles[0];
if (!file) return;
@ -103,7 +105,8 @@ export default function CollectPage() {
}
};
if (!isLoggedIn) {
if (!ready) return null;
// isLoggedIn check removed
router.push("/login");
return null;
}

View File

@ -5,10 +5,12 @@ import { useRouter } from "next/navigation";
import toast from "react-hot-toast";
import api from "@/lib/api";
import { useAuthStore } from "@/lib/store";
import { useAuth } from "@/hooks/useAuth";
import { SUBJECTS } from "@/types";
export default function ExamPage() {
const router = useRouter();
const { ready } = useAuth();
const isLoggedIn = useAuthStore((s) => s.isLoggedIn);
const [title, setTitle] = useState("错题练习试卷");
const [selectedSubjects, setSelectedSubjects] = useState<string[]>([]);
@ -18,8 +20,8 @@ export default function ExamPage() {
const [pdfUrl, setPdfUrl] = useState<string | null>(null);
useEffect(() => {
if (!isLoggedIn) router.push("/login");
}, [isLoggedIn]);
// redirect handled by useAuth
}, [ready]);
const toggleSubject = (s: string) => {
setSelectedSubjects((prev) =>
@ -53,7 +55,7 @@ export default function ExamPage() {
window.open(downloadUrl, "_blank");
};
if (!isLoggedIn) return null;
if (!ready) return null;
return (
<div className="max-w-lg mx-auto px-4 pt-6">

View File

@ -5,11 +5,13 @@ import { useRouter } from "next/navigation";
import toast from "react-hot-toast";
import api from "@/lib/api";
import { useAuthStore } from "@/lib/store";
import { useAuth } from "@/hooks/useAuth";
import { SUBJECTS, SUBJECT_COLORS } from "@/types";
import type { Mistake, MistakeListResponse, AIAnalysis } from "@/types";
export default function MistakesPage() {
const router = useRouter();
const { ready } = useAuth();
const isLoggedIn = useAuthStore((s) => s.isLoggedIn);
const [mistakes, setMistakes] = useState<Mistake[]>([]);
const [total, setTotal] = useState(0);
@ -20,12 +22,12 @@ export default function MistakesPage() {
const [analyzingId, setAnalyzingId] = useState<number | null>(null);
useEffect(() => {
if (!isLoggedIn) {
if (!ready) return null;
// isLoggedIn check removed
router.push("/login");
return;
}
loadMistakes();
}, [isLoggedIn, page, subject]);
}, [ready, page, subject]);
const loadMistakes = async () => {
setLoading(true);
@ -72,7 +74,7 @@ export default function MistakesPage() {
}
};
if (!isLoggedIn) return null;
if (!ready) return null;
const totalPages = Math.ceil(total / 20);

View File

@ -4,23 +4,22 @@ import { useEffect, useState } from "react";
import { useRouter } from "next/navigation";
import Link from "next/link";
import { useAuthStore } from "@/lib/store";
import { useAuth } from "@/hooks/useAuth";
import api from "@/lib/api";
import type { MistakeStats, ReviewProgressResponse } from "@/types";
export default function DashboardPage() {
const router = useRouter();
const { ready } = useAuth();
const isLoggedIn = useAuthStore((s) => s.isLoggedIn);
const displayName = useAuthStore((s) => s.displayName);
const [stats, setStats] = useState<MistakeStats | null>(null);
const [progress, setProgress] = useState<ReviewProgressResponse | null>(null);
useEffect(() => {
if (!isLoggedIn) {
router.push("/login");
return;
}
if (!ready) return;
loadData();
}, [isLoggedIn]);
}, [ready]);
const loadData = async () => {
try {
@ -33,7 +32,7 @@ export default function DashboardPage() {
} catch {}
};
if (!isLoggedIn) return null;
if (!ready) return null;
return (
<div className="max-w-lg mx-auto px-4 pt-6">

View File

@ -5,11 +5,13 @@ import { useRouter } from "next/navigation";
import toast from "react-hot-toast";
import api from "@/lib/api";
import { useAuthStore } from "@/lib/store";
import { useAuth } from "@/hooks/useAuth";
import type { ReviewCardResponse, ReviewTodayResponse } from "@/types";
import { REVIEW_QUALITY_LABELS } from "@/types";
export default function ReviewPage() {
const router = useRouter();
const { ready } = useAuth();
const isLoggedIn = useAuthStore((s) => s.isLoggedIn);
const [data, setData] = useState<ReviewTodayResponse | null>(null);
const [currentIndex, setCurrentIndex] = useState(0);
@ -20,12 +22,9 @@ export default function ReviewPage() {
const [analyzing, setAnalyzing] = useState(false);
useEffect(() => {
if (!isLoggedIn) {
router.push("/login");
return;
}
if (!ready) return;
loadToday();
}, [isLoggedIn]);
}, [ready]);
const loadToday = async () => {
try {
@ -87,7 +86,7 @@ export default function ReviewPage() {
}
};
if (!isLoggedIn) return null;
if (!ready) return null;
if (loading) {
return (

View File

@ -5,10 +5,12 @@ import { useRouter } from "next/navigation";
import toast from "react-hot-toast";
import api from "@/lib/api";
import { useAuthStore } from "@/lib/store";
import { useAuth } from "@/hooks/useAuth";
import type { ReviewConfigResponse } from "@/types";
export default function SettingsPage() {
const router = useRouter();
const { ready } = useAuth();
const isLoggedIn = useAuthStore((s) => s.isLoggedIn);
const logout = useAuthStore((s) => s.logout);
const displayName = useAuthStore((s) => s.displayName);
@ -18,12 +20,12 @@ export default function SettingsPage() {
const [mastery, setMastery] = useState(3);
useEffect(() => {
if (!isLoggedIn) {
if (!ready) return null;
// isLoggedIn check removed
router.push("/login");
return;
}
loadConfig();
}, [isLoggedIn]);
}, [ready]);
const loadConfig = async () => {
try {
@ -54,7 +56,7 @@ export default function SettingsPage() {
router.push("/login");
};
if (!isLoggedIn) return null;
if (!ready) return null;
return (
<div className="max-w-lg mx-auto px-4 pt-6">

View File

@ -0,0 +1,24 @@
import { useEffect, useState } from "react";
import { useRouter } from "next/navigation";
import { useAuthStore } from "@/lib/store";
export function useAuth() {
const router = useRouter();
const isLoggedIn = useAuthStore((s) => s.isLoggedIn);
const loadFromStorage = useAuthStore((s) => s.loadFromStorage);
const [ready, setReady] = useState(false);
useEffect(() => {
if (!isLoggedIn) {
loadFromStorage();
}
const token = localStorage.getItem("token");
if (!isLoggedIn && !token) {
router.push("/login");
} else {
setReady(true);
}
}, [isLoggedIn]);
return { ready };
}