From b4a25edebc3c21d1746edb560e5aea3eee222386 Mon Sep 17 00:00:00 2001 From: wblx <904653630@qq.com> Date: Mon, 29 Jul 2024 15:51:30 +0800 Subject: [PATCH] solved all the problems Signed-off-by: wblx <904653630@qq.com> --- src/{api => helpers}/githubApi.ts | 5 +- src/locales/en/translation.json | 26 ++++- src/locales/zh_CN/translation.json | 26 ++++- src/pages/Options/GitHubToken.tsx | 97 --------------- src/pages/Options/Options.css | 3 +- src/pages/Options/Options.tsx | 12 +- src/pages/Options/components/GitHubToken.tsx | 117 +++++++++++++++++++ 7 files changed, 177 insertions(+), 109 deletions(-) rename src/{api => helpers}/githubApi.ts (87%) delete mode 100644 src/pages/Options/GitHubToken.tsx create mode 100644 src/pages/Options/components/GitHubToken.tsx diff --git a/src/api/githubApi.ts b/src/helpers/githubApi.ts similarity index 87% rename from src/api/githubApi.ts rename to src/helpers/githubApi.ts index 46c33ec5..24abc342 100644 --- a/src/api/githubApi.ts +++ b/src/helpers/githubApi.ts @@ -1,9 +1,8 @@ -// src/api/githubApi.ts let githubToken = ''; export const saveToken = (token: string) => { githubToken = token; - localStorage.setItem('github_token', token); // 保存 token 到 localStorage + localStorage.setItem('github_token', token); }; export const getToken = () => { @@ -32,4 +31,4 @@ export const githubRequest = async (endpoint: string, options: RequestInit = {}) } return response.json(); -}; \ No newline at end of file +}; diff --git a/src/locales/en/translation.json b/src/locales/en/translation.json index cf9b6f6a..b84caa86 100644 --- a/src/locales/en/translation.json +++ b/src/locales/en/translation.json @@ -60,5 +60,29 @@ "activity_icon": "activity", "openrank_icon": "openrank", "contributors_participants_icon": "contributors and participants", - "merged_lines_icon": "code lines change" + "merged_lines_icon": "code lines change", + "github_token_configuration": "GitHub Token Configuration", + "github_token_tooltip": "Enter your GitHub Token here for authentication.", + "github_token_description": "Providing a GitHub Token ensures that HyperCRX can securely and effectively access and operate on your GitHub data for personalized analysis.", + "github_token_how_to_generate": "How to generate a GitHub Token?", + "github_token_step1": "1. Log in to GitHub and go to Settings.", + "github_token_step2": "2. Select Developer settings.", + "github_token_step3": "3. Choose Personal access tokens, click Tokens(classic), then Generate a personal access token.", + "github_token_step4": "4. Set token details:", + "github_token_note": "Note", + "github_token_note_description": "A descriptive name, e.g., \"HyperCrx Token\".", + "github_token_expiration": "Expiration", + "github_token_expiration_description": "Choose the validity period.", + "github_token_scopes": "Scopes", + "github_token_scopes_description": "Select permission scopes, such as repo and workflow.", + "github_token_step5": "5. Click the Generate token button.", + "github_token_step6": "6. Copy the generated token and paste it into the input box below.", + "github_token_placeholder": "GitHub Token", + "github_token_save": "Save", + "github_token_edit": "Edit", + "github_token_test": "Test Token", + "github_token_error_empty": "Token cannot be empty", + "github_token_success_save": "Token saved successfully", + "github_token_success_valid": "Token is valid. Username: {{username}}", + "github_token_error_invalid": "Invalid token or request failed" } diff --git a/src/locales/zh_CN/translation.json b/src/locales/zh_CN/translation.json index f4181599..a229fa26 100644 --- a/src/locales/zh_CN/translation.json +++ b/src/locales/zh_CN/translation.json @@ -59,5 +59,29 @@ "activity_icon": "activity数", "openrank_icon": "openrank值", "contributors_participants_icon": "contributors和participants数", - "merged_lines_icon": "代码变化量" + "merged_lines_icon": "代码变化量", + "github_token_configuration": "GitHub 令牌配置", + "github_token_tooltip": "在此输入您的 GitHub 令牌以进行身份验证。", + "github_token_description": "提供 GitHub 令牌可确保 HyperCRX 能够安全有效地访问和操作您的 GitHub 数据以进行个性化分析。", + "github_token_how_to_generate": "如何生成 GitHub 令牌?", + "github_token_step1": "1. 登录 GitHub 并进入设置。", + "github_token_step2": "2. 选择开发者设置。", + "github_token_step3": "3. 选择个人访问令牌,Tokens(classic),然后生成个人访问令牌。", + "github_token_step4": "4. 设置令牌详细信息:", + "github_token_note": "注意", + "github_token_note_description": "描述性名称,例如“HyperCrx Token", + "github_token_expiration": "过期时间", + "github_token_expiration_description": "选择有效期。", + "github_token_scopes": "权限范围", + "github_token_scopes_description": "选择权限范围,例如 repo 和 workflow。", + "github_token_step5": "5. 点击生成令牌按钮。", + "github_token_step6": "6. 复制生成的令牌并将其粘贴到下面的输入框中。", + "github_token_placeholder": "GitHub 令牌", + "github_token_save": "保存", + "github_token_edit": "编辑", + "github_token_test": "测试令牌", + "github_token_error_empty": "令牌不能为空", + "github_token_success_save": "令牌保存成功", + "github_token_success_valid": "令牌有效。用户名:{{username}}", + "github_token_error_invalid": "令牌无效或请求失败" } diff --git a/src/pages/Options/GitHubToken.tsx b/src/pages/Options/GitHubToken.tsx deleted file mode 100644 index 9a13fc3e..00000000 --- a/src/pages/Options/GitHubToken.tsx +++ /dev/null @@ -1,97 +0,0 @@ -// src/pages/Options/GitHubToken.tsx -import React, { useState, useEffect } from 'react'; -import TooltipTrigger from '../../components/TooltipTrigger'; -import { saveToken, getToken, githubRequest } from '../../api/githubApi'; // 引入保存和获取 token 的方法 - -const GitHubToken = () => { - const [token, setToken] = useState(''); - const [isCollapsed, setIsCollapsed] = useState(true); - - useEffect(() => { - const storedToken = getToken(); - if (storedToken) { - setToken(storedToken); - } - }, []); - - const handleSave = () => { - if (!token) { - console.error('Token 不能为空'); - return; - } - - saveToken(token); // 保存 token - alert('Token 已保存'); // 提示用户 token 已保存 - }; - - const handleTestToken = async () => { - try { - const userData = await githubRequest('/user'); - alert(`Token 有效,用户名: ${userData.login}`); - } catch (error) { - console.error('Token 测试失败:', error); - alert('Token 无效或请求失败'); - } - }; - - return ( -
-
-

GitHub Token 配置

- -
-

提供 GitHub Token 可以确保 HyperCRX 安全、有效地访问和操作用户的 GitHub 数据并进行个性化分析。

-
-
setIsCollapsed(!isCollapsed)} - style={{ cursor: 'pointer', display: 'flex', alignItems: 'center' }} - > -

{'如何生成 GitHub Token?'}

- {isCollapsed ? '▶' : '▼'} -
- {!isCollapsed && ( -
-
    -
  • - 1. 登录 GitHub 并进入 Settings。 -
  • -
  • - 2. 选择 Developer settings。 -
  • -
  • - 3. 选择 Personal access tokens,点击 Fine-grained tokens,再点击{' '} - Generate a personal access token。 -
  • -
  • - 4. 设置 token 细节: -
      -
    • - Note:描述性名称,如 "HyperCrx Token"。 -
    • -
    • - Expiration:选择有效期。 -
    • -
    • - Scopes:选择权限范围,如 repoworkflow。 -
    • -
    -
  • -
  • - 5. 点击 Generate token 按钮。 -
  • -
  • 6. 复制生成的 token 并粘贴到下面的输入框中。
  • -
-
- )} -
- setToken(e.target.value)} placeholder="GitHub Token" /> - - -
- ); -}; - -export default GitHubToken; \ No newline at end of file diff --git a/src/pages/Options/Options.css b/src/pages/Options/Options.css index 66034b23..890cee97 100644 --- a/src/pages/Options/Options.css +++ b/src/pages/Options/Options.css @@ -1,4 +1,3 @@ -/* src/pages/Options/Options.css */ .container { width: 98vw; min-height: calc(100vh - 100px); @@ -112,4 +111,4 @@ a { .github-token-options button:hover { background-color: #0056b3; -} \ No newline at end of file +} diff --git a/src/pages/Options/Options.tsx b/src/pages/Options/Options.tsx index 06a1adbd..e0027977 100644 --- a/src/pages/Options/Options.tsx +++ b/src/pages/Options/Options.tsx @@ -1,4 +1,3 @@ -// src/pages/Options/index.tsx import React, { useState, useEffect } from 'react'; import { Checkbox, Radio, Space, Row, Col } from 'antd'; import { importedFeatures } from '../../../README.md'; @@ -8,7 +7,7 @@ import TooltipTrigger from '../../components/TooltipTrigger'; import './Options.css'; import { useTranslation } from 'react-i18next'; import '../../helpers/i18n'; -import GitHubToken from './GitHubToken'; // 引入 GitHubToken 组件 +import GitHubToken from './components/GitHubToken'; const stacksStyleOptions = { headerStack: { @@ -20,6 +19,9 @@ const stacksStyleOptions = { settingStack: { margin: '10px 25px', }, + tokenStack: { + margin: '10px 25px', + }, }; const Options = (): JSX.Element => { @@ -70,7 +72,7 @@ const Options = (): JSX.Element => { { display: 'flex', justifyContent: 'center', alignItems: 'center', + margin: stacksStyleOptions.tokenStack.margin, }} > - {/* 添加 GitHubToken 组件 */} + {/* Add GitHubToken component */} @@ -166,4 +169,3 @@ const Options = (): JSX.Element => { }; export default Options; - diff --git a/src/pages/Options/components/GitHubToken.tsx b/src/pages/Options/components/GitHubToken.tsx new file mode 100644 index 00000000..e1ea089f --- /dev/null +++ b/src/pages/Options/components/GitHubToken.tsx @@ -0,0 +1,117 @@ +import React, { useState, useEffect } from 'react'; +import TooltipTrigger from '../../../components/TooltipTrigger'; +import { saveToken, getToken, githubRequest } from '../../../helpers/githubApi'; +import { message } from 'antd'; +import { useTranslation } from 'react-i18next'; + +message.config({ + top: 1130, + duration: 2, + maxCount: 3, +}); + +const GitHubToken = () => { + const [token, setToken] = useState(''); + const [isCollapsed, setIsCollapsed] = useState(true); + const [isEditing, setIsEditing] = useState(false); + const { t } = useTranslation(); + + useEffect(() => { + const storedToken = getToken(); + if (storedToken) { + setToken(storedToken); + } + }, []); + + const handleSave = () => { + if (!token.trim()) { + message.error(t('github_token_error_empty')); + return; + } + saveToken(token); + message.success(t('github_token_success_save')); + setIsEditing(false); + }; + + const handleEdit = () => { + setIsEditing(true); + }; + + const handleTestToken = async () => { + try { + const userData = await githubRequest('/user', { + headers: { Authorization: `Bearer ${token}` } + }); + message.success(t('github_token_success_valid', { username: userData.login })); + } catch (error) { + console.error('Token test failed:', error); + message.error(t('github_token_error_invalid')); + } + }; + + const obfuscateToken = (token: string) => { + if (token.length <= 4) return token; + return `${token[0]}${'*'.repeat(token.length - 2)}${token[token.length - 1]}`; + }; + + return ( +
+
+

{t('github_token_configuration')}

+ +
+

{t('github_token_description')}

+
+
setIsCollapsed(!isCollapsed)} + style={{ cursor: 'pointer', display: 'flex', alignItems: 'center' }} + > +

{t('github_token_how_to_generate')}

+ {isCollapsed ? '▶' : '▼'} +
+ {!isCollapsed && ( +
+
    +
  1. {t('github_token_step1')}
  2. +
  3. {t('github_token_step2')}
  4. +
  5. {t('github_token_step3')}
  6. +
  7. + {t('github_token_step4')} +
      +
    • {t('github_token_note')}: {t('github_token_note_description')}
    • +
    • {t('github_token_expiration')}: {t('github_token_expiration_description')}
    • +
    • {t('github_token_scopes')}: {t('github_token_scopes_description')}
    • +
    +
  8. +
  9. {t('github_token_step5')}
  10. +
  11. {t('github_token_step6')}
  12. +
+
+ )} +
+
{/* Container for displaying messages */} +
+ setToken(e.target.value)} + placeholder={t('github_token_placeholder')} + style={{ marginRight: '10px', flex: 1 }} + disabled={!isEditing} + /> + {isEditing ? ( + + ) : ( + + )} + +
+
+ ); +}; + +export default GitHubToken; + + +