diff --git a/src/assets/icons/antigravity.png b/src/assets/icons/antigravity.png
new file mode 100644
index 0000000..6d59399
Binary files /dev/null and b/src/assets/icons/antigravity.png differ
diff --git a/src/assets/icons/claude.png b/src/assets/icons/claude.png
new file mode 100644
index 0000000..d33a916
Binary files /dev/null and b/src/assets/icons/claude.png differ
diff --git a/src/assets/icons/gemini.png b/src/assets/icons/gemini.png
new file mode 100644
index 0000000..9c71f88
Binary files /dev/null and b/src/assets/icons/gemini.png differ
diff --git a/src/assets/icons/iflow.svg b/src/assets/icons/iflow.svg
new file mode 100644
index 0000000..ec7a6f4
--- /dev/null
+++ b/src/assets/icons/iflow.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/src/assets/icons/openai-dark.png b/src/assets/icons/openai-dark.png
new file mode 100644
index 0000000..d975014
Binary files /dev/null and b/src/assets/icons/openai-dark.png differ
diff --git a/src/assets/icons/openai-light.png b/src/assets/icons/openai-light.png
new file mode 100644
index 0000000..56781b6
Binary files /dev/null and b/src/assets/icons/openai-light.png differ
diff --git a/src/assets/icons/qwen.png b/src/assets/icons/qwen.png
new file mode 100644
index 0000000..a43556f
Binary files /dev/null and b/src/assets/icons/qwen.png differ
diff --git a/src/pages/OAuthPage.module.scss b/src/pages/OAuthPage.module.scss
index 5173c0f..1b73426 100644
--- a/src/pages/OAuthPage.module.scss
+++ b/src/pages/OAuthPage.module.scss
@@ -4,6 +4,17 @@
width: 100%;
}
+.cardTitle {
+ display: flex;
+ align-items: center;
+ gap: $spacing-sm;
+}
+
+.cardTitleIcon {
+ width: 24px;
+ height: 24px;
+}
+
.pageTitle {
font-size: 28px;
font-weight: 700;
diff --git a/src/pages/OAuthPage.tsx b/src/pages/OAuthPage.tsx
index 4d1c1f9..e91abdd 100644
--- a/src/pages/OAuthPage.tsx
+++ b/src/pages/OAuthPage.tsx
@@ -3,9 +3,16 @@ import { useTranslation } from 'react-i18next';
import { Card } from '@/components/ui/Card';
import { Button } from '@/components/ui/Button';
import { Input } from '@/components/ui/Input';
-import { useNotificationStore } from '@/stores';
+import { useNotificationStore, useThemeStore } from '@/stores';
import { oauthApi, type OAuthProvider, type IFlowCookieAuthResponse } from '@/services/api/oauth';
import styles from './OAuthPage.module.scss';
+import iconOpenaiLight from '@/assets/icons/openai-light.png';
+import iconOpenaiDark from '@/assets/icons/openai-dark.png';
+import iconClaude from '@/assets/icons/claude.png';
+import iconAntigravity from '@/assets/icons/antigravity.png';
+import iconGemini from '@/assets/icons/gemini.png';
+import iconQwen from '@/assets/icons/qwen.png';
+import iconIflow from '@/assets/icons/iflow.svg';
interface ProviderState {
url?: string;
@@ -29,20 +36,25 @@ interface IFlowCookieState {
errorType?: 'error' | 'warning';
}
-const PROVIDERS: { id: OAuthProvider; titleKey: string; hintKey: string; urlLabelKey: string }[] = [
- { id: 'codex', titleKey: 'auth_login.codex_oauth_title', hintKey: 'auth_login.codex_oauth_hint', urlLabelKey: 'auth_login.codex_oauth_url_label' },
- { id: 'anthropic', titleKey: 'auth_login.anthropic_oauth_title', hintKey: 'auth_login.anthropic_oauth_hint', urlLabelKey: 'auth_login.anthropic_oauth_url_label' },
- { id: 'antigravity', titleKey: 'auth_login.antigravity_oauth_title', hintKey: 'auth_login.antigravity_oauth_hint', urlLabelKey: 'auth_login.antigravity_oauth_url_label' },
- { id: 'gemini-cli', titleKey: 'auth_login.gemini_cli_oauth_title', hintKey: 'auth_login.gemini_cli_oauth_hint', urlLabelKey: 'auth_login.gemini_cli_oauth_url_label' },
- { id: 'qwen', titleKey: 'auth_login.qwen_oauth_title', hintKey: 'auth_login.qwen_oauth_hint', urlLabelKey: 'auth_login.qwen_oauth_url_label' },
- { id: 'iflow', titleKey: 'auth_login.iflow_oauth_title', hintKey: 'auth_login.iflow_oauth_hint', urlLabelKey: 'auth_login.iflow_oauth_url_label' }
+const PROVIDERS: { id: OAuthProvider; titleKey: string; hintKey: string; urlLabelKey: string; icon: string | { light: string; dark: string } }[] = [
+ { id: 'codex', titleKey: 'auth_login.codex_oauth_title', hintKey: 'auth_login.codex_oauth_hint', urlLabelKey: 'auth_login.codex_oauth_url_label', icon: { light: iconOpenaiLight, dark: iconOpenaiDark } },
+ { id: 'anthropic', titleKey: 'auth_login.anthropic_oauth_title', hintKey: 'auth_login.anthropic_oauth_hint', urlLabelKey: 'auth_login.anthropic_oauth_url_label', icon: iconClaude },
+ { id: 'antigravity', titleKey: 'auth_login.antigravity_oauth_title', hintKey: 'auth_login.antigravity_oauth_hint', urlLabelKey: 'auth_login.antigravity_oauth_url_label', icon: iconAntigravity },
+ { id: 'gemini-cli', titleKey: 'auth_login.gemini_cli_oauth_title', hintKey: 'auth_login.gemini_cli_oauth_hint', urlLabelKey: 'auth_login.gemini_cli_oauth_url_label', icon: iconGemini },
+ { id: 'qwen', titleKey: 'auth_login.qwen_oauth_title', hintKey: 'auth_login.qwen_oauth_hint', urlLabelKey: 'auth_login.qwen_oauth_url_label', icon: iconQwen },
+ { id: 'iflow', titleKey: 'auth_login.iflow_oauth_title', hintKey: 'auth_login.iflow_oauth_hint', urlLabelKey: 'auth_login.iflow_oauth_url_label', icon: iconIflow }
];
const CALLBACK_SUPPORTED: OAuthProvider[] = ['codex', 'anthropic', 'antigravity', 'gemini-cli', 'iflow'];
+const getIcon = (icon: string | { light: string; dark: string }, theme: 'light' | 'dark') => {
+ return typeof icon === 'string' ? icon : icon[theme];
+};
+
export function OAuthPage() {
const { t } = useTranslation();
const { showNotification } = useNotificationStore();
+ const { theme } = useThemeStore();
const [states, setStates] = useState>({} as Record);
const [iflowCookie, setIflowCookie] = useState({ cookie: '', loading: false });
const timers = useRef>({});
@@ -215,7 +227,12 @@ export function OAuthPage() {
return (
+
+ {t(provider.titleKey)}
+
+ }
extra={