diff --git a/frontend/src/app/pages/LoginPage.tsx b/frontend/src/app/pages/LoginPage.tsx
index 3366ada..535fbb4 100644
--- a/frontend/src/app/pages/LoginPage.tsx
+++ b/frontend/src/app/pages/LoginPage.tsx
@@ -11,51 +11,135 @@ function isWechatMiniProgram(): boolean {
return ua.includes("micromessenger") && ua.includes("miniprogram");
}
+// โโโ ๐ ่ฐ่ฏๅบๅ๏ผๆๆฅๅๅ ้ค โโโ
+
+interface DebugInfo {
+ url: string;
+ ua: string;
+ isWxMp: boolean;
+ hasTokenParam: boolean;
+ tokenPrefix: string;
+ decodeResult: string;
+ fetchError: string;
+ devLoginError: string;
+ step: string;
+ tokenInStorage: boolean;
+}
+
+const INIT_DEBUG: DebugInfo = {
+ url: "", ua: "", isWxMp: false, hasTokenParam: false,
+ tokenPrefix: "", decodeResult: "", fetchError: "",
+ devLoginError: "", step: "init", tokenInStorage: false,
+};
+
+function DebugPanel({ info }: { info: DebugInfo }) {
+ return (
+
+
๐ ่ฐ่ฏไฟกๆฏ (ๅ
ณ้ญ้ๅปๆ ?debug=1)
+
+
+ {Object.entries(info).map(([k, v]) => (
+
+ | {k} |
+ {v || (็ฉบ)} |
+
+ ))}
+
+
+
+ );
+}
+
+// โโโ ๐ ่ฐ่ฏๅบๅ็ปๆ โโโ
+
export function LoginPage() {
const navigate = useNavigate();
const { setTokenAndUser, fetchProfile } = useUser();
const [error, setError] = useState("");
+ const [debug] = useState(() => ({ ...INIT_DEBUG }));
+
+ // โโโ ๐ ่ฐ่ฏๆดๆฐๅฝๆฐ โโโ
+ const dbg = (patch: Partial) => {
+ if (debug) Object.assign(debug, patch);
+ };
+ // โโโ ๐ ่ฐ่ฏๆดๆฐ็ปๆ โโโ
useEffect(() => {
+ // โโโ ๐ โโโ
+ if (debug) {
+ debug.url = window.location.href;
+ debug.ua = navigator.userAgent;
+ debug.tokenInStorage = !!getToken();
+ }
+ // โโโ ๐ ็ปๆ โโโ
+
// ไผๅ
ไฝฟ็จ URL ไธญ็ token๏ผๅฐ็จๅบไผ ๅ๏ผ
const params = new URLSearchParams(window.location.search);
const tokenFromUrl = params.get('token');
+ // โโโ ๐ โโโ
+ dbg({ step: "check-url-token", hasTokenParam: !!tokenFromUrl, tokenPrefix: tokenFromUrl ? tokenFromUrl.substring(0, 30) + "..." : "" });
+ // โโโ ๐ โโโ
+
if (tokenFromUrl) {
// token ๅไบๅฐฑๆดๆฐๅญๅจ
const oldToken = getToken();
if (tokenFromUrl !== oldToken) {
- const payload = decodeToken(tokenFromUrl);
- setTokenAndUser(tokenFromUrl, {
- id: String(payload.uid),
- openid: payload.openid,
- phone: payload.phone,
- });
+ try {
+ const payload = decodeToken(tokenFromUrl);
+ // โโโ ๐ โโโ
+ dbg({ step: "decode-ok", decodeResult: `uid=${payload.uid}, openid=${payload.openid?.substring(0,15)}..., phone=${payload.phone}` });
+ // โโโ ๐ โโโ
+ setTokenAndUser(tokenFromUrl, {
+ id: String(payload.uid),
+ openid: payload.openid,
+ phone: payload.phone,
+ });
+ } catch (e: any) {
+ // โโโ ๐ โโโ
+ dbg({ step: "decode-fail", decodeResult: `่งฃๆๅคฑ่ดฅ: ${e?.message || e}` });
+ // โโโ ๐ โโโ
+ setError("Token ่งฃๆๅคฑ่ดฅ: " + (e?.message || "ๆ ผๅผ้่ฏฏ"));
+ return;
+ }
} else {
// token ๆฒกๅ๏ผ็กฎไฟ localStorage ๆๆฐๆฎ
saveToken(tokenFromUrl);
}
- // ๆๅๅญๆๆฐๆฎ๏ผ่ฟๅ
ฅ้ฆ้กตๆ onboarding
+ // ๆๅ็จๆทๆฐๆฎ๏ผ่ฟๅ
ฅ้ฆ้กตๆ onboarding
+ dbg({ step: "fetch-profile" });
fetchProfile().then((dto) => {
+ // โโโ ๐ โโโ
+ dbg({ step: "fetch-ok", fetchError: `is_onboarded=${dto?.is_onboarded}` });
+ // โโโ ๐ โโโ
navigate(dto?.is_onboarded ? "/home" : "/onboarding", { replace: true });
- }).catch(() => {
+ }).catch((e: any) => {
+ // โโโ ๐ โโโ
+ dbg({ step: "fetch-fail", fetchError: `${e?.message || e}` });
+ // โโโ ๐ โโโ
setError("็ปๅฝๅทฒๅคฑๆ๏ผ่ฏทๅจๅฐ็จๅบ้ๆฐ่ฟๅ
ฅ");
});
return;
}
// ๅฐ็จๅบ็ฏๅขไฝๆฒกๆ token โ ้็ฅๅฐ็จๅบไผ ้
+ dbg({ step: "check-wx-mp", isWxMp: isWechatMiniProgram() });
if (isWechatMiniProgram()) {
try {
(window as any).wx?.miniProgram?.postMessage({ type: "NEED_TOKEN" });
- } catch { /* ignore */ }
+ dbg({ step: "wx-postMessage-done" });
+ } catch (e: any) {
+ dbg({ step: "wx-postMessage-error", fetchError: `${e?.message || e}` });
+ }
setError("ๆญฃๅจ่ทๅ็ปๅฝไฟกๆฏ...");
return;
}
// ๆต่งๅจๅผๅ็ฏๅข โ ่ชๅจไฝฟ็จๆต่ฏ่ดฆๅท
+ dbg({ step: "dev-login" });
devLogin().then((res) => {
+ dbg({ step: "dev-login-ok" });
setTokenAndUser(res.token, {
id: res.user_id,
openid: res.openid,
@@ -65,12 +149,14 @@ export function LoginPage() {
navigate(dto?.is_onboarded ? "/home" : "/onboarding", { replace: true });
});
}).catch((err) => {
+ dbg({ step: "dev-login-fail", devLoginError: err?.message || String(err) });
setError(err?.message || "็ปๅฝๅคฑ่ดฅ๏ผ่ฏทๅทๆฐ้่ฏ");
});
}, []); // eslint-disable-line react-hooks/exhaustive-deps
return (
-