@lastbrain/ai-ui-react 1.0.67 → 1.0.69
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 +8 -3
- package/dist/components/AiChipLabel.d.ts.map +1 -1
- package/dist/components/AiChipLabel.js +21 -70
- package/dist/components/AiContextButton.d.ts +5 -1
- package/dist/components/AiContextButton.d.ts.map +1 -1
- package/dist/components/AiContextButton.js +67 -291
- package/dist/components/AiImageButton.d.ts +5 -1
- package/dist/components/AiImageButton.d.ts.map +1 -1
- package/dist/components/AiImageButton.js +6 -142
- package/dist/components/AiInput.d.ts +5 -3
- package/dist/components/AiInput.d.ts.map +1 -1
- package/dist/components/AiInput.js +13 -25
- package/dist/components/AiPromptPanel.d.ts.map +1 -1
- package/dist/components/AiPromptPanel.js +58 -212
- package/dist/components/AiSelect.d.ts +5 -3
- package/dist/components/AiSelect.d.ts.map +1 -1
- package/dist/components/AiSelect.js +21 -30
- package/dist/components/AiStatusButton.d.ts +4 -1
- package/dist/components/AiStatusButton.d.ts.map +1 -1
- package/dist/components/AiStatusButton.js +198 -626
- package/dist/components/AiTextarea.d.ts +4 -2
- package/dist/components/AiTextarea.d.ts.map +1 -1
- package/dist/components/AiTextarea.js +14 -26
- package/dist/components/LBApiKeySelector.d.ts.map +1 -1
- package/dist/components/LBApiKeySelector.js +5 -166
- package/dist/components/LBConnectButton.d.ts +4 -7
- package/dist/components/LBConnectButton.d.ts.map +1 -1
- package/dist/components/LBConnectButton.js +17 -86
- package/dist/components/LBSigninModal.d.ts +1 -1
- package/dist/components/LBSigninModal.d.ts.map +1 -1
- package/dist/components/LBSigninModal.js +42 -320
- package/dist/examples/AiUiPremiumShowcase.d.ts +2 -0
- package/dist/examples/AiUiPremiumShowcase.d.ts.map +1 -0
- package/dist/examples/AiUiPremiumShowcase.js +15 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/styles/inline.d.ts +1 -0
- package/dist/styles/inline.d.ts.map +1 -1
- package/dist/styles/inline.js +25 -129
- package/dist/styles.css +1268 -369
- package/dist/types.d.ts +3 -0
- package/dist/types.d.ts.map +1 -1
- package/package.json +2 -2
- package/src/components/AiChipLabel.tsx +64 -101
- package/src/components/AiContextButton.tsx +138 -430
- package/src/components/AiImageButton.tsx +29 -190
- package/src/components/AiInput.tsx +49 -74
- package/src/components/AiPromptPanel.tsx +71 -254
- package/src/components/AiSelect.tsx +61 -69
- package/src/components/AiStatusButton.tsx +477 -1219
- package/src/components/AiTextarea.tsx +49 -64
- package/src/components/LBApiKeySelector.tsx +86 -274
- package/src/components/LBConnectButton.tsx +46 -334
- package/src/components/LBSigninModal.tsx +140 -481
- package/src/examples/AiUiPremiumShowcase.tsx +91 -0
- package/src/index.ts +3 -0
- package/src/styles/inline.ts +27 -148
- package/src/styles.css +1268 -369
- package/src/types.ts +3 -0
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import { type TextareaHTMLAttributes } from "react";
|
|
2
|
-
import type { BaseAiProps } from "../types";
|
|
2
|
+
import type { AiRadius, AiSize, BaseAiProps } from "../types";
|
|
3
3
|
export interface AiTextareaProps extends Omit<BaseAiProps, "type">, Omit<TextareaHTMLAttributes<HTMLTextAreaElement>, "onValue"> {
|
|
4
4
|
uiMode?: "modal" | "drawer";
|
|
5
|
+
size?: AiSize;
|
|
6
|
+
radius?: AiRadius;
|
|
5
7
|
}
|
|
6
|
-
export declare function AiTextarea({ baseUrl: propBaseUrl, apiKeyId: propApiKeyId, uiMode, context, model, prompt, editMode, enableModelManagement, storeOutputs, artifactTitle, onValue, onToast, disabled, className, ...textareaProps }: AiTextareaProps): import("react/jsx-runtime").JSX.Element;
|
|
8
|
+
export declare function AiTextarea({ baseUrl: propBaseUrl, apiKeyId: propApiKeyId, uiMode, size, radius, context, model, prompt, editMode, enableModelManagement, storeOutputs, artifactTitle, onValue, onToast, disabled, className, ...textareaProps }: AiTextareaProps): import("react/jsx-runtime").JSX.Element;
|
|
7
9
|
//# sourceMappingURL=AiTextarea.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AiTextarea.d.ts","sourceRoot":"","sources":["../../src/components/AiTextarea.tsx"],"names":[],"mappings":"AAEA,OAAc,EAIZ,KAAK,sBAAsB,EAC5B,MAAM,OAAO,CAAC;AAEf,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;
|
|
1
|
+
{"version":3,"file":"AiTextarea.d.ts","sourceRoot":"","sources":["../../src/components/AiTextarea.tsx"],"names":[],"mappings":"AAEA,OAAc,EAIZ,KAAK,sBAAsB,EAC5B,MAAM,OAAO,CAAC;AAEf,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAU9D,MAAM,WAAW,eACf,SACE,IAAI,CAAC,WAAW,EAAE,MAAM,CAAC,EACzB,IAAI,CAAC,sBAAsB,CAAC,mBAAmB,CAAC,EAAE,SAAS,CAAC;IAC9D,MAAM,CAAC,EAAE,OAAO,GAAG,QAAQ,CAAC;IAC5B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,QAAQ,CAAC;CACnB;AAED,wBAAgB,UAAU,CAAC,EACzB,OAAO,EAAE,WAAW,EACpB,QAAQ,EAAE,YAAY,EACtB,MAAgB,EAChB,IAAW,EACX,MAAa,EACb,OAAO,EACP,KAAK,EACL,MAAM,EACN,QAAgB,EAChB,qBAAqB,EACrB,YAAY,EACZ,aAAa,EACb,OAAO,EACP,OAAO,EACP,QAAQ,EACR,SAAS,EACT,GAAG,aAAa,EACjB,EAAE,eAAe,2CA6NjB"}
|
|
@@ -1,24 +1,21 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
3
|
import { useState, useRef, useLayoutEffect, } from "react";
|
|
4
|
-
import {
|
|
4
|
+
import { Loader2, Lock, Sparkles } from "lucide-react";
|
|
5
5
|
import { useAiCallText } from "../hooks/useAiCallText";
|
|
6
6
|
import { useAiModels } from "../hooks/useAiModels";
|
|
7
7
|
import { AiPromptPanel } from "./AiPromptPanel";
|
|
8
8
|
import { UsageToast, useUsageToast } from "./UsageToast";
|
|
9
|
-
import { aiStyles } from "../styles/inline";
|
|
10
9
|
import { handleAIError } from "../utils/errorHandler";
|
|
11
10
|
import { useLB } from "../context/LBAuthProvider";
|
|
12
11
|
import { LBSigninModal } from "./LBSigninModal";
|
|
13
12
|
import { useAiContext } from "../context/AiProvider";
|
|
14
|
-
export function AiTextarea({ baseUrl: propBaseUrl, apiKeyId: propApiKeyId, uiMode = "modal", context, model, prompt, editMode = false, enableModelManagement, storeOutputs, artifactTitle, onValue, onToast, disabled, className, ...textareaProps }) {
|
|
13
|
+
export function AiTextarea({ baseUrl: propBaseUrl, apiKeyId: propApiKeyId, uiMode = "modal", size = "md", radius = "lg", context, model, prompt, editMode = false, enableModelManagement, storeOutputs, artifactTitle, onValue, onToast, disabled, className, ...textareaProps }) {
|
|
15
14
|
const [isOpen, setIsOpen] = useState(false);
|
|
16
15
|
const [showAuthModal, setShowAuthModal] = useState(false);
|
|
17
16
|
const [textareaValue, setTextareaValue] = useState(textareaProps.value?.toString() ||
|
|
18
17
|
textareaProps.defaultValue?.toString() ||
|
|
19
18
|
"");
|
|
20
|
-
const [isFocused, setIsFocused] = useState(false);
|
|
21
|
-
const [isButtonHovered, setIsButtonHovered] = useState(false);
|
|
22
19
|
const textareaRef = useRef(null);
|
|
23
20
|
const { showUsageToast, toastData, toastKey, clearToast } = useUsageToast();
|
|
24
21
|
// Rendre l'authentification optionnelle
|
|
@@ -140,25 +137,16 @@ export function AiTextarea({ baseUrl: propBaseUrl, apiKeyId: propApiKeyId, uiMod
|
|
|
140
137
|
useLayoutEffect(() => {
|
|
141
138
|
adjustHeight();
|
|
142
139
|
}, [textareaValue]);
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
...(isButtonHovered && aiStyles.textareaAiButtonHover),
|
|
156
|
-
...(disabled || loading
|
|
157
|
-
? { opacity: 0.5, cursor: "not-allowed" }
|
|
158
|
-
: {}),
|
|
159
|
-
}, onClick: hasConfiguration ? handleQuickGenerate : handleOpenPanel, onMouseEnter: () => setIsButtonHovered(true), onMouseLeave: () => setIsButtonHovered(false), disabled: disabled || loading || !isAuthReady, type: "button", title: !isAuthReady
|
|
160
|
-
? "Authentication required"
|
|
161
|
-
: hasConfiguration
|
|
162
|
-
? "Generate with AI"
|
|
163
|
-
: "Setup AI", children: loading ? (_jsx("svg", { style: aiStyles.spinner, width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", children: _jsx("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" }) })) : shouldShowSparkles ? (_jsx(Sparkles, { size: 16 })) : (_jsx(Lock, { size: 16 })) }), isOpen && (_jsx(AiPromptPanel, { isOpen: isOpen, onClose: handleClosePanel, onSubmit: handleSubmit, uiMode: uiMode, models: [], modelCategory: "text", sourceText: textareaValue || undefined, baseUrl: baseUrl, apiKey: apiKeyId, enableModelManagement: enableModelManagement, showOnlyUserModels: true })), Boolean(toastData) && (_jsx(UsageToast, { result: toastData, position: "bottom-right", onComplete: clearToast }, toastKey)), _jsx(LBSigninModal, { isOpen: showAuthModal, onClose: () => setShowAuthModal(false) })] }));
|
|
140
|
+
const sizeClass = `ai-size-${size}`;
|
|
141
|
+
const radiusClass = `ai-radius-${radius}`;
|
|
142
|
+
return (_jsxs("div", { className: `ai-control-group ai-glow ${className || ""}`, children: [_jsxs("div", { className: `ai-shell ai-shell--textarea ${sizeClass} ${radiusClass}`, children: [_jsx("textarea", { ref: textareaRef, ...textareaProps, className: `ai-control ai-control-textarea ${sizeClass} ${radiusClass}`, value: textareaValue, onChange: handleTextareaChange, onFocus: (e) => {
|
|
143
|
+
textareaProps.onFocus?.(e);
|
|
144
|
+
adjustHeight();
|
|
145
|
+
}, onBlur: (e) => {
|
|
146
|
+
textareaProps.onBlur?.(e);
|
|
147
|
+
}, "aria-invalid": Boolean(textareaProps["aria-invalid"]), disabled: disabled || loading }), _jsx("button", { className: `ai-control-action ai-spark ${sizeClass} ${radiusClass}`, onClick: hasConfiguration ? handleQuickGenerate : handleOpenPanel, disabled: disabled || loading || !isAuthReady, type: "button", title: !isAuthReady
|
|
148
|
+
? "Authentication required"
|
|
149
|
+
: hasConfiguration
|
|
150
|
+
? "Generate with AI"
|
|
151
|
+
: "Setup AI", children: loading ? (_jsx(Loader2, { size: 16, className: "ai-spinner" })) : shouldShowSparkles ? (_jsx(Sparkles, { size: 16 })) : (_jsx(Lock, { size: 16 })) })] }), isOpen && (_jsx(AiPromptPanel, { isOpen: isOpen, onClose: handleClosePanel, onSubmit: handleSubmit, uiMode: uiMode, models: [], modelCategory: "text", sourceText: textareaValue || undefined, baseUrl: baseUrl, apiKey: apiKeyId, enableModelManagement: enableModelManagement, showOnlyUserModels: true })), Boolean(toastData) && (_jsx(UsageToast, { result: toastData, position: "bottom-right", onComplete: clearToast }, toastKey)), _jsx(LBSigninModal, { isOpen: showAuthModal, onClose: () => setShowAuthModal(false) })] }));
|
|
164
152
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"LBApiKeySelector.d.ts","sourceRoot":"","sources":["../../src/components/LBApiKeySelector.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"LBApiKeySelector.d.ts","sourceRoot":"","sources":["../../src/components/LBApiKeySelector.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AAEtD,UAAU,qBAAqB;IAC7B,OAAO,EAAE,QAAQ,EAAE,CAAC;IACpB,QAAQ,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC9C,QAAQ,EAAE,MAAM,IAAI,CAAC;IACrB,MAAM,EAAE,OAAO,CAAC;CACjB;AAED,wBAAgB,gBAAgB,CAAC,EAC/B,OAAO,EACP,QAAQ,EACR,QAAQ,EACR,MAAM,GACP,EAAE,qBAAqB,kDA4HvB"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
2
|
import { useState } from "react";
|
|
3
|
+
import { CheckCircle2, KeyRound, Loader2, XCircle } from "lucide-react";
|
|
3
4
|
export function LBApiKeySelector({ apiKeys, onSelect, onCancel, isOpen, }) {
|
|
4
5
|
const [selectedKeyId, setSelectedKeyId] = useState(apiKeys.find((k) => k.isActive)?.id || apiKeys[0]?.id || "");
|
|
5
6
|
const [loading, setLoading] = useState(false);
|
|
@@ -22,171 +23,9 @@ export function LBApiKeySelector({ apiKeys, onSelect, onCancel, isOpen, }) {
|
|
|
22
23
|
setLoading(false);
|
|
23
24
|
}
|
|
24
25
|
};
|
|
25
|
-
return (_jsxs("div", { style: {
|
|
26
|
-
position: "fixed",
|
|
27
|
-
top: 0,
|
|
28
|
-
left: 0,
|
|
29
|
-
right: 0,
|
|
30
|
-
bottom: 0,
|
|
31
|
-
zIndex: 10000,
|
|
32
|
-
display: "flex",
|
|
33
|
-
alignItems: "center",
|
|
34
|
-
justifyContent: "center",
|
|
35
|
-
padding: "16px",
|
|
36
|
-
}, onClick: onCancel, children: [_jsx("div", { style: {
|
|
37
|
-
position: "absolute",
|
|
38
|
-
top: 0,
|
|
39
|
-
left: 0,
|
|
40
|
-
right: 0,
|
|
41
|
-
bottom: 0,
|
|
42
|
-
background: "rgba(0, 0, 0, 0.75)",
|
|
43
|
-
backdropFilter: "blur(8px)",
|
|
44
|
-
height: "110%",
|
|
45
|
-
} }), _jsxs("div", { style: {
|
|
46
|
-
position: "relative",
|
|
47
|
-
background: "light-dark(#ffffff, #1e293b)",
|
|
48
|
-
border: "1px solid light-dark(#e2e8f0, #334155)",
|
|
49
|
-
borderRadius: "12px",
|
|
50
|
-
padding: "24px",
|
|
51
|
-
maxWidth: "500px",
|
|
52
|
-
width: "100%",
|
|
53
|
-
boxShadow: "0 20px 50px rgba(0, 0, 0, 0.5)",
|
|
54
|
-
}, onClick: (e) => e.stopPropagation(), children: [_jsx("h2", { style: {
|
|
55
|
-
margin: "0 0 8px 0",
|
|
56
|
-
fontSize: "20px",
|
|
57
|
-
fontWeight: 600,
|
|
58
|
-
color: "light-dark(#1e293b, #f8fafc)",
|
|
59
|
-
textAlign: "center",
|
|
60
|
-
}, children: "S\u00E9lectionnez une cl\u00E9 API" }), _jsx("p", { style: {
|
|
61
|
-
margin: "0 0 24px 0",
|
|
62
|
-
fontSize: "14px",
|
|
63
|
-
color: "light-dark(#64748b, #94a3b8)",
|
|
64
|
-
textAlign: "center",
|
|
65
|
-
lineHeight: "1.5",
|
|
66
|
-
}, children: "Choisissez la cl\u00E9 API \u00E0 utiliser pour vos requ\u00EAtes IA" }), _jsxs("form", { onSubmit: handleSubmit, children: [_jsx("div", { style: {
|
|
67
|
-
display: "flex",
|
|
68
|
-
flexDirection: "column",
|
|
69
|
-
gap: "8px",
|
|
70
|
-
marginBottom: "24px",
|
|
71
|
-
maxHeight: "300px",
|
|
72
|
-
overflowY: "auto",
|
|
73
|
-
}, children: apiKeys.map((key) => {
|
|
26
|
+
return (_jsx("div", { className: "ai-signin-overlay", onClick: onCancel, children: _jsxs("div", { className: "ai-signin-panel ai-key-modal-panel", onClick: (e) => e.stopPropagation(), children: [_jsxs("div", { className: "ai-signin-header", children: [_jsx("div", { className: "ai-center mb-3", children: _jsx("span", { className: "ai-icon-badge", children: _jsx(KeyRound, { size: 20 }) }) }), _jsx("h2", { className: "ai-signin-title", children: "S\u00E9lectionnez une cl\u00E9 API" }), _jsx("p", { className: "ai-signin-subtitle", children: "Choisissez la cl\u00E9 API \u00E0 utiliser pour vos requ\u00EAtes IA." })] }), _jsx("div", { className: "ai-signin-content", children: _jsxs("form", { onSubmit: handleSubmit, children: [_jsx("div", { className: "ai-model-mgmt-list", style: { maxHeight: 300, overflowY: "auto", marginBottom: 16 }, children: apiKeys.map((key) => {
|
|
74
27
|
const isSelected = key.id === selectedKeyId;
|
|
75
28
|
const isActive = key.isActive;
|
|
76
|
-
return (_jsxs("label", {
|
|
77
|
-
|
|
78
|
-
alignItems: "center",
|
|
79
|
-
padding: "12px 16px",
|
|
80
|
-
background: isSelected
|
|
81
|
-
? "light-dark(#f1f5f9, #334155)"
|
|
82
|
-
: "light-dark(#f8fafc, #0f172a)",
|
|
83
|
-
border: `2px solid ${isSelected ? "#8b5cf6" : "light-dark(#e2e8f0, #334155)"}`,
|
|
84
|
-
borderRadius: "8px",
|
|
85
|
-
cursor: isActive ? "pointer" : "not-allowed",
|
|
86
|
-
opacity: isActive ? 1 : 0.5,
|
|
87
|
-
transition: "all 0.2s ease",
|
|
88
|
-
}, onMouseEnter: (e) => {
|
|
89
|
-
if (isActive && !isSelected) {
|
|
90
|
-
e.currentTarget.style.borderColor =
|
|
91
|
-
"light-dark(#cbd5e1, #475569)";
|
|
92
|
-
e.currentTarget.style.background =
|
|
93
|
-
"light-dark(#f1f5f9, #334155)";
|
|
94
|
-
}
|
|
95
|
-
}, onMouseLeave: (e) => {
|
|
96
|
-
if (isActive && !isSelected) {
|
|
97
|
-
e.currentTarget.style.borderColor =
|
|
98
|
-
"light-dark(#e2e8f0, #334155)";
|
|
99
|
-
e.currentTarget.style.background =
|
|
100
|
-
"light-dark(#f8fafc, #0f172a)";
|
|
101
|
-
}
|
|
102
|
-
}, children: [_jsx("input", { type: "radio", name: "apiKey", value: key.id, checked: isSelected, disabled: !isActive, onChange: (e) => setSelectedKeyId(e.target.value), style: {
|
|
103
|
-
marginRight: "12px",
|
|
104
|
-
accentColor: "#8b5cf6",
|
|
105
|
-
cursor: isActive ? "pointer" : "not-allowed",
|
|
106
|
-
} }), _jsxs("div", { style: { flex: 1 }, children: [_jsx("div", { style: {
|
|
107
|
-
fontSize: "14px",
|
|
108
|
-
fontWeight: 500,
|
|
109
|
-
color: "light-dark(#1e293b, #f8fafc)",
|
|
110
|
-
marginBottom: "4px",
|
|
111
|
-
}, children: key.name }), _jsx("div", { style: {
|
|
112
|
-
fontSize: "12px",
|
|
113
|
-
color: "light-dark(#64748b, #94a3b8)",
|
|
114
|
-
fontFamily: "monospace",
|
|
115
|
-
}, children: key.keyPrefix || key.id.substring(0, 12) + "..." })] }), isActive ? (_jsx("div", { style: {
|
|
116
|
-
fontSize: "11px",
|
|
117
|
-
padding: "4px 8px",
|
|
118
|
-
borderRadius: "4px",
|
|
119
|
-
background: "rgba(16, 185, 129, 0.1)",
|
|
120
|
-
color: "#10b981",
|
|
121
|
-
fontWeight: 600,
|
|
122
|
-
}, children: "Active" })) : (_jsx("div", { style: {
|
|
123
|
-
fontSize: "11px",
|
|
124
|
-
padding: "4px 8px",
|
|
125
|
-
borderRadius: "4px",
|
|
126
|
-
background: "rgba(239, 68, 68, 0.1)",
|
|
127
|
-
color: "#ef4444",
|
|
128
|
-
fontWeight: 600,
|
|
129
|
-
}, children: "Inactive" }))] }, key.id));
|
|
130
|
-
}) }), error && (_jsx("div", { style: {
|
|
131
|
-
padding: "12px",
|
|
132
|
-
background: "rgba(239, 68, 68, 0.1)",
|
|
133
|
-
border: "1px solid rgba(239, 68, 68, 0.3)",
|
|
134
|
-
borderRadius: "6px",
|
|
135
|
-
marginBottom: "16px",
|
|
136
|
-
}, children: _jsx("p", { style: {
|
|
137
|
-
margin: 0,
|
|
138
|
-
fontSize: "13px",
|
|
139
|
-
color: "#ef4444",
|
|
140
|
-
lineHeight: "1.5",
|
|
141
|
-
}, children: error }) })), _jsxs("div", { style: { display: "flex", gap: "12px" }, children: [_jsx("button", { type: "button", onClick: onCancel, disabled: loading, style: {
|
|
142
|
-
flex: 1,
|
|
143
|
-
padding: "12px",
|
|
144
|
-
background: "transparent",
|
|
145
|
-
border: "1px solid light-dark(#e2e8f0, #334155)",
|
|
146
|
-
borderRadius: "8px",
|
|
147
|
-
color: "light-dark(#64748b, #94a3b8)",
|
|
148
|
-
fontSize: "14px",
|
|
149
|
-
fontWeight: 600,
|
|
150
|
-
cursor: loading ? "not-allowed" : "pointer",
|
|
151
|
-
opacity: loading ? 0.5 : 1,
|
|
152
|
-
transition: "all 0.2s ease",
|
|
153
|
-
}, onMouseEnter: (e) => {
|
|
154
|
-
if (!loading) {
|
|
155
|
-
e.currentTarget.style.background =
|
|
156
|
-
"light-dark(#f8fafc, #0f172a)";
|
|
157
|
-
e.currentTarget.style.borderColor =
|
|
158
|
-
"light-dark(#cbd5e1, #475569)";
|
|
159
|
-
}
|
|
160
|
-
}, onMouseLeave: (e) => {
|
|
161
|
-
if (!loading) {
|
|
162
|
-
e.currentTarget.style.background = "transparent";
|
|
163
|
-
e.currentTarget.style.borderColor =
|
|
164
|
-
"light-dark(#e2e8f0, #334155)";
|
|
165
|
-
}
|
|
166
|
-
}, children: "Annuler" }), _jsx("button", { type: "submit", disabled: loading || !selectedKeyId, style: {
|
|
167
|
-
flex: 1,
|
|
168
|
-
padding: "12px",
|
|
169
|
-
background: loading
|
|
170
|
-
? "light-dark(#e2e8f0, #0f172a)"
|
|
171
|
-
: "linear-gradient(135deg, #8b5cf6 0%, #7c3aed 100%)",
|
|
172
|
-
border: "none",
|
|
173
|
-
borderRadius: "8px",
|
|
174
|
-
color: "#ffffff",
|
|
175
|
-
fontSize: "14px",
|
|
176
|
-
fontWeight: 600,
|
|
177
|
-
cursor: loading || !selectedKeyId ? "not-allowed" : "pointer",
|
|
178
|
-
opacity: loading || !selectedKeyId ? 0.5 : 1,
|
|
179
|
-
transition: "all 0.2s ease",
|
|
180
|
-
}, onMouseEnter: (e) => {
|
|
181
|
-
if (!loading && selectedKeyId) {
|
|
182
|
-
e.currentTarget.style.transform = "translateY(-1px)";
|
|
183
|
-
e.currentTarget.style.boxShadow =
|
|
184
|
-
"0 8px 20px rgba(139, 92, 246, 0.4)";
|
|
185
|
-
}
|
|
186
|
-
}, onMouseLeave: (e) => {
|
|
187
|
-
if (!loading && selectedKeyId) {
|
|
188
|
-
e.currentTarget.style.transform = "none";
|
|
189
|
-
e.currentTarget.style.boxShadow = "none";
|
|
190
|
-
}
|
|
191
|
-
}, children: loading ? "Connexion..." : "Continuer" })] })] })] })] }));
|
|
29
|
+
return (_jsxs("label", { className: `ai-model-item ${isSelected ? "ai-model-item--active" : ""} ${!isActive ? "ai-model-item--disabled" : ""}`, children: [_jsxs("div", { className: "ai-model-item-main", children: [_jsx("input", { type: "radio", name: "apiKey", value: key.id, checked: isSelected, disabled: !isActive, onChange: (e) => setSelectedKeyId(e.target.value), className: "ai-key-radio" }), _jsxs("div", { children: [_jsx("div", { className: "ai-model-item-title", children: key.name }), _jsx("div", { className: "ai-model-item-meta", children: _jsx("span", { children: key.keyPrefix || key.id.substring(0, 12) + "..." }) })] })] }), isActive ? (_jsxs("span", { className: "ai-pill ai-pill--cost", children: [_jsx(CheckCircle2, { size: 12 }), "Active"] })) : (_jsxs("span", { className: "ai-pill ai-pill--cost", children: [_jsx(XCircle, { size: 12 }), "Inactive"] }))] }, key.id));
|
|
30
|
+
}) }), error ? (_jsxs("div", { className: "ai-signin-error", role: "alert", children: [_jsx(XCircle, { size: 16 }), _jsx("span", { children: error })] })) : null, _jsxs("div", { className: "ai-signin-actions", children: [_jsx("button", { type: "button", onClick: onCancel, disabled: loading, className: "ai-btn ai-btn--ghost", children: "Annuler" }), _jsx("button", { type: "submit", disabled: loading || !selectedKeyId, className: "ai-btn ai-btn--primary", children: loading ? (_jsxs(_Fragment, { children: [_jsx(Loader2, { size: 16, className: "ai-spinner" }), "Connexion..."] })) : ("Continuer") })] })] }) })] }) }));
|
|
192
31
|
}
|
|
@@ -1,20 +1,17 @@
|
|
|
1
1
|
interface LBConnectButtonProps {
|
|
2
|
-
/** Texte du bouton */
|
|
3
2
|
label?: string;
|
|
4
|
-
/** Classe CSS personnalisée */
|
|
5
3
|
className?: string;
|
|
6
|
-
/** Callback après connexion réussie */
|
|
7
4
|
onConnected?: () => void;
|
|
8
|
-
/** Callback à l'ouverture de la modal */
|
|
9
5
|
onOpenModal?: () => void;
|
|
10
6
|
}
|
|
11
7
|
export declare function LBConnectButton({ label, className, onConnected, onOpenModal, }: LBConnectButtonProps): import("react/jsx-runtime").JSX.Element;
|
|
12
8
|
/**
|
|
13
|
-
*
|
|
9
|
+
* Compat export (ancien API): on garde un wrapper minimal
|
|
10
|
+
* pour éviter de casser les imports existants.
|
|
14
11
|
*/
|
|
15
12
|
interface LBAuthModalProps {
|
|
16
13
|
onClose: (success: boolean) => void;
|
|
17
14
|
}
|
|
18
|
-
declare function LBAuthModal({ onClose }: LBAuthModalProps): import("react/jsx-runtime").JSX.Element;
|
|
19
|
-
export {
|
|
15
|
+
export declare function LBAuthModal({ onClose }: LBAuthModalProps): import("react/jsx-runtime").JSX.Element;
|
|
16
|
+
export {};
|
|
20
17
|
//# sourceMappingURL=LBConnectButton.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"LBConnectButton.d.ts","sourceRoot":"","sources":["../../src/components/LBConnectButton.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"LBConnectButton.d.ts","sourceRoot":"","sources":["../../src/components/LBConnectButton.tsx"],"names":[],"mappings":"AAOA,UAAU,oBAAoB;IAC5B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,IAAI,CAAC;IACzB,WAAW,CAAC,EAAE,MAAM,IAAI,CAAC;CAC1B;AAED,wBAAgB,eAAe,CAAC,EAC9B,KAAsB,EACtB,SAAc,EACd,WAAW,EACX,WAAW,GACZ,EAAE,oBAAoB,2CAwDtB;AAED;;;GAGG;AACH,UAAU,gBAAgB;IACxB,OAAO,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,CAAC;CACrC;AAED,wBAAgB,WAAW,CAAC,EAAE,OAAO,EAAE,EAAE,gBAAgB,2CAOxD"}
|
|
@@ -1,98 +1,29 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
-
/**
|
|
4
|
-
* Bouton de connexion LastBrain
|
|
5
|
-
* Ouvre la modal d'authentification
|
|
6
|
-
*/
|
|
7
3
|
import React from "react";
|
|
4
|
+
import { Loader2, LogIn, LogOut } from "lucide-react";
|
|
8
5
|
import { useLB } from "../context/LBAuthProvider";
|
|
9
|
-
|
|
6
|
+
import { LBSigninModal } from "./LBSigninModal";
|
|
7
|
+
export function LBConnectButton({ label = "Se connecter", className = "", onConnected, onOpenModal, }) {
|
|
10
8
|
const { status, user, logout } = useLB();
|
|
11
9
|
const [showModal, setShowModal] = React.useState(false);
|
|
10
|
+
React.useEffect(() => {
|
|
11
|
+
if (status === "ready" && user && showModal) {
|
|
12
|
+
setShowModal(false);
|
|
13
|
+
onConnected?.();
|
|
14
|
+
}
|
|
15
|
+
}, [status, user, showModal, onConnected]);
|
|
12
16
|
const handleClick = () => {
|
|
13
17
|
if (status === "ready" && user) {
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
// Redirection propre après logout
|
|
17
|
-
if (typeof window !== "undefined") {
|
|
18
|
-
// Garder la langue actuelle de l'URL
|
|
19
|
-
const currentPath = window.location.pathname;
|
|
20
|
-
const langMatch = currentPath.match(/^\/([a-z]{2})\//);
|
|
21
|
-
const currentLang = langMatch ? langMatch[1] : "en";
|
|
22
|
-
// Rediriger vers la page d'accueil dans la langue actuelle
|
|
23
|
-
window.location.href = `/${currentLang}`;
|
|
24
|
-
}
|
|
25
|
-
});
|
|
26
|
-
}
|
|
27
|
-
else {
|
|
28
|
-
// Pas connecté, ouvrir la modal
|
|
29
|
-
setShowModal(true);
|
|
30
|
-
onOpenModal?.();
|
|
18
|
+
void logout();
|
|
19
|
+
return;
|
|
31
20
|
}
|
|
21
|
+
setShowModal(true);
|
|
22
|
+
onOpenModal?.();
|
|
32
23
|
};
|
|
33
|
-
const
|
|
34
|
-
|
|
35
|
-
if (success) {
|
|
36
|
-
onConnected?.();
|
|
37
|
-
}
|
|
38
|
-
};
|
|
39
|
-
return (_jsxs(_Fragment, { children: [_jsx("button", { onClick: handleClick, className: className ||
|
|
40
|
-
(status === "ready" && user
|
|
41
|
-
? "px-4 py-2 bg-gradient-to-r from-emerald-500 to-teal-600 text-white rounded-lg hover:from-emerald-600 hover:to-teal-700 transition-all duration-200 shadow-md hover:shadow-lg"
|
|
42
|
-
: "px-4 py-2 bg-gradient-to-r from-violet-500 to-purple-600 text-white rounded-lg hover:from-violet-600 hover:to-purple-700 transition-all duration-200 shadow-md hover:shadow-lg"), disabled: status === "loading", children: status === "loading"
|
|
43
|
-
? "⏳ Chargement..."
|
|
44
|
-
: status === "ready" && user
|
|
45
|
-
? `✓ ${user.email}`
|
|
46
|
-
: `🔐 ${label}` }), showModal && _jsx(LBAuthModal, { onClose: handleModalClose })] }));
|
|
24
|
+
const buttonLabel = status === "ready" && user ? "Déconnexion" : label;
|
|
25
|
+
return (_jsxs(_Fragment, { children: [_jsx("button", { type: "button", onClick: handleClick, className: className || "ai-btn ai-btn--auth", disabled: status === "loading", children: status === "loading" ? (_jsxs(_Fragment, { children: [_jsx(Loader2, { size: 16, className: "animate-spin" }), "Chargement..."] })) : status === "ready" && user ? (_jsxs(_Fragment, { children: [_jsx(LogOut, { size: 16 }), buttonLabel] })) : (_jsxs(_Fragment, { children: [_jsx(LogIn, { size: 16 }), buttonLabel] })) }), _jsx(LBSigninModal, { isOpen: showModal, onClose: () => setShowModal(false) })] }));
|
|
47
26
|
}
|
|
48
|
-
function LBAuthModal({ onClose }) {
|
|
49
|
-
|
|
50
|
-
const [step, setStep] = React.useState("login");
|
|
51
|
-
const [email, setEmail] = React.useState("");
|
|
52
|
-
const [password, setPassword] = React.useState("");
|
|
53
|
-
const [error, setError] = React.useState("");
|
|
54
|
-
const [loading, setLoading] = React.useState(false);
|
|
55
|
-
const [accessToken, setAccessToken] = React.useState("");
|
|
56
|
-
const [apiKeys, setApiKeys] = React.useState([]);
|
|
57
|
-
const handleLogin = async (e) => {
|
|
58
|
-
e.preventDefault();
|
|
59
|
-
setError("");
|
|
60
|
-
setLoading(true);
|
|
61
|
-
try {
|
|
62
|
-
const result = await login(email, password);
|
|
63
|
-
if (!result.success) {
|
|
64
|
-
setError(result.error || "Échec de la connexion");
|
|
65
|
-
return;
|
|
66
|
-
}
|
|
67
|
-
// Note: avec le nouveau système, login gère automatiquement
|
|
68
|
-
// la récupération et sélection de clé. Ce modal n'est plus nécessaire.
|
|
69
|
-
onClose(true);
|
|
70
|
-
}
|
|
71
|
-
catch (err) {
|
|
72
|
-
setError(err instanceof Error ? err.message : "Échec de la connexion");
|
|
73
|
-
}
|
|
74
|
-
finally {
|
|
75
|
-
setLoading(false);
|
|
76
|
-
}
|
|
77
|
-
};
|
|
78
|
-
const handleSelectKey = async (apiKeyId) => {
|
|
79
|
-
setError("");
|
|
80
|
-
setLoading(true);
|
|
81
|
-
try {
|
|
82
|
-
await selectApiKey(accessToken, apiKeyId);
|
|
83
|
-
onClose(true); // Succès
|
|
84
|
-
}
|
|
85
|
-
catch (err) {
|
|
86
|
-
setError(err instanceof Error ? err.message : "Échec de la sélection");
|
|
87
|
-
}
|
|
88
|
-
finally {
|
|
89
|
-
setLoading(false);
|
|
90
|
-
}
|
|
91
|
-
};
|
|
92
|
-
return (_jsx("div", { className: "fixed inset-0 bg-black/60 dark:bg-black/80 backdrop-blur-md flex items-center justify-center z-50 p-4 animate-in fade-in duration-200", children: _jsxs("div", { className: "bg-white/95 dark:bg-slate-900/95 backdrop-blur-xl rounded-3xl shadow-2xl max-w-md w-full border border-slate-200/50 dark:border-slate-700/50 overflow-hidden animate-in zoom-in-95 duration-200", children: [_jsxs("div", { className: "relative bg-gradient-to-r from-violet-600 via-purple-600 to-fuchsia-600 dark:from-violet-500 dark:via-purple-500 dark:to-fuchsia-500 px-6 py-8 text-white overflow-hidden", children: [_jsx("div", { className: "absolute inset-0 bg-[url('data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNjAiIGhlaWdodD0iNjAiIHZpZXdCb3g9IjAgMCA2MCA2MCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48ZyBmaWxsPSJub25lIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiPjxnIGZpbGw9IiNmZmYiIGZpbGwtb3BhY2l0eT0iMC4wNSI+PHBhdGggZD0iTTM2IDE0YzAtMTEuMDUgOC45NS0yMCAyMC0yMHMyMCA4Ljk1IDIwIDIwLTguOTUgMjAtMjAgMjAtMjAtOC45NS0yMC0yMHoiLz48L2c+PC9nPjwvc3ZnPg==')] opacity-30" }), _jsxs("div", { className: "relative flex justify-between items-start", children: [_jsxs("div", { className: "flex-1", children: [_jsxs("div", { className: "flex items-center gap-3 mb-2", children: [_jsx("div", { className: "w-10 h-10 rounded-xl bg-white/20 backdrop-blur-sm flex items-center justify-center", children: step === "login" ? "🔐" : "🔑" }), _jsx("h2", { className: "text-2xl font-bold tracking-tight", children: step === "login" ? "Connexion" : "Sélection clé" })] }), _jsx("p", { className: "text-white/90 text-sm font-medium mt-1 ml-13", children: step === "login"
|
|
93
|
-
? "Accédez à vos outils IA"
|
|
94
|
-
: "Session sécurisée 72h" })] }), _jsx("button", { onClick: () => onClose(false), className: "text-white/80 hover:text-white hover:bg-white/20 rounded-lg p-2 transition-all duration-200 backdrop-blur-sm", children: _jsx("svg", { className: "w-5 h-5", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2.5, d: "M6 18L18 6M6 6l12 12" }) }) })] })] }), _jsx("div", { className: "p-8", children: step === "login" ? (_jsxs("form", { onSubmit: handleLogin, className: "space-y-5", children: [_jsxs("div", { className: "space-y-2", children: [_jsx("label", { className: "block text-sm font-semibold text-slate-700 dark:text-slate-200 mb-2 tracking-wide", children: "\uD83D\uDCE7 Adresse email" }), _jsx("input", { type: "email", value: email, onChange: (e) => setEmail(e.target.value), className: "w-full px-4 py-3.5 text-base border-2 border-slate-200 dark:border-slate-600 rounded-xl bg-white dark:bg-slate-800 text-slate-900 dark:text-white placeholder:text-slate-400 dark:placeholder:text-slate-500 focus:border-violet-500 dark:focus:border-violet-400 focus:ring-4 focus:ring-violet-100 dark:focus:ring-violet-900/30 transition-all outline-none font-medium tracking-wide", placeholder: "votre@email.com", required: true, autoFocus: true, autoComplete: "email", style: { letterSpacing: "0.01em" } })] }), _jsxs("div", { className: "space-y-2", children: [_jsx("label", { className: "block text-sm font-semibold text-slate-700 dark:text-slate-200 mb-2 tracking-wide", children: "\uD83D\uDD12 Mot de passe" }), _jsx("input", { type: "password", value: password, onChange: (e) => setPassword(e.target.value), className: "w-full px-4 py-3.5 text-base border-2 border-slate-200 dark:border-slate-600 rounded-xl bg-white dark:bg-slate-800 text-slate-900 dark:text-white placeholder:text-slate-400 dark:placeholder:text-slate-500 focus:border-violet-500 dark:focus:border-violet-400 focus:ring-4 focus:ring-violet-100 dark:focus:ring-violet-900/30 transition-all outline-none font-medium tracking-wide", placeholder: "\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022", required: true, autoComplete: "current-password", style: { letterSpacing: "0.15em" } })] }), error && (_jsx("div", { className: "bg-red-50 dark:bg-red-900/20 border-l-4 border-red-500 dark:border-red-400 px-4 py-3.5 rounded-lg animate-in slide-in-from-top-2 duration-200", children: _jsxs("div", { className: "flex items-start gap-3", children: [_jsx("span", { className: "text-red-500 dark:text-red-400 text-xl flex-shrink-0 mt-0.5", children: "\u26A0\uFE0F" }), _jsx("p", { className: "text-red-700 dark:text-red-300 text-sm font-medium leading-relaxed", children: error })] }) })), _jsx("button", { type: "submit", disabled: loading, className: "w-full mt-6 px-6 py-4 bg-gradient-to-r from-violet-600 to-purple-600 hover:from-violet-700 hover:to-purple-700 disabled:from-slate-400 disabled:to-slate-500 text-white font-bold text-base rounded-xl disabled:cursor-not-allowed transition-all duration-200 shadow-lg shadow-violet-500/30 hover:shadow-xl hover:shadow-violet-500/40 disabled:shadow-none transform hover:translate-y-[-2px] active:translate-y-0 disabled:translate-y-0 tracking-wide", children: loading ? (_jsxs("span", { className: "flex items-center justify-center gap-3", children: [_jsxs("svg", { className: "animate-spin h-5 w-5", xmlns: "http://www.w3.org/2000/svg", fill: "none", viewBox: "0 0 24 24", children: [_jsx("circle", { className: "opacity-25", cx: "12", cy: "12", r: "10", stroke: "currentColor", strokeWidth: "4" }), _jsx("path", { className: "opacity-75", fill: "currentColor", d: "M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z" })] }), _jsx("span", { className: "font-semibold", children: "Connexion en cours..." })] })) : (_jsxs("span", { className: "flex items-center justify-center gap-2", children: ["\uD83D\uDE80 ", _jsx("span", { children: "Se connecter" })] })) }), _jsxs("div", { className: "relative my-8", children: [_jsx("div", { className: "absolute inset-0 flex items-center", children: _jsx("div", { className: "w-full border-t border-slate-200 dark:border-slate-700" }) }), _jsx("div", { className: "relative flex justify-center text-sm", children: _jsx("span", { className: "px-4 bg-white dark:bg-slate-900 text-slate-500 dark:text-slate-400 font-medium", children: "ou" }) })] }), _jsxs("div", { className: "bg-gradient-to-br from-violet-50 to-purple-50 dark:from-violet-900/20 dark:to-purple-900/20 rounded-xl p-5 border border-violet-200 dark:border-violet-800/50 backdrop-blur-sm", children: [_jsx("p", { className: "text-sm text-slate-700 dark:text-slate-300 text-center font-medium mb-3", children: "Pas encore de compte ?" }), _jsx("a", { href: "https://prompt.lastbrain.io/signup", target: "_blank", rel: "noopener noreferrer", className: "block text-center px-4 py-3 bg-white dark:bg-slate-800 text-violet-600 dark:text-violet-400 hover:text-violet-700 dark:hover:text-violet-300 font-bold text-sm rounded-lg hover:shadow-md transition-all duration-200 border-2 border-violet-200 dark:border-violet-700", children: "\u2728 Cr\u00E9er un compte gratuitement" })] })] })) : (_jsxs("div", { className: "space-y-4", children: [_jsx("p", { className: "text-sm text-slate-600 dark:text-slate-400 bg-blue-50 dark:bg-blue-900/20 p-3 rounded-lg border border-blue-200 dark:border-blue-800", children: "\u2139\uFE0F S\u00E9lectionnez une cl\u00E9 API pour cr\u00E9er une session s\u00E9curis\u00E9e de 72h" }), _jsx("div", { className: "space-y-3 max-h-96 overflow-y-auto", children: apiKeys.map((key) => (_jsx("button", { onClick: () => handleSelectKey(key.id), disabled: !key.isActive || loading, className: `w-full text-left px-5 py-4 border-2 rounded-lg transition-all transform hover:scale-[1.02] ${key.isActive
|
|
95
|
-
? "border-slate-200 dark:border-slate-600 hover:border-violet-400 dark:hover:border-violet-500 hover:bg-gradient-to-r hover:from-violet-50 hover:to-purple-50 dark:hover:from-violet-900/20 dark:hover:to-purple-900/20"
|
|
96
|
-
: "border-slate-200 dark:border-slate-700 bg-slate-50 dark:bg-slate-800/50 opacity-50 cursor-not-allowed"}`, children: _jsxs("div", { className: "flex items-start justify-between gap-2", children: [_jsxs("div", { className: "flex-1", children: [_jsxs("div", { className: "font-semibold text-slate-900 dark:text-white flex items-center gap-2", children: [key.isActive ? "🔑" : "🔒", key.name] }), _jsxs("div", { className: "text-sm text-slate-500 dark:text-slate-400 mt-1 font-mono", children: [key.keyPrefix, "..."] }), key.scopes && (_jsxs("div", { className: "flex gap-1 mt-2 flex-wrap", children: [key.scopes.slice(0, 3).map((scope) => (_jsx("span", { className: "text-xs px-2 py-1 bg-violet-100 dark:bg-violet-900/30 text-violet-700 dark:text-violet-300 rounded", children: scope }, scope))), key.scopes.length > 3 && (_jsxs("span", { className: "text-xs px-2 py-1 bg-slate-100 dark:bg-slate-700 text-slate-600 dark:text-slate-400 rounded", children: ["+", key.scopes.length - 3] }))] }))] }), key.isActive ? (_jsx("svg", { className: "w-5 h-5 text-violet-500 flex-shrink-0 mt-1", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M9 5l7 7-7 7" }) })) : (_jsx("span", { className: "text-xs text-red-600 dark:text-red-400 font-semibold bg-red-100 dark:bg-red-900/30 px-2 py-1 rounded", children: "Inactive" }))] }) }, key.id))) }), error && (_jsx("div", { className: "bg-red-50 dark:bg-red-900/20 border-l-4 border-red-500 p-4 rounded", children: _jsxs("div", { className: "flex items-start gap-2", children: [_jsx("span", { className: "text-red-500 text-xl", children: "\u26A0\uFE0F" }), _jsx("p", { className: "text-red-700 dark:text-red-400 text-sm font-medium", children: error })] }) }))] })) })] }) }));
|
|
27
|
+
export function LBAuthModal({ onClose }) {
|
|
28
|
+
return (_jsx(LBSigninModal, { isOpen: true, onClose: () => onClose(false) }));
|
|
97
29
|
}
|
|
98
|
-
export { LBAuthModal };
|
|
@@ -2,5 +2,5 @@ export interface LBSigninModalProps {
|
|
|
2
2
|
isOpen: boolean;
|
|
3
3
|
onClose: () => void;
|
|
4
4
|
}
|
|
5
|
-
export declare function LBSigninModal({ isOpen, onClose }: LBSigninModalProps): import("react
|
|
5
|
+
export declare function LBSigninModal({ isOpen, onClose }: LBSigninModalProps): import("react").ReactPortal | null;
|
|
6
6
|
//# sourceMappingURL=LBSigninModal.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"LBSigninModal.d.ts","sourceRoot":"","sources":["../../src/components/LBSigninModal.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"LBSigninModal.d.ts","sourceRoot":"","sources":["../../src/components/LBSigninModal.tsx"],"names":[],"mappings":"AAQA,MAAM,WAAW,kBAAkB;IACjC,MAAM,EAAE,OAAO,CAAC;IAChB,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB;AAED,wBAAgB,aAAa,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,EAAE,kBAAkB,sCA2NpE"}
|