Skip to content

Commit 5567d6d

Browse files
committed
Merge branch 'main' into bugfix-for-stable
2 parents 0164889 + f511a27 commit 5567d6d

File tree

2 files changed

+117
-20
lines changed

2 files changed

+117
-20
lines changed

app/commit.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
{ "commit": "8110c69eda7ae71914ef6b1e78dd51c3a6fd9f5b" }
1+
{ "commit": "016488998ddd5d21157854246daa7b8224aa8989" }

app/components/settings/connections/ConnectionsTab.tsx

Lines changed: 116 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,93 @@
1-
import React, { useState } from 'react';
1+
import React, { useState, useEffect } from 'react';
22
import { toast } from 'react-toastify';
33
import Cookies from 'js-cookie';
44
import { logStore } from '~/lib/stores/logs';
55

6+
interface GitHubUserResponse {
7+
login: string;
8+
id: number;
9+
[key: string]: any; // for other properties we don't explicitly need
10+
}
11+
612
export default function ConnectionsTab() {
713
const [githubUsername, setGithubUsername] = useState(Cookies.get('githubUsername') || '');
814
const [githubToken, setGithubToken] = useState(Cookies.get('githubToken') || '');
15+
const [isConnected, setIsConnected] = useState(false);
16+
const [isVerifying, setIsVerifying] = useState(false);
17+
18+
useEffect(() => {
19+
// Check if credentials exist and verify them
20+
if (githubUsername && githubToken) {
21+
verifyGitHubCredentials();
22+
}
23+
}, []);
24+
25+
const verifyGitHubCredentials = async () => {
26+
setIsVerifying(true);
27+
28+
try {
29+
const response = await fetch('https://api.github.com/user', {
30+
headers: {
31+
Authorization: `Bearer ${githubToken}`,
32+
},
33+
});
34+
35+
if (response.ok) {
36+
const data = (await response.json()) as GitHubUserResponse;
37+
38+
if (data.login === githubUsername) {
39+
setIsConnected(true);
40+
return true;
41+
}
42+
}
43+
44+
setIsConnected(false);
45+
46+
return false;
47+
} catch (error) {
48+
console.error('Error verifying GitHub credentials:', error);
49+
setIsConnected(false);
950

10-
const handleSaveConnection = () => {
11-
Cookies.set('githubUsername', githubUsername);
12-
Cookies.set('githubToken', githubToken);
13-
logStore.logSystem('GitHub connection settings updated', {
14-
username: githubUsername,
15-
hasToken: !!githubToken,
16-
});
17-
toast.success('GitHub credentials saved successfully!');
18-
Cookies.set('git:github.com', JSON.stringify({ username: githubToken, password: 'x-oauth-basic' }));
51+
return false;
52+
} finally {
53+
setIsVerifying(false);
54+
}
55+
};
56+
57+
const handleSaveConnection = async () => {
58+
if (!githubUsername || !githubToken) {
59+
toast.error('Please provide both GitHub username and token');
60+
return;
61+
}
62+
63+
setIsVerifying(true);
64+
65+
const isValid = await verifyGitHubCredentials();
66+
67+
if (isValid) {
68+
Cookies.set('githubUsername', githubUsername);
69+
Cookies.set('githubToken', githubToken);
70+
logStore.logSystem('GitHub connection settings updated', {
71+
username: githubUsername,
72+
hasToken: !!githubToken,
73+
});
74+
toast.success('GitHub credentials verified and saved successfully!');
75+
Cookies.set('git:github.com', JSON.stringify({ username: githubToken, password: 'x-oauth-basic' }));
76+
setIsConnected(true);
77+
} else {
78+
toast.error('Invalid GitHub credentials. Please check your username and token.');
79+
}
80+
};
81+
82+
const handleDisconnect = () => {
83+
Cookies.remove('githubUsername');
84+
Cookies.remove('githubToken');
85+
Cookies.remove('git:github.com');
86+
setGithubUsername('');
87+
setGithubToken('');
88+
setIsConnected(false);
89+
logStore.logSystem('GitHub connection removed');
90+
toast.success('GitHub connection removed successfully!');
1991
};
2092

2193
return (
@@ -28,7 +100,8 @@ export default function ConnectionsTab() {
28100
type="text"
29101
value={githubUsername}
30102
onChange={(e) => setGithubUsername(e.target.value)}
31-
className="w-full bg-white dark:bg-bolt-elements-background-depth-4 relative px-2 py-1.5 rounded-md focus:outline-none placeholder-bolt-elements-textTertiary text-bolt-elements-textPrimary dark:text-bolt-elements-textPrimary border border-bolt-elements-borderColor"
103+
disabled={isVerifying}
104+
className="w-full bg-white dark:bg-bolt-elements-background-depth-4 relative px-2 py-1.5 rounded-md focus:outline-none placeholder-bolt-elements-textTertiary text-bolt-elements-textPrimary dark:text-bolt-elements-textPrimary border border-bolt-elements-borderColor disabled:opacity-50"
32105
/>
33106
</div>
34107
<div className="flex-1">
@@ -37,17 +110,41 @@ export default function ConnectionsTab() {
37110
type="password"
38111
value={githubToken}
39112
onChange={(e) => setGithubToken(e.target.value)}
40-
className="w-full bg-white dark:bg-bolt-elements-background-depth-4 relative px-2 py-1.5 rounded-md focus:outline-none placeholder-bolt-elements-textTertiary text-bolt-elements-textPrimary dark:text-bolt-elements-textPrimary border border-bolt-elements-borderColor"
113+
disabled={isVerifying}
114+
className="w-full bg-white dark:bg-bolt-elements-background-depth-4 relative px-2 py-1.5 rounded-md focus:outline-none placeholder-bolt-elements-textTertiary text-bolt-elements-textPrimary dark:text-bolt-elements-textPrimary border border-bolt-elements-borderColor disabled:opacity-50"
41115
/>
42116
</div>
43117
</div>
44-
<div className="flex mb-4">
45-
<button
46-
onClick={handleSaveConnection}
47-
className="bg-bolt-elements-button-primary-background rounded-lg px-4 py-2 mr-2 transition-colors duration-200 hover:bg-bolt-elements-button-primary-backgroundHover text-bolt-elements-button-primary-text"
48-
>
49-
Save Connection
50-
</button>
118+
<div className="flex mb-4 items-center">
119+
{!isConnected ? (
120+
<button
121+
onClick={handleSaveConnection}
122+
disabled={isVerifying || !githubUsername || !githubToken}
123+
className="bg-bolt-elements-button-primary-background rounded-lg px-4 py-2 mr-2 transition-colors duration-200 hover:bg-bolt-elements-button-primary-backgroundHover text-bolt-elements-button-primary-text disabled:opacity-50 disabled:cursor-not-allowed flex items-center"
124+
>
125+
{isVerifying ? (
126+
<>
127+
<div className="i-ph:spinner animate-spin mr-2" />
128+
Verifying...
129+
</>
130+
) : (
131+
'Connect'
132+
)}
133+
</button>
134+
) : (
135+
<button
136+
onClick={handleDisconnect}
137+
className="bg-bolt-elements-button-danger-background rounded-lg px-4 py-2 mr-2 transition-colors duration-200 hover:bg-bolt-elements-button-danger-backgroundHover text-bolt-elements-button-danger-text"
138+
>
139+
Disconnect
140+
</button>
141+
)}
142+
{isConnected && (
143+
<span className="text-sm text-green-600 flex items-center">
144+
<div className="i-ph:check-circle mr-1" />
145+
Connected to GitHub
146+
</span>
147+
)}
51148
</div>
52149
</div>
53150
);

0 commit comments

Comments
 (0)