@turtleclub/hooks 0.4.0-beta.6 → 0.4.0-beta.7
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/index.cjs +229 -87
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +224 -86
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
- package/src/v2/lib/authenticated-api-client.ts +7 -0
- package/src/v2/products/api.ts +128 -43
- package/src/v2/products/hooks.ts +66 -30
- package/src/v2/products/index.ts +6 -10
- package/src/v2/products/queries.ts +12 -13
- package/src/v2/products/schema.ts +100 -22
package/dist/index.cjs
CHANGED
|
@@ -103,6 +103,7 @@ __export(index_exports, {
|
|
|
103
103
|
useSignup: () => useSignup,
|
|
104
104
|
useTokenBalance: () => useTokenBalance,
|
|
105
105
|
useUpdateProduct: () => useUpdateProduct,
|
|
106
|
+
useUploadProductLogo: () => useUploadProductLogo,
|
|
106
107
|
useWidgetOpportunities: () => useWidgetOpportunities,
|
|
107
108
|
vaultConfigSchema: () => vaultConfigSchema,
|
|
108
109
|
walletBalanceSchema: () => walletBalanceSchema,
|
|
@@ -1073,110 +1074,219 @@ var earnDepositsQueries = (0, import_query_key_factory5.createQueryKeys)("earnDe
|
|
|
1073
1074
|
// src/v2/products/queries.ts
|
|
1074
1075
|
var import_query_key_factory6 = require("@lukemorales/query-key-factory");
|
|
1075
1076
|
|
|
1077
|
+
// src/v2/lib/authenticated-api-client.ts
|
|
1078
|
+
async function authenticatedApiClient(endpoint, options, token = null) {
|
|
1079
|
+
return apiClient(endpoint, {
|
|
1080
|
+
...options,
|
|
1081
|
+
headers: {
|
|
1082
|
+
...token && { Authorization: `Bearer ${token}` },
|
|
1083
|
+
...options?.headers
|
|
1084
|
+
}
|
|
1085
|
+
});
|
|
1086
|
+
}
|
|
1087
|
+
|
|
1076
1088
|
// src/v2/products/schema.ts
|
|
1077
1089
|
var import_zod7 = require("zod");
|
|
1078
|
-
var
|
|
1079
|
-
|
|
1080
|
-
|
|
1090
|
+
var ProductTypeSchema = import_zod7.z.enum(["deal", "campaign"]);
|
|
1091
|
+
var ProductStatusSchema = import_zod7.z.enum(["active", "paused", "ended"]);
|
|
1092
|
+
var TurtleOrganizationSchema = import_zod7.z.object({
|
|
1093
|
+
id: import_zod7.z.string().uuid(),
|
|
1094
|
+
name: import_zod7.z.string(),
|
|
1095
|
+
iconUrl: import_zod7.z.string(),
|
|
1096
|
+
landingUrl: import_zod7.z.string()
|
|
1081
1097
|
});
|
|
1082
|
-
var
|
|
1098
|
+
var ProductSchema = import_zod7.z.object({
|
|
1099
|
+
id: import_zod7.z.string().uuid(),
|
|
1083
1100
|
name: import_zod7.z.string(),
|
|
1084
|
-
title: import_zod7.z.string()
|
|
1085
|
-
subtitle: import_zod7.z.string()
|
|
1086
|
-
description: import_zod7.z.string()
|
|
1087
|
-
logoUrl: import_zod7.z.string()
|
|
1088
|
-
productUrl: import_zod7.z.string()
|
|
1101
|
+
title: import_zod7.z.string(),
|
|
1102
|
+
subtitle: import_zod7.z.string(),
|
|
1103
|
+
description: import_zod7.z.string(),
|
|
1104
|
+
logoUrl: import_zod7.z.string(),
|
|
1105
|
+
productUrl: import_zod7.z.string(),
|
|
1089
1106
|
startedAt: import_zod7.z.string().optional().nullable(),
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1107
|
+
endedAt: import_zod7.z.string().optional().nullable(),
|
|
1108
|
+
status: ProductStatusSchema,
|
|
1109
|
+
productType: ProductTypeSchema,
|
|
1110
|
+
organization: TurtleOrganizationSchema.nullable(),
|
|
1111
|
+
createdAt: import_zod7.z.string()
|
|
1112
|
+
});
|
|
1113
|
+
var CreateProductInputSchema = import_zod7.z.object({
|
|
1114
|
+
product: ProductSchema.omit({
|
|
1115
|
+
id: true,
|
|
1116
|
+
createdAt: true,
|
|
1117
|
+
organization: true
|
|
1118
|
+
}),
|
|
1093
1119
|
organizationId: import_zod7.z.string().uuid()
|
|
1094
1120
|
});
|
|
1095
|
-
var
|
|
1121
|
+
var UpdateProductInputSchema = import_zod7.z.object({
|
|
1122
|
+
product: ProductSchema.partial().omit({
|
|
1123
|
+
organization: true
|
|
1124
|
+
})
|
|
1125
|
+
// organizationId: z.string().uuid(),
|
|
1126
|
+
});
|
|
1127
|
+
var ProductsResponseSchema = import_zod7.z.object({
|
|
1128
|
+
products: import_zod7.z.array(ProductSchema),
|
|
1129
|
+
total: import_zod7.z.number().optional()
|
|
1130
|
+
});
|
|
1131
|
+
var ProductResponseSchema = import_zod7.z.object({
|
|
1132
|
+
product: ProductSchema
|
|
1133
|
+
});
|
|
1134
|
+
var CreateProductResponseSchema = import_zod7.z.object({
|
|
1096
1135
|
id: import_zod7.z.string().uuid()
|
|
1097
1136
|
});
|
|
1137
|
+
var UpdateProductResponseSchema = import_zod7.z.object({
|
|
1138
|
+
success: import_zod7.z.boolean()
|
|
1139
|
+
});
|
|
1140
|
+
var fileSchema = import_zod7.z.any().refine((value) => {
|
|
1141
|
+
if (!value) return false;
|
|
1142
|
+
if (!(value instanceof File)) return false;
|
|
1143
|
+
if (value.size > 10 * 1024 * 1024) return false;
|
|
1144
|
+
return true;
|
|
1145
|
+
}, "Invalid file");
|
|
1146
|
+
var UploadProductLogoRequestSchema = import_zod7.z.object({
|
|
1147
|
+
// Form data - file upload (required)
|
|
1148
|
+
file: fileSchema,
|
|
1149
|
+
// Form data - optional filename override
|
|
1150
|
+
filename: import_zod7.z.string().optional()
|
|
1151
|
+
});
|
|
1152
|
+
var UploadProductLogoResponseSchema = import_zod7.z.object({
|
|
1153
|
+
url: import_zod7.z.string().url(),
|
|
1154
|
+
error: import_zod7.z.string().optional()
|
|
1155
|
+
});
|
|
1156
|
+
var ProductFiltersSchema = import_zod7.z.object({
|
|
1157
|
+
organizationId: import_zod7.z.string().uuid().optional()
|
|
1158
|
+
});
|
|
1098
1159
|
|
|
1099
1160
|
// src/v2/products/api.ts
|
|
1100
|
-
async function getProducts(
|
|
1161
|
+
async function getProducts(filters, token) {
|
|
1101
1162
|
const params = new URLSearchParams();
|
|
1163
|
+
if (filters?.organizationId) params.append("organizationId", filters.organizationId);
|
|
1102
1164
|
const queryString = params.toString();
|
|
1103
1165
|
const endpoint = `/admin/products${queryString ? `?${queryString}` : ""}`;
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
1166
|
+
console.log("endpoint", endpoint, filters);
|
|
1167
|
+
const data = await authenticatedApiClient(
|
|
1168
|
+
endpoint,
|
|
1169
|
+
{
|
|
1170
|
+
method: "GET"
|
|
1171
|
+
},
|
|
1172
|
+
token
|
|
1173
|
+
);
|
|
1174
|
+
const result = ProductsResponseSchema.safeParse(data);
|
|
1109
1175
|
if (result.success === false) {
|
|
1110
1176
|
console.log("[ZOD ERROR]", result.error);
|
|
1111
1177
|
throw new Error(`Failed to parse products: ${result.error.message}`);
|
|
1112
1178
|
}
|
|
1113
1179
|
return result.data;
|
|
1114
1180
|
}
|
|
1115
|
-
async function
|
|
1181
|
+
async function getProduct(id, token) {
|
|
1182
|
+
const endpoint = `/admin/products/${id}`;
|
|
1183
|
+
const data = await authenticatedApiClient(
|
|
1184
|
+
endpoint,
|
|
1185
|
+
{
|
|
1186
|
+
method: "GET"
|
|
1187
|
+
},
|
|
1188
|
+
token
|
|
1189
|
+
);
|
|
1190
|
+
console.log(data);
|
|
1191
|
+
const result = ProductResponseSchema.safeParse(data);
|
|
1192
|
+
if (result.success === false) {
|
|
1193
|
+
console.log("[ZOD ERROR]", result.error);
|
|
1194
|
+
throw new Error(`Failed to parse product: ${result.error.message}`);
|
|
1195
|
+
}
|
|
1196
|
+
return result.data;
|
|
1197
|
+
}
|
|
1198
|
+
async function createProduct(input, token) {
|
|
1116
1199
|
const endpoint = `/admin/products`;
|
|
1117
|
-
const data = await
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1200
|
+
const data = await authenticatedApiClient(
|
|
1201
|
+
endpoint,
|
|
1202
|
+
{
|
|
1203
|
+
method: "POST",
|
|
1204
|
+
body: JSON.stringify(input),
|
|
1205
|
+
headers: {
|
|
1206
|
+
"Content-Type": "application/json"
|
|
1207
|
+
}
|
|
1122
1208
|
},
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
const result =
|
|
1209
|
+
token
|
|
1210
|
+
);
|
|
1211
|
+
const result = CreateProductResponseSchema.safeParse(data);
|
|
1126
1212
|
if (result.success === false) {
|
|
1127
1213
|
console.log("[ZOD ERROR]", result.error);
|
|
1128
1214
|
throw new Error(`Failed to create product: ${result.error.message}`);
|
|
1129
1215
|
}
|
|
1130
1216
|
return result.data;
|
|
1131
1217
|
}
|
|
1132
|
-
async function updateProduct(input,
|
|
1133
|
-
const endpoint = `/admin/products/${input.id}`;
|
|
1134
|
-
const data = await
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1218
|
+
async function updateProduct(input, token) {
|
|
1219
|
+
const endpoint = `/admin/products/${input.product.id}`;
|
|
1220
|
+
const data = await authenticatedApiClient(
|
|
1221
|
+
endpoint,
|
|
1222
|
+
{
|
|
1223
|
+
method: "PUT",
|
|
1224
|
+
body: JSON.stringify(input),
|
|
1225
|
+
headers: {
|
|
1226
|
+
"Content-Type": "application/json"
|
|
1227
|
+
}
|
|
1139
1228
|
},
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
const result =
|
|
1229
|
+
token
|
|
1230
|
+
);
|
|
1231
|
+
const result = UpdateProductResponseSchema.safeParse(data);
|
|
1143
1232
|
if (result.success === false) {
|
|
1144
1233
|
console.log("[ZOD ERROR]", result.error);
|
|
1145
1234
|
throw new Error(`Failed to update product: ${result.error.message}`);
|
|
1146
1235
|
}
|
|
1147
1236
|
return result.data;
|
|
1148
1237
|
}
|
|
1149
|
-
async function deleteProduct(id,
|
|
1238
|
+
async function deleteProduct(id, token) {
|
|
1150
1239
|
const endpoint = `/admin/products/${id}`;
|
|
1151
|
-
const data = await
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
|
|
1240
|
+
const data = await authenticatedApiClient(
|
|
1241
|
+
endpoint,
|
|
1242
|
+
{
|
|
1243
|
+
method: "DELETE",
|
|
1244
|
+
headers: {
|
|
1245
|
+
"Content-Type": "application/json"
|
|
1246
|
+
}
|
|
1155
1247
|
},
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
const result =
|
|
1248
|
+
token
|
|
1249
|
+
);
|
|
1250
|
+
const result = ProductResponseSchema.safeParse(data);
|
|
1159
1251
|
if (result.success === false) {
|
|
1160
1252
|
console.log("[ZOD ERROR]", result.error);
|
|
1161
1253
|
throw new Error(`Failed to delete product: ${result.error.message}`);
|
|
1162
1254
|
}
|
|
1163
1255
|
}
|
|
1256
|
+
async function uploadProductLogo({ file, filename }, token) {
|
|
1257
|
+
const endpoint = `/admin/products/upload-logo`;
|
|
1258
|
+
const formData = new FormData();
|
|
1259
|
+
formData.append("file", file, filename || file.name);
|
|
1260
|
+
const data = await authenticatedApiClient(
|
|
1261
|
+
endpoint,
|
|
1262
|
+
{
|
|
1263
|
+
method: "POST",
|
|
1264
|
+
body: formData
|
|
1265
|
+
},
|
|
1266
|
+
token
|
|
1267
|
+
);
|
|
1268
|
+
const result = UploadProductLogoResponseSchema.safeParse(data);
|
|
1269
|
+
if (result.success === false) {
|
|
1270
|
+
console.log("[ZOD ERROR]", result.error);
|
|
1271
|
+
throw new Error(`Failed to upload product logo: ${result.error.message}`);
|
|
1272
|
+
}
|
|
1273
|
+
return result.data;
|
|
1274
|
+
}
|
|
1164
1275
|
|
|
1165
1276
|
// src/v2/products/queries.ts
|
|
1166
1277
|
var productsQueries = (0, import_query_key_factory6.createQueryKeys)("products", {
|
|
1167
1278
|
// Get all products (no filters)
|
|
1168
|
-
all: {
|
|
1169
|
-
queryKey:
|
|
1170
|
-
queryFn: () => getProducts()
|
|
1171
|
-
},
|
|
1172
|
-
|
|
1173
|
-
|
|
1279
|
+
all: (token) => ({
|
|
1280
|
+
queryKey: ["all"],
|
|
1281
|
+
queryFn: () => getProducts(void 0, token)
|
|
1282
|
+
}),
|
|
1283
|
+
list: (filters, token) => ({
|
|
1284
|
+
queryKey: [{ filters }],
|
|
1285
|
+
queryFn: () => getProducts(filters, token)
|
|
1286
|
+
}),
|
|
1287
|
+
byId: (id, token) => ({
|
|
1174
1288
|
queryKey: [id],
|
|
1175
|
-
|
|
1176
|
-
queryFn: async () => {
|
|
1177
|
-
const products = await getProducts();
|
|
1178
|
-
return products.products.find((product) => product.id === id);
|
|
1179
|
-
}
|
|
1289
|
+
queryFn: () => getProduct(id, token)
|
|
1180
1290
|
})
|
|
1181
1291
|
});
|
|
1182
1292
|
|
|
@@ -1415,38 +1525,84 @@ function useOpportunity({ id, ...options }) {
|
|
|
1415
1525
|
|
|
1416
1526
|
// src/v2/products/hooks.ts
|
|
1417
1527
|
var import_react_query23 = require("@tanstack/react-query");
|
|
1418
|
-
|
|
1419
|
-
|
|
1528
|
+
|
|
1529
|
+
// src/v2/lib/auth-provider.tsx
|
|
1530
|
+
var import_react2 = require("react");
|
|
1531
|
+
var import_jsx_runtime = require("react/jsx-runtime");
|
|
1532
|
+
var AuthContext = (0, import_react2.createContext)(null);
|
|
1533
|
+
function AuthProvider({ getToken, children }) {
|
|
1534
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(AuthContext.Provider, { value: { getToken }, children });
|
|
1535
|
+
}
|
|
1536
|
+
function useAuthToken() {
|
|
1537
|
+
const context = (0, import_react2.useContext)(AuthContext);
|
|
1538
|
+
if (!context) {
|
|
1539
|
+
throw new Error("useAuthToken must be used within AuthProvider");
|
|
1540
|
+
}
|
|
1541
|
+
return context;
|
|
1420
1542
|
}
|
|
1421
|
-
|
|
1422
|
-
|
|
1543
|
+
|
|
1544
|
+
// src/v2/products/hooks.ts
|
|
1545
|
+
function useProducts({ filters, enabled = true }) {
|
|
1546
|
+
const { getToken } = useAuthToken();
|
|
1547
|
+
return (0, import_react_query23.useQuery)({
|
|
1548
|
+
...productsQueries.list(filters, getToken()),
|
|
1549
|
+
...queryDefaults,
|
|
1550
|
+
enabled
|
|
1551
|
+
});
|
|
1423
1552
|
}
|
|
1424
|
-
function
|
|
1425
|
-
|
|
1553
|
+
function useProduct({ id, enabled = true }) {
|
|
1554
|
+
const { getToken } = useAuthToken();
|
|
1555
|
+
return (0, import_react_query23.useQuery)({
|
|
1556
|
+
...productsQueries.byId(id, getToken()),
|
|
1557
|
+
...queryDefaults,
|
|
1558
|
+
enabled
|
|
1559
|
+
});
|
|
1426
1560
|
}
|
|
1427
|
-
function
|
|
1428
|
-
|
|
1561
|
+
function useCreateProduct(options) {
|
|
1562
|
+
const { getToken } = useAuthToken();
|
|
1563
|
+
return (0, import_react_query23.useMutation)({
|
|
1564
|
+
mutationFn: (input) => createProduct(input, getToken()),
|
|
1565
|
+
...options
|
|
1566
|
+
});
|
|
1567
|
+
}
|
|
1568
|
+
function useUpdateProduct(options) {
|
|
1569
|
+
const { getToken } = useAuthToken();
|
|
1570
|
+
return (0, import_react_query23.useMutation)({
|
|
1571
|
+
mutationFn: (input) => updateProduct(input, getToken()),
|
|
1572
|
+
...options
|
|
1573
|
+
});
|
|
1429
1574
|
}
|
|
1430
|
-
function useDeleteProduct(
|
|
1431
|
-
|
|
1575
|
+
function useDeleteProduct(options) {
|
|
1576
|
+
const { getToken } = useAuthToken();
|
|
1577
|
+
return (0, import_react_query23.useMutation)({
|
|
1578
|
+
mutationFn: (id) => deleteProduct(id, getToken()),
|
|
1579
|
+
...options
|
|
1580
|
+
});
|
|
1581
|
+
}
|
|
1582
|
+
function useUploadProductLogo(options) {
|
|
1583
|
+
const { getToken } = useAuthToken();
|
|
1584
|
+
return (0, import_react_query23.useMutation)({
|
|
1585
|
+
mutationFn: (request) => uploadProductLogo(request, getToken()),
|
|
1586
|
+
...options
|
|
1587
|
+
});
|
|
1432
1588
|
}
|
|
1433
1589
|
|
|
1434
1590
|
// src/v2/balance/useTokenBalance.ts
|
|
1435
|
-
var
|
|
1591
|
+
var import_react3 = require("react");
|
|
1436
1592
|
var import_viem = require("viem");
|
|
1437
1593
|
var import_utils2 = require("@turtleclub/utils");
|
|
1438
1594
|
function useTokenBalance({ token, amount, setAmount }) {
|
|
1439
|
-
const usdValue = (0,
|
|
1440
|
-
const hasInsufficientBalance = (0,
|
|
1595
|
+
const usdValue = (0, import_react3.useMemo)(() => (0, import_utils2.calculateUsdValue)(amount, token?.price), [amount, token?.price]);
|
|
1596
|
+
const hasInsufficientBalance = (0, import_react3.useMemo)(
|
|
1441
1597
|
() => (0, import_utils2.checkInsufficientBalance)(token, amount),
|
|
1442
1598
|
[token, amount]
|
|
1443
1599
|
);
|
|
1444
|
-
const handleMaxClick = (0,
|
|
1600
|
+
const handleMaxClick = (0, import_react3.useCallback)(() => {
|
|
1445
1601
|
if (!token) return;
|
|
1446
1602
|
const maxAmount = (0, import_utils2.calculateMaxAmount)(token.balance, token.decimals);
|
|
1447
1603
|
setAmount(maxAmount);
|
|
1448
1604
|
}, [token, setAmount]);
|
|
1449
|
-
const amountBigInt = (0,
|
|
1605
|
+
const amountBigInt = (0, import_react3.useMemo)(() => {
|
|
1450
1606
|
if (!token || !amount) return void 0;
|
|
1451
1607
|
try {
|
|
1452
1608
|
return (0, import_viem.parseUnits)(amount, token.decimals);
|
|
@@ -1481,21 +1637,6 @@ function useWidgetOpportunities(distributorId) {
|
|
|
1481
1637
|
});
|
|
1482
1638
|
}
|
|
1483
1639
|
|
|
1484
|
-
// src/v2/lib/auth-provider.tsx
|
|
1485
|
-
var import_react3 = require("react");
|
|
1486
|
-
var import_jsx_runtime = require("react/jsx-runtime");
|
|
1487
|
-
var AuthContext = (0, import_react3.createContext)(null);
|
|
1488
|
-
function AuthProvider({ getToken, children }) {
|
|
1489
|
-
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(AuthContext.Provider, { value: { getToken }, children });
|
|
1490
|
-
}
|
|
1491
|
-
function useAuthToken() {
|
|
1492
|
-
const context = (0, import_react3.useContext)(AuthContext);
|
|
1493
|
-
if (!context) {
|
|
1494
|
-
throw new Error("useAuthToken must be used within AuthProvider");
|
|
1495
|
-
}
|
|
1496
|
-
return context;
|
|
1497
|
-
}
|
|
1498
|
-
|
|
1499
1640
|
// src/v2/index.ts
|
|
1500
1641
|
var queries = (0, import_query_key_factory9.mergeQueryKeys)(
|
|
1501
1642
|
opportunitiesQueries,
|
|
@@ -1592,6 +1733,7 @@ var queries = (0, import_query_key_factory9.mergeQueryKeys)(
|
|
|
1592
1733
|
useSignup,
|
|
1593
1734
|
useTokenBalance,
|
|
1594
1735
|
useUpdateProduct,
|
|
1736
|
+
useUploadProductLogo,
|
|
1595
1737
|
useWidgetOpportunities,
|
|
1596
1738
|
vaultConfigSchema,
|
|
1597
1739
|
walletBalanceSchema,
|