codacus commited on
Commit
f511a27
·
2 Parent(s): e4866eb e61459e

Merge remote-tracking branch 'upstream/main'

Browse files
app/commit.json CHANGED
@@ -1 +1 @@
1
- { "commit": "25b80ab267541b6ea290985dde09863f1a29c85c" , "version": "0.0.1" }
 
1
+ { "commit": "c257129a61e258650b321c19323ddebaf03b0a54" , "version": "0.0.1" }
app/components/settings/connections/ConnectionsTab.tsx CHANGED
@@ -1,21 +1,87 @@
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 +94,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 +104,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
+ try {
28
+ const response = await fetch('https://api.github.com/user', {
29
+ headers: {
30
+ Authorization: `Bearer ${githubToken}`,
31
+ },
32
+ });
33
+
34
+ if (response.ok) {
35
+ const data = (await response.json()) as GitHubUserResponse;
36
+ if (data.login === githubUsername) {
37
+ setIsConnected(true);
38
+ return true;
39
+ }
40
+ }
41
+ setIsConnected(false);
42
+ return false;
43
+ } catch (error) {
44
+ console.error('Error verifying GitHub credentials:', error);
45
+ setIsConnected(false);
46
+ return false;
47
+ } finally {
48
+ setIsVerifying(false);
49
+ }
50
+ };
51
+
52
+ const handleSaveConnection = async () => {
53
+ if (!githubUsername || !githubToken) {
54
+ toast.error('Please provide both GitHub username and token');
55
+ return;
56
+ }
57
+
58
+ setIsVerifying(true);
59
+ const isValid = await verifyGitHubCredentials();
60
+
61
+ if (isValid) {
62
+ Cookies.set('githubUsername', githubUsername);
63
+ Cookies.set('githubToken', githubToken);
64
+ logStore.logSystem('GitHub connection settings updated', {
65
+ username: githubUsername,
66
+ hasToken: !!githubToken,
67
+ });
68
+ toast.success('GitHub credentials verified and saved successfully!');
69
+ Cookies.set('git:github.com', JSON.stringify({ username: githubToken, password: 'x-oauth-basic' }));
70
+ setIsConnected(true);
71
+ } else {
72
+ toast.error('Invalid GitHub credentials. Please check your username and token.');
73
+ }
74
+ };
75
+
76
+ const handleDisconnect = () => {
77
+ Cookies.remove('githubUsername');
78
+ Cookies.remove('githubToken');
79
+ Cookies.remove('git:github.com');
80
+ setGithubUsername('');
81
+ setGithubToken('');
82
+ setIsConnected(false);
83
+ logStore.logSystem('GitHub connection removed');
84
+ toast.success('GitHub connection removed successfully!');
85
  };
86
 
87
  return (
 
94
  type="text"
95
  value={githubUsername}
96
  onChange={(e) => setGithubUsername(e.target.value)}
97
+ disabled={isVerifying}
98
+ 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"
99
  />
100
  </div>
101
  <div className="flex-1">
 
104
  type="password"
105
  value={githubToken}
106
  onChange={(e) => setGithubToken(e.target.value)}
107
+ disabled={isVerifying}
108
+ 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"
109
  />
110
  </div>
111
  </div>
112
+ <div className="flex mb-4 items-center">
113
+ {!isConnected ? (
114
+ <button
115
+ onClick={handleSaveConnection}
116
+ disabled={isVerifying || !githubUsername || !githubToken}
117
+ 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"
118
+ >
119
+ {isVerifying ? (
120
+ <>
121
+ <div className="i-ph:spinner animate-spin mr-2" />
122
+ Verifying...
123
+ </>
124
+ ) : (
125
+ 'Connect'
126
+ )}
127
+ </button>
128
+ ) : (
129
+ <button
130
+ onClick={handleDisconnect}
131
+ 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"
132
+ >
133
+ Disconnect
134
+ </button>
135
+ )}
136
+ {isConnected && (
137
+ <span className="text-sm text-green-600 flex items-center">
138
+ <div className="i-ph:check-circle mr-1" />
139
+ Connected to GitHub
140
+ </span>
141
+ )}
142
  </div>
143
  </div>
144
  );