codacus commited on
Commit
5567d6d
·
2 Parent(s): 0164889 f511a27

Merge branch 'main' into bugfix-for-stable

Browse files
app/commit.json CHANGED
@@ -1 +1 @@
1
- { "commit": "8110c69eda7ae71914ef6b1e78dd51c3a6fd9f5b" }
 
1
+ { "commit": "016488998ddd5d21157854246daa7b8224aa8989" }
app/components/settings/connections/ConnectionsTab.tsx CHANGED
@@ -1,21 +1,93 @@
1
- import React, { useState } from 'react';
2
  import { toast } from 'react-toastify';
3
  import Cookies from 'js-cookie';
4
  import { logStore } from '~/lib/stores/logs';
5
 
 
 
 
 
 
 
6
  export default function ConnectionsTab() {
7
  const [githubUsername, setGithubUsername] = useState(Cookies.get('githubUsername') || '');
8
  const [githubToken, setGithubToken] = useState(Cookies.get('githubToken') || '');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
9
 
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' }));
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
19
  };
20
 
21
  return (
@@ -28,7 +100,8 @@ export default function ConnectionsTab() {
28
  type="text"
29
  value={githubUsername}
30
  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"
 
32
  />
33
  </div>
34
  <div className="flex-1">
@@ -37,17 +110,41 @@ export default function ConnectionsTab() {
37
  type="password"
38
  value={githubToken}
39
  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"
 
41
  />
42
  </div>
43
  </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>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
51
  </div>
52
  </div>
53
  );
 
1
+ import React, { useState, useEffect } from 'react';
2
  import { toast } from 'react-toastify';
3
  import Cookies from 'js-cookie';
4
  import { logStore } from '~/lib/stores/logs';
5
 
6
+ interface GitHubUserResponse {
7
+ login: string;
8
+ id: number;
9
+ [key: string]: any; // for other properties we don't explicitly need
10
+ }
11
+
12
  export default function ConnectionsTab() {
13
  const [githubUsername, setGithubUsername] = useState(Cookies.get('githubUsername') || '');
14
  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);
50
 
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!');
91
  };
92
 
93
  return (
 
100
  type="text"
101
  value={githubUsername}
102
  onChange={(e) => setGithubUsername(e.target.value)}
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"
105
  />
106
  </div>
107
  <div className="flex-1">
 
110
  type="password"
111
  value={githubToken}
112
  onChange={(e) => setGithubToken(e.target.value)}
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"
115
  />
116
  </div>
117
  </div>
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
+ )}
148
  </div>
149
  </div>
150
  );