Commit
·
96020a5
1
Parent(s):
19816d9
More styling changes
Browse filesAdded settings scss file and a settings slider scss
app/components/ui/Settings.tsx
CHANGED
@@ -11,6 +11,8 @@ import { useNavigate } from '@remix-run/react';
|
|
11 |
import commit from '~/commit.json';
|
12 |
import Cookies from 'js-cookie';
|
13 |
import { SettingsSlider } from './SettingsSlider';
|
|
|
|
|
14 |
|
15 |
interface SettingsProps {
|
16 |
open: boolean;
|
@@ -28,6 +30,7 @@ export const Settings = ({ open, onClose }: SettingsProps) => {
|
|
28 |
const [isDebugEnabled, setIsDebugEnabled] = useState(false);
|
29 |
const [searchTerm, setSearchTerm] = useState('');
|
30 |
const [isDeleting, setIsDeleting] = useState(false);
|
|
|
31 |
|
32 |
// Load base URLs from cookies
|
33 |
const [baseUrls, setBaseUrls] = useState(() => {
|
@@ -211,16 +214,13 @@ export const Settings = ({ open, onClose }: SettingsProps) => {
|
|
211 |
variants={dialogVariants}
|
212 |
>
|
213 |
<div className="flex h-full">
|
214 |
-
<div className="w-48 border-r border-bolt-elements-borderColor bg-gray-700 p-4 flex flex-col justify-between">
|
215 |
{tabs.map((tab) => (
|
216 |
<button
|
217 |
key={tab.id}
|
218 |
onClick={() => setActiveTab(tab.id)}
|
219 |
className={classNames(
|
220 |
-
|
221 |
-
activeTab === tab.id
|
222 |
-
? 'bg-gradient-to-r from-purple-500 to-blue-500 text-white'
|
223 |
-
: 'bg-gray-600 text-gray-200 hover:bg-gradient-to-r hover:from-purple-400 hover:to-blue-400',
|
224 |
)}
|
225 |
>
|
226 |
<div className={tab.icon} />
|
@@ -232,16 +232,18 @@ export const Settings = ({ open, onClose }: SettingsProps) => {
|
|
232 |
href="https://github.com/coleam00/bolt.new-any-llm"
|
233 |
target="_blank"
|
234 |
rel="noopener noreferrer"
|
235 |
-
className="flex items-center
|
236 |
>
|
|
|
237 |
GitHub
|
238 |
</a>
|
239 |
<a
|
240 |
href="https://coleam00.github.io/bolt.new-any-llm"
|
241 |
target="_blank"
|
242 |
rel="noopener noreferrer"
|
243 |
-
className="flex items-center
|
244 |
>
|
|
|
245 |
Docs
|
246 |
</a>
|
247 |
</div>
|
@@ -260,7 +262,7 @@ export const Settings = ({ open, onClose }: SettingsProps) => {
|
|
260 |
Export All Chats
|
261 |
</button>
|
262 |
|
263 |
-
<div className="text-white rounded-lg p-4 mb-4">
|
264 |
<h4 className="font-semibold">Danger Area</h4>
|
265 |
<p className="mb-2">This action cannot be undone!</p>
|
266 |
<button
|
@@ -302,12 +304,14 @@ export const Settings = ({ open, onClose }: SettingsProps) => {
|
|
302 |
checked={provider.isEnabled}
|
303 |
onChange={() => handleToggleProvider(provider.name)}
|
304 |
/>
|
305 |
-
<div className={
|
306 |
-
|
307 |
-
|
308 |
-
|
309 |
-
|
310 |
-
|
|
|
|
|
311 |
</label>
|
312 |
</div>
|
313 |
{/* Base URL input for configurable providers */}
|
@@ -328,7 +332,7 @@ export const Settings = ({ open, onClose }: SettingsProps) => {
|
|
328 |
</div>
|
329 |
)}
|
330 |
{activeTab === 'features' && (
|
331 |
-
<div className="p-4 bg-bolt-elements-background-depth-2 border border-bolt-elements-borderColor rounded-lg">
|
332 |
<h3 className="text-lg font-medium text-white mb-4">Feature Settings</h3>
|
333 |
<div className="flex items-center justify-between mb-2">
|
334 |
<span className="text-white">Debug Info</span>
|
@@ -339,15 +343,40 @@ export const Settings = ({ open, onClose }: SettingsProps) => {
|
|
339 |
checked={isDebugEnabled}
|
340 |
onChange={() => setIsDebugEnabled(!isDebugEnabled)}
|
341 |
/>
|
342 |
-
<div className={
|
343 |
-
|
344 |
-
|
345 |
-
|
346 |
-
|
347 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
348 |
</label>
|
349 |
</div>
|
350 |
-
<div className="feature-row">{/* Your feature content here */}</div>
|
351 |
</div>
|
352 |
)}
|
353 |
{activeTab === 'debug' && isDebugEnabled && (
|
|
|
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 |
|
17 |
interface SettingsProps {
|
18 |
open: boolean;
|
|
|
30 |
const [isDebugEnabled, setIsDebugEnabled] = useState(false);
|
31 |
const [searchTerm, setSearchTerm] = useState('');
|
32 |
const [isDeleting, setIsDeleting] = useState(false);
|
33 |
+
const [isJustSayEnabled, setIsJustSayEnabled] = useState(false);
|
34 |
|
35 |
// Load base URLs from cookies
|
36 |
const [baseUrls, setBaseUrls] = useState(() => {
|
|
|
214 |
variants={dialogVariants}
|
215 |
>
|
216 |
<div className="flex h-full">
|
217 |
+
<div className="w-48 border-r border-bolt-elements-borderColor bg-gray-700 p-4 flex flex-col justify-between settings-tabs">
|
218 |
{tabs.map((tab) => (
|
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} />
|
|
|
232 |
href="https://github.com/coleam00/bolt.new-any-llm"
|
233 |
target="_blank"
|
234 |
rel="noopener noreferrer"
|
235 |
+
className="settings-button flex items-center gap-2"
|
236 |
>
|
237 |
+
<div className="i-ph:github-logo" />
|
238 |
GitHub
|
239 |
</a>
|
240 |
<a
|
241 |
href="https://coleam00.github.io/bolt.new-any-llm"
|
242 |
target="_blank"
|
243 |
rel="noopener noreferrer"
|
244 |
+
className="settings-button flex items-center gap-2"
|
245 |
>
|
246 |
+
<div className="i-ph:book" />
|
247 |
Docs
|
248 |
</a>
|
249 |
</div>
|
|
|
262 |
Export All Chats
|
263 |
</button>
|
264 |
|
265 |
+
<div className="text-white rounded-lg p-4 mb-4 settings-danger-area">
|
266 |
<h4 className="font-semibold">Danger Area</h4>
|
267 |
<p className="mb-2">This action cannot be undone!</p>
|
268 |
<button
|
|
|
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 */}
|
|
|
332 |
</div>
|
333 |
)}
|
334 |
{activeTab === 'features' && (
|
335 |
+
<div className="p-4 bg-bolt-elements-background-depth-2 border border-bolt-elements-borderColor rounded-lg mb-4">
|
336 |
<h3 className="text-lg font-medium text-white mb-4">Feature Settings</h3>
|
337 |
<div className="flex items-center justify-between mb-2">
|
338 |
<span className="text-white">Debug Info</span>
|
|
|
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>
|
357 |
+
)}
|
358 |
+
{activeTab === 'features' && (
|
359 |
+
<div className="p-4 bg-bolt-elements-background-depth-2 border border-bolt-elements-borderColor rounded-lg">
|
360 |
+
<h3 className="text-lg font-medium text-white mb-4">Experimental Area</h3>
|
361 |
+
<div className="flex items-center justify-between mb-2">
|
362 |
+
<span className="text-white">Replace with local models</span>
|
363 |
+
<label className="relative inline-flex items-center cursor-pointer">
|
364 |
+
<input
|
365 |
+
type="checkbox"
|
366 |
+
className="sr-only"
|
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>
|
381 |
)}
|
382 |
{activeTab === 'debug' && isDebugEnabled && (
|
app/components/ui/SettingsSlider.tsx
CHANGED
@@ -1,6 +1,7 @@
|
|
1 |
import { motion } from 'framer-motion';
|
2 |
import { memo } from 'react';
|
3 |
import { classNames } from '~/utils/classNames';
|
|
|
4 |
|
5 |
interface SliderOption<T> {
|
6 |
value: T;
|
@@ -22,11 +23,11 @@ export const SettingsSlider = memo(<T,>({ selected, options, setSelected }: Sett
|
|
22 |
const isLeftSelected = selected === options.left.value;
|
23 |
|
24 |
return (
|
25 |
-
<div className="
|
26 |
<motion.div
|
27 |
className={classNames(
|
28 |
-
'
|
29 |
-
isLeftSelected ? 'left
|
30 |
)}
|
31 |
initial={false}
|
32 |
animate={{
|
@@ -42,8 +43,8 @@ export const SettingsSlider = memo(<T,>({ selected, options, setSelected }: Sett
|
|
42 |
<button
|
43 |
onClick={() => setSelected?.(options.left.value)}
|
44 |
className={classNames(
|
45 |
-
'
|
46 |
-
isLeftSelected ? '
|
47 |
)}
|
48 |
>
|
49 |
{options.left.text}
|
@@ -51,8 +52,8 @@ export const SettingsSlider = memo(<T,>({ selected, options, setSelected }: Sett
|
|
51 |
<button
|
52 |
onClick={() => setSelected?.(options.right.value)}
|
53 |
className={classNames(
|
54 |
-
'
|
55 |
-
!isLeftSelected ? '
|
56 |
)}
|
57 |
>
|
58 |
{options.right.text}
|
|
|
1 |
import { motion } from 'framer-motion';
|
2 |
import { memo } from 'react';
|
3 |
import { classNames } from '~/utils/classNames';
|
4 |
+
import '~/styles/components/SettingsSlider.scss';
|
5 |
|
6 |
interface SliderOption<T> {
|
7 |
value: T;
|
|
|
23 |
const isLeftSelected = selected === options.left.value;
|
24 |
|
25 |
return (
|
26 |
+
<div className="settings-slider">
|
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={{
|
|
|
43 |
<button
|
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}
|
|
|
52 |
<button
|
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}
|
app/styles/components/Settings.scss
ADDED
@@ -0,0 +1,60 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
.settings-tabs {
|
2 |
+
button {
|
3 |
+
width: 100%;
|
4 |
+
display: flex;
|
5 |
+
align-items: center;
|
6 |
+
gap: 0.5rem;
|
7 |
+
padding: 0.75rem 1rem;
|
8 |
+
border-radius: 0.5rem;
|
9 |
+
text-align: left;
|
10 |
+
font-size: 0.875rem;
|
11 |
+
transition: all 0.2s;
|
12 |
+
margin-bottom: 0.5rem;
|
13 |
+
|
14 |
+
&.active {
|
15 |
+
background: #b44aff;
|
16 |
+
color: white;
|
17 |
+
}
|
18 |
+
|
19 |
+
&:not(.active) {
|
20 |
+
background: #4b5563;
|
21 |
+
color: #e5e7eb;
|
22 |
+
|
23 |
+
&:hover {
|
24 |
+
background: linear-gradient(to right, #6b5bff, #3b82f6);
|
25 |
+
}
|
26 |
+
}
|
27 |
+
}
|
28 |
+
}
|
29 |
+
|
30 |
+
.settings-button {
|
31 |
+
background-color: #b44aff;
|
32 |
+
color: white;
|
33 |
+
border-radius: 0.5rem;
|
34 |
+
padding: 0.5rem 1rem;
|
35 |
+
transition: background-color 0.2s;
|
36 |
+
|
37 |
+
&:hover {
|
38 |
+
background-color: #2563eb;
|
39 |
+
}
|
40 |
+
}
|
41 |
+
|
42 |
+
.settings-danger-area {
|
43 |
+
background-color: transparent;
|
44 |
+
color: white;
|
45 |
+
border-radius: 0.5rem;
|
46 |
+
padding: 1rem;
|
47 |
+
margin-bottom: 1rem;
|
48 |
+
|
49 |
+
button {
|
50 |
+
background-color: #dc2626;
|
51 |
+
color: white;
|
52 |
+
border-radius: 0.5rem;
|
53 |
+
padding: 0.5rem 1rem;
|
54 |
+
transition: background-color 0.2s;
|
55 |
+
|
56 |
+
&:hover {
|
57 |
+
background-color: #b91c1c;
|
58 |
+
}
|
59 |
+
}
|
60 |
+
}
|
app/styles/components/SettingsSlider.scss
ADDED
@@ -0,0 +1,50 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
.settings-slider {
|
2 |
+
@apply relative flex items-center bg-bolt-elements-prompt-background rounded-lg;
|
3 |
+
|
4 |
+
&__thumb {
|
5 |
+
@apply absolute h-full transition-all duration-300 rounded-lg;
|
6 |
+
background-color: #b44aff;
|
7 |
+
|
8 |
+
&--left {
|
9 |
+
@apply left-0 w-1/2;
|
10 |
+
}
|
11 |
+
|
12 |
+
&--right {
|
13 |
+
@apply right-0 w-1/2;
|
14 |
+
}
|
15 |
+
}
|
16 |
+
|
17 |
+
&__button {
|
18 |
+
@apply relative z-10 flex-1 p-2 rounded-lg text-sm transition-colors duration-200;
|
19 |
+
|
20 |
+
&--selected {
|
21 |
+
@apply text-white;
|
22 |
+
}
|
23 |
+
|
24 |
+
&--unselected {
|
25 |
+
@apply text-bolt-elements-textSecondary hover:text-bolt-elements-textPrimary;
|
26 |
+
}
|
27 |
+
}
|
28 |
+
}
|
29 |
+
|
30 |
+
.settings-toggle {
|
31 |
+
&__track {
|
32 |
+
@apply w-11 h-6 rounded-full shadow-inner transition-colors duration-200;
|
33 |
+
|
34 |
+
&--enabled {
|
35 |
+
background-color: #b44aff;
|
36 |
+
}
|
37 |
+
|
38 |
+
&--disabled {
|
39 |
+
@apply bg-gray-300;
|
40 |
+
}
|
41 |
+
}
|
42 |
+
|
43 |
+
&__thumb {
|
44 |
+
@apply absolute left-0 w-6 h-6 rounded-full shadow transition-transform duration-200 ease-in-out bg-white;
|
45 |
+
|
46 |
+
&--enabled {
|
47 |
+
@apply transform translate-x-full;
|
48 |
+
}
|
49 |
+
}
|
50 |
+
}
|