@lastbrain/ai-ui-react 1.0.49 → 1.0.52
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/AiChipLabel.d.ts.map +1 -1
- package/dist/components/AiChipLabel.js +27 -5
- package/dist/components/AiContextButton.d.ts.map +1 -1
- package/dist/components/AiContextButton.js +5 -3
- package/dist/components/AiImageButton.d.ts.map +1 -1
- package/dist/components/AiImageButton.js +5 -2
- package/dist/components/AiSelect.d.ts.map +1 -1
- package/dist/components/AiSelect.js +38 -2
- package/dist/components/AiStatusButton.d.ts.map +1 -1
- package/dist/components/AiStatusButton.js +24 -12
- package/dist/components/AiTextarea.d.ts.map +1 -1
- package/dist/components/AiTextarea.js +2 -2
- package/dist/components/LBApiKeySelector.d.ts.map +1 -1
- package/dist/components/LBApiKeySelector.js +21 -23
- package/dist/components/LBSigninModal.d.ts.map +1 -1
- package/dist/components/LBSigninModal.js +206 -115
- package/dist/context/LBAuthProvider.d.ts +5 -1
- package/dist/context/LBAuthProvider.d.ts.map +1 -1
- package/dist/context/LBAuthProvider.js +67 -0
- package/package.json +2 -2
- package/src/components/AiChipLabel.tsx +34 -5
- package/src/components/AiContextButton.tsx +9 -13
- package/src/components/AiImageButton.tsx +15 -12
- package/src/components/AiSelect.tsx +71 -1
- package/src/components/AiStatusButton.tsx +28 -15
- package/src/components/AiTextarea.tsx +2 -12
- package/src/components/LBApiKeySelector.tsx +21 -23
- package/src/components/LBSigninModal.tsx +278 -159
- package/src/context/LBAuthProvider.tsx +77 -3
- package/README.md +0 -147
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
|
|
3
3
|
import { useState, type ButtonHTMLAttributes } from "react";
|
|
4
|
-
import { Loader2, X, FileText, Sparkle, Download } from "lucide-react";
|
|
4
|
+
import { Loader2, X, FileText, Sparkle, Download, Lock } from "lucide-react";
|
|
5
5
|
import type { BaseAiProps } from "../types";
|
|
6
6
|
import { useAiCallText } from "../hooks/useAiCallText";
|
|
7
7
|
import { AiPromptPanel } from "./AiPromptPanel";
|
|
@@ -272,7 +272,7 @@ Analyse ces données et réponds de manière structurée et claire.`;
|
|
|
272
272
|
border: "none",
|
|
273
273
|
borderRadius: "12px",
|
|
274
274
|
// padding: "12px 20px",
|
|
275
|
-
|
|
275
|
+
|
|
276
276
|
fontSize: "14px",
|
|
277
277
|
fontWeight: "600",
|
|
278
278
|
minWidth: "20px",
|
|
@@ -332,17 +332,13 @@ Analyse ces données et réponds de manière structurée et claire.`;
|
|
|
332
332
|
</>
|
|
333
333
|
) : !isAuthReady ? (
|
|
334
334
|
<>
|
|
335
|
-
<
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
>
|
|
343
|
-
<rect x="3" y="11" width="18" height="11" rx="2" ry="2" />
|
|
344
|
-
<path d="M7 11V7a5 5 0 0 1 10 0v4" />
|
|
345
|
-
</svg>
|
|
335
|
+
<Lock
|
|
336
|
+
size={18}
|
|
337
|
+
style={{
|
|
338
|
+
color: "white",
|
|
339
|
+
filter: "drop-shadow(0 0 2px rgba(255,255,255,0.2))",
|
|
340
|
+
}}
|
|
341
|
+
/>
|
|
346
342
|
{children || <span>Connexion requise</span>}
|
|
347
343
|
</>
|
|
348
344
|
) : (
|
|
@@ -1,7 +1,14 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
|
|
3
3
|
import { useState, type ButtonHTMLAttributes } from "react";
|
|
4
|
-
import {
|
|
4
|
+
import {
|
|
5
|
+
ImageIcon,
|
|
6
|
+
Loader2,
|
|
7
|
+
Download,
|
|
8
|
+
ExternalLink,
|
|
9
|
+
X,
|
|
10
|
+
Lock,
|
|
11
|
+
} from "lucide-react";
|
|
5
12
|
import type { BaseAiProps } from "../types";
|
|
6
13
|
import { useAiCallImage } from "../hooks/useAiCallImage";
|
|
7
14
|
import { AiPromptPanel } from "./AiPromptPanel";
|
|
@@ -291,17 +298,13 @@ export function AiImageButton({
|
|
|
291
298
|
</>
|
|
292
299
|
) : !isAuthReady ? (
|
|
293
300
|
<>
|
|
294
|
-
<
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
>
|
|
302
|
-
<rect x="3" y="11" width="18" height="11" rx="2" ry="2" />
|
|
303
|
-
<path d="M7 11V7a5 5 0 0 1 10 0v4" />
|
|
304
|
-
</svg>
|
|
301
|
+
<Lock
|
|
302
|
+
size={18}
|
|
303
|
+
style={{
|
|
304
|
+
color: "white",
|
|
305
|
+
filter: "drop-shadow(0 0 2px rgba(255,255,255,0.2))",
|
|
306
|
+
}}
|
|
307
|
+
/>
|
|
305
308
|
{children || <span>Connexion requise</span>}
|
|
306
309
|
</>
|
|
307
310
|
) : (
|
|
@@ -1,13 +1,16 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
|
|
3
3
|
import React, { useState, type SelectHTMLAttributes } from "react";
|
|
4
|
+
import { Sparkles, Lock } from "lucide-react";
|
|
4
5
|
import type { BaseAiProps } from "../types";
|
|
5
6
|
import { useAiCallText } from "../hooks/useAiCallText";
|
|
6
7
|
import { useAiModels } from "../hooks/useAiModels";
|
|
7
8
|
import { AiPromptPanel } from "./AiPromptPanel";
|
|
8
9
|
import { UsageToast, useUsageToast } from "./UsageToast";
|
|
10
|
+
import { LBSigninModal } from "./LBSigninModal";
|
|
9
11
|
import { aiStyles } from "../styles/inline";
|
|
10
12
|
import { handleAIError } from "../utils/errorHandler";
|
|
13
|
+
import { useLB } from "../context/LBAuthProvider";
|
|
11
14
|
|
|
12
15
|
export interface AiSelectProps
|
|
13
16
|
extends
|
|
@@ -34,9 +37,20 @@ export function AiSelect({
|
|
|
34
37
|
...selectProps
|
|
35
38
|
}: AiSelectProps) {
|
|
36
39
|
const [isOpen, setIsOpen] = useState(false);
|
|
40
|
+
const [showAuthModal, setShowAuthModal] = useState(false);
|
|
37
41
|
const [isFocused, setIsFocused] = useState(false);
|
|
38
42
|
const { showUsageToast, toastData, toastKey, clearToast } = useUsageToast();
|
|
39
43
|
|
|
44
|
+
// Rendre l'authentification optionnelle
|
|
45
|
+
let lbStatus: string | undefined;
|
|
46
|
+
try {
|
|
47
|
+
const lbContext = useLB();
|
|
48
|
+
lbStatus = lbContext.status;
|
|
49
|
+
} catch {
|
|
50
|
+
// LBProvider n'est pas disponible, ignorer
|
|
51
|
+
lbStatus = undefined;
|
|
52
|
+
}
|
|
53
|
+
|
|
40
54
|
const { models } = useAiModels({
|
|
41
55
|
baseUrl,
|
|
42
56
|
apiKeyId,
|
|
@@ -44,7 +58,14 @@ export function AiSelect({
|
|
|
44
58
|
});
|
|
45
59
|
const { generateText, loading } = useAiCallText({ baseUrl, apiKeyId });
|
|
46
60
|
|
|
61
|
+
const isAuthReady = lbStatus === "ready" || Boolean(process.env.LB_API_KEY);
|
|
62
|
+
const shouldShowSparkles = isAuthReady && !disabled;
|
|
63
|
+
|
|
47
64
|
const handleOpenPanel = () => {
|
|
65
|
+
if (!isAuthReady) {
|
|
66
|
+
setShowAuthModal(true);
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
48
69
|
setIsOpen(true);
|
|
49
70
|
};
|
|
50
71
|
|
|
@@ -79,12 +100,13 @@ export function AiSelect({
|
|
|
79
100
|
};
|
|
80
101
|
|
|
81
102
|
return (
|
|
82
|
-
<div style={{ width: "100%" }} className={className}>
|
|
103
|
+
<div style={{ width: "100%", position: "relative" }} className={className}>
|
|
83
104
|
<select
|
|
84
105
|
{...selectProps}
|
|
85
106
|
style={{
|
|
86
107
|
...aiStyles.select,
|
|
87
108
|
...(isFocused && aiStyles.selectFocus),
|
|
109
|
+
paddingRight: "40px", // Space for AI button
|
|
88
110
|
}}
|
|
89
111
|
onFocus={(e) => {
|
|
90
112
|
setIsFocused(true);
|
|
@@ -98,6 +120,48 @@ export function AiSelect({
|
|
|
98
120
|
>
|
|
99
121
|
{children}
|
|
100
122
|
</select>
|
|
123
|
+
|
|
124
|
+
{/* AI Button */}
|
|
125
|
+
<button
|
|
126
|
+
onClick={handleOpenPanel}
|
|
127
|
+
style={{
|
|
128
|
+
position: "absolute",
|
|
129
|
+
right: "8px",
|
|
130
|
+
top: "50%",
|
|
131
|
+
transform: "translateY(-50%)",
|
|
132
|
+
background: "none",
|
|
133
|
+
border: "none",
|
|
134
|
+
cursor: "pointer",
|
|
135
|
+
padding: "4px",
|
|
136
|
+
borderRadius: "4px",
|
|
137
|
+
display: "flex",
|
|
138
|
+
alignItems: "center",
|
|
139
|
+
color: shouldShowSparkles ? "#6366f1" : "#ef4444",
|
|
140
|
+
}}
|
|
141
|
+
title={
|
|
142
|
+
shouldShowSparkles
|
|
143
|
+
? "Générer avec l'IA"
|
|
144
|
+
: "Se connecter pour utiliser l'IA"
|
|
145
|
+
}
|
|
146
|
+
disabled={disabled || loading}
|
|
147
|
+
>
|
|
148
|
+
{loading ? (
|
|
149
|
+
<svg
|
|
150
|
+
style={aiStyles.spinner}
|
|
151
|
+
width="16"
|
|
152
|
+
height="16"
|
|
153
|
+
viewBox="0 0 24 24"
|
|
154
|
+
fill="none"
|
|
155
|
+
stroke="currentColor"
|
|
156
|
+
>
|
|
157
|
+
<path d="M12 2v4m0 12v4M4.93 4.93l2.83 2.83m8.48 8.48l2.83 2.83M2 12h4m12 0h4M4.93 19.07l2.83-2.83m8.48-8.48l2.83-2.83" />
|
|
158
|
+
</svg>
|
|
159
|
+
) : shouldShowSparkles ? (
|
|
160
|
+
<Sparkles size={16} />
|
|
161
|
+
) : (
|
|
162
|
+
<Lock size={16} />
|
|
163
|
+
)}
|
|
164
|
+
</button>
|
|
101
165
|
{isOpen && (
|
|
102
166
|
<AiPromptPanel
|
|
103
167
|
isOpen={isOpen}
|
|
@@ -115,6 +179,12 @@ export function AiSelect({
|
|
|
115
179
|
onComplete={clearToast}
|
|
116
180
|
/>
|
|
117
181
|
)}
|
|
182
|
+
|
|
183
|
+
{/* Modal signin pour les utilisateurs non connectés */}
|
|
184
|
+
<LBSigninModal
|
|
185
|
+
isOpen={showAuthModal}
|
|
186
|
+
onClose={() => setShowAuthModal(false)}
|
|
187
|
+
/>
|
|
118
188
|
</div>
|
|
119
189
|
);
|
|
120
190
|
}
|
|
@@ -12,7 +12,7 @@ import {
|
|
|
12
12
|
Power,
|
|
13
13
|
LogOut,
|
|
14
14
|
Key,
|
|
15
|
-
|
|
15
|
+
ArrowRightLeft,
|
|
16
16
|
} from "lucide-react";
|
|
17
17
|
import { aiStyles, calculateTooltipPosition } from "../styles/inline";
|
|
18
18
|
import { useLB } from "../context/LBAuthProvider";
|
|
@@ -38,6 +38,7 @@ export function AiStatusButton({
|
|
|
38
38
|
let apiKeys: any[] = [];
|
|
39
39
|
let accessToken: string | undefined;
|
|
40
40
|
let selectApiKeyWithToken: ((apiKeyId: string) => Promise<void>) | undefined;
|
|
41
|
+
let lbApiStatus: any = null;
|
|
41
42
|
|
|
42
43
|
try {
|
|
43
44
|
const lbContext = useLB();
|
|
@@ -47,6 +48,7 @@ export function AiStatusButton({
|
|
|
47
48
|
apiKeys = lbContext.apiKeys || [];
|
|
48
49
|
accessToken = lbContext.accessToken;
|
|
49
50
|
selectApiKeyWithToken = lbContext.selectApiKeyWithToken;
|
|
51
|
+
lbApiStatus = lbContext.apiStatus;
|
|
50
52
|
} catch {
|
|
51
53
|
// LBProvider n'est pas disponible, ignorer
|
|
52
54
|
lbStatus = undefined;
|
|
@@ -54,6 +56,9 @@ export function AiStatusButton({
|
|
|
54
56
|
logout = undefined;
|
|
55
57
|
}
|
|
56
58
|
|
|
59
|
+
// Utiliser le status du contexte LB si pas de prop status
|
|
60
|
+
const effectiveStatus = status || lbApiStatus;
|
|
61
|
+
|
|
57
62
|
// Récupérer refetchProviders depuis AiProvider si disponible
|
|
58
63
|
let refetchProviders: (() => Promise<void>) | undefined;
|
|
59
64
|
try {
|
|
@@ -155,8 +160,8 @@ export function AiStatusButton({
|
|
|
155
160
|
);
|
|
156
161
|
};
|
|
157
162
|
|
|
158
|
-
const balanceUsage =
|
|
159
|
-
const storageUsage =
|
|
163
|
+
const balanceUsage = effectiveStatus?.balance as BalanceUsage | undefined;
|
|
164
|
+
const storageUsage = effectiveStatus?.storage as StorageUsage | undefined;
|
|
160
165
|
|
|
161
166
|
const balanceTotal =
|
|
162
167
|
balanceUsage?.total ??
|
|
@@ -300,7 +305,7 @@ export function AiStatusButton({
|
|
|
300
305
|
);
|
|
301
306
|
}
|
|
302
307
|
|
|
303
|
-
if (!
|
|
308
|
+
if (!effectiveStatus) {
|
|
304
309
|
// Si pas de statut API et pas de LBProvider, afficher message simple
|
|
305
310
|
if (!lbStatus && lbStatus !== "ready") {
|
|
306
311
|
return (
|
|
@@ -592,7 +597,6 @@ export function AiStatusButton({
|
|
|
592
597
|
</div>
|
|
593
598
|
<div
|
|
594
599
|
style={{
|
|
595
|
-
...aiStyles.tooltipSection,
|
|
596
600
|
paddingBottom: "12px",
|
|
597
601
|
}}
|
|
598
602
|
>
|
|
@@ -691,7 +695,7 @@ export function AiStatusButton({
|
|
|
691
695
|
<div style={aiStyles.tooltipHeader}>API Status</div>
|
|
692
696
|
|
|
693
697
|
{/* User Info Section */}
|
|
694
|
-
{
|
|
698
|
+
{effectiveStatus.user?.email && (
|
|
695
699
|
<div
|
|
696
700
|
style={{
|
|
697
701
|
...aiStyles.tooltipSection,
|
|
@@ -709,7 +713,7 @@ export function AiStatusButton({
|
|
|
709
713
|
textOverflow: "ellipsis",
|
|
710
714
|
}}
|
|
711
715
|
>
|
|
712
|
-
{
|
|
716
|
+
{effectiveStatus.user.email}
|
|
713
717
|
</span>
|
|
714
718
|
</div>
|
|
715
719
|
</div>
|
|
@@ -718,7 +722,9 @@ export function AiStatusButton({
|
|
|
718
722
|
<div
|
|
719
723
|
style={{
|
|
720
724
|
...aiStyles.tooltipSection,
|
|
721
|
-
...(
|
|
725
|
+
...(effectiveStatus.user?.email
|
|
726
|
+
? {}
|
|
727
|
+
: aiStyles.tooltipSectionFirst),
|
|
722
728
|
}}
|
|
723
729
|
>
|
|
724
730
|
<div style={aiStyles.tooltipRow}>
|
|
@@ -731,12 +737,15 @@ export function AiStatusButton({
|
|
|
731
737
|
}}
|
|
732
738
|
>
|
|
733
739
|
<span style={aiStyles.tooltipValue}>
|
|
734
|
-
{
|
|
740
|
+
{effectiveStatus.apiKey?.name ||
|
|
741
|
+
effectiveStatus.api_key?.name ||
|
|
742
|
+
"Unknown"}
|
|
735
743
|
</span>
|
|
736
|
-
{
|
|
744
|
+
{selectApiKeyWithToken && (
|
|
737
745
|
<button
|
|
738
746
|
onClick={(e) => {
|
|
739
747
|
e.stopPropagation();
|
|
748
|
+
setShowTooltip(false);
|
|
740
749
|
setShowApiKeySelector(true);
|
|
741
750
|
}}
|
|
742
751
|
style={{
|
|
@@ -766,7 +775,7 @@ export function AiStatusButton({
|
|
|
766
775
|
}}
|
|
767
776
|
title="Change API Key"
|
|
768
777
|
>
|
|
769
|
-
<
|
|
778
|
+
<ArrowRightLeft
|
|
770
779
|
size={12}
|
|
771
780
|
style={{ color: "rgba(139, 92, 246, 1)" }}
|
|
772
781
|
/>
|
|
@@ -777,14 +786,16 @@ export function AiStatusButton({
|
|
|
777
786
|
<div style={aiStyles.tooltipRow}>
|
|
778
787
|
<span style={aiStyles.tooltipLabel}>Env:</span>
|
|
779
788
|
<span style={aiStyles.tooltipValue}>
|
|
780
|
-
{
|
|
789
|
+
{effectiveStatus.apiKey?.env ||
|
|
790
|
+
effectiveStatus.api_key?.env ||
|
|
791
|
+
"N/A"}
|
|
781
792
|
</span>
|
|
782
793
|
</div>
|
|
783
794
|
<div style={aiStyles.tooltipRow}>
|
|
784
795
|
<span style={aiStyles.tooltipLabel}>Rate Limit:</span>
|
|
785
796
|
<span style={aiStyles.tooltipValue}>
|
|
786
|
-
{
|
|
787
|
-
|
|
797
|
+
{effectiveStatus.apiKey?.rate_limit_rpm ||
|
|
798
|
+
effectiveStatus.api_key?.rate_limit_rpm ||
|
|
788
799
|
0}{" "}
|
|
789
800
|
req/min
|
|
790
801
|
</span>
|
|
@@ -792,7 +803,7 @@ export function AiStatusButton({
|
|
|
792
803
|
</div>
|
|
793
804
|
|
|
794
805
|
<div style={aiStyles.tooltipSection}>
|
|
795
|
-
<div style={aiStyles.tooltipSubtitle}>
|
|
806
|
+
<div style={aiStyles.tooltipSubtitle}>Wallet</div>
|
|
796
807
|
<div style={aiStyles.tooltipRow}>
|
|
797
808
|
<span style={aiStyles.tooltipLabel}>Total:</span>
|
|
798
809
|
<span style={aiStyles.tooltipValue}>
|
|
@@ -1001,6 +1012,7 @@ export function AiStatusButton({
|
|
|
1001
1012
|
justifyContent: "center",
|
|
1002
1013
|
color: "#8b5cf6",
|
|
1003
1014
|
transition: "all 0.2s ease",
|
|
1015
|
+
borderRadius: "4px",
|
|
1004
1016
|
}}
|
|
1005
1017
|
onMouseEnter={(e) => {
|
|
1006
1018
|
Object.assign(e.currentTarget.style, {
|
|
@@ -1043,6 +1055,7 @@ export function AiStatusButton({
|
|
|
1043
1055
|
justifyContent: "center",
|
|
1044
1056
|
color: "#ef4444",
|
|
1045
1057
|
transition: "all 0.2s ease",
|
|
1058
|
+
borderRadius: "4px",
|
|
1046
1059
|
}}
|
|
1047
1060
|
onMouseEnter={(e) => {
|
|
1048
1061
|
Object.assign(e.currentTarget.style, {
|
|
@@ -6,7 +6,7 @@ import React, {
|
|
|
6
6
|
useLayoutEffect,
|
|
7
7
|
type TextareaHTMLAttributes,
|
|
8
8
|
} from "react";
|
|
9
|
-
import { Sparkles } from "lucide-react";
|
|
9
|
+
import { Sparkles, Lock } from "lucide-react";
|
|
10
10
|
import type { BaseAiProps } from "../types";
|
|
11
11
|
import { useAiCallText } from "../hooks/useAiCallText";
|
|
12
12
|
import { useAiModels } from "../hooks/useAiModels";
|
|
@@ -233,17 +233,7 @@ export function AiTextarea({
|
|
|
233
233
|
) : shouldShowSparkles ? (
|
|
234
234
|
<Sparkles size={16} />
|
|
235
235
|
) : (
|
|
236
|
-
<
|
|
237
|
-
width="16"
|
|
238
|
-
height="16"
|
|
239
|
-
viewBox="0 0 24 24"
|
|
240
|
-
fill="none"
|
|
241
|
-
stroke="currentColor"
|
|
242
|
-
strokeWidth="2"
|
|
243
|
-
>
|
|
244
|
-
<rect x="3" y="11" width="18" height="11" rx="2" ry="2" />
|
|
245
|
-
<path d="M7 11V7a5 5 0 0 1 10 0v4" />
|
|
246
|
-
</svg>
|
|
236
|
+
<Lock size={16} />
|
|
247
237
|
)}
|
|
248
238
|
</button>
|
|
249
239
|
{isOpen && (
|
|
@@ -66,7 +66,7 @@ export function LBApiKeySelector({
|
|
|
66
66
|
left: 0,
|
|
67
67
|
right: 0,
|
|
68
68
|
bottom: 0,
|
|
69
|
-
background: "
|
|
69
|
+
background: "rgba(0, 0, 0, 0.75)",
|
|
70
70
|
backdropFilter: "blur(8px)",
|
|
71
71
|
}}
|
|
72
72
|
/>
|
|
@@ -75,8 +75,8 @@ export function LBApiKeySelector({
|
|
|
75
75
|
<div
|
|
76
76
|
style={{
|
|
77
77
|
position: "relative",
|
|
78
|
-
background: "
|
|
79
|
-
border: "1px solid
|
|
78
|
+
background: "light-dark(#ffffff, #1e293b)",
|
|
79
|
+
border: "1px solid light-dark(#e2e8f0, #334155)",
|
|
80
80
|
borderRadius: "12px",
|
|
81
81
|
padding: "24px",
|
|
82
82
|
maxWidth: "500px",
|
|
@@ -90,7 +90,7 @@ export function LBApiKeySelector({
|
|
|
90
90
|
margin: "0 0 8px 0",
|
|
91
91
|
fontSize: "20px",
|
|
92
92
|
fontWeight: 600,
|
|
93
|
-
color: "
|
|
93
|
+
color: "light-dark(#1e293b, #f8fafc)",
|
|
94
94
|
textAlign: "center",
|
|
95
95
|
}}
|
|
96
96
|
>
|
|
@@ -101,7 +101,7 @@ export function LBApiKeySelector({
|
|
|
101
101
|
style={{
|
|
102
102
|
margin: "0 0 24px 0",
|
|
103
103
|
fontSize: "14px",
|
|
104
|
-
color: "
|
|
104
|
+
color: "light-dark(#64748b, #94a3b8)",
|
|
105
105
|
textAlign: "center",
|
|
106
106
|
lineHeight: "1.5",
|
|
107
107
|
}}
|
|
@@ -133,12 +133,10 @@ export function LBApiKeySelector({
|
|
|
133
133
|
alignItems: "center",
|
|
134
134
|
padding: "12px 16px",
|
|
135
135
|
background: isSelected
|
|
136
|
-
? "
|
|
137
|
-
: "
|
|
136
|
+
? "light-dark(#f1f5f9, #334155)"
|
|
137
|
+
: "light-dark(#f8fafc, #0f172a)",
|
|
138
138
|
border: `2px solid ${
|
|
139
|
-
isSelected
|
|
140
|
-
? "var(--ai-accent-primary, #8b5cf6)"
|
|
141
|
-
: "var(--ai-border-primary, #374151)"
|
|
139
|
+
isSelected ? "#8b5cf6" : "light-dark(#e2e8f0, #334155)"
|
|
142
140
|
}`,
|
|
143
141
|
borderRadius: "8px",
|
|
144
142
|
cursor: isActive ? "pointer" : "not-allowed",
|
|
@@ -148,17 +146,17 @@ export function LBApiKeySelector({
|
|
|
148
146
|
onMouseEnter={(e) => {
|
|
149
147
|
if (isActive && !isSelected) {
|
|
150
148
|
e.currentTarget.style.borderColor =
|
|
151
|
-
"
|
|
149
|
+
"light-dark(#cbd5e1, #475569)";
|
|
152
150
|
e.currentTarget.style.background =
|
|
153
|
-
"
|
|
151
|
+
"light-dark(#f1f5f9, #334155)";
|
|
154
152
|
}
|
|
155
153
|
}}
|
|
156
154
|
onMouseLeave={(e) => {
|
|
157
155
|
if (isActive && !isSelected) {
|
|
158
156
|
e.currentTarget.style.borderColor =
|
|
159
|
-
"
|
|
157
|
+
"light-dark(#e2e8f0, #334155)";
|
|
160
158
|
e.currentTarget.style.background =
|
|
161
|
-
"
|
|
159
|
+
"light-dark(#f8fafc, #0f172a)";
|
|
162
160
|
}
|
|
163
161
|
}}
|
|
164
162
|
>
|
|
@@ -171,7 +169,7 @@ export function LBApiKeySelector({
|
|
|
171
169
|
onChange={(e) => setSelectedKeyId(e.target.value)}
|
|
172
170
|
style={{
|
|
173
171
|
marginRight: "12px",
|
|
174
|
-
accentColor: "
|
|
172
|
+
accentColor: "#8b5cf6",
|
|
175
173
|
cursor: isActive ? "pointer" : "not-allowed",
|
|
176
174
|
}}
|
|
177
175
|
/>
|
|
@@ -180,7 +178,7 @@ export function LBApiKeySelector({
|
|
|
180
178
|
style={{
|
|
181
179
|
fontSize: "14px",
|
|
182
180
|
fontWeight: 500,
|
|
183
|
-
color: "
|
|
181
|
+
color: "light-dark(#1e293b, #f8fafc)",
|
|
184
182
|
marginBottom: "4px",
|
|
185
183
|
}}
|
|
186
184
|
>
|
|
@@ -189,7 +187,7 @@ export function LBApiKeySelector({
|
|
|
189
187
|
<div
|
|
190
188
|
style={{
|
|
191
189
|
fontSize: "12px",
|
|
192
|
-
color: "
|
|
190
|
+
color: "light-dark(#64748b, #94a3b8)",
|
|
193
191
|
fontFamily: "monospace",
|
|
194
192
|
}}
|
|
195
193
|
>
|
|
@@ -261,9 +259,9 @@ export function LBApiKeySelector({
|
|
|
261
259
|
flex: 1,
|
|
262
260
|
padding: "12px",
|
|
263
261
|
background: "transparent",
|
|
264
|
-
border: "1px solid
|
|
262
|
+
border: "1px solid light-dark(#e2e8f0, #334155)",
|
|
265
263
|
borderRadius: "8px",
|
|
266
|
-
color: "
|
|
264
|
+
color: "light-dark(#64748b, #94a3b8)",
|
|
267
265
|
fontSize: "14px",
|
|
268
266
|
fontWeight: 600,
|
|
269
267
|
cursor: loading ? "not-allowed" : "pointer",
|
|
@@ -273,16 +271,16 @@ export function LBApiKeySelector({
|
|
|
273
271
|
onMouseEnter={(e) => {
|
|
274
272
|
if (!loading) {
|
|
275
273
|
e.currentTarget.style.background =
|
|
276
|
-
"
|
|
274
|
+
"light-dark(#f8fafc, #0f172a)";
|
|
277
275
|
e.currentTarget.style.borderColor =
|
|
278
|
-
"
|
|
276
|
+
"light-dark(#cbd5e1, #475569)";
|
|
279
277
|
}
|
|
280
278
|
}}
|
|
281
279
|
onMouseLeave={(e) => {
|
|
282
280
|
if (!loading) {
|
|
283
281
|
e.currentTarget.style.background = "transparent";
|
|
284
282
|
e.currentTarget.style.borderColor =
|
|
285
|
-
"
|
|
283
|
+
"light-dark(#e2e8f0, #334155)";
|
|
286
284
|
}
|
|
287
285
|
}}
|
|
288
286
|
>
|
|
@@ -295,7 +293,7 @@ export function LBApiKeySelector({
|
|
|
295
293
|
flex: 1,
|
|
296
294
|
padding: "12px",
|
|
297
295
|
background: loading
|
|
298
|
-
? "
|
|
296
|
+
? "light-dark(#e2e8f0, #0f172a)"
|
|
299
297
|
: "linear-gradient(135deg, #8b5cf6 0%, #7c3aed 100%)",
|
|
300
298
|
border: "none",
|
|
301
299
|
borderRadius: "8px",
|