byokay-kit
Version:
Byokay Kit lets users bring their own AI API keys and store them securely in their browser. This eliminates the need for your app to manage sensitive credentials or maintain AI API backend infrastructure.
29 lines (28 loc) • 3.57 kB
JavaScript
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
// src/ui/ByokaiKeyProvider.tsx
import { useState, useCallback } from "react";
import { useMultiApiKeys } from "../hooks/useMultiApiKeys";
import { Modal } from "./components/Modal";
import { ProviderList } from "./components/ProviderList";
// ... rest of your ByokaiKeyProvider.tsx code remains the same
// (using the render prop pattern we discussed, where 'children' is a function)
const defaultProviders = ["openai"];
export function ByokaiKeyProvider({ providers = defaultProviders, children, }) {
const [showModal, setShowModal] = useState(false);
const [confirmingClearAll, setConfirmingClearAll] = useState(false);
const { keys, saved, validating, validated, handleKeyChange, handleClear, handleClearAll, handleValidate, handleSaveAllAndClose, hasAnyKey, providerNames, } = useMultiApiKeys(providers);
const openModal = useCallback(() => setShowModal(true), []);
const closeModal = useCallback(() => {
setShowModal(false);
setConfirmingClearAll(false);
}, []);
const hasKeysToClearCurrently = Object.values(keys).some((key) => !!key);
const startClearAll = () => setConfirmingClearAll(true);
const cancelClearAll = () => setConfirmingClearAll(false);
const confirmAndClearAll = () => {
handleClearAll();
setConfirmingClearAll(false);
};
const modalFooter = (_jsxs("div", { className: "flex justify-between items-center", children: [_jsxs("div", { children: [hasKeysToClearCurrently && !confirmingClearAll && (_jsxs("button", { onClick: startClearAll, className: "text-gray-500 hover:text-red-600 text-xs flex items-center gap-1 py-1 px-2 rounded hover:bg-gray-50 transition-colors", title: "Clear all API keys", children: [_jsx("svg", { xmlns: "http://www.w3.org/2000/svg", className: "h-3 w-3", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16" }) }), "Clear All"] })), confirmingClearAll && (_jsxs("div", { className: "flex items-center space-x-2", children: [_jsx("span", { className: "text-xs text-red-600", children: "Are you sure?" }), _jsx("button", { onClick: confirmAndClearAll, className: "text-xs bg-red-50 text-red-600 hover:bg-red-100 py-1 px-2 rounded transition-colors", children: "Yes, clear all" }), _jsx("button", { onClick: cancelClearAll, className: "text-xs bg-gray-50 text-gray-600 hover:bg-gray-100 py-1 px-2 rounded transition-colors", children: "Cancel" })] }))] }), _jsxs("div", { className: "flex space-x-3", children: [_jsx("button", { onClick: closeModal, className: "px-4 py-2 bg-gray-100 text-gray-700 text-sm font-medium rounded-lg hover:bg-gray-200 transition-colors", children: "Cancel" }), _jsx("button", { onClick: () => handleSaveAllAndClose(closeModal), className: "px-4 py-2 bg-blue-600 text-white text-sm font-medium rounded-lg hover:bg-blue-700 transition-colors", children: "Save" })] })] }));
return (_jsxs(_Fragment, { children: [children(openModal, hasAnyKey), _jsx(Modal, { isOpen: showModal, onClose: closeModal, title: "Connect AI Providers", footer: modalFooter, children: _jsx(ProviderList, { providers: providers, providerNames: providerNames, keys: keys, saved: saved, validating: validating, validated: validated, onKeyChange: handleKeyChange, onValidate: handleValidate, onClear: handleClear }) })] }));
}