@pol-studios/ui 1.0.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/dist/adapters/index.js +359 -0
- package/dist/auth/index.js +588 -0
- package/dist/canvas-UVNDA54X.node +0 -0
- package/dist/cards/index.js +872 -0
- package/dist/charts/index.js +54148 -0
- package/dist/components/chat-agent/index.js +21434 -0
- package/dist/components/index.js +148416 -0
- package/dist/contexts/index.js +188 -0
- package/dist/crud/index.js +6550 -0
- package/dist/data/index.js +372 -0
- package/dist/feedback/index.js +9534 -0
- package/dist/file/index.js +256 -0
- package/dist/forms/index.js +504 -0
- package/dist/hooks/index.js +345 -0
- package/dist/index.js +15650 -0
- package/dist/nav/index.js +1556 -0
- package/dist/navbar/index.js +45262 -0
- package/dist/primitives/index.js +15646 -0
- package/dist/providers/index.js +1927 -0
- package/dist/types/index.js +1 -0
- package/package.json +226 -0
- package/src/styles/globals.css +157 -0
|
@@ -0,0 +1,359 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
// src/adapters/tanstack-router-adapter.ts
|
|
4
|
+
import React, { useMemo } from "react";
|
|
5
|
+
import {
|
|
6
|
+
useNavigate as useTanStackNavigate,
|
|
7
|
+
useLocation as useTanStackLocation,
|
|
8
|
+
useParams as useTanStackParams,
|
|
9
|
+
useRouter,
|
|
10
|
+
Link as TanStackLink
|
|
11
|
+
} from "@tanstack/react-router";
|
|
12
|
+
function TanStackLinkWrapper({ to, params, children, className, onClick }) {
|
|
13
|
+
const linkProps = {
|
|
14
|
+
to,
|
|
15
|
+
params,
|
|
16
|
+
className,
|
|
17
|
+
onClick,
|
|
18
|
+
children
|
|
19
|
+
};
|
|
20
|
+
return React.createElement(TanStackLink, linkProps);
|
|
21
|
+
}
|
|
22
|
+
function createTanStackRouterAdapter(navigateFn) {
|
|
23
|
+
return {
|
|
24
|
+
navigate: navigateFn ?? (() => {
|
|
25
|
+
console.warn("Navigate called on adapter created outside React. Use useTanStackRouterAdapter() hook instead.");
|
|
26
|
+
}),
|
|
27
|
+
useLocation: function tanStackUseLocation() {
|
|
28
|
+
const location = useTanStackLocation();
|
|
29
|
+
return {
|
|
30
|
+
pathname: location.pathname,
|
|
31
|
+
search: location.searchStr || "",
|
|
32
|
+
hash: location.hash || ""
|
|
33
|
+
};
|
|
34
|
+
},
|
|
35
|
+
useParams: function tanStackUseParams() {
|
|
36
|
+
return useTanStackParams({ strict: false });
|
|
37
|
+
},
|
|
38
|
+
Link: TanStackLinkWrapper
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
function useTanStackNavigateAdapter() {
|
|
42
|
+
const navigate = useTanStackNavigate();
|
|
43
|
+
return (options) => {
|
|
44
|
+
const navOptions = {
|
|
45
|
+
to: options.to,
|
|
46
|
+
params: options.params,
|
|
47
|
+
search: options.search,
|
|
48
|
+
replace: options.replace
|
|
49
|
+
};
|
|
50
|
+
navigate(navOptions);
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
var noopRouterAdapter = {
|
|
54
|
+
navigate: (_options) => {
|
|
55
|
+
},
|
|
56
|
+
useLocation: function noopUseLocation() {
|
|
57
|
+
return {
|
|
58
|
+
pathname: "/",
|
|
59
|
+
search: "",
|
|
60
|
+
hash: ""
|
|
61
|
+
};
|
|
62
|
+
},
|
|
63
|
+
useParams: function noopUseParams() {
|
|
64
|
+
return {};
|
|
65
|
+
},
|
|
66
|
+
Link: TanStackLinkWrapper
|
|
67
|
+
};
|
|
68
|
+
function useSafeRouter() {
|
|
69
|
+
try {
|
|
70
|
+
return useRouter({ warn: false });
|
|
71
|
+
} catch {
|
|
72
|
+
return null;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
function useTanStackRouterAdapter() {
|
|
76
|
+
const router = useSafeRouter();
|
|
77
|
+
return useMemo(() => {
|
|
78
|
+
if (!router) {
|
|
79
|
+
return noopRouterAdapter;
|
|
80
|
+
}
|
|
81
|
+
return {
|
|
82
|
+
navigate: (options) => {
|
|
83
|
+
const navOptions = {
|
|
84
|
+
to: options.to,
|
|
85
|
+
params: options.params,
|
|
86
|
+
search: options.search,
|
|
87
|
+
replace: options.replace
|
|
88
|
+
};
|
|
89
|
+
router.navigate(navOptions);
|
|
90
|
+
},
|
|
91
|
+
useLocation: function tanStackUseLocation() {
|
|
92
|
+
const location = useTanStackLocation();
|
|
93
|
+
return {
|
|
94
|
+
pathname: location.pathname,
|
|
95
|
+
search: location.searchStr || "",
|
|
96
|
+
hash: location.hash || ""
|
|
97
|
+
};
|
|
98
|
+
},
|
|
99
|
+
useParams: function tanStackUseParams() {
|
|
100
|
+
return useTanStackParams({ strict: false });
|
|
101
|
+
},
|
|
102
|
+
Link: TanStackLinkWrapper
|
|
103
|
+
};
|
|
104
|
+
}, [router]);
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
// src/adapters/auth-adapter.ts
|
|
108
|
+
import { useMemo as useMemo2 } from "react";
|
|
109
|
+
function createPolDbHooksAuthValue(auth) {
|
|
110
|
+
const user = auth.user ? { id: auth.user.id, email: auth.user.email } : auth.user;
|
|
111
|
+
const profile = auth.profile;
|
|
112
|
+
const isAuthenticated = Boolean(auth.user) && !auth.isLoading;
|
|
113
|
+
return {
|
|
114
|
+
user,
|
|
115
|
+
profile,
|
|
116
|
+
isLoading: auth.isLoading,
|
|
117
|
+
isAuthenticated,
|
|
118
|
+
access: auth.access ?? [],
|
|
119
|
+
hasAccess: auth.hasAccess,
|
|
120
|
+
signInAsync: auth.signInAsync,
|
|
121
|
+
signOutAsync: auth.signOutAsync,
|
|
122
|
+
isArchived: auth.isArchived,
|
|
123
|
+
isSuspended: auth.isSuspended
|
|
124
|
+
};
|
|
125
|
+
}
|
|
126
|
+
function usePolDbHooksAuthAdapter(useSetupAuthHook) {
|
|
127
|
+
const auth = useSetupAuthHook();
|
|
128
|
+
return useMemo2(
|
|
129
|
+
() => createPolDbHooksAuthValue(auth),
|
|
130
|
+
[
|
|
131
|
+
auth.user,
|
|
132
|
+
auth.profile,
|
|
133
|
+
auth.isLoading,
|
|
134
|
+
auth.access,
|
|
135
|
+
auth.hasAccess,
|
|
136
|
+
auth.signInAsync,
|
|
137
|
+
auth.signOutAsync,
|
|
138
|
+
auth.isArchived,
|
|
139
|
+
auth.isSuspended
|
|
140
|
+
]
|
|
141
|
+
);
|
|
142
|
+
}
|
|
143
|
+
function createPolDbHooksAuthAdapter(useSetupAuthHook) {
|
|
144
|
+
return () => usePolDbHooksAuthAdapter(useSetupAuthHook);
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
// src/adapters/supabase-data-adapter.ts
|
|
148
|
+
import { useMemo as useMemo3 } from "react";
|
|
149
|
+
function applyFilters(query, filters) {
|
|
150
|
+
if (!filters || filters.length === 0) return query;
|
|
151
|
+
for (const filter of filters) {
|
|
152
|
+
const { field, operator, value } = filter;
|
|
153
|
+
switch (operator) {
|
|
154
|
+
case "eq":
|
|
155
|
+
query = query.eq(field, value);
|
|
156
|
+
break;
|
|
157
|
+
case "neq":
|
|
158
|
+
query = query.neq(field, value);
|
|
159
|
+
break;
|
|
160
|
+
case "gt":
|
|
161
|
+
query = query.gt(field, value);
|
|
162
|
+
break;
|
|
163
|
+
case "gte":
|
|
164
|
+
query = query.gte(field, value);
|
|
165
|
+
break;
|
|
166
|
+
case "lt":
|
|
167
|
+
query = query.lt(field, value);
|
|
168
|
+
break;
|
|
169
|
+
case "lte":
|
|
170
|
+
query = query.lte(field, value);
|
|
171
|
+
break;
|
|
172
|
+
case "like":
|
|
173
|
+
query = query.like(field, value);
|
|
174
|
+
break;
|
|
175
|
+
case "ilike":
|
|
176
|
+
query = query.ilike(field, value);
|
|
177
|
+
break;
|
|
178
|
+
case "in":
|
|
179
|
+
query = query.in(field, value);
|
|
180
|
+
break;
|
|
181
|
+
case "contains":
|
|
182
|
+
query = query.contains(field, value);
|
|
183
|
+
break;
|
|
184
|
+
case "is":
|
|
185
|
+
query = query.is(field, value);
|
|
186
|
+
break;
|
|
187
|
+
default:
|
|
188
|
+
console.warn(`Unknown filter operator: ${operator}`);
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
return query;
|
|
192
|
+
}
|
|
193
|
+
function applySorting(query, sort) {
|
|
194
|
+
if (!sort || sort.length === 0) return query;
|
|
195
|
+
for (const sortItem of sort) {
|
|
196
|
+
query = query.order(sortItem.field, { ascending: sortItem.direction === "asc" });
|
|
197
|
+
}
|
|
198
|
+
return query;
|
|
199
|
+
}
|
|
200
|
+
function applyPagination(query, pagination) {
|
|
201
|
+
if (!pagination) return query;
|
|
202
|
+
const { page, pageSize, offset, limit } = pagination;
|
|
203
|
+
if (offset !== void 0 && limit !== void 0) {
|
|
204
|
+
return query.range(offset, offset + limit - 1);
|
|
205
|
+
}
|
|
206
|
+
if (page !== void 0 && pageSize !== void 0) {
|
|
207
|
+
const calculatedOffset = (page - 1) * pageSize;
|
|
208
|
+
return query.range(calculatedOffset, calculatedOffset + pageSize - 1);
|
|
209
|
+
}
|
|
210
|
+
if (limit !== void 0) {
|
|
211
|
+
return query.limit(limit);
|
|
212
|
+
}
|
|
213
|
+
return query;
|
|
214
|
+
}
|
|
215
|
+
function createSupabaseDataAdapter(client, options = {}) {
|
|
216
|
+
const { schema = "public", primaryKey = "id" } = options;
|
|
217
|
+
const adapter = {
|
|
218
|
+
async getById(table, id) {
|
|
219
|
+
const { data, error } = await client.schema(schema).from(table).select("*").eq(primaryKey, id).single();
|
|
220
|
+
if (error) {
|
|
221
|
+
if (error.code === "PGRST116") {
|
|
222
|
+
return null;
|
|
223
|
+
}
|
|
224
|
+
throw new Error(`Failed to fetch ${table} by id: ${error.message}`);
|
|
225
|
+
}
|
|
226
|
+
return data;
|
|
227
|
+
},
|
|
228
|
+
async getMany(table, params) {
|
|
229
|
+
let query = client.schema(schema).from(table).select(params?.select ?? "*");
|
|
230
|
+
query = applyFilters(query, params?.filters);
|
|
231
|
+
query = applySorting(query, params?.sort);
|
|
232
|
+
query = applyPagination(query, params?.pagination);
|
|
233
|
+
const { data, error } = await query;
|
|
234
|
+
if (error) {
|
|
235
|
+
throw new Error(`Failed to fetch ${table}: ${error.message}`);
|
|
236
|
+
}
|
|
237
|
+
return data ?? [];
|
|
238
|
+
},
|
|
239
|
+
async getManyWithCount(table, params) {
|
|
240
|
+
let query = client.schema(schema).from(table).select(params?.select ?? "*", { count: "exact" });
|
|
241
|
+
query = applyFilters(query, params?.filters);
|
|
242
|
+
query = applySorting(query, params?.sort);
|
|
243
|
+
query = applyPagination(query, params?.pagination);
|
|
244
|
+
const { data, count, error } = await query;
|
|
245
|
+
if (error) {
|
|
246
|
+
throw new Error(`Failed to fetch ${table} with count: ${error.message}`);
|
|
247
|
+
}
|
|
248
|
+
return {
|
|
249
|
+
data: data ?? [],
|
|
250
|
+
count: count ?? 0
|
|
251
|
+
};
|
|
252
|
+
},
|
|
253
|
+
async create(table, data) {
|
|
254
|
+
const { data: result, error } = await client.schema(schema).from(table).insert(data).select().single();
|
|
255
|
+
if (error) {
|
|
256
|
+
throw new Error(`Failed to create ${table}: ${error.message}`);
|
|
257
|
+
}
|
|
258
|
+
return result;
|
|
259
|
+
},
|
|
260
|
+
async update(table, id, data) {
|
|
261
|
+
const { data: result, error } = await client.schema(schema).from(table).update(data).eq(primaryKey, id).select().single();
|
|
262
|
+
if (error) {
|
|
263
|
+
throw new Error(`Failed to update ${table}: ${error.message}`);
|
|
264
|
+
}
|
|
265
|
+
return result;
|
|
266
|
+
},
|
|
267
|
+
async delete(table, id) {
|
|
268
|
+
const { error } = await client.schema(schema).from(table).delete().eq(primaryKey, id);
|
|
269
|
+
if (error) {
|
|
270
|
+
throw new Error(`Failed to delete ${table}: ${error.message}`);
|
|
271
|
+
}
|
|
272
|
+
},
|
|
273
|
+
async query(queryFn) {
|
|
274
|
+
return queryFn();
|
|
275
|
+
},
|
|
276
|
+
subscribe(table, callback, filter) {
|
|
277
|
+
let filterString;
|
|
278
|
+
if (filter && filter.length > 0) {
|
|
279
|
+
const eqFilter = filter.find((f) => f.operator === "eq");
|
|
280
|
+
if (eqFilter) {
|
|
281
|
+
filterString = `${eqFilter.field}=eq.${eqFilter.value}`;
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
const channelName = `${table}-${Date.now()}`;
|
|
285
|
+
const channel = client.channel(channelName).on(
|
|
286
|
+
"postgres_changes",
|
|
287
|
+
{
|
|
288
|
+
event: "*",
|
|
289
|
+
schema,
|
|
290
|
+
table,
|
|
291
|
+
filter: filterString
|
|
292
|
+
},
|
|
293
|
+
(payload) => {
|
|
294
|
+
const realtimePayload = {
|
|
295
|
+
eventType: payload.eventType,
|
|
296
|
+
new: payload.new,
|
|
297
|
+
old: payload.old,
|
|
298
|
+
table
|
|
299
|
+
};
|
|
300
|
+
callback(realtimePayload);
|
|
301
|
+
}
|
|
302
|
+
).subscribe();
|
|
303
|
+
return () => {
|
|
304
|
+
channel.unsubscribe();
|
|
305
|
+
client.removeChannel(channel);
|
|
306
|
+
};
|
|
307
|
+
},
|
|
308
|
+
async uploadFile(bucket, path, file) {
|
|
309
|
+
const { data, error } = await client.storage.from(bucket).upload(path, file, {
|
|
310
|
+
cacheControl: "3600",
|
|
311
|
+
upsert: false
|
|
312
|
+
});
|
|
313
|
+
if (error) {
|
|
314
|
+
throw new Error(`Failed to upload file: ${error.message}`);
|
|
315
|
+
}
|
|
316
|
+
const {
|
|
317
|
+
data: { publicUrl }
|
|
318
|
+
} = client.storage.from(bucket).getPublicUrl(data.path);
|
|
319
|
+
return {
|
|
320
|
+
path: data.path,
|
|
321
|
+
url: publicUrl
|
|
322
|
+
};
|
|
323
|
+
},
|
|
324
|
+
getFileUrl(bucket, path) {
|
|
325
|
+
const {
|
|
326
|
+
data: { publicUrl }
|
|
327
|
+
} = client.storage.from(bucket).getPublicUrl(path);
|
|
328
|
+
return publicUrl;
|
|
329
|
+
},
|
|
330
|
+
async deleteFile(bucket, path) {
|
|
331
|
+
const { error } = await client.storage.from(bucket).remove([path]);
|
|
332
|
+
if (error) {
|
|
333
|
+
throw new Error(`Failed to delete file: ${error.message}`);
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
};
|
|
337
|
+
return adapter;
|
|
338
|
+
}
|
|
339
|
+
function useSupabaseDataAdapter(useSupabaseHook, options = {}) {
|
|
340
|
+
const client = useSupabaseHook();
|
|
341
|
+
return useMemo3(
|
|
342
|
+
() => createSupabaseDataAdapter(client, options),
|
|
343
|
+
[client, options.schema, options.primaryKey]
|
|
344
|
+
);
|
|
345
|
+
}
|
|
346
|
+
function createSupabaseDataAdapterHook(useSupabaseHook, options = {}) {
|
|
347
|
+
return () => useSupabaseDataAdapter(useSupabaseHook, options);
|
|
348
|
+
}
|
|
349
|
+
export {
|
|
350
|
+
createPolDbHooksAuthAdapter,
|
|
351
|
+
createPolDbHooksAuthValue,
|
|
352
|
+
createSupabaseDataAdapter,
|
|
353
|
+
createSupabaseDataAdapterHook,
|
|
354
|
+
createTanStackRouterAdapter,
|
|
355
|
+
usePolDbHooksAuthAdapter,
|
|
356
|
+
useSupabaseDataAdapter,
|
|
357
|
+
useTanStackNavigateAdapter,
|
|
358
|
+
useTanStackRouterAdapter
|
|
359
|
+
};
|