@merit-systems/echo-react-sdk 1.0.16 → 1.0.18
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/README.md +1 -1
- package/dist/echo-react-sdk.umd.js +2 -2
- package/dist/echo-react-sdk.umd.js.map +1 -1
- package/dist/index.cjs +2 -2
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +23 -2
- package/dist/index.js +709 -127
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -27130,13 +27130,16 @@ var EchoClient = class {
|
|
|
27130
27130
|
this.models = new ModelsResource(this.http);
|
|
27131
27131
|
}
|
|
27132
27132
|
};
|
|
27133
|
-
function createEchoOpenAI({ appId, baseRouterUrl = ROUTER_BASE_URL }, getTokenFn) {
|
|
27133
|
+
function createEchoOpenAI({ appId, baseRouterUrl = ROUTER_BASE_URL }, getTokenFn, onInsufficientFunds) {
|
|
27134
27134
|
const getProvider = async () => {
|
|
27135
27135
|
const token = await getTokenFn(appId);
|
|
27136
27136
|
return createOpenAI({
|
|
27137
27137
|
baseURL: baseRouterUrl,
|
|
27138
|
-
apiKey: token ?? ""
|
|
27138
|
+
apiKey: token ?? "",
|
|
27139
27139
|
// null will fail auth
|
|
27140
|
+
...onInsufficientFunds && {
|
|
27141
|
+
fetch: fetchWith402Interceptor(fetch, onInsufficientFunds)
|
|
27142
|
+
}
|
|
27140
27143
|
});
|
|
27141
27144
|
};
|
|
27142
27145
|
const openaiFunction = async (modelId) => {
|
|
@@ -27192,13 +27195,21 @@ function createEchoOpenAI({ appId, baseRouterUrl = ROUTER_BASE_URL }, getTokenFn
|
|
|
27192
27195
|
});
|
|
27193
27196
|
return implementation;
|
|
27194
27197
|
}
|
|
27195
|
-
function createEchoAnthropic({ appId, baseRouterUrl = ROUTER_BASE_URL }, getTokenFn) {
|
|
27198
|
+
function createEchoAnthropic({ appId, baseRouterUrl = ROUTER_BASE_URL }, getTokenFn, onInsufficientFunds) {
|
|
27196
27199
|
const getProvider = async () => {
|
|
27197
27200
|
const token = await getTokenFn(appId);
|
|
27198
27201
|
return createAnthropic({
|
|
27199
27202
|
baseURL: baseRouterUrl,
|
|
27200
|
-
apiKey: token ?? ""
|
|
27203
|
+
apiKey: token ?? "",
|
|
27201
27204
|
// null will fail auth
|
|
27205
|
+
headers: {
|
|
27206
|
+
// this is safe in Echo because the token is an echo oauth jwt
|
|
27207
|
+
// not a long lived anthropic api key
|
|
27208
|
+
"anthropic-dangerous-direct-browser-access": "true"
|
|
27209
|
+
},
|
|
27210
|
+
...onInsufficientFunds && {
|
|
27211
|
+
fetch: fetchWith402Interceptor(fetch, onInsufficientFunds)
|
|
27212
|
+
}
|
|
27202
27213
|
});
|
|
27203
27214
|
};
|
|
27204
27215
|
const anthropicFunction = async (modelId) => {
|
|
@@ -27235,13 +27246,16 @@ function createEchoAnthropic({ appId, baseRouterUrl = ROUTER_BASE_URL }, getToke
|
|
|
27235
27246
|
);
|
|
27236
27247
|
return implementation;
|
|
27237
27248
|
}
|
|
27238
|
-
function createEchoGoogle({ appId, baseRouterUrl = ROUTER_BASE_URL }, getTokenFn) {
|
|
27249
|
+
function createEchoGoogle({ appId, baseRouterUrl = ROUTER_BASE_URL }, getTokenFn, onInsufficientFunds) {
|
|
27239
27250
|
const getProvider = async () => {
|
|
27240
27251
|
const token = await getTokenFn(appId);
|
|
27241
27252
|
return createGoogleGenerativeAI({
|
|
27242
27253
|
baseURL: baseRouterUrl,
|
|
27243
|
-
apiKey: token ?? ""
|
|
27254
|
+
apiKey: token ?? "",
|
|
27244
27255
|
// null will fail auth
|
|
27256
|
+
...onInsufficientFunds && {
|
|
27257
|
+
fetch: fetchWith402Interceptor(fetch, onInsufficientFunds)
|
|
27258
|
+
}
|
|
27245
27259
|
});
|
|
27246
27260
|
};
|
|
27247
27261
|
const googleFunction = async (modelId) => {
|
|
@@ -27291,6 +27305,15 @@ function createEchoGoogle({ appId, baseRouterUrl = ROUTER_BASE_URL }, getTokenFn
|
|
|
27291
27305
|
});
|
|
27292
27306
|
return implementation;
|
|
27293
27307
|
}
|
|
27308
|
+
function fetchWith402Interceptor(originalFetch, onInsufficientFunds) {
|
|
27309
|
+
return async (input, init) => {
|
|
27310
|
+
const response = await originalFetch(input, init);
|
|
27311
|
+
if (response.status === 402) {
|
|
27312
|
+
onInsufficientFunds();
|
|
27313
|
+
}
|
|
27314
|
+
return response;
|
|
27315
|
+
};
|
|
27316
|
+
}
|
|
27294
27317
|
function useEchoBalance(echoClient, appId) {
|
|
27295
27318
|
const [balance, setBalance] = useState(null);
|
|
27296
27319
|
const [freeTierBalance, setFreeTierBalance] = useState(
|
|
@@ -27422,6 +27445,47 @@ function useEchoPayments(echoClient) {
|
|
|
27422
27445
|
isLoading
|
|
27423
27446
|
};
|
|
27424
27447
|
}
|
|
27448
|
+
function useEchoUser(echoClient) {
|
|
27449
|
+
const [user, setUser] = useState(null);
|
|
27450
|
+
const [error2, setError] = useState(null);
|
|
27451
|
+
const [isLoading, setIsLoading] = useState(false);
|
|
27452
|
+
const refreshUser = useCallback(async () => {
|
|
27453
|
+
if (!echoClient) {
|
|
27454
|
+
throw new Error("Not authenticated");
|
|
27455
|
+
}
|
|
27456
|
+
setIsLoading(true);
|
|
27457
|
+
try {
|
|
27458
|
+
const userResponse = await echoClient.users.getUserInfo();
|
|
27459
|
+
setUser(userResponse);
|
|
27460
|
+
setError(null);
|
|
27461
|
+
} catch (err) {
|
|
27462
|
+
const echoError = parseEchoError(
|
|
27463
|
+
err instanceof Error ? err : new Error(String(err)),
|
|
27464
|
+
"refreshing user"
|
|
27465
|
+
);
|
|
27466
|
+
setError(echoError.message);
|
|
27467
|
+
throw echoError;
|
|
27468
|
+
} finally {
|
|
27469
|
+
setIsLoading(false);
|
|
27470
|
+
}
|
|
27471
|
+
}, [echoClient]);
|
|
27472
|
+
useEffect(() => {
|
|
27473
|
+
if (echoClient) {
|
|
27474
|
+
refreshUser().catch((err) => {
|
|
27475
|
+
console.error("Error loading initial user:", err);
|
|
27476
|
+
});
|
|
27477
|
+
} else {
|
|
27478
|
+
setUser(null);
|
|
27479
|
+
setError(null);
|
|
27480
|
+
}
|
|
27481
|
+
}, [echoClient, refreshUser]);
|
|
27482
|
+
return {
|
|
27483
|
+
user,
|
|
27484
|
+
error: error2,
|
|
27485
|
+
isLoading,
|
|
27486
|
+
refreshUser
|
|
27487
|
+
};
|
|
27488
|
+
}
|
|
27425
27489
|
const EchoContext = createContext(null);
|
|
27426
27490
|
const EchoRefreshContext = createContext(
|
|
27427
27491
|
null
|
|
@@ -27430,10 +27494,10 @@ function EchoProviderInternal({ config: config2, children }) {
|
|
|
27430
27494
|
var _a10, _b, _c;
|
|
27431
27495
|
const auth = useAuth();
|
|
27432
27496
|
const user = auth.user;
|
|
27433
|
-
const echoUser = user ? parseEchoUser(user) : null;
|
|
27434
27497
|
const apiUrl = config2.baseEchoUrl || "https://echo.merit.systems";
|
|
27435
27498
|
const token = ((_a10 = auth.user) == null ? void 0 : _a10.access_token) || null;
|
|
27436
27499
|
const echoClient = useEchoClient({ apiUrl });
|
|
27500
|
+
const [isInsufficientFunds, setIsInsufficientFunds] = useState(false);
|
|
27437
27501
|
const {
|
|
27438
27502
|
balance,
|
|
27439
27503
|
freeTierBalance,
|
|
@@ -27441,6 +27505,11 @@ function EchoProviderInternal({ config: config2, children }) {
|
|
|
27441
27505
|
error: balanceError,
|
|
27442
27506
|
isLoading: balanceLoading
|
|
27443
27507
|
} = useEchoBalance(echoClient, config2.appId);
|
|
27508
|
+
const {
|
|
27509
|
+
user: echoUser,
|
|
27510
|
+
error: userError,
|
|
27511
|
+
isLoading: userLoading
|
|
27512
|
+
} = useEchoUser(echoClient);
|
|
27444
27513
|
const {
|
|
27445
27514
|
createPaymentLink,
|
|
27446
27515
|
error: paymentError,
|
|
@@ -27457,13 +27526,13 @@ function EchoProviderInternal({ config: config2, children }) {
|
|
|
27457
27526
|
var _a15;
|
|
27458
27527
|
return ((_a15 = auth.user) == null ? void 0 : _a15.access_token) || null;
|
|
27459
27528
|
}, [(_b = auth.user) == null ? void 0 : _b.access_token]);
|
|
27460
|
-
const combinedError = ((_c = auth.error) == null ? void 0 : _c.message) || balanceError || paymentError || null;
|
|
27529
|
+
const combinedError = ((_c = auth.error) == null ? void 0 : _c.message) || balanceError || paymentError || userError || null;
|
|
27461
27530
|
const isInitialAuthLoading = auth.isLoading && !auth.isAuthenticated;
|
|
27462
27531
|
const isTokenRefreshing = auth.isLoading && auth.isAuthenticated;
|
|
27463
|
-
const combinedLoading = isInitialAuthLoading || balanceLoading || paymentLoading;
|
|
27532
|
+
const combinedLoading = isInitialAuthLoading || balanceLoading || paymentLoading || userLoading;
|
|
27464
27533
|
const contextValue = useMemo(
|
|
27465
27534
|
() => ({
|
|
27466
|
-
user: echoUser
|
|
27535
|
+
user: echoUser,
|
|
27467
27536
|
rawUser: user,
|
|
27468
27537
|
balance,
|
|
27469
27538
|
freeTierBalance,
|
|
@@ -27478,7 +27547,9 @@ function EchoProviderInternal({ config: config2, children }) {
|
|
|
27478
27547
|
createPaymentLink,
|
|
27479
27548
|
getToken,
|
|
27480
27549
|
clearAuth,
|
|
27481
|
-
config: config2
|
|
27550
|
+
config: config2,
|
|
27551
|
+
isInsufficientFunds,
|
|
27552
|
+
setIsInsufficientFunds
|
|
27482
27553
|
}),
|
|
27483
27554
|
[
|
|
27484
27555
|
echoUser,
|
|
@@ -27495,7 +27566,8 @@ function EchoProviderInternal({ config: config2, children }) {
|
|
|
27495
27566
|
refreshBalance,
|
|
27496
27567
|
createPaymentLink,
|
|
27497
27568
|
getToken,
|
|
27498
|
-
config2
|
|
27569
|
+
config2,
|
|
27570
|
+
isInsufficientFunds
|
|
27499
27571
|
]
|
|
27500
27572
|
);
|
|
27501
27573
|
const refreshContextValue = useMemo(
|
|
@@ -27553,14 +27625,6 @@ function EchoProvider({ config: config2, children }) {
|
|
|
27553
27625
|
};
|
|
27554
27626
|
return /* @__PURE__ */ jsx(AuthProvider, { ...oidcConfig, children: /* @__PURE__ */ jsx(EchoProviderInternal, { config: config2, children }) });
|
|
27555
27627
|
}
|
|
27556
|
-
function parseEchoUser(user) {
|
|
27557
|
-
return {
|
|
27558
|
-
id: user.profile.sub || "",
|
|
27559
|
-
email: user.profile.email || "",
|
|
27560
|
-
name: user.profile.name || user.profile.preferred_username || "",
|
|
27561
|
-
picture: user.profile.picture || ""
|
|
27562
|
-
};
|
|
27563
|
-
}
|
|
27564
27628
|
function useEcho() {
|
|
27565
27629
|
const context = useContext(EchoContext);
|
|
27566
27630
|
if (!context) {
|
|
@@ -28597,7 +28661,7 @@ function sanitizeUrl(url2) {
|
|
|
28597
28661
|
}
|
|
28598
28662
|
}
|
|
28599
28663
|
async function openPaymentFlow(paymentUrl, options = {}) {
|
|
28600
|
-
const { onComplete,
|
|
28664
|
+
const { onComplete, onError } = options;
|
|
28601
28665
|
const safeUrl = sanitizeUrl(paymentUrl);
|
|
28602
28666
|
if (!safeUrl) {
|
|
28603
28667
|
const error2 = new Error("Invalid payment URL provided");
|
|
@@ -28605,62 +28669,7 @@ async function openPaymentFlow(paymentUrl, options = {}) {
|
|
|
28605
28669
|
throw error2;
|
|
28606
28670
|
}
|
|
28607
28671
|
try {
|
|
28608
|
-
|
|
28609
|
-
safeUrl,
|
|
28610
|
-
"echo-payment",
|
|
28611
|
-
"width=600,height=700,scrollbars=yes,resizable=yes"
|
|
28612
|
-
);
|
|
28613
|
-
if (popup && !popup.closed) {
|
|
28614
|
-
return new Promise((resolve2) => {
|
|
28615
|
-
const checkComplete = () => {
|
|
28616
|
-
try {
|
|
28617
|
-
if (popup.closed) {
|
|
28618
|
-
onComplete == null ? void 0 : onComplete();
|
|
28619
|
-
resolve2();
|
|
28620
|
-
return;
|
|
28621
|
-
}
|
|
28622
|
-
setTimeout(checkComplete, 1e3);
|
|
28623
|
-
} catch {
|
|
28624
|
-
onComplete == null ? void 0 : onComplete();
|
|
28625
|
-
resolve2();
|
|
28626
|
-
}
|
|
28627
|
-
};
|
|
28628
|
-
checkComplete();
|
|
28629
|
-
setTimeout(() => {
|
|
28630
|
-
popup.close();
|
|
28631
|
-
onCancel == null ? void 0 : onCancel();
|
|
28632
|
-
resolve2();
|
|
28633
|
-
}, 6e5);
|
|
28634
|
-
});
|
|
28635
|
-
} else {
|
|
28636
|
-
const confirmed = confirm(
|
|
28637
|
-
"Payment will open in a new tab. Click OK to continue, or Cancel to abort."
|
|
28638
|
-
);
|
|
28639
|
-
if (confirmed) {
|
|
28640
|
-
sessionStorage.setItem("echo_payment_flow", "true");
|
|
28641
|
-
window.location.href = safeUrl;
|
|
28642
|
-
return new Promise((resolve2) => {
|
|
28643
|
-
const handleFocus = () => {
|
|
28644
|
-
if (sessionStorage.getItem("echo_payment_flow") === "completed") {
|
|
28645
|
-
sessionStorage.removeItem("echo_payment_flow");
|
|
28646
|
-
onComplete == null ? void 0 : onComplete();
|
|
28647
|
-
window.removeEventListener("focus", handleFocus);
|
|
28648
|
-
resolve2();
|
|
28649
|
-
}
|
|
28650
|
-
};
|
|
28651
|
-
window.addEventListener("focus", handleFocus);
|
|
28652
|
-
setTimeout(() => {
|
|
28653
|
-
window.removeEventListener("focus", handleFocus);
|
|
28654
|
-
sessionStorage.removeItem("echo_payment_flow");
|
|
28655
|
-
onCancel == null ? void 0 : onCancel();
|
|
28656
|
-
resolve2();
|
|
28657
|
-
}, 18e5);
|
|
28658
|
-
});
|
|
28659
|
-
} else {
|
|
28660
|
-
onCancel == null ? void 0 : onCancel();
|
|
28661
|
-
return Promise.resolve();
|
|
28662
|
-
}
|
|
28663
|
-
}
|
|
28672
|
+
window.location.href = safeUrl;
|
|
28664
28673
|
} catch (err) {
|
|
28665
28674
|
const error2 = err instanceof Error ? err : new Error("Payment flow failed");
|
|
28666
28675
|
onError == null ? void 0 : onError(error2);
|
|
@@ -28896,6 +28905,482 @@ function EchoSignIn({
|
|
|
28896
28905
|
}
|
|
28897
28906
|
) });
|
|
28898
28907
|
}
|
|
28908
|
+
function EchoSignOut({
|
|
28909
|
+
onSuccess,
|
|
28910
|
+
onError,
|
|
28911
|
+
className = "",
|
|
28912
|
+
children
|
|
28913
|
+
}) {
|
|
28914
|
+
const { signOut, isLoading, user, error: error2 } = useEcho();
|
|
28915
|
+
const [isHovered, setIsHovered] = useState(false);
|
|
28916
|
+
const [isSigningOut, setIsSigningOut] = useState(false);
|
|
28917
|
+
React2.useEffect(() => {
|
|
28918
|
+
if (!user && onSuccess && isSigningOut) {
|
|
28919
|
+
onSuccess();
|
|
28920
|
+
setIsSigningOut(false);
|
|
28921
|
+
}
|
|
28922
|
+
}, [user, onSuccess, isSigningOut]);
|
|
28923
|
+
React2.useEffect(() => {
|
|
28924
|
+
if (error2 && onError) {
|
|
28925
|
+
onError(new Error(error2));
|
|
28926
|
+
}
|
|
28927
|
+
}, [error2, onError]);
|
|
28928
|
+
const handleSignOut = async () => {
|
|
28929
|
+
try {
|
|
28930
|
+
setIsSigningOut(true);
|
|
28931
|
+
await signOut();
|
|
28932
|
+
} catch (err) {
|
|
28933
|
+
setIsSigningOut(false);
|
|
28934
|
+
if (onError) {
|
|
28935
|
+
onError(err instanceof Error ? err : new Error("Sign out failed"));
|
|
28936
|
+
}
|
|
28937
|
+
}
|
|
28938
|
+
};
|
|
28939
|
+
if (!user) {
|
|
28940
|
+
return /* @__PURE__ */ jsx("div", { className: `echo-signout-success ${className}`, children: /* @__PURE__ */ jsxs(
|
|
28941
|
+
"div",
|
|
28942
|
+
{
|
|
28943
|
+
style: {
|
|
28944
|
+
display: "flex",
|
|
28945
|
+
alignItems: "center",
|
|
28946
|
+
gap: "8px",
|
|
28947
|
+
padding: "12px 16px",
|
|
28948
|
+
backgroundColor: "#f8fafc",
|
|
28949
|
+
border: "1px solid #e2e8f0",
|
|
28950
|
+
borderRadius: "8px",
|
|
28951
|
+
color: "#334155",
|
|
28952
|
+
fontSize: "14px",
|
|
28953
|
+
fontFamily: "HelveticaNowDisplay, sans-serif",
|
|
28954
|
+
fontWeight: "800",
|
|
28955
|
+
width: "fit-content"
|
|
28956
|
+
},
|
|
28957
|
+
children: [
|
|
28958
|
+
/* @__PURE__ */ jsx(Logo, { width: 16, height: 16, variant: "light" }),
|
|
28959
|
+
/* @__PURE__ */ jsx("span", { children: "Signed out" })
|
|
28960
|
+
]
|
|
28961
|
+
}
|
|
28962
|
+
) });
|
|
28963
|
+
}
|
|
28964
|
+
return /* @__PURE__ */ jsx("div", { className: `echo-signout ${className}`, children: children ? /* @__PURE__ */ jsx("div", { onClick: handleSignOut, style: { cursor: "pointer" }, children }) : /* @__PURE__ */ jsxs(
|
|
28965
|
+
"button",
|
|
28966
|
+
{
|
|
28967
|
+
onClick: handleSignOut,
|
|
28968
|
+
disabled: isLoading || isSigningOut,
|
|
28969
|
+
className: "echo-signout-button",
|
|
28970
|
+
style: {
|
|
28971
|
+
display: "flex",
|
|
28972
|
+
alignItems: "center",
|
|
28973
|
+
gap: "8px",
|
|
28974
|
+
padding: "12px 20px",
|
|
28975
|
+
backgroundColor: isLoading || isSigningOut ? "#f3f4f6" : isHovered ? "#fef2f2" : "#ffffff",
|
|
28976
|
+
color: isLoading || isSigningOut ? "#9ca3af" : isHovered ? "#dc2626" : "#374151",
|
|
28977
|
+
border: "1px solid #e2e8f0",
|
|
28978
|
+
borderRadius: "8px",
|
|
28979
|
+
cursor: isLoading || isSigningOut ? "not-allowed" : "pointer",
|
|
28980
|
+
fontSize: "14px",
|
|
28981
|
+
fontWeight: "800",
|
|
28982
|
+
fontFamily: "HelveticaNowDisplay, sans-serif",
|
|
28983
|
+
transition: "all 0.2s ease",
|
|
28984
|
+
boxShadow: "0 1px 2px 0 rgba(0, 0, 0, 0.05)",
|
|
28985
|
+
backdropFilter: "blur(8px)"
|
|
28986
|
+
},
|
|
28987
|
+
onMouseEnter: () => setIsHovered(true),
|
|
28988
|
+
onMouseLeave: () => setIsHovered(false),
|
|
28989
|
+
children: [
|
|
28990
|
+
/* @__PURE__ */ jsx(Logo, { width: 16, height: 16, variant: "light" }),
|
|
28991
|
+
/* @__PURE__ */ jsx("span", { children: isLoading || isSigningOut ? "Signing out..." : `Sign out` })
|
|
28992
|
+
]
|
|
28993
|
+
}
|
|
28994
|
+
) });
|
|
28995
|
+
}
|
|
28996
|
+
const CustomAmountInput$1 = ({
|
|
28997
|
+
onAddCredits,
|
|
28998
|
+
onCancel,
|
|
28999
|
+
isProcessing
|
|
29000
|
+
}) => {
|
|
29001
|
+
const [amount, setAmount] = useState("");
|
|
29002
|
+
const inputRef = useRef(null);
|
|
29003
|
+
useEffect(() => {
|
|
29004
|
+
if (inputRef.current) {
|
|
29005
|
+
inputRef.current.focus();
|
|
29006
|
+
}
|
|
29007
|
+
}, []);
|
|
29008
|
+
const handleAddCredits = () => {
|
|
29009
|
+
const purchaseAmount = Number(amount);
|
|
29010
|
+
if (purchaseAmount > 0) {
|
|
29011
|
+
onAddCredits(purchaseAmount);
|
|
29012
|
+
}
|
|
29013
|
+
};
|
|
29014
|
+
const isValidAmount = amount !== "" && Number(amount) > 0;
|
|
29015
|
+
return /* @__PURE__ */ jsxs("div", { style: { display: "flex", flexDirection: "column", gap: "8px" }, children: [
|
|
29016
|
+
/* @__PURE__ */ jsxs("div", { style: { display: "flex", alignItems: "center", gap: "8px" }, children: [
|
|
29017
|
+
/* @__PURE__ */ jsx(
|
|
29018
|
+
"span",
|
|
29019
|
+
{
|
|
29020
|
+
style: {
|
|
29021
|
+
fontSize: "14px",
|
|
29022
|
+
color: "#6b7280",
|
|
29023
|
+
fontFamily: "HelveticaNowDisplay, sans-serif"
|
|
29024
|
+
},
|
|
29025
|
+
children: "$"
|
|
29026
|
+
}
|
|
29027
|
+
),
|
|
29028
|
+
/* @__PURE__ */ jsx(
|
|
29029
|
+
"input",
|
|
29030
|
+
{
|
|
29031
|
+
ref: inputRef,
|
|
29032
|
+
type: "number",
|
|
29033
|
+
value: amount,
|
|
29034
|
+
onChange: (e) => setAmount(e.target.value),
|
|
29035
|
+
placeholder: "0.00",
|
|
29036
|
+
min: "1",
|
|
29037
|
+
step: "0.01",
|
|
29038
|
+
style: {
|
|
29039
|
+
flex: 1,
|
|
29040
|
+
padding: "8px 12px",
|
|
29041
|
+
border: "1px solid #d1d5db",
|
|
29042
|
+
borderRadius: "6px",
|
|
29043
|
+
fontSize: "14px",
|
|
29044
|
+
fontFamily: "HelveticaNowDisplay, sans-serif",
|
|
29045
|
+
outline: "none"
|
|
29046
|
+
},
|
|
29047
|
+
onKeyDown: (e) => {
|
|
29048
|
+
if (e.key === "Enter" && isValidAmount && !isProcessing) {
|
|
29049
|
+
handleAddCredits();
|
|
29050
|
+
} else if (e.key === "Escape") {
|
|
29051
|
+
onCancel();
|
|
29052
|
+
}
|
|
29053
|
+
}
|
|
29054
|
+
}
|
|
29055
|
+
)
|
|
29056
|
+
] }),
|
|
29057
|
+
/* @__PURE__ */ jsxs("div", { style: { display: "flex", gap: "8px" }, children: [
|
|
29058
|
+
/* @__PURE__ */ jsx(
|
|
29059
|
+
"button",
|
|
29060
|
+
{
|
|
29061
|
+
onClick: onCancel,
|
|
29062
|
+
style: {
|
|
29063
|
+
flex: 1,
|
|
29064
|
+
padding: "8px 16px",
|
|
29065
|
+
backgroundColor: "transparent",
|
|
29066
|
+
color: "#6b7280",
|
|
29067
|
+
border: "1px solid #d1d5db",
|
|
29068
|
+
borderRadius: "6px",
|
|
29069
|
+
fontSize: "14px",
|
|
29070
|
+
cursor: "pointer",
|
|
29071
|
+
fontFamily: "HelveticaNowDisplay, sans-serif"
|
|
29072
|
+
},
|
|
29073
|
+
children: "Cancel"
|
|
29074
|
+
}
|
|
29075
|
+
),
|
|
29076
|
+
/* @__PURE__ */ jsx(
|
|
29077
|
+
"button",
|
|
29078
|
+
{
|
|
29079
|
+
onClick: handleAddCredits,
|
|
29080
|
+
disabled: !isValidAmount || isProcessing,
|
|
29081
|
+
style: {
|
|
29082
|
+
flex: 1,
|
|
29083
|
+
padding: "8px 16px",
|
|
29084
|
+
backgroundColor: isValidAmount && !isProcessing ? "#dc2626" : "#9ca3af",
|
|
29085
|
+
color: "white",
|
|
29086
|
+
border: "none",
|
|
29087
|
+
borderRadius: "6px",
|
|
29088
|
+
fontSize: "14px",
|
|
29089
|
+
fontWeight: "600",
|
|
29090
|
+
cursor: isValidAmount && !isProcessing ? "pointer" : "not-allowed",
|
|
29091
|
+
fontFamily: "HelveticaNowDisplay, sans-serif"
|
|
29092
|
+
},
|
|
29093
|
+
children: isProcessing ? "Processing..." : "Add Credits"
|
|
29094
|
+
}
|
|
29095
|
+
)
|
|
29096
|
+
] })
|
|
29097
|
+
] });
|
|
29098
|
+
};
|
|
29099
|
+
function InsufficientFundsModal({
|
|
29100
|
+
isOpen,
|
|
29101
|
+
onClose,
|
|
29102
|
+
onPurchaseComplete,
|
|
29103
|
+
onError
|
|
29104
|
+
}) {
|
|
29105
|
+
const { createPaymentLink, user, refreshBalance } = useEcho();
|
|
29106
|
+
const [isProcessing, setIsProcessing] = useState(false);
|
|
29107
|
+
const [purchaseError, setPurchaseError] = useState(null);
|
|
29108
|
+
const [showCustomAmount, setShowCustomAmount] = useState(false);
|
|
29109
|
+
const handlePurchase = async (amount) => {
|
|
29110
|
+
if (!user) {
|
|
29111
|
+
const error2 = new Error("Please sign in to purchase tokens");
|
|
29112
|
+
setPurchaseError(error2.message);
|
|
29113
|
+
onError == null ? void 0 : onError(error2);
|
|
29114
|
+
return;
|
|
29115
|
+
}
|
|
29116
|
+
try {
|
|
29117
|
+
setIsProcessing(true);
|
|
29118
|
+
setPurchaseError(null);
|
|
29119
|
+
const paymentUrl = await createPaymentLink(amount);
|
|
29120
|
+
await openPaymentFlow(paymentUrl, {
|
|
29121
|
+
onComplete: async () => {
|
|
29122
|
+
try {
|
|
29123
|
+
await refreshBalance();
|
|
29124
|
+
onPurchaseComplete == null ? void 0 : onPurchaseComplete();
|
|
29125
|
+
onClose();
|
|
29126
|
+
} catch (refreshError) {
|
|
29127
|
+
console.error("Failed to refresh balance:", refreshError);
|
|
29128
|
+
}
|
|
29129
|
+
},
|
|
29130
|
+
onError: (error2) => {
|
|
29131
|
+
setPurchaseError(error2.message);
|
|
29132
|
+
onError == null ? void 0 : onError(error2);
|
|
29133
|
+
}
|
|
29134
|
+
});
|
|
29135
|
+
} catch (error2) {
|
|
29136
|
+
const errorMessage = error2 instanceof Error ? error2.message : "Purchase failed";
|
|
29137
|
+
setPurchaseError(errorMessage);
|
|
29138
|
+
onError == null ? void 0 : onError(error2 instanceof Error ? error2 : new Error(errorMessage));
|
|
29139
|
+
} finally {
|
|
29140
|
+
setIsProcessing(false);
|
|
29141
|
+
}
|
|
29142
|
+
};
|
|
29143
|
+
if (!isOpen) return null;
|
|
29144
|
+
return /* @__PURE__ */ jsx(
|
|
29145
|
+
"div",
|
|
29146
|
+
{
|
|
29147
|
+
style: {
|
|
29148
|
+
position: "fixed",
|
|
29149
|
+
top: 0,
|
|
29150
|
+
left: 0,
|
|
29151
|
+
right: 0,
|
|
29152
|
+
bottom: 0,
|
|
29153
|
+
backgroundColor: "rgba(0, 0, 0, 0.5)",
|
|
29154
|
+
display: "flex",
|
|
29155
|
+
alignItems: "center",
|
|
29156
|
+
justifyContent: "center",
|
|
29157
|
+
zIndex: 1e3,
|
|
29158
|
+
padding: "16px",
|
|
29159
|
+
margin: 0,
|
|
29160
|
+
boxSizing: "border-box",
|
|
29161
|
+
// CSS reset to prevent inheritance issues
|
|
29162
|
+
border: "none",
|
|
29163
|
+
outline: "none",
|
|
29164
|
+
textDecoration: "none",
|
|
29165
|
+
listStyle: "none"
|
|
29166
|
+
},
|
|
29167
|
+
onClick: (e) => {
|
|
29168
|
+
if (e.target === e.currentTarget) {
|
|
29169
|
+
onClose();
|
|
29170
|
+
}
|
|
29171
|
+
},
|
|
29172
|
+
children: /* @__PURE__ */ jsxs(
|
|
29173
|
+
"div",
|
|
29174
|
+
{
|
|
29175
|
+
style: {
|
|
29176
|
+
backgroundColor: "#ffffff",
|
|
29177
|
+
borderRadius: "12px",
|
|
29178
|
+
border: "1px solid #e5e7eb",
|
|
29179
|
+
padding: "0",
|
|
29180
|
+
margin: "0",
|
|
29181
|
+
width: "100%",
|
|
29182
|
+
maxWidth: "450px",
|
|
29183
|
+
maxHeight: "90vh",
|
|
29184
|
+
overflow: "hidden",
|
|
29185
|
+
boxShadow: "0 10px 25px -5px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05)",
|
|
29186
|
+
fontFamily: "HelveticaNowDisplay, sans-serif",
|
|
29187
|
+
display: "flex",
|
|
29188
|
+
flexDirection: "column",
|
|
29189
|
+
minHeight: "320px",
|
|
29190
|
+
boxSizing: "border-box"
|
|
29191
|
+
},
|
|
29192
|
+
children: [
|
|
29193
|
+
/* @__PURE__ */ jsx("div", { style: { padding: "16px 16px 0 16px", marginBottom: "12px" }, children: /* @__PURE__ */ jsxs(
|
|
29194
|
+
"div",
|
|
29195
|
+
{
|
|
29196
|
+
style: {
|
|
29197
|
+
display: "flex",
|
|
29198
|
+
alignItems: "center",
|
|
29199
|
+
gap: "8px"
|
|
29200
|
+
},
|
|
29201
|
+
children: [
|
|
29202
|
+
/* @__PURE__ */ jsx(Logo, { width: 20, height: 20, variant: "light" }),
|
|
29203
|
+
/* @__PURE__ */ jsx(
|
|
29204
|
+
"h2",
|
|
29205
|
+
{
|
|
29206
|
+
style: {
|
|
29207
|
+
fontSize: "18px",
|
|
29208
|
+
fontWeight: "500",
|
|
29209
|
+
color: "#111827",
|
|
29210
|
+
margin: 0,
|
|
29211
|
+
fontFamily: "HelveticaNowDisplay, sans-serif"
|
|
29212
|
+
},
|
|
29213
|
+
children: "Insufficient Balance"
|
|
29214
|
+
}
|
|
29215
|
+
)
|
|
29216
|
+
]
|
|
29217
|
+
}
|
|
29218
|
+
) }),
|
|
29219
|
+
/* @__PURE__ */ jsx("div", { style: { padding: "0 16px 16px 16px" }, children: /* @__PURE__ */ jsx(
|
|
29220
|
+
"p",
|
|
29221
|
+
{
|
|
29222
|
+
style: {
|
|
29223
|
+
fontSize: "14px",
|
|
29224
|
+
color: "#6b7280",
|
|
29225
|
+
margin: "0 0 12px 0",
|
|
29226
|
+
fontFamily: "HelveticaNowDisplay, sans-serif"
|
|
29227
|
+
},
|
|
29228
|
+
children: "You don't have enough credits to complete this request. Please add credits to your account."
|
|
29229
|
+
}
|
|
29230
|
+
) }),
|
|
29231
|
+
/* @__PURE__ */ jsx(
|
|
29232
|
+
"div",
|
|
29233
|
+
{
|
|
29234
|
+
style: {
|
|
29235
|
+
padding: "0 16px 16px 16px",
|
|
29236
|
+
borderTop: "1px solid #f3f4f6",
|
|
29237
|
+
paddingTop: "16px"
|
|
29238
|
+
},
|
|
29239
|
+
children: !showCustomAmount ? /* @__PURE__ */ jsxs(
|
|
29240
|
+
"div",
|
|
29241
|
+
{
|
|
29242
|
+
style: { display: "flex", flexDirection: "column", gap: "8px" },
|
|
29243
|
+
children: [
|
|
29244
|
+
/* @__PURE__ */ jsx(
|
|
29245
|
+
"button",
|
|
29246
|
+
{
|
|
29247
|
+
onClick: () => handlePurchase(10),
|
|
29248
|
+
disabled: isProcessing,
|
|
29249
|
+
style: {
|
|
29250
|
+
width: "100%",
|
|
29251
|
+
padding: "12px 16px",
|
|
29252
|
+
backgroundColor: isProcessing ? "#9ca3af" : "#dc2626",
|
|
29253
|
+
color: "white",
|
|
29254
|
+
border: "none",
|
|
29255
|
+
borderRadius: "6px",
|
|
29256
|
+
fontSize: "14px",
|
|
29257
|
+
fontWeight: "600",
|
|
29258
|
+
cursor: isProcessing ? "not-allowed" : "pointer",
|
|
29259
|
+
transition: "background-color 0.2s ease",
|
|
29260
|
+
fontFamily: "HelveticaNowDisplay, sans-serif"
|
|
29261
|
+
},
|
|
29262
|
+
onMouseEnter: (e) => {
|
|
29263
|
+
if (!isProcessing) {
|
|
29264
|
+
e.currentTarget.style.backgroundColor = "#b91c1c";
|
|
29265
|
+
}
|
|
29266
|
+
},
|
|
29267
|
+
onMouseLeave: (e) => {
|
|
29268
|
+
if (!isProcessing) {
|
|
29269
|
+
e.currentTarget.style.backgroundColor = "#dc2626";
|
|
29270
|
+
}
|
|
29271
|
+
},
|
|
29272
|
+
children: isProcessing ? "Processing..." : "Add $10.00"
|
|
29273
|
+
}
|
|
29274
|
+
),
|
|
29275
|
+
/* @__PURE__ */ jsx(
|
|
29276
|
+
"button",
|
|
29277
|
+
{
|
|
29278
|
+
onClick: () => setShowCustomAmount(true),
|
|
29279
|
+
disabled: isProcessing,
|
|
29280
|
+
style: {
|
|
29281
|
+
width: "100%",
|
|
29282
|
+
padding: "8px 16px",
|
|
29283
|
+
backgroundColor: "transparent",
|
|
29284
|
+
color: "#dc2626",
|
|
29285
|
+
border: "1px solid #dc2626",
|
|
29286
|
+
borderRadius: "6px",
|
|
29287
|
+
fontSize: "14px",
|
|
29288
|
+
cursor: isProcessing ? "not-allowed" : "pointer",
|
|
29289
|
+
fontFamily: "HelveticaNowDisplay, sans-serif",
|
|
29290
|
+
transition: "all 0.2s ease"
|
|
29291
|
+
},
|
|
29292
|
+
onMouseEnter: (e) => {
|
|
29293
|
+
if (!isProcessing) {
|
|
29294
|
+
e.currentTarget.style.backgroundColor = "#fef2f2";
|
|
29295
|
+
e.currentTarget.style.borderColor = "#b91c1c";
|
|
29296
|
+
}
|
|
29297
|
+
},
|
|
29298
|
+
onMouseLeave: (e) => {
|
|
29299
|
+
if (!isProcessing) {
|
|
29300
|
+
e.currentTarget.style.backgroundColor = "transparent";
|
|
29301
|
+
e.currentTarget.style.borderColor = "#dc2626";
|
|
29302
|
+
}
|
|
29303
|
+
},
|
|
29304
|
+
children: "Custom Amount"
|
|
29305
|
+
}
|
|
29306
|
+
)
|
|
29307
|
+
]
|
|
29308
|
+
}
|
|
29309
|
+
) : /* @__PURE__ */ jsx(
|
|
29310
|
+
CustomAmountInput$1,
|
|
29311
|
+
{
|
|
29312
|
+
onAddCredits: handlePurchase,
|
|
29313
|
+
onCancel: () => setShowCustomAmount(false),
|
|
29314
|
+
isProcessing
|
|
29315
|
+
}
|
|
29316
|
+
)
|
|
29317
|
+
}
|
|
29318
|
+
),
|
|
29319
|
+
purchaseError && /* @__PURE__ */ jsx("div", { style: { padding: "0 16px 16px 16px" }, children: /* @__PURE__ */ jsx(
|
|
29320
|
+
"div",
|
|
29321
|
+
{
|
|
29322
|
+
style: {
|
|
29323
|
+
padding: "8px 12px",
|
|
29324
|
+
backgroundColor: "#fef2f2",
|
|
29325
|
+
borderRadius: "6px",
|
|
29326
|
+
border: "1px solid #fecaca"
|
|
29327
|
+
},
|
|
29328
|
+
children: /* @__PURE__ */ jsx(
|
|
29329
|
+
"p",
|
|
29330
|
+
{
|
|
29331
|
+
style: {
|
|
29332
|
+
color: "#dc2626",
|
|
29333
|
+
margin: 0,
|
|
29334
|
+
fontSize: "12px",
|
|
29335
|
+
fontFamily: "HelveticaNowDisplay, sans-serif"
|
|
29336
|
+
},
|
|
29337
|
+
children: purchaseError
|
|
29338
|
+
}
|
|
29339
|
+
)
|
|
29340
|
+
}
|
|
29341
|
+
) }),
|
|
29342
|
+
/* @__PURE__ */ jsx(
|
|
29343
|
+
"div",
|
|
29344
|
+
{
|
|
29345
|
+
style: {
|
|
29346
|
+
display: "flex",
|
|
29347
|
+
justifyContent: "flex-end",
|
|
29348
|
+
alignItems: "center",
|
|
29349
|
+
padding: "12px 16px",
|
|
29350
|
+
borderTop: "1px solid #f3f4f6",
|
|
29351
|
+
gap: "8px"
|
|
29352
|
+
},
|
|
29353
|
+
children: /* @__PURE__ */ jsx(
|
|
29354
|
+
"button",
|
|
29355
|
+
{
|
|
29356
|
+
onClick: onClose,
|
|
29357
|
+
style: {
|
|
29358
|
+
padding: "8px 16px",
|
|
29359
|
+
backgroundColor: "#f3f4f6",
|
|
29360
|
+
color: "#374151",
|
|
29361
|
+
border: "none",
|
|
29362
|
+
borderRadius: "6px",
|
|
29363
|
+
fontSize: "14px",
|
|
29364
|
+
cursor: "pointer",
|
|
29365
|
+
fontFamily: "HelveticaNowDisplay, sans-serif"
|
|
29366
|
+
},
|
|
29367
|
+
onMouseEnter: (e) => {
|
|
29368
|
+
e.currentTarget.style.backgroundColor = "#e5e7eb";
|
|
29369
|
+
},
|
|
29370
|
+
onMouseLeave: (e) => {
|
|
29371
|
+
e.currentTarget.style.backgroundColor = "#f3f4f6";
|
|
29372
|
+
},
|
|
29373
|
+
children: "Close"
|
|
29374
|
+
}
|
|
29375
|
+
)
|
|
29376
|
+
}
|
|
29377
|
+
)
|
|
29378
|
+
]
|
|
29379
|
+
}
|
|
29380
|
+
)
|
|
29381
|
+
}
|
|
29382
|
+
);
|
|
29383
|
+
}
|
|
28899
29384
|
const CustomAmountInput = ({
|
|
28900
29385
|
onAddCredits,
|
|
28901
29386
|
onCancel,
|
|
@@ -29020,13 +29505,22 @@ const CustomAmountInput = ({
|
|
|
29020
29505
|
}
|
|
29021
29506
|
);
|
|
29022
29507
|
};
|
|
29023
|
-
function
|
|
29508
|
+
function EchoTokens({
|
|
29024
29509
|
onPurchaseComplete,
|
|
29025
29510
|
onError,
|
|
29026
29511
|
className = "",
|
|
29027
|
-
children
|
|
29512
|
+
children,
|
|
29513
|
+
showAvatar = false
|
|
29028
29514
|
}) {
|
|
29029
|
-
const {
|
|
29515
|
+
const {
|
|
29516
|
+
createPaymentLink,
|
|
29517
|
+
user,
|
|
29518
|
+
balance,
|
|
29519
|
+
freeTierBalance,
|
|
29520
|
+
refreshBalance,
|
|
29521
|
+
isInsufficientFunds,
|
|
29522
|
+
setIsInsufficientFunds
|
|
29523
|
+
} = useEcho();
|
|
29030
29524
|
const [isProcessing, setIsProcessing] = useState(false);
|
|
29031
29525
|
const [purchaseError, setPurchaseError] = useState(null);
|
|
29032
29526
|
const [isModalOpen, setIsModalOpen] = useState(false);
|
|
@@ -29093,7 +29587,7 @@ function EchoTokenPurchase({
|
|
|
29093
29587
|
setPurchaseError(null);
|
|
29094
29588
|
};
|
|
29095
29589
|
if (!user) {
|
|
29096
|
-
return /* @__PURE__ */ jsx("div", { className: `echo-token-purchase ${className}`, children: /* @__PURE__ */
|
|
29590
|
+
return /* @__PURE__ */ jsx("div", { className: `echo-token-purchase ${className}`, children: children ? /* @__PURE__ */ jsxs(
|
|
29097
29591
|
"div",
|
|
29098
29592
|
{
|
|
29099
29593
|
className: "echo-token-purchase-unauthorized",
|
|
@@ -29102,11 +29596,15 @@ function EchoTokenPurchase({
|
|
|
29102
29596
|
backgroundColor: "#fef3c7",
|
|
29103
29597
|
color: "#92400e",
|
|
29104
29598
|
borderRadius: "8px",
|
|
29105
|
-
fontSize: "14px"
|
|
29599
|
+
fontSize: "14px",
|
|
29600
|
+
textAlign: "center"
|
|
29106
29601
|
},
|
|
29107
|
-
children:
|
|
29602
|
+
children: [
|
|
29603
|
+
/* @__PURE__ */ jsx("p", { style: { margin: "0 0 12px 0" }, children: "Please sign in to purchase tokens" }),
|
|
29604
|
+
/* @__PURE__ */ jsx(EchoSignIn, {})
|
|
29605
|
+
]
|
|
29108
29606
|
}
|
|
29109
|
-
) });
|
|
29607
|
+
) : /* @__PURE__ */ jsx(EchoSignIn, {}) });
|
|
29110
29608
|
}
|
|
29111
29609
|
const CompactButton = () => {
|
|
29112
29610
|
const [isHovered, setIsHovered] = useState(false);
|
|
@@ -29136,7 +29634,23 @@ function EchoTokenPurchase({
|
|
|
29136
29634
|
onMouseEnter: () => setIsHovered(true),
|
|
29137
29635
|
onMouseLeave: () => setIsHovered(false),
|
|
29138
29636
|
children: [
|
|
29139
|
-
|
|
29637
|
+
showAvatar && (user == null ? void 0 : user.picture) ? /* @__PURE__ */ jsx(
|
|
29638
|
+
"img",
|
|
29639
|
+
{
|
|
29640
|
+
src: user.picture,
|
|
29641
|
+
alt: user.name || user.email || "User avatar",
|
|
29642
|
+
style: {
|
|
29643
|
+
width: "24px",
|
|
29644
|
+
height: "24px",
|
|
29645
|
+
borderRadius: "50%",
|
|
29646
|
+
objectFit: "cover",
|
|
29647
|
+
flexShrink: 0
|
|
29648
|
+
},
|
|
29649
|
+
onError: (e) => {
|
|
29650
|
+
e.currentTarget.style.display = "none";
|
|
29651
|
+
}
|
|
29652
|
+
}
|
|
29653
|
+
) : /* @__PURE__ */ jsx(Logo, { width: 20, height: 20, variant: "light" }),
|
|
29140
29654
|
/* @__PURE__ */ jsx("span", { children: formatCurrency(calculateAvailableSpend()) }),
|
|
29141
29655
|
/* @__PURE__ */ jsxs(
|
|
29142
29656
|
"svg",
|
|
@@ -29204,17 +29718,30 @@ function EchoTokenPurchase({
|
|
|
29204
29718
|
minHeight: "320px"
|
|
29205
29719
|
},
|
|
29206
29720
|
children: [
|
|
29207
|
-
/* @__PURE__ */ jsx("div", { style: { padding: "16px 16px 0 16px", marginBottom: "12px" }, children: /* @__PURE__ */
|
|
29208
|
-
"
|
|
29721
|
+
/* @__PURE__ */ jsx("div", { style: { padding: "16px 16px 0 16px", marginBottom: "12px" }, children: /* @__PURE__ */ jsxs(
|
|
29722
|
+
"div",
|
|
29209
29723
|
{
|
|
29210
29724
|
style: {
|
|
29211
|
-
|
|
29212
|
-
|
|
29213
|
-
|
|
29214
|
-
margin: 0,
|
|
29215
|
-
fontFamily: "HelveticaNowDisplay, sans-serif"
|
|
29725
|
+
display: "flex",
|
|
29726
|
+
alignItems: "center",
|
|
29727
|
+
gap: "8px"
|
|
29216
29728
|
},
|
|
29217
|
-
children:
|
|
29729
|
+
children: [
|
|
29730
|
+
/* @__PURE__ */ jsx(Logo, { width: 20, height: 20, variant: "light" }),
|
|
29731
|
+
/* @__PURE__ */ jsx(
|
|
29732
|
+
"h2",
|
|
29733
|
+
{
|
|
29734
|
+
style: {
|
|
29735
|
+
fontSize: "18px",
|
|
29736
|
+
fontWeight: "500",
|
|
29737
|
+
color: "#111827",
|
|
29738
|
+
margin: 0,
|
|
29739
|
+
fontFamily: "HelveticaNowDisplay, sans-serif"
|
|
29740
|
+
},
|
|
29741
|
+
children: "Credits"
|
|
29742
|
+
}
|
|
29743
|
+
)
|
|
29744
|
+
]
|
|
29218
29745
|
}
|
|
29219
29746
|
) }),
|
|
29220
29747
|
/* @__PURE__ */ jsxs("div", { style: { padding: "0 16px", marginBottom: "16px" }, children: [
|
|
@@ -29351,10 +29878,10 @@ function EchoTokenPurchase({
|
|
|
29351
29878
|
/* @__PURE__ */ jsxs("span", { children: [
|
|
29352
29879
|
formatCurrency(balance.balance),
|
|
29353
29880
|
" Paid Credits",
|
|
29354
|
-
balance.
|
|
29881
|
+
balance.totalPaid > 0 && /* @__PURE__ */ jsxs("span", { style: { color: "#9ca3af", marginLeft: "8px" }, children: [
|
|
29355
29882
|
"(",
|
|
29356
29883
|
formatCurrency(balance.totalSpent),
|
|
29357
|
-
"
|
|
29884
|
+
" of",
|
|
29358
29885
|
" ",
|
|
29359
29886
|
formatCurrency(balance.totalPaid),
|
|
29360
29887
|
" spent)"
|
|
@@ -29502,38 +30029,78 @@ function EchoTokenPurchase({
|
|
|
29502
30029
|
children: purchaseError
|
|
29503
30030
|
}
|
|
29504
30031
|
),
|
|
29505
|
-
/* @__PURE__ */
|
|
30032
|
+
/* @__PURE__ */ jsxs(
|
|
29506
30033
|
"div",
|
|
29507
30034
|
{
|
|
29508
30035
|
style: {
|
|
29509
30036
|
padding: "12px 16px",
|
|
29510
30037
|
display: "flex",
|
|
29511
|
-
justifyContent: "
|
|
30038
|
+
justifyContent: "space-between",
|
|
30039
|
+
alignItems: "center",
|
|
29512
30040
|
borderTop: "1px solid #f3f4f6"
|
|
29513
30041
|
},
|
|
29514
|
-
children:
|
|
29515
|
-
|
|
29516
|
-
|
|
29517
|
-
|
|
29518
|
-
|
|
29519
|
-
|
|
29520
|
-
|
|
29521
|
-
|
|
29522
|
-
|
|
29523
|
-
|
|
29524
|
-
|
|
29525
|
-
|
|
29526
|
-
|
|
29527
|
-
|
|
29528
|
-
|
|
29529
|
-
|
|
29530
|
-
|
|
29531
|
-
|
|
29532
|
-
|
|
29533
|
-
|
|
29534
|
-
|
|
29535
|
-
|
|
29536
|
-
|
|
30042
|
+
children: [
|
|
30043
|
+
/* @__PURE__ */ jsx(
|
|
30044
|
+
EchoSignOut,
|
|
30045
|
+
{
|
|
30046
|
+
onSuccess: () => {
|
|
30047
|
+
console.log("Signed out from credits modal");
|
|
30048
|
+
closeModal();
|
|
30049
|
+
},
|
|
30050
|
+
onError: (error2) => {
|
|
30051
|
+
console.error("Sign out error from credits modal:", error2);
|
|
30052
|
+
},
|
|
30053
|
+
children: /* @__PURE__ */ jsx(
|
|
30054
|
+
"button",
|
|
30055
|
+
{
|
|
30056
|
+
style: {
|
|
30057
|
+
padding: "8px 16px",
|
|
30058
|
+
backgroundColor: "transparent",
|
|
30059
|
+
color: "#dc2626",
|
|
30060
|
+
border: "1px solid #dc2626",
|
|
30061
|
+
borderRadius: "6px",
|
|
30062
|
+
fontSize: "14px",
|
|
30063
|
+
cursor: "pointer",
|
|
30064
|
+
fontFamily: "HelveticaNowDisplay, sans-serif",
|
|
30065
|
+
transition: "all 0.2s ease"
|
|
30066
|
+
},
|
|
30067
|
+
onMouseEnter: (e) => {
|
|
30068
|
+
e.currentTarget.style.backgroundColor = "#fef2f2";
|
|
30069
|
+
e.currentTarget.style.borderColor = "#b91c1c";
|
|
30070
|
+
},
|
|
30071
|
+
onMouseLeave: (e) => {
|
|
30072
|
+
e.currentTarget.style.backgroundColor = "transparent";
|
|
30073
|
+
e.currentTarget.style.borderColor = "#dc2626";
|
|
30074
|
+
},
|
|
30075
|
+
children: "Sign Out"
|
|
30076
|
+
}
|
|
30077
|
+
)
|
|
30078
|
+
}
|
|
30079
|
+
),
|
|
30080
|
+
/* @__PURE__ */ jsx(
|
|
30081
|
+
"button",
|
|
30082
|
+
{
|
|
30083
|
+
onClick: closeModal,
|
|
30084
|
+
style: {
|
|
30085
|
+
padding: "8px 16px",
|
|
30086
|
+
backgroundColor: "#f3f4f6",
|
|
30087
|
+
color: "#374151",
|
|
30088
|
+
border: "none",
|
|
30089
|
+
borderRadius: "6px",
|
|
30090
|
+
fontSize: "14px",
|
|
30091
|
+
cursor: "pointer",
|
|
30092
|
+
fontFamily: "HelveticaNowDisplay, sans-serif"
|
|
30093
|
+
},
|
|
30094
|
+
onMouseEnter: (e) => {
|
|
30095
|
+
e.currentTarget.style.backgroundColor = "#e5e7eb";
|
|
30096
|
+
},
|
|
30097
|
+
onMouseLeave: (e) => {
|
|
30098
|
+
e.currentTarget.style.backgroundColor = "#f3f4f6";
|
|
30099
|
+
},
|
|
30100
|
+
children: "Close"
|
|
30101
|
+
}
|
|
30102
|
+
)
|
|
30103
|
+
]
|
|
29537
30104
|
}
|
|
29538
30105
|
)
|
|
29539
30106
|
]
|
|
@@ -29553,7 +30120,19 @@ function EchoTokenPurchase({
|
|
|
29553
30120
|
children
|
|
29554
30121
|
}
|
|
29555
30122
|
) : /* @__PURE__ */ jsx(CompactButton, {}),
|
|
29556
|
-
isModalOpen && /* @__PURE__ */ jsx(Modal, {})
|
|
30123
|
+
isModalOpen && /* @__PURE__ */ jsx(Modal, {}),
|
|
30124
|
+
/* @__PURE__ */ jsx(
|
|
30125
|
+
InsufficientFundsModal,
|
|
30126
|
+
{
|
|
30127
|
+
isOpen: isInsufficientFunds,
|
|
30128
|
+
onClose: () => setIsInsufficientFunds(false),
|
|
30129
|
+
onPurchaseComplete: () => {
|
|
30130
|
+
onPurchaseComplete == null ? void 0 : onPurchaseComplete(balance);
|
|
30131
|
+
setIsInsufficientFunds(false);
|
|
30132
|
+
},
|
|
30133
|
+
onError
|
|
30134
|
+
}
|
|
30135
|
+
)
|
|
29557
30136
|
] });
|
|
29558
30137
|
}
|
|
29559
30138
|
function useEchoOpenAI(options = {}) {
|
|
@@ -29628,7 +30207,8 @@ function useEchoOpenAI(options = {}) {
|
|
|
29628
30207
|
};
|
|
29629
30208
|
}
|
|
29630
30209
|
const useEchoModelProviders = () => {
|
|
29631
|
-
const { token, config: config2 } = useEcho();
|
|
30210
|
+
const { token, config: config2, setIsInsufficientFunds } = useEcho();
|
|
30211
|
+
const onInsufficientFunds = () => setIsInsufficientFunds(true);
|
|
29632
30212
|
return useMemo(() => {
|
|
29633
30213
|
const baseConfig = {
|
|
29634
30214
|
appId: config2.appId,
|
|
@@ -29636,11 +30216,11 @@ const useEchoModelProviders = () => {
|
|
|
29636
30216
|
};
|
|
29637
30217
|
const getToken = async () => token;
|
|
29638
30218
|
return {
|
|
29639
|
-
openai: createEchoOpenAI(baseConfig, getToken),
|
|
29640
|
-
anthropic: createEchoAnthropic(baseConfig, getToken),
|
|
29641
|
-
google: createEchoGoogle(baseConfig, getToken)
|
|
30219
|
+
openai: createEchoOpenAI(baseConfig, getToken, onInsufficientFunds),
|
|
30220
|
+
anthropic: createEchoAnthropic(baseConfig, getToken, onInsufficientFunds),
|
|
30221
|
+
google: createEchoGoogle(baseConfig, getToken, onInsufficientFunds)
|
|
29642
30222
|
};
|
|
29643
|
-
}, [token, config2.appId, config2.baseRouterUrl]);
|
|
30223
|
+
}, [token, config2.appId, config2.baseRouterUrl, setIsInsufficientFunds]);
|
|
29644
30224
|
};
|
|
29645
30225
|
const EchoChatConfigContext = createContext(null);
|
|
29646
30226
|
function EchoChatProvider({
|
|
@@ -33351,7 +33931,9 @@ export {
|
|
|
33351
33931
|
EchoChatProvider,
|
|
33352
33932
|
EchoProvider,
|
|
33353
33933
|
EchoSignIn,
|
|
33354
|
-
|
|
33934
|
+
EchoSignOut,
|
|
33935
|
+
EchoTokens,
|
|
33936
|
+
InsufficientFundsModal,
|
|
33355
33937
|
Logo,
|
|
33356
33938
|
useChat,
|
|
33357
33939
|
useEcho,
|