codacus commited on
Commit
b304749
·
1 Parent(s): 9f00227

added backdrop and loading screen

Browse files
app/components/git/GitUrlImport.client.tsx CHANGED
@@ -8,6 +8,8 @@ import { Chat } from '~/components/chat/Chat.client';
8
  import { useGit } from '~/lib/hooks/useGit';
9
  import { useChatHistory } from '~/lib/persistence';
10
  import { createCommandsMessage, detectProjectCommands } from '~/utils/projectCommands';
 
 
11
 
12
  const IGNORE_PATTERNS = [
13
  'node_modules/**',
@@ -38,6 +40,7 @@ export function GitUrlImport() {
38
  const { ready: historyReady, importChat } = useChatHistory();
39
  const { ready: gitReady, gitClone } = useGit();
40
  const [imported, setImported] = useState(false);
 
41
 
42
  const importRepo = async (repoUrl?: string) => {
43
  if (!gitReady && !historyReady) {
@@ -109,9 +112,23 @@ ${file.content}
109
  return;
110
  }
111
 
112
- importRepo(url);
 
 
 
 
 
113
  setImported(true);
114
  }, [searchParams, historyReady, gitReady, imported]);
115
 
116
- return <ClientOnly fallback={<BaseChat />}>{() => <Chat />}</ClientOnly>;
 
 
 
 
 
 
 
 
 
117
  }
 
8
  import { useGit } from '~/lib/hooks/useGit';
9
  import { useChatHistory } from '~/lib/persistence';
10
  import { createCommandsMessage, detectProjectCommands } from '~/utils/projectCommands';
11
+ import { LoadingOverlay } from '~/components/ui/LoadingOverlay';
12
+ import { toast } from 'react-toastify';
13
 
14
  const IGNORE_PATTERNS = [
15
  'node_modules/**',
 
40
  const { ready: historyReady, importChat } = useChatHistory();
41
  const { ready: gitReady, gitClone } = useGit();
42
  const [imported, setImported] = useState(false);
43
+ const [loading, setLoading] = useState(true);
44
 
45
  const importRepo = async (repoUrl?: string) => {
46
  if (!gitReady && !historyReady) {
 
112
  return;
113
  }
114
 
115
+ importRepo(url).catch((error) => {
116
+ console.error('Error importing repo:', error);
117
+ toast.error('Failed to import repository');
118
+ setLoading(false);
119
+ window.location.href = '/';
120
+ });
121
  setImported(true);
122
  }, [searchParams, historyReady, gitReady, imported]);
123
 
124
+ return (
125
+ <ClientOnly fallback={<BaseChat />}>
126
+ {() => (
127
+ <>
128
+ <Chat />
129
+ {loading && <LoadingOverlay message="Please wait while we clone the repository..." />}
130
+ </>
131
+ )}
132
+ </ClientOnly>
133
+ );
134
  }
app/components/ui/LoadingOverlay.tsx ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ export const LoadingOverlay = ({ message = 'Loading...' }) => {
2
+ return (
3
+ <div className="fixed inset-0 flex items-center justify-center bg-black/80 z-50 backdrop-blur-sm">
4
+ {/* Loading content */}
5
+ <div className="relative flex flex-col items-center gap-4 p-8 rounded-lg bg-bolt-elements-background-depth-2 shadow-lg">
6
+ <div
7
+ className={'i-svg-spinners:90-ring-with-bg text-bolt-elements-loader-progress'}
8
+ style={{ fontSize: '2rem' }}
9
+ ></div>
10
+ <p className="text-lg text-bolt-elements-textTertiary">{message}</p>
11
+ </div>
12
+ </div>
13
+ );
14
+ };
app/components/ui/Settings.tsx CHANGED
@@ -10,7 +10,6 @@ import { toast } from 'react-toastify';
10
  import { useNavigate } from '@remix-run/react';
11
  import commit from '~/commit.json';
12
  import Cookies from 'js-cookie';
13
- import { SettingsSlider } from './SettingsSlider';
14
  import '~/styles/components/SettingsSlider.scss';
15
  import '~/styles/components/Settings.scss';
16
 
@@ -219,9 +218,7 @@ export const Settings = ({ open, onClose }: SettingsProps) => {
219
  <button
220
  key={tab.id}
221
  onClick={() => setActiveTab(tab.id)}
222
- className={classNames(
223
- activeTab === tab.id ? 'active' : ''
224
- )}
225
  >
226
  <div className={tab.icon} />
227
  {tab.label}
@@ -250,7 +247,9 @@ export const Settings = ({ open, onClose }: SettingsProps) => {
250
  </div>
251
 
252
  <div className="flex-1 flex flex-col p-8 bg-gray-50 dark:bg-gray-800">
253
- <DialogTitle className="flex-shrink-0 text-lg font-semibold text-bolt-elements-textPrimary">Settings</DialogTitle>
 
 
254
  <div className="flex-1 overflow-y-auto">
255
  {activeTab === 'chat-history' && (
256
  <div className="p-4">
@@ -304,14 +303,20 @@ export const Settings = ({ open, onClose }: SettingsProps) => {
304
  checked={provider.isEnabled}
305
  onChange={() => handleToggleProvider(provider.name)}
306
  />
307
- <div className={classNames(
308
- 'settings-toggle__track',
309
- provider.isEnabled ? 'settings-toggle__track--enabled' : 'settings-toggle__track--disabled'
310
- )}></div>
311
- <div className={classNames(
312
- 'settings-toggle__thumb',
313
- provider.isEnabled ? 'settings-toggle__thumb--enabled' : ''
314
- )}></div>
 
 
 
 
 
 
315
  </label>
316
  </div>
317
  {/* Base URL input for configurable providers */}
@@ -343,14 +348,18 @@ export const Settings = ({ open, onClose }: SettingsProps) => {
343
  checked={isDebugEnabled}
344
  onChange={() => setIsDebugEnabled(!isDebugEnabled)}
345
  />
346
- <div className={classNames(
347
- 'settings-toggle__track',
348
- isDebugEnabled ? 'settings-toggle__track--enabled' : 'settings-toggle__track--disabled'
349
- )}></div>
350
- <div className={classNames(
351
- 'settings-toggle__thumb',
352
- isDebugEnabled ? 'settings-toggle__thumb--enabled' : ''
353
- )}></div>
 
 
 
 
354
  </label>
355
  </div>
356
  </div>
@@ -367,14 +376,18 @@ export const Settings = ({ open, onClose }: SettingsProps) => {
367
  checked={isJustSayEnabled}
368
  onChange={() => setIsJustSayEnabled(!isJustSayEnabled)}
369
  />
370
- <div className={classNames(
371
- 'settings-toggle__track',
372
- isJustSayEnabled ? 'settings-toggle__track--enabled' : 'settings-toggle__track--disabled'
373
- )}></div>
374
- <div className={classNames(
375
- 'settings-toggle__thumb',
376
- isJustSayEnabled ? 'settings-toggle__thumb--enabled' : ''
377
- )}></div>
 
 
 
 
378
  </label>
379
  </div>
380
  </div>
@@ -408,7 +421,9 @@ export const Settings = ({ open, onClose }: SettingsProps) => {
408
  <ul>
409
  <li className="text-bolt-elements-textSecondary">Ollama: {process.env.REACT_APP_OLLAMA_URL}</li>
410
  <li className="text-bolt-elements-textSecondary">OpenAI: {process.env.REACT_APP_OPENAI_URL}</li>
411
- <li className="text-bolt-elements-textSecondary">LM Studio: {process.env.REACT_APP_LM_STUDIO_URL}</li>
 
 
412
  </ul>
413
 
414
  <h4 className="text-md font-medium text-bolt-elements-textPrimary mt-4">Version Information</h4>
 
10
  import { useNavigate } from '@remix-run/react';
11
  import commit from '~/commit.json';
12
  import Cookies from 'js-cookie';
 
13
  import '~/styles/components/SettingsSlider.scss';
14
  import '~/styles/components/Settings.scss';
15
 
 
218
  <button
219
  key={tab.id}
220
  onClick={() => setActiveTab(tab.id)}
221
+ className={classNames(activeTab === tab.id ? 'active' : '')}
 
 
222
  >
223
  <div className={tab.icon} />
224
  {tab.label}
 
247
  </div>
248
 
249
  <div className="flex-1 flex flex-col p-8 bg-gray-50 dark:bg-gray-800">
250
+ <DialogTitle className="flex-shrink-0 text-lg font-semibold text-bolt-elements-textPrimary">
251
+ Settings
252
+ </DialogTitle>
253
  <div className="flex-1 overflow-y-auto">
254
  {activeTab === 'chat-history' && (
255
  <div className="p-4">
 
303
  checked={provider.isEnabled}
304
  onChange={() => handleToggleProvider(provider.name)}
305
  />
306
+ <div
307
+ className={classNames(
308
+ 'settings-toggle__track',
309
+ provider.isEnabled
310
+ ? 'settings-toggle__track--enabled'
311
+ : 'settings-toggle__track--disabled',
312
+ )}
313
+ ></div>
314
+ <div
315
+ className={classNames(
316
+ 'settings-toggle__thumb',
317
+ provider.isEnabled ? 'settings-toggle__thumb--enabled' : '',
318
+ )}
319
+ ></div>
320
  </label>
321
  </div>
322
  {/* Base URL input for configurable providers */}
 
348
  checked={isDebugEnabled}
349
  onChange={() => setIsDebugEnabled(!isDebugEnabled)}
350
  />
351
+ <div
352
+ className={classNames(
353
+ 'settings-toggle__track',
354
+ isDebugEnabled ? 'settings-toggle__track--enabled' : 'settings-toggle__track--disabled',
355
+ )}
356
+ ></div>
357
+ <div
358
+ className={classNames(
359
+ 'settings-toggle__thumb',
360
+ isDebugEnabled ? 'settings-toggle__thumb--enabled' : '',
361
+ )}
362
+ ></div>
363
  </label>
364
  </div>
365
  </div>
 
376
  checked={isJustSayEnabled}
377
  onChange={() => setIsJustSayEnabled(!isJustSayEnabled)}
378
  />
379
+ <div
380
+ className={classNames(
381
+ 'settings-toggle__track',
382
+ isJustSayEnabled ? 'settings-toggle__track--enabled' : 'settings-toggle__track--disabled',
383
+ )}
384
+ ></div>
385
+ <div
386
+ className={classNames(
387
+ 'settings-toggle__thumb',
388
+ isJustSayEnabled ? 'settings-toggle__thumb--enabled' : '',
389
+ )}
390
+ ></div>
391
  </label>
392
  </div>
393
  </div>
 
421
  <ul>
422
  <li className="text-bolt-elements-textSecondary">Ollama: {process.env.REACT_APP_OLLAMA_URL}</li>
423
  <li className="text-bolt-elements-textSecondary">OpenAI: {process.env.REACT_APP_OPENAI_URL}</li>
424
+ <li className="text-bolt-elements-textSecondary">
425
+ LM Studio: {process.env.REACT_APP_LM_STUDIO_URL}
426
+ </li>
427
  </ul>
428
 
429
  <h4 className="text-md font-medium text-bolt-elements-textPrimary mt-4">Version Information</h4>
app/components/ui/SettingsSlider.tsx CHANGED
@@ -27,7 +27,7 @@ export const SettingsSlider = memo(<T,>({ selected, options, setSelected }: Sett
27
  <motion.div
28
  className={classNames(
29
  'settings-slider__thumb',
30
- isLeftSelected ? 'settings-slider__thumb--left' : 'settings-slider__thumb--right'
31
  )}
32
  initial={false}
33
  animate={{
@@ -44,7 +44,7 @@ export const SettingsSlider = memo(<T,>({ selected, options, setSelected }: Sett
44
  onClick={() => setSelected?.(options.left.value)}
45
  className={classNames(
46
  'settings-slider__button',
47
- isLeftSelected ? 'settings-slider__button--selected' : 'settings-slider__button--unselected'
48
  )}
49
  >
50
  {options.left.text}
@@ -53,7 +53,7 @@ export const SettingsSlider = memo(<T,>({ selected, options, setSelected }: Sett
53
  onClick={() => setSelected?.(options.right.value)}
54
  className={classNames(
55
  'settings-slider__button',
56
- !isLeftSelected ? 'settings-slider__button--selected' : 'settings-slider__button--unselected'
57
  )}
58
  >
59
  {options.right.text}
 
27
  <motion.div
28
  className={classNames(
29
  'settings-slider__thumb',
30
+ isLeftSelected ? 'settings-slider__thumb--left' : 'settings-slider__thumb--right',
31
  )}
32
  initial={false}
33
  animate={{
 
44
  onClick={() => setSelected?.(options.left.value)}
45
  className={classNames(
46
  'settings-slider__button',
47
+ isLeftSelected ? 'settings-slider__button--selected' : 'settings-slider__button--unselected',
48
  )}
49
  >
50
  {options.left.text}
 
53
  onClick={() => setSelected?.(options.right.value)}
54
  className={classNames(
55
  'settings-slider__button',
56
+ !isLeftSelected ? 'settings-slider__button--selected' : 'settings-slider__button--unselected',
57
  )}
58
  >
59
  {options.right.text}