@geenius/adapters 0.1.0 → 0.3.0
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 +79 -42
- package/package.json +23 -4
- package/packages/convex/README.md +1 -1
- package/packages/convex/dist/index.cjs +300 -0
- package/packages/convex/dist/index.cjs.map +1 -0
- package/packages/convex/dist/index.d.cts +231 -0
- package/packages/convex/dist/index.d.ts +231 -0
- package/packages/convex/dist/index.js +263 -0
- package/packages/convex/dist/index.js.map +1 -0
- package/packages/react/README.md +1 -1
- package/packages/react/dist/index.d.mts +106 -0
- package/packages/react/dist/index.d.ts +106 -0
- package/packages/react/dist/index.js +611 -0
- package/packages/react/dist/index.js.map +1 -0
- package/packages/react/dist/index.mjs +570 -0
- package/packages/react/dist/index.mjs.map +1 -0
- package/packages/react-css/README.md +1 -1
- package/packages/react-css/dist/index.cjs +515 -0
- package/packages/react-css/dist/index.cjs.map +1 -0
- package/packages/react-css/dist/index.d.cts +105 -0
- package/packages/react-css/dist/index.d.ts +105 -0
- package/packages/react-css/dist/index.js +467 -0
- package/packages/react-css/dist/index.js.map +1 -0
- package/packages/shared/README.md +1 -1
- package/packages/shared/dist/index.d.mts +625 -0
- package/packages/shared/dist/index.d.ts +625 -0
- package/packages/shared/dist/index.js +1567 -0
- package/packages/shared/dist/index.js.map +1 -0
- package/packages/shared/dist/index.mjs +1489 -0
- package/packages/shared/dist/index.mjs.map +1 -0
- package/packages/solidjs/README.md +1 -1
- package/packages/solidjs/dist/index.d.mts +97 -0
- package/packages/solidjs/dist/index.d.ts +97 -0
- package/packages/solidjs/dist/index.js +250 -0
- package/packages/solidjs/dist/index.js.map +1 -0
- package/packages/solidjs/dist/index.mjs +202 -0
- package/packages/solidjs/dist/index.mjs.map +1 -0
- package/packages/solidjs-css/README.md +1 -1
- package/packages/solidjs-css/dist/index.cjs +343 -0
- package/packages/solidjs-css/dist/index.cjs.map +1 -0
- package/packages/solidjs-css/dist/index.d.cts +67 -0
- package/packages/solidjs-css/dist/index.d.ts +67 -0
- package/packages/solidjs-css/dist/index.js +326 -0
- package/packages/solidjs-css/dist/index.js.map +1 -0
- package/.changeset/config.json +0 -11
- package/.github/CODEOWNERS +0 -1
- package/.github/ISSUE_TEMPLATE/bug_report.md +0 -16
- package/.github/ISSUE_TEMPLATE/feature_request.md +0 -11
- package/.github/PULL_REQUEST_TEMPLATE.md +0 -10
- package/.github/dependabot.yml +0 -11
- package/.github/workflows/ci.yml +0 -23
- package/.github/workflows/release.yml +0 -29
- package/.nvmrc +0 -1
- package/.project/ACCOUNT.yaml +0 -4
- package/.project/IDEAS.yaml +0 -7
- package/.project/PROJECT.yaml +0 -11
- package/.project/ROADMAP.yaml +0 -15
- package/CODE_OF_CONDUCT.md +0 -16
- package/CONTRIBUTING.md +0 -26
- package/SECURITY.md +0 -15
- package/SUPPORT.md +0 -8
- package/packages/convex/package.json +0 -42
- package/packages/convex/src/adapter.ts +0 -39
- package/packages/convex/src/index.ts +0 -19
- package/packages/convex/src/mutations.ts +0 -142
- package/packages/convex/src/queries.ts +0 -106
- package/packages/convex/src/schema.ts +0 -54
- package/packages/convex/src/types.ts +0 -20
- package/packages/convex/tsconfig.json +0 -11
- package/packages/convex/tsup.config.ts +0 -10
- package/packages/react/package.json +0 -45
- package/packages/react/src/components/AdapterCard.tsx +0 -49
- package/packages/react/src/components/AdapterConfigForm.tsx +0 -118
- package/packages/react/src/components/AdapterList.tsx +0 -84
- package/packages/react/src/components/AdapterStatusBadge.tsx +0 -30
- package/packages/react/src/components/index.ts +0 -4
- package/packages/react/src/hooks/index.ts +0 -75
- package/packages/react/src/index.tsx +0 -44
- package/packages/react/src/pages/AdapterDetailPage.tsx +0 -133
- package/packages/react/src/pages/AdaptersPage.tsx +0 -111
- package/packages/react/src/pages/index.ts +0 -2
- package/packages/react/src/provider/AdapterProvider.tsx +0 -115
- package/packages/react/src/provider/index.ts +0 -2
- package/packages/react/tsconfig.json +0 -18
- package/packages/react/tsup.config.ts +0 -10
- package/packages/react-css/package.json +0 -44
- package/packages/react-css/src/adapters.css +0 -1576
- package/packages/react-css/src/components/AdapterCard.tsx +0 -34
- package/packages/react-css/src/components/AdapterConfigForm.tsx +0 -63
- package/packages/react-css/src/components/AdapterList.tsx +0 -40
- package/packages/react-css/src/components/AdapterStatusBadge.tsx +0 -21
- package/packages/react-css/src/components/index.ts +0 -4
- package/packages/react-css/src/hooks/index.ts +0 -75
- package/packages/react-css/src/index.tsx +0 -25
- package/packages/react-css/src/pages/AdapterDetailPage.tsx +0 -133
- package/packages/react-css/src/pages/AdaptersPage.tsx +0 -111
- package/packages/react-css/src/pages/index.ts +0 -2
- package/packages/react-css/src/provider/AdapterProvider.tsx +0 -115
- package/packages/react-css/src/provider/index.ts +0 -2
- package/packages/react-css/src/styles.css +0 -494
- package/packages/react-css/tsconfig.json +0 -19
- package/packages/react-css/tsup.config.ts +0 -2
- package/packages/shared/package.json +0 -39
- package/packages/shared/src/__tests__/adapters.test.ts +0 -545
- package/packages/shared/src/admin/index.ts +0 -2
- package/packages/shared/src/admin/interface.ts +0 -34
- package/packages/shared/src/admin/localStorage.ts +0 -109
- package/packages/shared/src/ai/anthropic.ts +0 -123
- package/packages/shared/src/ai/cloudflare-gateway.ts +0 -130
- package/packages/shared/src/ai/gemini.ts +0 -181
- package/packages/shared/src/ai/index.ts +0 -14
- package/packages/shared/src/ai/interface.ts +0 -11
- package/packages/shared/src/ai/localStorage.ts +0 -78
- package/packages/shared/src/ai/ollama.ts +0 -143
- package/packages/shared/src/ai/openai.ts +0 -120
- package/packages/shared/src/ai/vercel-ai.ts +0 -101
- package/packages/shared/src/auth/better-auth.ts +0 -118
- package/packages/shared/src/auth/clerk.ts +0 -151
- package/packages/shared/src/auth/convex-auth.ts +0 -125
- package/packages/shared/src/auth/index.ts +0 -10
- package/packages/shared/src/auth/interface.ts +0 -17
- package/packages/shared/src/auth/localStorage.ts +0 -125
- package/packages/shared/src/auth/supabase-auth.ts +0 -136
- package/packages/shared/src/config.ts +0 -57
- package/packages/shared/src/constants.ts +0 -122
- package/packages/shared/src/db/convex.ts +0 -146
- package/packages/shared/src/db/index.ts +0 -10
- package/packages/shared/src/db/interface.ts +0 -13
- package/packages/shared/src/db/localStorage.ts +0 -91
- package/packages/shared/src/db/mongodb.ts +0 -125
- package/packages/shared/src/db/neon.ts +0 -171
- package/packages/shared/src/db/supabase.ts +0 -158
- package/packages/shared/src/index.ts +0 -117
- package/packages/shared/src/payments/index.ts +0 -4
- package/packages/shared/src/payments/interface.ts +0 -11
- package/packages/shared/src/payments/localStorage.ts +0 -81
- package/packages/shared/src/payments/stripe.ts +0 -177
- package/packages/shared/src/storage/convex.ts +0 -113
- package/packages/shared/src/storage/index.ts +0 -14
- package/packages/shared/src/storage/interface.ts +0 -11
- package/packages/shared/src/storage/localStorage.ts +0 -95
- package/packages/shared/src/storage/minio.ts +0 -47
- package/packages/shared/src/storage/r2.ts +0 -123
- package/packages/shared/src/storage/s3.ts +0 -128
- package/packages/shared/src/storage/supabase-storage.ts +0 -116
- package/packages/shared/src/storage/uploadthing.ts +0 -126
- package/packages/shared/src/styles/adapters.css +0 -494
- package/packages/shared/src/tier-gate.ts +0 -119
- package/packages/shared/src/types.ts +0 -162
- package/packages/shared/tsconfig.json +0 -18
- package/packages/shared/tsup.config.ts +0 -9
- package/packages/shared/vitest.config.ts +0 -14
- package/packages/solidjs/package.json +0 -44
- package/packages/solidjs/src/components/AdapterCard.tsx +0 -24
- package/packages/solidjs/src/components/AdapterConfigForm.tsx +0 -54
- package/packages/solidjs/src/components/AdapterList.tsx +0 -28
- package/packages/solidjs/src/components/AdapterStatusBadge.tsx +0 -20
- package/packages/solidjs/src/components/index.ts +0 -4
- package/packages/solidjs/src/index.tsx +0 -17
- package/packages/solidjs/src/pages/AdapterDetailPage.tsx +0 -38
- package/packages/solidjs/src/pages/AdaptersPage.tsx +0 -39
- package/packages/solidjs/src/pages/index.ts +0 -2
- package/packages/solidjs/src/primitives/index.ts +0 -78
- package/packages/solidjs/src/provider/AdapterProvider.tsx +0 -62
- package/packages/solidjs/src/provider/index.ts +0 -2
- package/packages/solidjs/tsconfig.json +0 -20
- package/packages/solidjs/tsup.config.ts +0 -10
- package/packages/solidjs-css/package.json +0 -43
- package/packages/solidjs-css/src/adapters.css +0 -1576
- package/packages/solidjs-css/src/components/AdapterCard.tsx +0 -43
- package/packages/solidjs-css/src/components/AdapterConfigForm.tsx +0 -119
- package/packages/solidjs-css/src/components/AdapterList.tsx +0 -68
- package/packages/solidjs-css/src/components/AdapterStatusBadge.tsx +0 -24
- package/packages/solidjs-css/src/components/index.ts +0 -8
- package/packages/solidjs-css/src/index.tsx +0 -30
- package/packages/solidjs-css/src/pages/AdapterDetailPage.tsx +0 -107
- package/packages/solidjs-css/src/pages/AdaptersPage.tsx +0 -94
- package/packages/solidjs-css/src/pages/index.ts +0 -4
- package/packages/solidjs-css/src/primitives/index.ts +0 -1
- package/packages/solidjs-css/src/provider/AdapterProvider.tsx +0 -61
- package/packages/solidjs-css/src/provider/index.ts +0 -2
- package/packages/solidjs-css/tsconfig.json +0 -20
- package/packages/solidjs-css/tsup.config.ts +0 -2
- package/pnpm-workspace.yaml +0 -2
- package/tsconfig.json +0 -17
|
@@ -0,0 +1,515 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/index.tsx
|
|
21
|
+
var index_exports = {};
|
|
22
|
+
__export(index_exports, {
|
|
23
|
+
ADAPTER_DOMAINS: () => import_adapters_shared7.ADAPTER_DOMAINS,
|
|
24
|
+
AdapterCard: () => AdapterCard,
|
|
25
|
+
AdapterConfigForm: () => AdapterConfigForm,
|
|
26
|
+
AdapterDetailPage: () => AdapterDetailPage,
|
|
27
|
+
AdapterList: () => AdapterList,
|
|
28
|
+
AdapterProvider: () => AdapterProvider,
|
|
29
|
+
AdapterStatusBadge: () => AdapterStatusBadge,
|
|
30
|
+
AdaptersPage: () => AdaptersPage,
|
|
31
|
+
DOMAIN_DESCRIPTIONS: () => import_adapters_shared7.DOMAIN_DESCRIPTIONS,
|
|
32
|
+
DOMAIN_ICONS: () => import_adapters_shared7.DOMAIN_ICONS,
|
|
33
|
+
DOMAIN_LABELS: () => import_adapters_shared7.DOMAIN_LABELS,
|
|
34
|
+
configureAdapters: () => import_adapters_shared7.configureAdapters,
|
|
35
|
+
getAdapterConfig: () => import_adapters_shared7.getAdapterConfig,
|
|
36
|
+
useAdapterContext: () => useAdapterContext,
|
|
37
|
+
useAdapterStatus: () => useAdapterStatus,
|
|
38
|
+
useAdapterStatuses: () => useAdapterStatuses,
|
|
39
|
+
useAdapters: () => useAdapters,
|
|
40
|
+
useAdmin: () => useAdmin,
|
|
41
|
+
useAi: () => useAi,
|
|
42
|
+
useAuth: () => useAuth,
|
|
43
|
+
useDb: () => useDb,
|
|
44
|
+
useIsAdapterReady: () => useIsAdapterReady,
|
|
45
|
+
usePayments: () => usePayments,
|
|
46
|
+
useStorage: () => useStorage
|
|
47
|
+
});
|
|
48
|
+
module.exports = __toCommonJS(index_exports);
|
|
49
|
+
var import_adapters_shared7 = require("@geenius/adapters-shared");
|
|
50
|
+
|
|
51
|
+
// src/provider/AdapterProvider.tsx
|
|
52
|
+
var import_react = require("react");
|
|
53
|
+
var import_adapters_shared = require("@geenius/adapters-shared");
|
|
54
|
+
var import_jsx_runtime = require("react/jsx-runtime");
|
|
55
|
+
var AdapterContext = (0, import_react.createContext)(null);
|
|
56
|
+
function AdapterProvider({ adapters, children, healthCheck = false }) {
|
|
57
|
+
const [isLoading, setIsLoading] = (0, import_react.useState)(healthCheck);
|
|
58
|
+
const [statuses, setStatuses] = (0, import_react.useState)(() => {
|
|
59
|
+
const initial = {};
|
|
60
|
+
for (const domain of import_adapters_shared.ADAPTER_DOMAINS) {
|
|
61
|
+
const adapter = adapters[domain];
|
|
62
|
+
initial[domain] = {
|
|
63
|
+
domain,
|
|
64
|
+
provider: adapter ? "configured" : "none",
|
|
65
|
+
status: adapter ? "connected" : "disconnected",
|
|
66
|
+
lastCheckedAt: Date.now()
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
return initial;
|
|
70
|
+
});
|
|
71
|
+
(0, import_react.useEffect)(() => {
|
|
72
|
+
if (!healthCheck) return;
|
|
73
|
+
setIsLoading(true);
|
|
74
|
+
const checks = import_adapters_shared.ADAPTER_DOMAINS.map(async (domain) => {
|
|
75
|
+
const adapter = adapters[domain];
|
|
76
|
+
if (!adapter) return;
|
|
77
|
+
try {
|
|
78
|
+
setStatuses((prev) => ({ ...prev, [domain]: { ...prev[domain], status: "initializing" } }));
|
|
79
|
+
if (domain === "auth" && adapter.getSession) {
|
|
80
|
+
await adapter.getSession();
|
|
81
|
+
}
|
|
82
|
+
setStatuses((prev) => ({
|
|
83
|
+
...prev,
|
|
84
|
+
[domain]: { ...prev[domain], status: "connected", lastCheckedAt: Date.now() }
|
|
85
|
+
}));
|
|
86
|
+
} catch (e) {
|
|
87
|
+
setStatuses((prev) => ({
|
|
88
|
+
...prev,
|
|
89
|
+
[domain]: {
|
|
90
|
+
...prev[domain],
|
|
91
|
+
status: "error",
|
|
92
|
+
error: e instanceof Error ? e.message : "Health check failed",
|
|
93
|
+
lastCheckedAt: Date.now()
|
|
94
|
+
}
|
|
95
|
+
}));
|
|
96
|
+
}
|
|
97
|
+
});
|
|
98
|
+
Promise.allSettled(checks).finally(() => setIsLoading(false));
|
|
99
|
+
}, [adapters, healthCheck]);
|
|
100
|
+
const getAdapter = (0, import_react.useCallback)((domain) => {
|
|
101
|
+
const adapter = adapters[domain];
|
|
102
|
+
if (!adapter) throw new Error(`${import_adapters_shared.DOMAIN_LABELS[domain] ?? domain} adapter not configured in <AdapterProvider>`);
|
|
103
|
+
return adapter;
|
|
104
|
+
}, [adapters]);
|
|
105
|
+
const isReady = (0, import_react.useCallback)((domain) => {
|
|
106
|
+
return !!adapters[domain] && statuses[domain]?.status === "connected";
|
|
107
|
+
}, [adapters, statuses]);
|
|
108
|
+
const value = (0, import_react.useMemo)(() => ({
|
|
109
|
+
adapters,
|
|
110
|
+
statuses,
|
|
111
|
+
getAdapter,
|
|
112
|
+
isReady,
|
|
113
|
+
isLoading
|
|
114
|
+
}), [adapters, statuses, getAdapter, isReady, isLoading]);
|
|
115
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(AdapterContext.Provider, { value, children });
|
|
116
|
+
}
|
|
117
|
+
function useAdapterContext() {
|
|
118
|
+
const ctx = (0, import_react.useContext)(AdapterContext);
|
|
119
|
+
if (!ctx) throw new Error("useAdapterContext must be used within <AdapterProvider>");
|
|
120
|
+
return ctx;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
// src/hooks/index.ts
|
|
124
|
+
var import_react2 = require("react");
|
|
125
|
+
function useDb() {
|
|
126
|
+
return useAdapterContext().getAdapter("db");
|
|
127
|
+
}
|
|
128
|
+
function useAuth() {
|
|
129
|
+
return useAdapterContext().getAdapter("auth");
|
|
130
|
+
}
|
|
131
|
+
function usePayments() {
|
|
132
|
+
return useAdapterContext().getAdapter("payments");
|
|
133
|
+
}
|
|
134
|
+
function useAi() {
|
|
135
|
+
return useAdapterContext().getAdapter("ai");
|
|
136
|
+
}
|
|
137
|
+
function useStorage() {
|
|
138
|
+
return useAdapterContext().getAdapter("storage");
|
|
139
|
+
}
|
|
140
|
+
function useAdmin() {
|
|
141
|
+
return useAdapterContext().getAdapter("admin");
|
|
142
|
+
}
|
|
143
|
+
function useAdapterStatuses() {
|
|
144
|
+
return useAdapterContext().statuses;
|
|
145
|
+
}
|
|
146
|
+
function useAdapterStatus(domain) {
|
|
147
|
+
return useAdapterContext().statuses[domain];
|
|
148
|
+
}
|
|
149
|
+
function useIsAdapterReady(domain) {
|
|
150
|
+
return useAdapterContext().isReady(domain);
|
|
151
|
+
}
|
|
152
|
+
function useAdapters() {
|
|
153
|
+
const ctx = useAdapterContext();
|
|
154
|
+
return (0, import_react2.useMemo)(() => ({
|
|
155
|
+
db: ctx.adapters.db,
|
|
156
|
+
auth: ctx.adapters.auth,
|
|
157
|
+
payments: ctx.adapters.payments,
|
|
158
|
+
ai: ctx.adapters.ai,
|
|
159
|
+
storage: ctx.adapters.storage,
|
|
160
|
+
admin: ctx.adapters.admin,
|
|
161
|
+
statuses: ctx.statuses,
|
|
162
|
+
isLoading: ctx.isLoading,
|
|
163
|
+
isReady: ctx.isReady
|
|
164
|
+
}), [ctx]);
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
// src/components/AdapterStatusBadge.tsx
|
|
168
|
+
var import_jsx_runtime2 = require("react/jsx-runtime");
|
|
169
|
+
function AdapterStatusBadge({ status, showLabel = true, className = "" }) {
|
|
170
|
+
const labels = {
|
|
171
|
+
connected: "Connected",
|
|
172
|
+
disconnected: "Disconnected",
|
|
173
|
+
error: "Error",
|
|
174
|
+
initializing: "Initializing"
|
|
175
|
+
};
|
|
176
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("span", { className: `adapter-badge adapter-badge--${status} ${className}`, children: [
|
|
177
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "adapter-badge__dot" }),
|
|
178
|
+
showLabel && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { children: labels[status] })
|
|
179
|
+
] });
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
// src/components/AdapterCard.tsx
|
|
183
|
+
var import_adapters_shared2 = require("@geenius/adapters-shared");
|
|
184
|
+
var import_jsx_runtime3 = require("react/jsx-runtime");
|
|
185
|
+
function AdapterCard({ domain, status, onClick, className = "" }) {
|
|
186
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("button", { type: "button", onClick, className: `adapter-card ${className}`, "aria-label": `${import_adapters_shared2.DOMAIN_LABELS[domain]} adapter`, children: [
|
|
187
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "adapter-card__icon", children: import_adapters_shared2.DOMAIN_ICONS[domain] }),
|
|
188
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "adapter-card__body", children: [
|
|
189
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "adapter-card__header", children: [
|
|
190
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("h3", { className: "adapter-card__name", children: import_adapters_shared2.DOMAIN_LABELS[domain] }),
|
|
191
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(AdapterStatusBadge, { status: status.status })
|
|
192
|
+
] }),
|
|
193
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "adapter-card__desc", children: import_adapters_shared2.DOMAIN_DESCRIPTIONS[domain] }),
|
|
194
|
+
status.provider && status.provider !== "none" && /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "adapter-card__meta", children: [
|
|
195
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "adapter-card__provider", children: status.provider }),
|
|
196
|
+
status.latency && /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("span", { className: "adapter-card__latency", children: [
|
|
197
|
+
status.latency,
|
|
198
|
+
"ms"
|
|
199
|
+
] })
|
|
200
|
+
] }),
|
|
201
|
+
status.error && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "adapter-card__error", children: status.error })
|
|
202
|
+
] })
|
|
203
|
+
] });
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
// src/components/AdapterList.tsx
|
|
207
|
+
var import_react3 = require("react");
|
|
208
|
+
var import_adapters_shared3 = require("@geenius/adapters-shared");
|
|
209
|
+
var import_jsx_runtime4 = require("react/jsx-runtime");
|
|
210
|
+
function AdapterList({ onSelect, filterStatus, className = "" }) {
|
|
211
|
+
const { statuses, isLoading } = useAdapters();
|
|
212
|
+
const [search, setSearch] = (0, import_react3.useState)("");
|
|
213
|
+
const filtered = (0, import_react3.useMemo)(() => {
|
|
214
|
+
let domains = [...import_adapters_shared3.ADAPTER_DOMAINS];
|
|
215
|
+
if (search) {
|
|
216
|
+
const q = search.toLowerCase();
|
|
217
|
+
domains = domains.filter((d) => import_adapters_shared3.DOMAIN_LABELS[d].toLowerCase().includes(q) || d.includes(q));
|
|
218
|
+
}
|
|
219
|
+
if (filterStatus) {
|
|
220
|
+
domains = domains.filter((d) => statuses[d]?.status === filterStatus);
|
|
221
|
+
}
|
|
222
|
+
return domains;
|
|
223
|
+
}, [search, filterStatus, statuses]);
|
|
224
|
+
if (isLoading) return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className, role: "status", children: [1, 2, 3, 4].map((i) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "adapter-skeleton", style: { height: "6rem", marginBottom: "0.75rem" } }, i)) });
|
|
225
|
+
return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className, children: [
|
|
226
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("input", { type: "text", value: search, onChange: (e) => setSearch(e.target.value), placeholder: "Search adapters...", className: "adapter-search", "aria-label": "Search adapters" }),
|
|
227
|
+
filtered.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "adapter-empty", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { className: "adapter-empty__text", children: search ? "No match" : "No adapters configured" }) }) : /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "adapter-grid", role: "list", children: filtered.map((d) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(AdapterCard, { domain: d, status: statuses[d], onClick: () => onSelect?.(d) }, d)) })
|
|
228
|
+
] });
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
// src/components/AdapterConfigForm.tsx
|
|
232
|
+
var import_react4 = require("react");
|
|
233
|
+
var import_adapters_shared4 = require("@geenius/adapters-shared");
|
|
234
|
+
var import_jsx_runtime5 = require("react/jsx-runtime");
|
|
235
|
+
function AdapterConfigForm({ domain, initialConfig, onSave, onCancel, className = "" }) {
|
|
236
|
+
const providers = (0, import_adapters_shared4.getProvidersForDomain)(domain);
|
|
237
|
+
const [provider, setProvider] = (0, import_react4.useState)(initialConfig?.provider ?? providers[0]?.id ?? "");
|
|
238
|
+
const [apiKey, setApiKey] = (0, import_react4.useState)(initialConfig?.apiKey ?? "");
|
|
239
|
+
const [baseUrl, setBaseUrl] = (0, import_react4.useState)(initialConfig?.baseUrl ?? "");
|
|
240
|
+
const [isSaving, setIsSaving] = (0, import_react4.useState)(false);
|
|
241
|
+
const [error, setError] = (0, import_react4.useState)(null);
|
|
242
|
+
const needsApiKey = !["localStorage", "noop"].includes(provider);
|
|
243
|
+
const needsBaseUrl = ["ollama", "minio", "neon", "supabase"].includes(provider);
|
|
244
|
+
const handleSubmit = async (e) => {
|
|
245
|
+
e.preventDefault();
|
|
246
|
+
setError(null);
|
|
247
|
+
if (!provider) {
|
|
248
|
+
setError("Select a provider");
|
|
249
|
+
return;
|
|
250
|
+
}
|
|
251
|
+
setIsSaving(true);
|
|
252
|
+
try {
|
|
253
|
+
await onSave({ provider, apiKey: apiKey || void 0, baseUrl: baseUrl || void 0 });
|
|
254
|
+
} catch (e2) {
|
|
255
|
+
setError(e2 instanceof Error ? e2.message : "Failed");
|
|
256
|
+
} finally {
|
|
257
|
+
setIsSaving(false);
|
|
258
|
+
}
|
|
259
|
+
};
|
|
260
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("form", { onSubmit: handleSubmit, className: `adapter-form ${className}`, noValidate: true, children: [
|
|
261
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("h3", { className: "adapter-form__title", children: [
|
|
262
|
+
"Configure ",
|
|
263
|
+
import_adapters_shared4.DOMAIN_LABELS[domain]
|
|
264
|
+
] }),
|
|
265
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { className: "adapter-form__subtitle", children: "Select your preferred provider." }),
|
|
266
|
+
error && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "adapter-alert adapter-alert--error", role: "alert", style: { marginTop: "1rem" }, children: error }),
|
|
267
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "adapter-field", children: [
|
|
268
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "adapter-field__label", children: "Provider" }),
|
|
269
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "adapter-provider-grid", children: providers.map((p) => /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("button", { type: "button", onClick: () => setProvider(p.id), className: `adapter-provider-option ${provider === p.id ? "adapter-provider-option--selected" : ""}`, children: [
|
|
270
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "adapter-provider-option__name", children: p.name }),
|
|
271
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "adapter-provider-option__desc", children: p.description }),
|
|
272
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: `adapter-tier-badge adapter-tier-badge--${p.tier}`, children: p.tier })
|
|
273
|
+
] }, p.id)) })
|
|
274
|
+
] }),
|
|
275
|
+
needsApiKey && /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "adapter-field", children: [
|
|
276
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("label", { className: "adapter-field__label", children: "API Key" }),
|
|
277
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("input", { type: "password", value: apiKey, onChange: (e) => setApiKey(e.target.value), className: "adapter-field__input", placeholder: "Enter API key" })
|
|
278
|
+
] }),
|
|
279
|
+
needsBaseUrl && /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "adapter-field", children: [
|
|
280
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("label", { className: "adapter-field__label", children: "Base URL" }),
|
|
281
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("input", { type: "url", value: baseUrl, onChange: (e) => setBaseUrl(e.target.value), className: "adapter-field__input", placeholder: "https://..." })
|
|
282
|
+
] }),
|
|
283
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { style: { display: "flex", justifyContent: "flex-end", gap: "0.75rem", marginTop: "1.5rem" }, children: [
|
|
284
|
+
onCancel && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("button", { type: "button", onClick: onCancel, className: "adapter-btn adapter-btn--ghost", children: "Cancel" }),
|
|
285
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("button", { type: "submit", disabled: isSaving || !provider, className: "adapter-btn adapter-btn--primary", children: isSaving ? "Saving\u2026" : "Save" })
|
|
286
|
+
] })
|
|
287
|
+
] });
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
// src/pages/AdaptersPage.tsx
|
|
291
|
+
var import_react5 = require("react");
|
|
292
|
+
var import_adapters_shared5 = require("@geenius/adapters-shared");
|
|
293
|
+
var import_jsx_runtime6 = require("react/jsx-runtime");
|
|
294
|
+
function AdaptersPage({ onNavigateDetail, className = "" }) {
|
|
295
|
+
const { statuses, isLoading } = useAdapters();
|
|
296
|
+
const [selectedDomain, setSelectedDomain] = (0, import_react5.useState)(null);
|
|
297
|
+
const [filterStatus, setFilterStatus] = (0, import_react5.useState)();
|
|
298
|
+
const counts = {
|
|
299
|
+
connected: import_adapters_shared5.ADAPTER_DOMAINS.filter((d) => statuses[d]?.status === "connected").length,
|
|
300
|
+
error: import_adapters_shared5.ADAPTER_DOMAINS.filter((d) => statuses[d]?.status === "error").length,
|
|
301
|
+
total: import_adapters_shared5.ADAPTER_DOMAINS.length
|
|
302
|
+
};
|
|
303
|
+
if (isLoading) {
|
|
304
|
+
return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: `max-w-4xl mx-auto space-y-6 ${className}`, children: /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "animate-pulse space-y-4", children: [
|
|
305
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "h-8 w-48 rounded bg-white/10" }),
|
|
306
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "h-4 w-72 rounded bg-white/5" }),
|
|
307
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "grid gap-3 sm:grid-cols-3", children: [1, 2, 3].map((i) => /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "h-20 rounded-2xl bg-white/[0.03]" }, i)) }),
|
|
308
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "grid gap-3 sm:grid-cols-2", children: [1, 2, 3, 4].map((i) => /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "h-28 rounded-2xl bg-white/[0.03]" }, i)) })
|
|
309
|
+
] }) });
|
|
310
|
+
}
|
|
311
|
+
return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: `max-w-4xl mx-auto space-y-8 ${className}`, children: [
|
|
312
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { children: [
|
|
313
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("h1", { className: "text-2xl font-extrabold text-white/95 tracking-tight", children: "Adapters" }),
|
|
314
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("p", { className: "mt-1 text-sm text-white/40", children: "Manage your infrastructure adapters \u2014 database, auth, AI, storage, payments, and admin." })
|
|
315
|
+
] }),
|
|
316
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "grid gap-3 sm:grid-cols-3", children: [
|
|
317
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "rounded-2xl border border-white/10 bg-white/[0.03] p-4 backdrop-blur-sm", children: [
|
|
318
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("p", { className: "text-xs font-semibold uppercase tracking-wider text-white/30", children: "Total" }),
|
|
319
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("p", { className: "mt-1 text-2xl font-extrabold text-white/90", children: counts.total }),
|
|
320
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("p", { className: "text-[0.625rem] text-white/30", children: "adapter domains" })
|
|
321
|
+
] }),
|
|
322
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "rounded-2xl border border-emerald-500/10 bg-emerald-500/[0.03] p-4 backdrop-blur-sm", children: [
|
|
323
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("p", { className: "text-xs font-semibold uppercase tracking-wider text-emerald-400/60", children: "Connected" }),
|
|
324
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("p", { className: "mt-1 text-2xl font-extrabold text-emerald-400", children: counts.connected }),
|
|
325
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("p", { className: "text-[0.625rem] text-emerald-400/40", children: "active adapters" })
|
|
326
|
+
] }),
|
|
327
|
+
counts.error > 0 && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "rounded-2xl border border-red-500/10 bg-red-500/[0.03] p-4 backdrop-blur-sm", children: [
|
|
328
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("p", { className: "text-xs font-semibold uppercase tracking-wider text-red-400/60", children: "Errors" }),
|
|
329
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("p", { className: "mt-1 text-2xl font-extrabold text-red-400", children: counts.error }),
|
|
330
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("p", { className: "text-[0.625rem] text-red-400/40", children: "need attention" })
|
|
331
|
+
] })
|
|
332
|
+
] }),
|
|
333
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "flex items-center gap-2", children: [
|
|
334
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
335
|
+
"button",
|
|
336
|
+
{
|
|
337
|
+
onClick: () => setFilterStatus(void 0),
|
|
338
|
+
className: `rounded-lg px-3 py-1.5 text-xs font-semibold transition-all ${!filterStatus ? "bg-white/10 text-white/80" : "text-white/30 hover:text-white/50"}`,
|
|
339
|
+
children: "All"
|
|
340
|
+
}
|
|
341
|
+
),
|
|
342
|
+
import_adapters_shared5.ADAPTER_STATUSES.map((s) => /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
|
|
343
|
+
"button",
|
|
344
|
+
{
|
|
345
|
+
onClick: () => setFilterStatus(s),
|
|
346
|
+
className: `flex items-center gap-1.5 rounded-lg px-3 py-1.5 text-xs font-semibold transition-all ${filterStatus === s ? "bg-white/10 text-white/80" : "text-white/30 hover:text-white/50"}`,
|
|
347
|
+
children: [
|
|
348
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(AdapterStatusBadge, { status: s, showLabel: false }),
|
|
349
|
+
s
|
|
350
|
+
]
|
|
351
|
+
},
|
|
352
|
+
s
|
|
353
|
+
))
|
|
354
|
+
] }),
|
|
355
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
356
|
+
AdapterList,
|
|
357
|
+
{
|
|
358
|
+
onSelect: (domain) => {
|
|
359
|
+
if (onNavigateDetail) {
|
|
360
|
+
onNavigateDetail(domain);
|
|
361
|
+
} else {
|
|
362
|
+
setSelectedDomain(domain);
|
|
363
|
+
}
|
|
364
|
+
},
|
|
365
|
+
filterStatus
|
|
366
|
+
}
|
|
367
|
+
),
|
|
368
|
+
selectedDomain && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "fixed inset-0 z-50 flex items-center justify-center bg-black/60 backdrop-blur-sm", onClick: () => setSelectedDomain(null), children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "max-w-lg w-full mx-4", onClick: (e) => e.stopPropagation(), children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
369
|
+
AdapterConfigForm,
|
|
370
|
+
{
|
|
371
|
+
domain: selectedDomain,
|
|
372
|
+
onSave: async () => {
|
|
373
|
+
setSelectedDomain(null);
|
|
374
|
+
},
|
|
375
|
+
onCancel: () => setSelectedDomain(null)
|
|
376
|
+
}
|
|
377
|
+
) }) })
|
|
378
|
+
] });
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
// src/pages/AdapterDetailPage.tsx
|
|
382
|
+
var import_react6 = require("react");
|
|
383
|
+
var import_adapters_shared6 = require("@geenius/adapters-shared");
|
|
384
|
+
var import_jsx_runtime7 = require("react/jsx-runtime");
|
|
385
|
+
function AdapterDetailPage({ domain, onBack, className = "" }) {
|
|
386
|
+
const { isLoading } = useAdapters();
|
|
387
|
+
const status = useAdapterStatus(domain);
|
|
388
|
+
const [isEditing, setIsEditing] = (0, import_react6.useState)(false);
|
|
389
|
+
const providers = (0, import_adapters_shared6.getProvidersForDomain)(domain);
|
|
390
|
+
const label = import_adapters_shared6.DOMAIN_LABELS[domain];
|
|
391
|
+
const icon = import_adapters_shared6.DOMAIN_ICONS[domain];
|
|
392
|
+
const desc = import_adapters_shared6.DOMAIN_DESCRIPTIONS[domain];
|
|
393
|
+
if (isLoading) {
|
|
394
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: `max-w-3xl mx-auto space-y-6 ${className}`, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "animate-pulse space-y-4", children: [
|
|
395
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "h-6 w-32 rounded bg-white/10" }),
|
|
396
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "h-40 rounded-2xl bg-white/[0.03]" }),
|
|
397
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "h-60 rounded-2xl bg-white/[0.03]" })
|
|
398
|
+
] }) });
|
|
399
|
+
}
|
|
400
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: `max-w-3xl mx-auto space-y-8 ${className}`, children: [
|
|
401
|
+
onBack && /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("button", { onClick: onBack, className: "flex items-center gap-1.5 text-sm text-white/30 hover:text-white/60 transition-colors", children: [
|
|
402
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { children: "\u2190" }),
|
|
403
|
+
" Back to Adapters"
|
|
404
|
+
] }),
|
|
405
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "flex items-start gap-5", children: [
|
|
406
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "flex h-16 w-16 items-center justify-center rounded-2xl bg-white/5 text-3xl", children: icon }),
|
|
407
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "flex-1", children: [
|
|
408
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "flex items-center gap-3", children: [
|
|
409
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("h1", { className: "text-2xl font-extrabold text-white/95 tracking-tight", children: label }),
|
|
410
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(AdapterStatusBadge, { status: status.status })
|
|
411
|
+
] }),
|
|
412
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("p", { className: "mt-1 text-sm text-white/40", children: desc })
|
|
413
|
+
] })
|
|
414
|
+
] }),
|
|
415
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "rounded-2xl border border-white/10 bg-white/[0.03] p-6 backdrop-blur-sm", children: [
|
|
416
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("h2", { className: "text-xs font-semibold uppercase tracking-wider text-white/30 mb-4", children: "Current Status" }),
|
|
417
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "grid gap-4 sm:grid-cols-3", children: [
|
|
418
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { children: [
|
|
419
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("p", { className: "text-[0.625rem] text-white/30 uppercase", children: "Provider" }),
|
|
420
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("p", { className: "mt-0.5 text-sm font-semibold text-white/80", children: status.provider !== "none" ? status.provider : "\u2014" })
|
|
421
|
+
] }),
|
|
422
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { children: [
|
|
423
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("p", { className: "text-[0.625rem] text-white/30 uppercase", children: "Status" }),
|
|
424
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("p", { className: "mt-0.5", children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(AdapterStatusBadge, { status: status.status }) })
|
|
425
|
+
] }),
|
|
426
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { children: [
|
|
427
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("p", { className: "text-[0.625rem] text-white/30 uppercase", children: "Last Checked" }),
|
|
428
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("p", { className: "mt-0.5 text-sm text-white/60", children: status.lastCheckedAt ? new Date(status.lastCheckedAt).toLocaleTimeString() : "\u2014" })
|
|
429
|
+
] })
|
|
430
|
+
] }),
|
|
431
|
+
status.error && /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "mt-4 rounded-lg border border-red-500/20 bg-red-500/10 px-4 py-3 text-sm text-red-400", children: [
|
|
432
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "font-semibold", children: "Error:" }),
|
|
433
|
+
" ",
|
|
434
|
+
status.error
|
|
435
|
+
] }),
|
|
436
|
+
status.latency && /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "mt-4", children: [
|
|
437
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("p", { className: "text-[0.625rem] text-white/30 uppercase mb-1", children: "Latency" }),
|
|
438
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "h-2 w-full rounded-full bg-white/5 overflow-hidden", children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
439
|
+
"div",
|
|
440
|
+
{
|
|
441
|
+
className: `h-full rounded-full transition-all ${status.latency < 100 ? "bg-emerald-400" : status.latency < 500 ? "bg-amber-400" : "bg-red-400"}`,
|
|
442
|
+
style: { width: `${Math.min(100, status.latency / 1e3 * 100)}%` }
|
|
443
|
+
}
|
|
444
|
+
) }),
|
|
445
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("p", { className: "mt-1 text-xs text-white/40", children: [
|
|
446
|
+
status.latency,
|
|
447
|
+
"ms"
|
|
448
|
+
] })
|
|
449
|
+
] })
|
|
450
|
+
] }),
|
|
451
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "rounded-2xl border border-white/10 bg-white/[0.03] p-6 backdrop-blur-sm", children: [
|
|
452
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "flex items-center justify-between mb-4", children: [
|
|
453
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("h2", { className: "text-xs font-semibold uppercase tracking-wider text-white/30", children: "Available Providers" }),
|
|
454
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("span", { className: "text-xs text-white/20", children: [
|
|
455
|
+
providers.length,
|
|
456
|
+
" providers"
|
|
457
|
+
] })
|
|
458
|
+
] }),
|
|
459
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "divide-y divide-white/5", children: providers.map((p) => /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "flex items-center justify-between py-3 first:pt-0 last:pb-0", children: [
|
|
460
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { children: [
|
|
461
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("p", { className: "text-sm font-semibold text-white/80", children: p.name }),
|
|
462
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("p", { className: "text-xs text-white/30", children: p.description })
|
|
463
|
+
] }),
|
|
464
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: `self-start rounded px-2 py-0.5 text-[0.625rem] font-bold uppercase ${p.tier === "pronto" ? "bg-emerald-500/10 text-emerald-400" : p.tier === "lancio" ? "bg-blue-500/10 text-blue-400" : "bg-purple-500/10 text-purple-400"}`, children: p.tier })
|
|
465
|
+
] }, p.id)) })
|
|
466
|
+
] }),
|
|
467
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { children: isEditing ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
468
|
+
AdapterConfigForm,
|
|
469
|
+
{
|
|
470
|
+
domain,
|
|
471
|
+
onSave: async () => setIsEditing(false),
|
|
472
|
+
onCancel: () => setIsEditing(false)
|
|
473
|
+
}
|
|
474
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
|
|
475
|
+
"button",
|
|
476
|
+
{
|
|
477
|
+
onClick: () => setIsEditing(true),
|
|
478
|
+
className: "w-full rounded-2xl border border-dashed border-white/10 bg-white/[0.01] p-6 text-center text-sm text-white/30 hover:border-white/20 hover:text-white/50 transition-all",
|
|
479
|
+
children: [
|
|
480
|
+
"\u2699\uFE0F Configure ",
|
|
481
|
+
label,
|
|
482
|
+
" Adapter"
|
|
483
|
+
]
|
|
484
|
+
}
|
|
485
|
+
) })
|
|
486
|
+
] });
|
|
487
|
+
}
|
|
488
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
489
|
+
0 && (module.exports = {
|
|
490
|
+
ADAPTER_DOMAINS,
|
|
491
|
+
AdapterCard,
|
|
492
|
+
AdapterConfigForm,
|
|
493
|
+
AdapterDetailPage,
|
|
494
|
+
AdapterList,
|
|
495
|
+
AdapterProvider,
|
|
496
|
+
AdapterStatusBadge,
|
|
497
|
+
AdaptersPage,
|
|
498
|
+
DOMAIN_DESCRIPTIONS,
|
|
499
|
+
DOMAIN_ICONS,
|
|
500
|
+
DOMAIN_LABELS,
|
|
501
|
+
configureAdapters,
|
|
502
|
+
getAdapterConfig,
|
|
503
|
+
useAdapterContext,
|
|
504
|
+
useAdapterStatus,
|
|
505
|
+
useAdapterStatuses,
|
|
506
|
+
useAdapters,
|
|
507
|
+
useAdmin,
|
|
508
|
+
useAi,
|
|
509
|
+
useAuth,
|
|
510
|
+
useDb,
|
|
511
|
+
useIsAdapterReady,
|
|
512
|
+
usePayments,
|
|
513
|
+
useStorage
|
|
514
|
+
});
|
|
515
|
+
//# sourceMappingURL=index.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/index.tsx","../src/provider/AdapterProvider.tsx","../src/hooks/index.ts","../src/components/AdapterStatusBadge.tsx","../src/components/AdapterCard.tsx","../src/components/AdapterList.tsx","../src/components/AdapterConfigForm.tsx","../src/pages/AdaptersPage.tsx","../src/pages/AdapterDetailPage.tsx"],"sourcesContent":["// @geenius/adapters-react-css — Barrel export\n\n/**\n * @geenius/adapters-react-css\n * React components using vanilla CSS (no Tailwind).\n * Import: `import '@geenius/adapters-react-css/styles.css'`\n */\n\nexport type {\n AuthAdapter, DbAdapter, PaymentsAdapter, AiAdapter, FileStorageAdapter,\n AdminAdapter, AdapterDomain, AdapterConfig, AdapterStatusType, AdapterStatusInfo,\n} from '@geenius/adapters-shared'\n\nexport { ADAPTER_DOMAINS, DOMAIN_LABELS, DOMAIN_ICONS, DOMAIN_DESCRIPTIONS, configureAdapters, getAdapterConfig } from '@geenius/adapters-shared'\n\nexport { AdapterProvider, useAdapterContext } from './provider'\nexport type { AdapterProviderProps, AdapterSet, AdapterContextValue } from './provider'\n\nexport { useDb, useAuth, usePayments, useAi, useStorage, useAdmin, useAdapters, useAdapterStatuses, useAdapterStatus, useIsAdapterReady } from './hooks'\n\nexport { AdapterStatusBadge, AdapterCard, AdapterList, AdapterConfigForm } from './components'\nexport type { AdapterStatusBadgeProps, AdapterCardProps, AdapterListProps, AdapterConfigFormProps } from './components'\n\nexport { AdaptersPage, AdapterDetailPage } from './pages'\nexport type { AdaptersPageProps, AdapterDetailPageProps } from './pages'\n","// @geenius/adapters-react — Provider\n\n'use client'\n\nimport { createContext, useContext, useState, useCallback, useEffect, useMemo, type ReactNode } from 'react'\nimport type {\n AuthAdapter, DbAdapter, PaymentsAdapter, AiAdapter, FileStorageAdapter, AdminAdapter,\n AdapterDomain, AdapterStatusType, AdapterStatusInfo,\n} from '@geenius/adapters-shared'\nimport { ADAPTER_DOMAINS, DOMAIN_LABELS } from '@geenius/adapters-shared'\n\n// ─── Adapter Set ─────────────────────────────────────────────────────────────\n\nexport interface AdapterSet {\n db?: DbAdapter\n auth?: AuthAdapter\n payments?: PaymentsAdapter\n ai?: AiAdapter\n storage?: FileStorageAdapter\n admin?: AdminAdapter\n}\n\n// ─── Context ─────────────────────────────────────────────────────────────────\n\nexport interface AdapterContextValue {\n adapters: AdapterSet\n statuses: Record<AdapterDomain, AdapterStatusInfo>\n getAdapter: <K extends keyof AdapterSet>(domain: K) => NonNullable<AdapterSet[K]>\n isReady: (domain: AdapterDomain) => boolean\n isLoading: boolean\n}\n\nconst AdapterContext = createContext<AdapterContextValue | null>(null)\n\n// ─── Provider ────────────────────────────────────────────────────────────────\n\nexport interface AdapterProviderProps {\n adapters: AdapterSet\n children: ReactNode\n /** Check adapter health on mount */\n healthCheck?: boolean\n}\n\nexport function AdapterProvider({ adapters, children, healthCheck = false }: AdapterProviderProps) {\n const [isLoading, setIsLoading] = useState(healthCheck)\n const [statuses, setStatuses] = useState<Record<AdapterDomain, AdapterStatusInfo>>(() => {\n const initial = {} as Record<AdapterDomain, AdapterStatusInfo>\n for (const domain of ADAPTER_DOMAINS) {\n const adapter = adapters[domain as keyof AdapterSet]\n initial[domain] = {\n domain,\n provider: adapter ? 'configured' : 'none',\n status: adapter ? 'connected' : 'disconnected',\n lastCheckedAt: Date.now(),\n }\n }\n return initial\n })\n\n useEffect(() => {\n if (!healthCheck) return\n setIsLoading(true)\n // Simple health check — verify adapters are callable\n const checks = ADAPTER_DOMAINS.map(async (domain) => {\n const adapter = adapters[domain as keyof AdapterSet]\n if (!adapter) return\n try {\n setStatuses(prev => ({ ...prev, [domain]: { ...prev[domain], status: 'initializing' } }))\n // Basic connectivity test for each domain\n if (domain === 'auth' && (adapter as AuthAdapter).getSession) {\n await (adapter as AuthAdapter).getSession()\n }\n setStatuses(prev => ({\n ...prev,\n [domain]: { ...prev[domain], status: 'connected' as AdapterStatusType, lastCheckedAt: Date.now() },\n }))\n } catch (e) {\n setStatuses(prev => ({\n ...prev,\n [domain]: {\n ...prev[domain],\n status: 'error' as AdapterStatusType,\n error: e instanceof Error ? e.message : 'Health check failed',\n lastCheckedAt: Date.now(),\n },\n }))\n }\n })\n Promise.allSettled(checks).finally(() => setIsLoading(false))\n }, [adapters, healthCheck])\n\n const getAdapter = useCallback(<K extends keyof AdapterSet>(domain: K): NonNullable<AdapterSet[K]> => {\n const adapter = adapters[domain]\n if (!adapter) throw new Error(`${DOMAIN_LABELS[domain as AdapterDomain] ?? domain} adapter not configured in <AdapterProvider>`)\n return adapter as NonNullable<AdapterSet[K]>\n }, [adapters])\n\n const isReady = useCallback((domain: AdapterDomain) => {\n return !!adapters[domain as keyof AdapterSet] && statuses[domain]?.status === 'connected'\n }, [adapters, statuses])\n\n const value = useMemo<AdapterContextValue>(() => ({\n adapters, statuses, getAdapter, isReady, isLoading,\n }), [adapters, statuses, getAdapter, isReady, isLoading])\n\n return <AdapterContext.Provider value={value}>{children}</AdapterContext.Provider>\n}\n\n// ─── Context Hook ────────────────────────────────────────────────────────────\n\nexport function useAdapterContext(): AdapterContextValue {\n const ctx = useContext(AdapterContext)\n if (!ctx) throw new Error('useAdapterContext must be used within <AdapterProvider>')\n return ctx\n}\n","// @geenius/adapters-react — Hooks\n\nimport { useMemo } from 'react'\nimport { useAdapterContext } from '../provider/AdapterProvider'\nimport type {\n AuthAdapter, DbAdapter, PaymentsAdapter, AiAdapter, FileStorageAdapter, AdminAdapter,\n AdapterDomain, AdapterStatusInfo,\n} from '@geenius/adapters-shared'\n\n// ─── Domain-specific hooks ───────────────────────────────────────────────────\n\n/** Access the database adapter */\nexport function useDb(): DbAdapter {\n return useAdapterContext().getAdapter('db')\n}\n\n/** Access the auth adapter */\nexport function useAuth(): AuthAdapter {\n return useAdapterContext().getAdapter('auth')\n}\n\n/** Access the payments adapter */\nexport function usePayments(): PaymentsAdapter {\n return useAdapterContext().getAdapter('payments')\n}\n\n/** Access the AI adapter */\nexport function useAi(): AiAdapter {\n return useAdapterContext().getAdapter('ai')\n}\n\n/** Access the file storage adapter */\nexport function useStorage(): FileStorageAdapter {\n return useAdapterContext().getAdapter('storage')\n}\n\n/** Access the admin adapter */\nexport function useAdmin(): AdminAdapter {\n return useAdapterContext().getAdapter('admin')\n}\n\n// ─── Status hooks ────────────────────────────────────────────────────────────\n\n/** Get all adapter statuses */\nexport function useAdapterStatuses(): Record<AdapterDomain, AdapterStatusInfo> {\n return useAdapterContext().statuses\n}\n\n/** Get status for a specific adapter domain */\nexport function useAdapterStatus(domain: AdapterDomain): AdapterStatusInfo {\n return useAdapterContext().statuses[domain]\n}\n\n/** Check if adapter is ready */\nexport function useIsAdapterReady(domain: AdapterDomain): boolean {\n return useAdapterContext().isReady(domain)\n}\n\n// ─── Full adapters hook ──────────────────────────────────────────────────────\n\n/** Access all adapters at once */\nexport function useAdapters() {\n const ctx = useAdapterContext()\n return useMemo(() => ({\n db: ctx.adapters.db,\n auth: ctx.adapters.auth,\n payments: ctx.adapters.payments,\n ai: ctx.adapters.ai,\n storage: ctx.adapters.storage,\n admin: ctx.adapters.admin,\n statuses: ctx.statuses,\n isLoading: ctx.isLoading,\n isReady: ctx.isReady,\n }), [ctx])\n}\n","// @geenius/adapters-react-css — AdapterStatusBadge\n\nimport type { AdapterStatusType } from '@geenius/adapters-shared'\n\nexport interface AdapterStatusBadgeProps {\n status: AdapterStatusType\n showLabel?: boolean\n className?: string\n}\n\nexport function AdapterStatusBadge({ status, showLabel = true, className = '' }: AdapterStatusBadgeProps) {\n const labels: Record<AdapterStatusType, string> = {\n connected: 'Connected', disconnected: 'Disconnected', error: 'Error', initializing: 'Initializing',\n }\n return (\n <span className={`adapter-badge adapter-badge--${status} ${className}`}>\n <span className=\"adapter-badge__dot\" />\n {showLabel && <span>{labels[status]}</span>}\n </span>\n )\n}\n","// @geenius/adapters-react-css — AdapterCard\n\nimport type { AdapterDomain, AdapterStatusInfo } from '@geenius/adapters-shared'\nimport { DOMAIN_LABELS, DOMAIN_ICONS, DOMAIN_DESCRIPTIONS } from '@geenius/adapters-shared'\nimport { AdapterStatusBadge } from './AdapterStatusBadge'\n\nexport interface AdapterCardProps {\n domain: AdapterDomain\n status: AdapterStatusInfo\n onClick?: () => void\n className?: string\n}\n\nexport function AdapterCard({ domain, status, onClick, className = '' }: AdapterCardProps) {\n return (\n <button type=\"button\" onClick={onClick} className={`adapter-card ${className}`} aria-label={`${DOMAIN_LABELS[domain]} adapter`}>\n <div className=\"adapter-card__icon\">{DOMAIN_ICONS[domain]}</div>\n <div className=\"adapter-card__body\">\n <div className=\"adapter-card__header\">\n <h3 className=\"adapter-card__name\">{DOMAIN_LABELS[domain]}</h3>\n <AdapterStatusBadge status={status.status} />\n </div>\n <p className=\"adapter-card__desc\">{DOMAIN_DESCRIPTIONS[domain]}</p>\n {status.provider && status.provider !== 'none' && (\n <div className=\"adapter-card__meta\">\n <span className=\"adapter-card__provider\">{status.provider}</span>\n {status.latency && <span className=\"adapter-card__latency\">{status.latency}ms</span>}\n </div>\n )}\n {status.error && <p className=\"adapter-card__error\">{status.error}</p>}\n </div>\n </button>\n )\n}\n","// @geenius/adapters-react-css — AdapterList\n\nimport { useState, useMemo } from 'react'\nimport { useAdapters } from '../hooks'\nimport { AdapterCard } from './AdapterCard'\nimport { ADAPTER_DOMAINS, DOMAIN_LABELS } from '@geenius/adapters-shared'\nimport type { AdapterDomain, AdapterStatusType } from '@geenius/adapters-shared'\n\nexport interface AdapterListProps {\n onSelect?: (domain: AdapterDomain) => void\n filterStatus?: AdapterStatusType\n className?: string\n}\n\nexport function AdapterList({ onSelect, filterStatus, className = '' }: AdapterListProps) {\n const { statuses, isLoading } = useAdapters()\n const [search, setSearch] = useState('')\n\n const filtered = useMemo(() => {\n let domains = [...ADAPTER_DOMAINS]\n if (search) { const q = search.toLowerCase(); domains = domains.filter(d => DOMAIN_LABELS[d].toLowerCase().includes(q) || d.includes(q)) }\n if (filterStatus) { domains = domains.filter(d => statuses[d]?.status === filterStatus) }\n return domains\n }, [search, filterStatus, statuses])\n\n if (isLoading) return (\n <div className={className} role=\"status\">{[1,2,3,4].map(i => <div key={i} className=\"adapter-skeleton\" style={{height: '6rem', marginBottom: '0.75rem'}} />)}</div>\n )\n\n return (\n <div className={className}>\n <input type=\"text\" value={search} onChange={e => setSearch(e.target.value)} placeholder=\"Search adapters...\" className=\"adapter-search\" aria-label=\"Search adapters\" />\n {filtered.length === 0 ? (\n <div className=\"adapter-empty\"><p className=\"adapter-empty__text\">{search ? 'No match' : 'No adapters configured'}</p></div>\n ) : (\n <div className=\"adapter-grid\" role=\"list\">{filtered.map(d => <AdapterCard key={d} domain={d} status={statuses[d]} onClick={() => onSelect?.(d)} />)}</div>\n )}\n </div>\n )\n}\n","// @geenius/adapters-react-css — AdapterConfigForm\n\nimport { useState } from 'react'\nimport type { AdapterDomain, DomainAdapterConfig } from '@geenius/adapters-shared'\nimport { DOMAIN_LABELS, getProvidersForDomain } from '@geenius/adapters-shared'\n\nexport interface AdapterConfigFormProps {\n domain: AdapterDomain\n initialConfig?: DomainAdapterConfig\n onSave: (config: DomainAdapterConfig) => Promise<void> | void\n onCancel?: () => void\n className?: string\n}\n\nexport function AdapterConfigForm({ domain, initialConfig, onSave, onCancel, className = '' }: AdapterConfigFormProps) {\n const providers = getProvidersForDomain(domain)\n const [provider, setProvider] = useState(initialConfig?.provider ?? providers[0]?.id ?? '')\n const [apiKey, setApiKey] = useState(initialConfig?.apiKey ?? '')\n const [baseUrl, setBaseUrl] = useState(initialConfig?.baseUrl ?? '')\n const [isSaving, setIsSaving] = useState(false)\n const [error, setError] = useState<string | null>(null)\n const needsApiKey = !['localStorage', 'noop'].includes(provider)\n const needsBaseUrl = ['ollama', 'minio', 'neon', 'supabase'].includes(provider)\n\n const handleSubmit = async (e: React.FormEvent) => {\n e.preventDefault(); setError(null)\n if (!provider) { setError('Select a provider'); return }\n setIsSaving(true)\n try { await onSave({ provider, apiKey: apiKey || undefined, baseUrl: baseUrl || undefined }) }\n catch (e) { setError(e instanceof Error ? e.message : 'Failed') }\n finally { setIsSaving(false) }\n }\n\n return (\n <form onSubmit={handleSubmit} className={`adapter-form ${className}`} noValidate>\n <h3 className=\"adapter-form__title\">Configure {DOMAIN_LABELS[domain]}</h3>\n <p className=\"adapter-form__subtitle\">Select your preferred provider.</p>\n {error && <div className=\"adapter-alert adapter-alert--error\" role=\"alert\" style={{marginTop: '1rem'}}>{error}</div>}\n <div className=\"adapter-field\">\n <span className=\"adapter-field__label\">Provider</span>\n <div className=\"adapter-provider-grid\">\n {providers.map(p => (\n <button key={p.id} type=\"button\" onClick={() => setProvider(p.id)} className={`adapter-provider-option ${provider === p.id ? 'adapter-provider-option--selected' : ''}`}>\n <span className=\"adapter-provider-option__name\">{p.name}</span>\n <span className=\"adapter-provider-option__desc\">{p.description}</span>\n <span className={`adapter-tier-badge adapter-tier-badge--${p.tier}`}>{p.tier}</span>\n </button>\n ))}\n </div>\n </div>\n {needsApiKey && (\n <div className=\"adapter-field\"><label className=\"adapter-field__label\">API Key</label><input type=\"password\" value={apiKey} onChange={e => setApiKey(e.target.value)} className=\"adapter-field__input\" placeholder=\"Enter API key\" /></div>\n )}\n {needsBaseUrl && (\n <div className=\"adapter-field\"><label className=\"adapter-field__label\">Base URL</label><input type=\"url\" value={baseUrl} onChange={e => setBaseUrl(e.target.value)} className=\"adapter-field__input\" placeholder=\"https://...\" /></div>\n )}\n <div style={{display: 'flex', justifyContent: 'flex-end', gap: '0.75rem', marginTop: '1.5rem'}}>\n {onCancel && <button type=\"button\" onClick={onCancel} className=\"adapter-btn adapter-btn--ghost\">Cancel</button>}\n <button type=\"submit\" disabled={isSaving || !provider} className=\"adapter-btn adapter-btn--primary\">{isSaving ? 'Saving…' : 'Save'}</button>\n </div>\n </form>\n )\n}\n","// @geenius/adapters-react — AdaptersPage\n\nimport { useState } from 'react'\nimport { useAdapters } from '../hooks'\nimport { AdapterList } from '../components/AdapterList'\nimport { AdapterConfigForm } from '../components/AdapterConfigForm'\nimport { AdapterStatusBadge } from '../components/AdapterStatusBadge'\nimport { ADAPTER_DOMAINS, ADAPTER_STATUSES, DOMAIN_LABELS } from '@geenius/adapters-shared'\nimport type { AdapterDomain, AdapterStatusType } from '@geenius/adapters-shared'\n\nexport interface AdaptersPageProps {\n onNavigateDetail?: (domain: AdapterDomain) => void\n className?: string\n}\n\nexport function AdaptersPage({ onNavigateDetail, className = '' }: AdaptersPageProps) {\n const { statuses, isLoading } = useAdapters()\n const [selectedDomain, setSelectedDomain] = useState<AdapterDomain | null>(null)\n const [filterStatus, setFilterStatus] = useState<AdapterStatusType | undefined>()\n\n // Status summary counts\n const counts = {\n connected: ADAPTER_DOMAINS.filter(d => statuses[d]?.status === 'connected').length,\n error: ADAPTER_DOMAINS.filter(d => statuses[d]?.status === 'error').length,\n total: ADAPTER_DOMAINS.length,\n }\n\n if (isLoading) {\n return (\n <div className={`max-w-4xl mx-auto space-y-6 ${className}`}>\n <div className=\"animate-pulse space-y-4\">\n <div className=\"h-8 w-48 rounded bg-white/10\" />\n <div className=\"h-4 w-72 rounded bg-white/5\" />\n <div className=\"grid gap-3 sm:grid-cols-3\">{[1,2,3].map(i => <div key={i} className=\"h-20 rounded-2xl bg-white/[0.03]\" />)}</div>\n <div className=\"grid gap-3 sm:grid-cols-2\">{[1,2,3,4].map(i => <div key={i} className=\"h-28 rounded-2xl bg-white/[0.03]\" />)}</div>\n </div>\n </div>\n )\n }\n\n return (\n <div className={`max-w-4xl mx-auto space-y-8 ${className}`}>\n {/* Header */}\n <div>\n <h1 className=\"text-2xl font-extrabold text-white/95 tracking-tight\">Adapters</h1>\n <p className=\"mt-1 text-sm text-white/40\">Manage your infrastructure adapters — database, auth, AI, storage, payments, and admin.</p>\n </div>\n\n {/* Status Summary */}\n <div className=\"grid gap-3 sm:grid-cols-3\">\n <div className=\"rounded-2xl border border-white/10 bg-white/[0.03] p-4 backdrop-blur-sm\">\n <p className=\"text-xs font-semibold uppercase tracking-wider text-white/30\">Total</p>\n <p className=\"mt-1 text-2xl font-extrabold text-white/90\">{counts.total}</p>\n <p className=\"text-[0.625rem] text-white/30\">adapter domains</p>\n </div>\n <div className=\"rounded-2xl border border-emerald-500/10 bg-emerald-500/[0.03] p-4 backdrop-blur-sm\">\n <p className=\"text-xs font-semibold uppercase tracking-wider text-emerald-400/60\">Connected</p>\n <p className=\"mt-1 text-2xl font-extrabold text-emerald-400\">{counts.connected}</p>\n <p className=\"text-[0.625rem] text-emerald-400/40\">active adapters</p>\n </div>\n {counts.error > 0 && (\n <div className=\"rounded-2xl border border-red-500/10 bg-red-500/[0.03] p-4 backdrop-blur-sm\">\n <p className=\"text-xs font-semibold uppercase tracking-wider text-red-400/60\">Errors</p>\n <p className=\"mt-1 text-2xl font-extrabold text-red-400\">{counts.error}</p>\n <p className=\"text-[0.625rem] text-red-400/40\">need attention</p>\n </div>\n )}\n </div>\n\n {/* Filters */}\n <div className=\"flex items-center gap-2\">\n <button\n onClick={() => setFilterStatus(undefined)}\n className={`rounded-lg px-3 py-1.5 text-xs font-semibold transition-all ${!filterStatus ? 'bg-white/10 text-white/80' : 'text-white/30 hover:text-white/50'}`}\n >All</button>\n {ADAPTER_STATUSES.map(s => (\n <button\n key={s}\n onClick={() => setFilterStatus(s)}\n className={`flex items-center gap-1.5 rounded-lg px-3 py-1.5 text-xs font-semibold transition-all ${filterStatus === s ? 'bg-white/10 text-white/80' : 'text-white/30 hover:text-white/50'}`}\n >\n <AdapterStatusBadge status={s} showLabel={false} />\n {s}\n </button>\n ))}\n </div>\n\n {/* Adapter Grid */}\n <AdapterList\n onSelect={(domain) => {\n if (onNavigateDetail) { onNavigateDetail(domain) }\n else { setSelectedDomain(domain) }\n }}\n filterStatus={filterStatus}\n />\n\n {/* Inline Config Modal */}\n {selectedDomain && (\n <div className=\"fixed inset-0 z-50 flex items-center justify-center bg-black/60 backdrop-blur-sm\" onClick={() => setSelectedDomain(null)}>\n <div className=\"max-w-lg w-full mx-4\" onClick={e => e.stopPropagation()}>\n <AdapterConfigForm\n domain={selectedDomain}\n onSave={async () => { setSelectedDomain(null) }}\n onCancel={() => setSelectedDomain(null)}\n />\n </div>\n </div>\n )}\n </div>\n )\n}\n","// @geenius/adapters-react — AdapterDetailPage\n\nimport { useState } from 'react'\nimport { useAdapters, useAdapterStatus } from '../hooks'\nimport { AdapterStatusBadge } from '../components/AdapterStatusBadge'\nimport { AdapterConfigForm } from '../components/AdapterConfigForm'\nimport type { AdapterDomain } from '@geenius/adapters-shared'\nimport { DOMAIN_LABELS, DOMAIN_ICONS, DOMAIN_DESCRIPTIONS, getProvidersForDomain } from '@geenius/adapters-shared'\n\nexport interface AdapterDetailPageProps {\n domain: AdapterDomain\n onBack?: () => void\n className?: string\n}\n\nexport function AdapterDetailPage({ domain, onBack, className = '' }: AdapterDetailPageProps) {\n const { isLoading } = useAdapters()\n const status = useAdapterStatus(domain)\n const [isEditing, setIsEditing] = useState(false)\n const providers = getProvidersForDomain(domain)\n\n const label = DOMAIN_LABELS[domain]\n const icon = DOMAIN_ICONS[domain]\n const desc = DOMAIN_DESCRIPTIONS[domain]\n\n if (isLoading) {\n return (\n <div className={`max-w-3xl mx-auto space-y-6 ${className}`}>\n <div className=\"animate-pulse space-y-4\">\n <div className=\"h-6 w-32 rounded bg-white/10\" />\n <div className=\"h-40 rounded-2xl bg-white/[0.03]\" />\n <div className=\"h-60 rounded-2xl bg-white/[0.03]\" />\n </div>\n </div>\n )\n }\n\n return (\n <div className={`max-w-3xl mx-auto space-y-8 ${className}`}>\n {/* Back navigation */}\n {onBack && (\n <button onClick={onBack} className=\"flex items-center gap-1.5 text-sm text-white/30 hover:text-white/60 transition-colors\">\n <span>←</span> Back to Adapters\n </button>\n )}\n\n {/* Header */}\n <div className=\"flex items-start gap-5\">\n <div className=\"flex h-16 w-16 items-center justify-center rounded-2xl bg-white/5 text-3xl\">{icon}</div>\n <div className=\"flex-1\">\n <div className=\"flex items-center gap-3\">\n <h1 className=\"text-2xl font-extrabold text-white/95 tracking-tight\">{label}</h1>\n <AdapterStatusBadge status={status.status} />\n </div>\n <p className=\"mt-1 text-sm text-white/40\">{desc}</p>\n </div>\n </div>\n\n {/* Status Card */}\n <div className=\"rounded-2xl border border-white/10 bg-white/[0.03] p-6 backdrop-blur-sm\">\n <h2 className=\"text-xs font-semibold uppercase tracking-wider text-white/30 mb-4\">Current Status</h2>\n <div className=\"grid gap-4 sm:grid-cols-3\">\n <div>\n <p className=\"text-[0.625rem] text-white/30 uppercase\">Provider</p>\n <p className=\"mt-0.5 text-sm font-semibold text-white/80\">{status.provider !== 'none' ? status.provider : '—'}</p>\n </div>\n <div>\n <p className=\"text-[0.625rem] text-white/30 uppercase\">Status</p>\n <p className=\"mt-0.5\"><AdapterStatusBadge status={status.status} /></p>\n </div>\n <div>\n <p className=\"text-[0.625rem] text-white/30 uppercase\">Last Checked</p>\n <p className=\"mt-0.5 text-sm text-white/60\">{status.lastCheckedAt ? new Date(status.lastCheckedAt).toLocaleTimeString() : '—'}</p>\n </div>\n </div>\n {status.error && (\n <div className=\"mt-4 rounded-lg border border-red-500/20 bg-red-500/10 px-4 py-3 text-sm text-red-400\">\n <span className=\"font-semibold\">Error:</span> {status.error}\n </div>\n )}\n {status.latency && (\n <div className=\"mt-4\">\n <p className=\"text-[0.625rem] text-white/30 uppercase mb-1\">Latency</p>\n <div className=\"h-2 w-full rounded-full bg-white/5 overflow-hidden\">\n <div className={`h-full rounded-full transition-all ${status.latency < 100 ? 'bg-emerald-400' : status.latency < 500 ? 'bg-amber-400' : 'bg-red-400'}`}\n style={{ width: `${Math.min(100, (status.latency / 1000) * 100)}%` }} />\n </div>\n <p className=\"mt-1 text-xs text-white/40\">{status.latency}ms</p>\n </div>\n )}\n </div>\n\n {/* Available Providers */}\n <div className=\"rounded-2xl border border-white/10 bg-white/[0.03] p-6 backdrop-blur-sm\">\n <div className=\"flex items-center justify-between mb-4\">\n <h2 className=\"text-xs font-semibold uppercase tracking-wider text-white/30\">Available Providers</h2>\n <span className=\"text-xs text-white/20\">{providers.length} providers</span>\n </div>\n <div className=\"divide-y divide-white/5\">\n {providers.map(p => (\n <div key={p.id} className=\"flex items-center justify-between py-3 first:pt-0 last:pb-0\">\n <div>\n <p className=\"text-sm font-semibold text-white/80\">{p.name}</p>\n <p className=\"text-xs text-white/30\">{p.description}</p>\n </div>\n <span className={`self-start rounded px-2 py-0.5 text-[0.625rem] font-bold uppercase ${\n p.tier === 'pronto' ? 'bg-emerald-500/10 text-emerald-400' : p.tier === 'lancio' ? 'bg-blue-500/10 text-blue-400' : 'bg-purple-500/10 text-purple-400'\n }`}>{p.tier}</span>\n </div>\n ))}\n </div>\n </div>\n\n {/* Configuration */}\n <div>\n {isEditing ? (\n <AdapterConfigForm\n domain={domain}\n onSave={async () => setIsEditing(false)}\n onCancel={() => setIsEditing(false)}\n />\n ) : (\n <button\n onClick={() => setIsEditing(true)}\n className=\"w-full rounded-2xl border border-dashed border-white/10 bg-white/[0.01] p-6 text-center text-sm text-white/30 hover:border-white/20 hover:text-white/50 transition-all\"\n >\n ⚙️ Configure {label} Adapter\n </button>\n )}\n </div>\n </div>\n )\n}\n"],"mappings":"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","names":["import_adapters_shared","import_react","import_jsx_runtime","import_adapters_shared","import_jsx_runtime","import_react","import_adapters_shared","import_jsx_runtime","import_react","import_adapters_shared","import_jsx_runtime","e","import_react","import_adapters_shared","import_jsx_runtime","import_react","import_adapters_shared","import_jsx_runtime"]}
|