Skip to content

Commit ab51d06

Browse files
fix: linter for account btn
1 parent 8e38188 commit ab51d06

File tree

2 files changed

+45
-42
lines changed

2 files changed

+45
-42
lines changed

src/features/form/components/AdminFormDetailPage.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@ export const AdminFormDetailPage = () => {
114114
<Button variant="secondary" onClick={handleViewForm}>
115115
檢視表單
116116
</Button>
117-
<Button variant="secondary" onClick={handleCopyFormLink} title="點按以複製連結">
117+
<Button variant="secondary" onClick={handleCopyFormLink} title="點擊按鈕以複製表單連結">
118118
<Link size={16} />
119119
</Button>
120120
</>

src/shared/components/AccountButton/AccountButton.tsx

Lines changed: 44 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import type { ButtonHTMLAttributes, ReactNode } from "react";
2-
import { useEffect, useRef, useState } from "react";
2+
import { useCallback, useEffect, useRef, useState } from "react";
33
import { useToast } from "../Toast/useToast";
44
import styles from "./AccountButton.module.css";
55

@@ -49,51 +49,54 @@ export const AccountButton = ({ logo, children, connected = false, connectedLabe
4949
}
5050
};
5151
}, []);
52-
const fetchAndApply = async (opts: { showToast: boolean }): Promise<boolean> => {
53-
if (!responseId || !questionId) return false;
54-
try {
55-
const resp = await fetch(`/api/responses/${responseId}/questions/${questionId}`, {
56-
credentials: "include"
57-
});
58-
if (!resp.ok) throw new Error(`HTTP ${resp.status}`);
59-
const data = (await resp.json()) as {
60-
answer?: {
61-
value?: { username?: string; avatarUrl?: string };
52+
const fetchAndApply = useCallback(
53+
async (opts: { showToast: boolean }): Promise<boolean> => {
54+
if (!responseId || !questionId) return false;
55+
try {
56+
const resp = await fetch(`/api/responses/${responseId}/questions/${questionId}`, {
57+
credentials: "include"
58+
});
59+
if (!resp.ok) throw new Error(`HTTP ${resp.status}`);
60+
const data = (await resp.json()) as {
61+
answer?: {
62+
value?: { username?: string; avatarUrl?: string };
63+
};
64+
displayValue?: string;
6265
};
63-
displayValue?: string;
64-
};
65-
66-
const oauthUsername = data?.answer?.value?.username ?? "";
67-
const fetchedAvatarUrl = data?.answer?.value?.avatarUrl ?? "";
68-
const displayValue = data?.displayValue ?? "";
69-
const finalValue = oauthUsername || displayValue;
70-
71-
if (finalValue) {
72-
setResolvedLabel(finalValue);
73-
setAvatarUrl(fetchedAvatarUrl);
74-
onConnectRef.current?.(finalValue);
66+
67+
const oauthUsername = data?.answer?.value?.username ?? "";
68+
const fetchedAvatarUrl = data?.answer?.value?.avatarUrl ?? "";
69+
const displayValue = data?.displayValue ?? "";
70+
const finalValue = oauthUsername || displayValue;
71+
72+
if (finalValue) {
73+
setResolvedLabel(finalValue);
74+
setAvatarUrl(fetchedAvatarUrl);
75+
onConnectRef.current?.(finalValue);
76+
if (opts.showToast) {
77+
pushToast({ title: "綁定成功", description: `已綁定帳號:${finalValue}`, variant: "success" });
78+
}
79+
return true;
80+
} else if (opts.showToast) {
81+
pushToast({ title: "綁定完成", description: "已完成授權,但尚未取得帳號資訊", variant: "warning" });
82+
onConnectRef.current?.("");
83+
}
84+
} catch (error) {
85+
const errMsg = (error as Error).message;
7586
if (opts.showToast) {
76-
pushToast({ title: "綁定成功", description: `已綁定帳號:${finalValue}`, variant: "success" });
87+
pushToast({ title: "讀取綁定結果失敗", description: errMsg, variant: "error" });
88+
onConnectErrorRef.current?.(errMsg);
7789
}
78-
return true;
79-
} else if (opts.showToast) {
80-
pushToast({ title: "綁定完成", description: "已完成授權,但尚未取得帳號資訊", variant: "warning" });
81-
onConnectRef.current?.("");
82-
}
83-
} catch (error) {
84-
const errMsg = (error as Error).message;
85-
if (opts.showToast) {
86-
pushToast({ title: "讀取綁定結果失敗", description: errMsg, variant: "error" });
87-
onConnectErrorRef.current?.(errMsg);
8890
}
89-
}
90-
return false;
91-
};
91+
return false;
92+
},
93+
[responseId, questionId, pushToast]
94+
);
9295

9396
useEffect(() => {
9497
if (!connected || !responseId || !questionId) return;
9598
fetchAndApply({ showToast: false });
96-
}, [connected, responseId, questionId]);
99+
}, [connected, responseId, questionId, fetchAndApply]);
97100

98101
const handleClick = () => {
99102
if (!responseId || !questionId) return;
@@ -121,12 +124,12 @@ export const AccountButton = ({ logo, children, connected = false, connectedLabe
121124
if (event.source !== popup) return;
122125
if (event.origin !== window.location.origin) return;
123126

124-
const data: any = event.data;
127+
const data = event.data as { type?: string; questionId?: string; responseId?: string; error?: string | unknown };
125128
if (!data || data.type !== "FORM_OAUTH_CONNECTED") return;
126129
if (data.questionId !== questionId || data.responseId !== responseId) return;
127130

128131
// Mark this popup as handled so the interval callback does not re-fetch
129-
(popup as any).__oauthHandled = true;
132+
(popup as Window & { __oauthHandled?: boolean }).__oauthHandled = true;
130133

131134
clearTimer();
132135
window.removeEventListener("message", handleMessage);
@@ -156,7 +159,7 @@ export const AccountButton = ({ logo, children, connected = false, connectedLabe
156159
clearTimer();
157160
window.removeEventListener("message", handleMessage);
158161
// If no FORM_OAUTH_CONNECTED message was handled, fall back to fetching
159-
if (!(popup as any).__oauthHandled) {
162+
if (!(popup as Window & { __oauthHandled?: boolean }).__oauthHandled) {
160163
await fetchAndApply({ showToast: true });
161164
}
162165
setIsConnecting(false);

0 commit comments

Comments
 (0)