@sonicjs-cms/core 2.0.1 → 2.0.2

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.
Files changed (55) hide show
  1. package/dist/{chunk-SRCY43RN.cjs → chunk-3NVJ6W27.cjs} +2 -2
  2. package/dist/chunk-3NVJ6W27.cjs.map +1 -0
  3. package/dist/chunk-4BJGEGX5.cjs +236 -0
  4. package/dist/chunk-4BJGEGX5.cjs.map +1 -0
  5. package/dist/{chunk-5FDDDD4J.cjs → chunk-7G6XT62S.cjs} +321 -311
  6. package/dist/chunk-7G6XT62S.cjs.map +1 -0
  7. package/dist/chunk-ALOS2CBJ.cjs.map +1 -1
  8. package/dist/chunk-CDBVZEWR.js.map +1 -1
  9. package/dist/{chunk-BITQ4MFX.js → chunk-EAELJXRV.js} +93 -115
  10. package/dist/chunk-EAELJXRV.js.map +1 -0
  11. package/dist/chunk-FICTAGD4.js +59 -0
  12. package/dist/chunk-FICTAGD4.js.map +1 -0
  13. package/dist/{chunk-FVMV5DKA.cjs → chunk-HJZOA2O5.cjs} +93 -115
  14. package/dist/chunk-HJZOA2O5.cjs.map +1 -0
  15. package/dist/chunk-LEG4KNFP.cjs.map +1 -1
  16. package/dist/{chunk-5XTB4FE5.js → chunk-LH4Z7QID.js} +2 -2
  17. package/dist/chunk-LH4Z7QID.js.map +1 -0
  18. package/dist/chunk-M6FPVS7E.js +214 -0
  19. package/dist/chunk-M6FPVS7E.js.map +1 -0
  20. package/dist/chunk-O46XKBFM.js.map +1 -1
  21. package/dist/chunk-RCQ2HIQD.cjs +61 -0
  22. package/dist/chunk-RCQ2HIQD.cjs.map +1 -0
  23. package/dist/{chunk-QSF34IYQ.js → chunk-SGGHTIWV.js} +218 -208
  24. package/dist/chunk-SGGHTIWV.js.map +1 -0
  25. package/dist/{chunk-NK6FN5R5.cjs → chunk-UL32L2KV.cjs} +3 -60
  26. package/dist/chunk-UL32L2KV.cjs.map +1 -0
  27. package/dist/{chunk-OL2OE3VJ.js → chunk-XJETEIRU.js} +4 -60
  28. package/dist/chunk-XJETEIRU.js.map +1 -0
  29. package/dist/index.cjs +134 -119
  30. package/dist/index.cjs.map +1 -1
  31. package/dist/index.js +16 -12
  32. package/dist/index.js.map +1 -1
  33. package/dist/middleware.cjs +26 -21
  34. package/dist/middleware.js +2 -1
  35. package/dist/plugins.cjs +7 -7
  36. package/dist/plugins.js +1 -1
  37. package/dist/routes.cjs +25 -24
  38. package/dist/routes.js +5 -4
  39. package/dist/services.cjs +7 -7
  40. package/dist/services.js +1 -1
  41. package/dist/utils.cjs +16 -15
  42. package/dist/utils.js +2 -1
  43. package/package.json +1 -1
  44. package/dist/chunk-5FDDDD4J.cjs.map +0 -1
  45. package/dist/chunk-5XTB4FE5.js.map +0 -1
  46. package/dist/chunk-BITQ4MFX.js.map +0 -1
  47. package/dist/chunk-FVMV5DKA.cjs.map +0 -1
  48. package/dist/chunk-KM4AJFXI.cjs +0 -101
  49. package/dist/chunk-KM4AJFXI.cjs.map +0 -1
  50. package/dist/chunk-NK6FN5R5.cjs.map +0 -1
  51. package/dist/chunk-OL2OE3VJ.js.map +0 -1
  52. package/dist/chunk-QSF34IYQ.js.map +0 -1
  53. package/dist/chunk-SRCY43RN.cjs.map +0 -1
  54. package/dist/chunk-TY3NHEBN.js +0 -80
  55. package/dist/chunk-TY3NHEBN.js.map +0 -1
@@ -1,10 +1,11 @@
1
1
  'use strict';
2
2
 
3
- var chunkSRCY43RN_cjs = require('./chunk-SRCY43RN.cjs');
4
- var chunkKM4AJFXI_cjs = require('./chunk-KM4AJFXI.cjs');
3
+ var chunk3NVJ6W27_cjs = require('./chunk-3NVJ6W27.cjs');
4
+ var chunk4BJGEGX5_cjs = require('./chunk-4BJGEGX5.cjs');
5
5
  var chunkLEG4KNFP_cjs = require('./chunk-LEG4KNFP.cjs');
6
6
  var chunkALOS2CBJ_cjs = require('./chunk-ALOS2CBJ.cjs');
7
- var chunkNK6FN5R5_cjs = require('./chunk-NK6FN5R5.cjs');
7
+ var chunkUL32L2KV_cjs = require('./chunk-UL32L2KV.cjs');
8
+ var chunkRCQ2HIQD_cjs = require('./chunk-RCQ2HIQD.cjs');
8
9
  var hono = require('hono');
9
10
  var cors = require('hono/cors');
10
11
  var zod = require('zod');
@@ -42,7 +43,7 @@ apiContentCrudRoutes.get("/:id", async (c) => {
42
43
  }, 500);
43
44
  }
44
45
  });
45
- apiContentCrudRoutes.post("/", chunkKM4AJFXI_cjs.requireAuth(), async (c) => {
46
+ apiContentCrudRoutes.post("/", chunk4BJGEGX5_cjs.requireAuth(), async (c) => {
46
47
  try {
47
48
  const db = c.env.DB;
48
49
  const user = c.get("user");
@@ -83,7 +84,7 @@ apiContentCrudRoutes.post("/", chunkKM4AJFXI_cjs.requireAuth(), async (c) => {
83
84
  now,
84
85
  now
85
86
  ).run();
86
- const cache = chunkSRCY43RN_cjs.getCacheService(chunkSRCY43RN_cjs.CACHE_CONFIGS.api);
87
+ const cache = chunk3NVJ6W27_cjs.getCacheService(chunk3NVJ6W27_cjs.CACHE_CONFIGS.api);
87
88
  await cache.invalidate(`content:list:${collectionId}:*`);
88
89
  await cache.invalidate("content-filtered:*");
89
90
  const getStmt = db.prepare("SELECT * FROM content WHERE id = ?");
@@ -108,7 +109,7 @@ apiContentCrudRoutes.post("/", chunkKM4AJFXI_cjs.requireAuth(), async (c) => {
108
109
  }, 500);
109
110
  }
110
111
  });
111
- apiContentCrudRoutes.put("/:id", chunkKM4AJFXI_cjs.requireAuth(), async (c) => {
112
+ apiContentCrudRoutes.put("/:id", chunk4BJGEGX5_cjs.requireAuth(), async (c) => {
112
113
  try {
113
114
  const id = c.req.param("id");
114
115
  const db = c.env.DB;
@@ -146,7 +147,7 @@ apiContentCrudRoutes.put("/:id", chunkKM4AJFXI_cjs.requireAuth(), async (c) => {
146
147
  WHERE id = ?
147
148
  `);
148
149
  await updateStmt.bind(...params).run();
149
- const cache = chunkSRCY43RN_cjs.getCacheService(chunkSRCY43RN_cjs.CACHE_CONFIGS.api);
150
+ const cache = chunk3NVJ6W27_cjs.getCacheService(chunk3NVJ6W27_cjs.CACHE_CONFIGS.api);
150
151
  await cache.delete(cache.generateKey("content", id));
151
152
  await cache.invalidate(`content:list:${existing.collection_id}:*`);
152
153
  await cache.invalidate("content-filtered:*");
@@ -172,7 +173,7 @@ apiContentCrudRoutes.put("/:id", chunkKM4AJFXI_cjs.requireAuth(), async (c) => {
172
173
  }, 500);
173
174
  }
174
175
  });
175
- apiContentCrudRoutes.delete("/:id", chunkKM4AJFXI_cjs.requireAuth(), async (c) => {
176
+ apiContentCrudRoutes.delete("/:id", chunk4BJGEGX5_cjs.requireAuth(), async (c) => {
176
177
  try {
177
178
  const id = c.req.param("id");
178
179
  const db = c.env.DB;
@@ -183,7 +184,7 @@ apiContentCrudRoutes.delete("/:id", chunkKM4AJFXI_cjs.requireAuth(), async (c) =
183
184
  }
184
185
  const deleteStmt = db.prepare("DELETE FROM content WHERE id = ?");
185
186
  await deleteStmt.bind(id).run();
186
- const cache = chunkSRCY43RN_cjs.getCacheService(chunkSRCY43RN_cjs.CACHE_CONFIGS.api);
187
+ const cache = chunk3NVJ6W27_cjs.getCacheService(chunk3NVJ6W27_cjs.CACHE_CONFIGS.api);
187
188
  await cache.delete(cache.generateKey("content", id));
188
189
  await cache.invalidate(`content:list:${existing.collection_id}:*`);
189
190
  await cache.invalidate("content-filtered:*");
@@ -208,7 +209,7 @@ apiRoutes.use("*", async (c, next) => {
208
209
  c.header("X-Response-Time", `${totalTime}ms`);
209
210
  });
210
211
  apiRoutes.use("*", async (c, next) => {
211
- const cacheEnabled = await chunkKM4AJFXI_cjs.isPluginActive(c.env.DB, "core-cache");
212
+ const cacheEnabled = await chunk4BJGEGX5_cjs.isPluginActive(c.env.DB, "core-cache");
212
213
  c.set("cacheEnabled", cacheEnabled);
213
214
  await next();
214
215
  });
@@ -256,7 +257,7 @@ apiRoutes.get("/collections", async (c) => {
256
257
  try {
257
258
  const db = c.env.DB;
258
259
  const cacheEnabled = c.get("cacheEnabled");
259
- const cache = chunkSRCY43RN_cjs.getCacheService(chunkSRCY43RN_cjs.CACHE_CONFIGS.api);
260
+ const cache = chunk3NVJ6W27_cjs.getCacheService(chunk3NVJ6W27_cjs.CACHE_CONFIGS.api);
260
261
  const cacheKey = cache.generateKey("collections", "all");
261
262
  if (cacheEnabled) {
262
263
  const cacheResult = await cache.getWithSource(cacheKey);
@@ -333,12 +334,12 @@ apiRoutes.get("/content", async (c) => {
333
334
  });
334
335
  }
335
336
  }
336
- const filter = chunkNK6FN5R5_cjs.QueryFilterBuilder.parseFromQuery(queryParams);
337
+ const filter = chunkUL32L2KV_cjs.QueryFilterBuilder.parseFromQuery(queryParams);
337
338
  if (!filter.limit) {
338
339
  filter.limit = 50;
339
340
  }
340
341
  filter.limit = Math.min(filter.limit, 1e3);
341
- const builder = new chunkNK6FN5R5_cjs.QueryFilterBuilder();
342
+ const builder = new chunkUL32L2KV_cjs.QueryFilterBuilder();
342
343
  const queryResult = builder.build("content", filter);
343
344
  if (queryResult.errors.length > 0) {
344
345
  return c.json({
@@ -347,7 +348,7 @@ apiRoutes.get("/content", async (c) => {
347
348
  }, 400);
348
349
  }
349
350
  const cacheEnabled = c.get("cacheEnabled");
350
- const cache = chunkSRCY43RN_cjs.getCacheService(chunkSRCY43RN_cjs.CACHE_CONFIGS.api);
351
+ const cache = chunk3NVJ6W27_cjs.getCacheService(chunk3NVJ6W27_cjs.CACHE_CONFIGS.api);
351
352
  const cacheKey = cache.generateKey("content-filtered", JSON.stringify({ filter, query: queryResult.sql }));
352
353
  if (cacheEnabled) {
353
354
  const cacheResult = await cache.getWithSource(cacheKey);
@@ -425,7 +426,7 @@ apiRoutes.get("/collections/:collection/content", async (c) => {
425
426
  if (!collectionResult) {
426
427
  return c.json({ error: "Collection not found" }, 404);
427
428
  }
428
- const filter = chunkNK6FN5R5_cjs.QueryFilterBuilder.parseFromQuery(queryParams);
429
+ const filter = chunkUL32L2KV_cjs.QueryFilterBuilder.parseFromQuery(queryParams);
429
430
  if (!filter.where) {
430
431
  filter.where = { and: [] };
431
432
  }
@@ -441,7 +442,7 @@ apiRoutes.get("/collections/:collection/content", async (c) => {
441
442
  filter.limit = 50;
442
443
  }
443
444
  filter.limit = Math.min(filter.limit, 1e3);
444
- const builder = new chunkNK6FN5R5_cjs.QueryFilterBuilder();
445
+ const builder = new chunkUL32L2KV_cjs.QueryFilterBuilder();
445
446
  const queryResult = builder.build("content", filter);
446
447
  if (queryResult.errors.length > 0) {
447
448
  return c.json({
@@ -450,7 +451,7 @@ apiRoutes.get("/collections/:collection/content", async (c) => {
450
451
  }, 400);
451
452
  }
452
453
  const cacheEnabled = c.get("cacheEnabled");
453
- const cache = chunkSRCY43RN_cjs.getCacheService(chunkSRCY43RN_cjs.CACHE_CONFIGS.api);
454
+ const cache = chunk3NVJ6W27_cjs.getCacheService(chunk3NVJ6W27_cjs.CACHE_CONFIGS.api);
454
455
  const cacheKey = cache.generateKey("collection-content-filtered", `${collection}:${JSON.stringify({ filter, query: queryResult.sql })}`);
455
456
  if (cacheEnabled) {
456
457
  const cacheResult = await cache.getWithSource(cacheKey);
@@ -566,7 +567,7 @@ var fileValidationSchema = zod.z.object({
566
567
  // 50MB max
567
568
  });
568
569
  var apiMediaRoutes = new hono.Hono();
569
- apiMediaRoutes.use("*", chunkKM4AJFXI_cjs.requireAuth());
570
+ apiMediaRoutes.use("*", chunk4BJGEGX5_cjs.requireAuth());
570
571
  apiMediaRoutes.post("/upload", async (c) => {
571
572
  try {
572
573
  const user = c.get("user");
@@ -1301,8 +1302,8 @@ apiSystemRoutes.get("/env", (c) => {
1301
1302
  });
1302
1303
  var api_system_default = apiSystemRoutes;
1303
1304
  var adminApiRoutes = new hono.Hono();
1304
- adminApiRoutes.use("*", chunkKM4AJFXI_cjs.requireAuth());
1305
- adminApiRoutes.use("*", chunkKM4AJFXI_cjs.requireRole(["admin", "editor"]));
1305
+ adminApiRoutes.use("*", chunk4BJGEGX5_cjs.requireAuth());
1306
+ adminApiRoutes.use("*", chunk4BJGEGX5_cjs.requireRole(["admin", "editor"]));
1306
1307
  adminApiRoutes.get("/stats", async (c) => {
1307
1308
  try {
1308
1309
  const db = c.env.DB;
@@ -2091,7 +2092,7 @@ authRoutes.post(
2091
2092
  if (existingUser) {
2092
2093
  return c.json({ error: "User with this email or username already exists" }, 400);
2093
2094
  }
2094
- const passwordHash = await chunkKM4AJFXI_cjs.AuthManager.hashPassword(password);
2095
+ const passwordHash = await chunk4BJGEGX5_cjs.AuthManager.hashPassword(password);
2095
2096
  const userId = crypto.randomUUID();
2096
2097
  const now = /* @__PURE__ */ new Date();
2097
2098
  await db.prepare(`
@@ -2111,7 +2112,7 @@ authRoutes.post(
2111
2112
  now.getTime(),
2112
2113
  now.getTime()
2113
2114
  ).run();
2114
- const token = await chunkKM4AJFXI_cjs.AuthManager.generateToken(userId, normalizedEmail, "viewer");
2115
+ const token = await chunk4BJGEGX5_cjs.AuthManager.generateToken(userId, normalizedEmail, "viewer");
2115
2116
  cookie.setCookie(c, "auth_token", token, {
2116
2117
  httpOnly: true,
2117
2118
  secure: true,
@@ -2146,7 +2147,7 @@ authRoutes.post("/login", async (c) => {
2146
2147
  const { email, password } = validation.data;
2147
2148
  const db = c.env.DB;
2148
2149
  const normalizedEmail = email.toLowerCase();
2149
- const cache = chunkSRCY43RN_cjs.getCacheService(chunkSRCY43RN_cjs.CACHE_CONFIGS.user);
2150
+ const cache = chunk3NVJ6W27_cjs.getCacheService(chunk3NVJ6W27_cjs.CACHE_CONFIGS.user);
2150
2151
  let user = await cache.get(cache.generateKey("user", `email:${normalizedEmail}`));
2151
2152
  if (!user) {
2152
2153
  user = await db.prepare("SELECT * FROM users WHERE email = ? AND is_active = 1").bind(normalizedEmail).first();
@@ -2158,11 +2159,11 @@ authRoutes.post("/login", async (c) => {
2158
2159
  if (!user) {
2159
2160
  return c.json({ error: "Invalid email or password" }, 401);
2160
2161
  }
2161
- const isValidPassword = await chunkKM4AJFXI_cjs.AuthManager.verifyPassword(password, user.password_hash);
2162
+ const isValidPassword = await chunk4BJGEGX5_cjs.AuthManager.verifyPassword(password, user.password_hash);
2162
2163
  if (!isValidPassword) {
2163
2164
  return c.json({ error: "Invalid email or password" }, 401);
2164
2165
  }
2165
- const token = await chunkKM4AJFXI_cjs.AuthManager.generateToken(user.id, user.email, user.role);
2166
+ const token = await chunk4BJGEGX5_cjs.AuthManager.generateToken(user.id, user.email, user.role);
2166
2167
  cookie.setCookie(c, "auth_token", token, {
2167
2168
  httpOnly: true,
2168
2169
  secure: true,
@@ -2211,7 +2212,7 @@ authRoutes.get("/logout", (c) => {
2211
2212
  });
2212
2213
  return c.redirect("/auth/login?message=You have been logged out successfully");
2213
2214
  });
2214
- authRoutes.get("/me", chunkKM4AJFXI_cjs.requireAuth(), async (c) => {
2215
+ authRoutes.get("/me", chunk4BJGEGX5_cjs.requireAuth(), async (c) => {
2215
2216
  try {
2216
2217
  const user = c.get("user");
2217
2218
  if (!user) {
@@ -2228,13 +2229,13 @@ authRoutes.get("/me", chunkKM4AJFXI_cjs.requireAuth(), async (c) => {
2228
2229
  return c.json({ error: "Failed to get user" }, 500);
2229
2230
  }
2230
2231
  });
2231
- authRoutes.post("/refresh", chunkKM4AJFXI_cjs.requireAuth(), async (c) => {
2232
+ authRoutes.post("/refresh", chunk4BJGEGX5_cjs.requireAuth(), async (c) => {
2232
2233
  try {
2233
2234
  const user = c.get("user");
2234
2235
  if (!user) {
2235
2236
  return c.json({ error: "Not authenticated" }, 401);
2236
2237
  }
2237
- const token = await chunkKM4AJFXI_cjs.AuthManager.generateToken(user.userId, user.email, user.role);
2238
+ const token = await chunk4BJGEGX5_cjs.AuthManager.generateToken(user.userId, user.email, user.role);
2238
2239
  cookie.setCookie(c, "auth_token", token, {
2239
2240
  httpOnly: true,
2240
2241
  secure: true,
@@ -2284,7 +2285,7 @@ authRoutes.post("/register/form", async (c) => {
2284
2285
  </div>
2285
2286
  `);
2286
2287
  }
2287
- const passwordHash = await chunkKM4AJFXI_cjs.AuthManager.hashPassword(password);
2288
+ const passwordHash = await chunk4BJGEGX5_cjs.AuthManager.hashPassword(password);
2288
2289
  const userId = crypto.randomUUID();
2289
2290
  const now = /* @__PURE__ */ new Date();
2290
2291
  await db.prepare(`
@@ -2304,7 +2305,7 @@ authRoutes.post("/register/form", async (c) => {
2304
2305
  now.getTime(),
2305
2306
  now.getTime()
2306
2307
  ).run();
2307
- const token = await chunkKM4AJFXI_cjs.AuthManager.generateToken(userId, normalizedEmail, "admin");
2308
+ const token = await chunk4BJGEGX5_cjs.AuthManager.generateToken(userId, normalizedEmail, "admin");
2308
2309
  cookie.setCookie(c, "auth_token", token, {
2309
2310
  httpOnly: true,
2310
2311
  secure: false,
@@ -2355,7 +2356,7 @@ authRoutes.post("/login/form", async (c) => {
2355
2356
  </div>
2356
2357
  `);
2357
2358
  }
2358
- const isValidPassword = await chunkKM4AJFXI_cjs.AuthManager.verifyPassword(password, user.password_hash);
2359
+ const isValidPassword = await chunk4BJGEGX5_cjs.AuthManager.verifyPassword(password, user.password_hash);
2359
2360
  if (!isValidPassword) {
2360
2361
  return c.html(html.html`
2361
2362
  <div class="bg-red-100 border border-red-400 text-red-700 px-4 py-3 rounded">
@@ -2363,7 +2364,7 @@ authRoutes.post("/login/form", async (c) => {
2363
2364
  </div>
2364
2365
  `);
2365
2366
  }
2366
- const token = await chunkKM4AJFXI_cjs.AuthManager.generateToken(user.id, user.email, user.role);
2367
+ const token = await chunk4BJGEGX5_cjs.AuthManager.generateToken(user.id, user.email, user.role);
2367
2368
  cookie.setCookie(c, "auth_token", token, {
2368
2369
  httpOnly: true,
2369
2370
  secure: false,
@@ -2432,7 +2433,7 @@ authRoutes.post("/seed-admin", async (c) => {
2432
2433
  }
2433
2434
  });
2434
2435
  }
2435
- const passwordHash = await chunkKM4AJFXI_cjs.AuthManager.hashPassword("admin123");
2436
+ const passwordHash = await chunk4BJGEGX5_cjs.AuthManager.hashPassword("admin123");
2436
2437
  const userId = "admin-user-id";
2437
2438
  const now = Date.now();
2438
2439
  const adminEmail = "admin@sonicjs.com".toLowerCase();
@@ -2652,7 +2653,7 @@ authRoutes.post("/accept-invitation", async (c) => {
2652
2653
  if (existingUsername) {
2653
2654
  return c.json({ error: "Username is already taken" }, 400);
2654
2655
  }
2655
- const passwordHash = await chunkKM4AJFXI_cjs.AuthManager.hashPassword(password);
2656
+ const passwordHash = await chunk4BJGEGX5_cjs.AuthManager.hashPassword(password);
2656
2657
  const updateStmt = db.prepare(`
2657
2658
  UPDATE users SET
2658
2659
  username = ?,
@@ -2671,7 +2672,7 @@ authRoutes.post("/accept-invitation", async (c) => {
2671
2672
  Date.now(),
2672
2673
  invitedUser.id
2673
2674
  ).run();
2674
- const authToken = await chunkKM4AJFXI_cjs.AuthManager.generateToken(invitedUser.id, invitedUser.email, invitedUser.role);
2675
+ const authToken = await chunk4BJGEGX5_cjs.AuthManager.generateToken(invitedUser.id, invitedUser.email, invitedUser.role);
2675
2676
  cookie.setCookie(c, "auth_token", authToken, {
2676
2677
  httpOnly: true,
2677
2678
  secure: true,
@@ -2901,7 +2902,7 @@ authRoutes.post("/reset-password", async (c) => {
2901
2902
  if (Date.now() > user.password_reset_expires) {
2902
2903
  return c.json({ error: "Reset token has expired" }, 400);
2903
2904
  }
2904
- const newPasswordHash = await chunkKM4AJFXI_cjs.AuthManager.hashPassword(password);
2905
+ const newPasswordHash = await chunk4BJGEGX5_cjs.AuthManager.hashPassword(password);
2905
2906
  try {
2906
2907
  const historyStmt = db.prepare(`
2907
2908
  INSERT INTO password_history (id, user_id, password_hash, created_at)
@@ -4706,8 +4707,9 @@ var isPluginActive2 = () => false;
4706
4707
 
4707
4708
  // src/routes/admin-content.ts
4708
4709
  var adminContentRoutes = new hono.Hono();
4710
+ adminContentRoutes.use("*", chunk4BJGEGX5_cjs.requireAuth());
4709
4711
  async function getCollectionFields(db, collectionId) {
4710
- const cache = chunkSRCY43RN_cjs.getCacheService(chunkSRCY43RN_cjs.CACHE_CONFIGS.collection);
4712
+ const cache = chunk3NVJ6W27_cjs.getCacheService(chunk3NVJ6W27_cjs.CACHE_CONFIGS.collection);
4711
4713
  return cache.getOrSet(
4712
4714
  cache.generateKey("fields", collectionId),
4713
4715
  async () => {
@@ -4731,7 +4733,7 @@ async function getCollectionFields(db, collectionId) {
4731
4733
  );
4732
4734
  }
4733
4735
  async function getCollection(db, collectionId) {
4734
- const cache = chunkSRCY43RN_cjs.getCacheService(chunkSRCY43RN_cjs.CACHE_CONFIGS.collection);
4736
+ const cache = chunk3NVJ6W27_cjs.getCacheService(chunk3NVJ6W27_cjs.CACHE_CONFIGS.collection);
4735
4737
  return cache.getOrSet(
4736
4738
  cache.generateKey("collection", collectionId),
4737
4739
  async () => {
@@ -4987,7 +4989,7 @@ adminContentRoutes.get("/:id/edit", async (c) => {
4987
4989
  const db = c.env.DB;
4988
4990
  const url = new URL(c.req.url);
4989
4991
  const referrerParams = url.searchParams.get("ref") || "";
4990
- const cache = chunkSRCY43RN_cjs.getCacheService(chunkSRCY43RN_cjs.CACHE_CONFIGS.content);
4992
+ const cache = chunk3NVJ6W27_cjs.getCacheService(chunk3NVJ6W27_cjs.CACHE_CONFIGS.content);
4991
4993
  const content = await cache.getOrSet(
4992
4994
  cache.generateKey("content", id),
4993
4995
  async () => {
@@ -5177,7 +5179,7 @@ adminContentRoutes.post("/", async (c) => {
5177
5179
  now,
5178
5180
  now
5179
5181
  ).run();
5180
- const cache = chunkSRCY43RN_cjs.getCacheService(chunkSRCY43RN_cjs.CACHE_CONFIGS.content);
5182
+ const cache = chunk3NVJ6W27_cjs.getCacheService(chunk3NVJ6W27_cjs.CACHE_CONFIGS.content);
5181
5183
  await cache.invalidate(`content:list:${collectionId}:*`);
5182
5184
  const versionStmt = db.prepare(`
5183
5185
  INSERT INTO content_versions (id, content_id, version, data, author_id, created_at)
@@ -5325,7 +5327,7 @@ adminContentRoutes.put("/:id", async (c) => {
5325
5327
  now,
5326
5328
  id
5327
5329
  ).run();
5328
- const cache = chunkSRCY43RN_cjs.getCacheService(chunkSRCY43RN_cjs.CACHE_CONFIGS.content);
5330
+ const cache = chunk3NVJ6W27_cjs.getCacheService(chunk3NVJ6W27_cjs.CACHE_CONFIGS.content);
5329
5331
  await cache.delete(cache.generateKey("content", id));
5330
5332
  await cache.invalidate(`content:list:${existingContent.collection_id}:*`);
5331
5333
  const existingData = JSON.parse(existingContent.data || "{}");
@@ -5618,7 +5620,7 @@ adminContentRoutes.post("/bulk-action", async (c) => {
5618
5620
  } else {
5619
5621
  return c.json({ success: false, error: "Invalid action" });
5620
5622
  }
5621
- const cache = chunkSRCY43RN_cjs.getCacheService(chunkSRCY43RN_cjs.CACHE_CONFIGS.content);
5623
+ const cache = chunk3NVJ6W27_cjs.getCacheService(chunk3NVJ6W27_cjs.CACHE_CONFIGS.content);
5622
5624
  for (const contentId of ids) {
5623
5625
  await cache.delete(cache.generateKey("content", contentId));
5624
5626
  }
@@ -5646,7 +5648,7 @@ adminContentRoutes.delete("/:id", async (c) => {
5646
5648
  WHERE id = ?
5647
5649
  `);
5648
5650
  await deleteStmt.bind(now, id).run();
5649
- const cache = chunkSRCY43RN_cjs.getCacheService(chunkSRCY43RN_cjs.CACHE_CONFIGS.content);
5651
+ const cache = chunk3NVJ6W27_cjs.getCacheService(chunk3NVJ6W27_cjs.CACHE_CONFIGS.content);
5650
5652
  await cache.delete(cache.generateKey("content", id));
5651
5653
  await cache.invalidate("content:list:*");
5652
5654
  return c.html(`
@@ -5838,170 +5840,157 @@ ${JSON.stringify(data, null, 2)}
5838
5840
  var admin_content_default = adminContentRoutes;
5839
5841
 
5840
5842
  // src/templates/pages/admin-profile.template.ts
5843
+ chunkALOS2CBJ_cjs.init_admin_layout_catalyst_template();
5841
5844
  function renderProfilePage(data) {
5842
5845
  const pageContent = `
5843
- <div class="w-full px-4 sm:px-6 lg:px-8 py-6">
5846
+ <div class="space-y-8">
5844
5847
  <!-- Header -->
5845
- <div class="flex flex-col sm:flex-row sm:items-center sm:justify-between mb-6">
5848
+ <div class="sm:flex sm:items-center sm:justify-between">
5846
5849
  <div>
5847
- <h1 class="text-2xl font-semibold text-white">User Profile</h1>
5848
- <p class="mt-2 text-sm text-gray-300">Manage your account settings and preferences</p>
5850
+ <h1 class="text-2xl/8 font-semibold text-zinc-950 dark:text-white sm:text-xl/8">User Profile</h1>
5851
+ <p class="mt-2 text-sm/6 text-zinc-500 dark:text-zinc-400">
5852
+ Manage your account settings and preferences
5853
+ </p>
5849
5854
  </div>
5850
5855
  </div>
5851
5856
 
5852
- <!-- Breadcrumb -->
5853
- <nav class="flex mb-6" aria-label="Breadcrumb">
5854
- <ol class="flex items-center space-x-3">
5855
- <li>
5856
- <a href="/admin" class="text-gray-300 hover:text-white transition-colors">
5857
- <svg class="h-5 w-5" fill="currentColor" viewBox="0 0 20 20">
5858
- <path d="M10.707 2.293a1 1 0 00-1.414 0l-7 7a1 1 0 001.414 1.414L4 10.414V17a1 1 0 001 1h2a1 1 0 001-1v-2a1 1 0 011-1h2a1 1 0 011 1v2a1 1 0 001 1h2a1 1 0 001-1v-6.586l.293.293a1 1 0 001.414-1.414l-7-7z"/>
5859
- </svg>
5860
- </a>
5861
- </li>
5862
- <li class="flex items-center">
5863
- <svg class="h-5 w-5 text-gray-400 mx-2" fill="currentColor" viewBox="0 0 20 20">
5864
- <path fill-rule="evenodd" d="M7.293 14.707a1 1 0 010-1.414L10.586 10 7.293 6.707a1 1 0 011.414-1.414l4 4a1 1 0 010 1.414l-4 4a1 1 0 01-1.414 0z" clip-rule="evenodd"/>
5865
- </svg>
5866
- <span class="text-sm font-medium text-gray-200">Profile</span>
5867
- </li>
5868
- </ol>
5869
- </nav>
5870
-
5871
5857
  <!-- Alert Messages -->
5872
5858
  ${data.error ? chunkALOS2CBJ_cjs.renderAlert({ type: "error", message: data.error, dismissible: true }) : ""}
5873
5859
  ${data.success ? chunkALOS2CBJ_cjs.renderAlert({ type: "success", message: data.success, dismissible: true }) : ""}
5874
5860
 
5875
5861
  <!-- Profile Form -->
5876
- <div class="grid grid-cols-1 lg:grid-cols-3 gap-6">
5862
+ <div class="grid grid-cols-1 lg:grid-cols-3 gap-8">
5877
5863
  <!-- Main Profile Form -->
5878
5864
  <div class="lg:col-span-2">
5879
- <div class="backdrop-blur-xl bg-white/10 rounded-3xl border border-white/20 shadow-2xl overflow-hidden">
5865
+ <div class="rounded-xl bg-white dark:bg-zinc-900 shadow-sm ring-1 ring-zinc-950/5 dark:ring-white/10">
5880
5866
  <!-- Form Header -->
5881
- <div class="relative px-8 py-6 border-b border-white/10">
5882
- <div class="absolute inset-0 bg-gradient-to-r from-blue-600/10 via-purple-600/10 to-pink-600/10"></div>
5883
- <div class="relative flex items-center gap-3">
5884
- <div class="w-12 h-12 rounded-xl bg-white/10 backdrop-blur-sm flex items-center justify-center">
5885
- <svg class="w-6 h-6 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24">
5867
+ <div class="px-6 py-5 border-b border-zinc-950/5 dark:border-white/5">
5868
+ <div class="flex items-center gap-x-3">
5869
+ <div class="flex h-10 w-10 items-center justify-center rounded-lg bg-zinc-950 dark:bg-white">
5870
+ <svg class="h-5 w-5 text-white dark:text-zinc-950" fill="none" stroke="currentColor" viewBox="0 0 24 24">
5886
5871
  <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M16 7a4 4 0 11-8 0 4 4 0 018 0zM12 14a7 7 0 00-7 7h14a7 7 0 00-7-7z"/>
5887
5872
  </svg>
5888
5873
  </div>
5889
5874
  <div>
5890
- <h2 class="text-xl font-semibold text-white">Profile Information</h2>
5891
- <p class="text-sm text-gray-300">Update your account details and preferences</p>
5875
+ <h2 class="text-base font-semibold text-zinc-950 dark:text-white">Profile Information</h2>
5876
+ <p class="text-sm text-zinc-500 dark:text-zinc-400">Update your account details</p>
5892
5877
  </div>
5893
5878
  </div>
5894
5879
  </div>
5895
5880
 
5896
5881
  <!-- Form Content -->
5897
- <form id="profile-form" hx-put="/admin/profile" hx-target="#form-messages" class="p-8 space-y-6">
5882
+ <form id="profile-form" hx-put="/admin/profile" hx-target="#form-messages" class="p-6 space-y-6">
5898
5883
  <div id="form-messages"></div>
5899
5884
 
5900
5885
  <!-- Basic Information -->
5901
5886
  <div class="grid grid-cols-1 md:grid-cols-2 gap-6">
5902
5887
  <div>
5903
- <label class="block text-sm font-medium text-gray-300 mb-2">First Name</label>
5904
- <input
5905
- type="text"
5906
- name="first_name"
5888
+ <label class="block text-sm font-medium text-zinc-950 dark:text-white mb-2">First Name</label>
5889
+ <input
5890
+ type="text"
5891
+ name="first_name"
5907
5892
  value="${data.profile.first_name}"
5908
5893
  required
5909
- class="w-full px-4 py-3 bg-white/5 backdrop-blur-sm border border-white/10 rounded-xl text-white focus:outline-none focus:bg-white/10 focus:border-white/30 focus:ring-2 focus:ring-white/20 transition-all"
5894
+ class="w-full rounded-lg bg-white dark:bg-zinc-800 px-3 py-2 text-sm text-zinc-950 dark:text-white shadow-sm ring-1 ring-inset ring-zinc-950/10 dark:ring-white/10 placeholder:text-zinc-400 dark:placeholder:text-zinc-500 focus:outline-none focus:ring-2 focus:ring-zinc-950 dark:focus:ring-white transition-shadow"
5910
5895
  placeholder="Enter your first name"
5911
5896
  >
5912
5897
  </div>
5913
5898
  <div>
5914
- <label class="block text-sm font-medium text-gray-300 mb-2">Last Name</label>
5915
- <input
5916
- type="text"
5917
- name="last_name"
5899
+ <label class="block text-sm font-medium text-zinc-950 dark:text-white mb-2">Last Name</label>
5900
+ <input
5901
+ type="text"
5902
+ name="last_name"
5918
5903
  value="${data.profile.last_name}"
5919
5904
  required
5920
- class="w-full px-4 py-3 bg-white/5 backdrop-blur-sm border border-white/10 rounded-xl text-white focus:outline-none focus:bg-white/10 focus:border-white/30 focus:ring-2 focus:ring-white/20 transition-all"
5905
+ class="w-full rounded-lg bg-white dark:bg-zinc-800 px-3 py-2 text-sm text-zinc-950 dark:text-white shadow-sm ring-1 ring-inset ring-zinc-950/10 dark:ring-white/10 placeholder:text-zinc-400 dark:placeholder:text-zinc-500 focus:outline-none focus:ring-2 focus:ring-zinc-950 dark:focus:ring-white transition-shadow"
5921
5906
  placeholder="Enter your last name"
5922
5907
  >
5923
5908
  </div>
5924
5909
  </div>
5925
5910
 
5926
5911
  <div>
5927
- <label class="block text-sm font-medium text-gray-300 mb-2">Username</label>
5928
- <input
5929
- type="text"
5930
- name="username"
5912
+ <label class="block text-sm font-medium text-zinc-950 dark:text-white mb-2">Username</label>
5913
+ <input
5914
+ type="text"
5915
+ name="username"
5931
5916
  value="${data.profile.username}"
5932
5917
  required
5933
- class="w-full px-4 py-3 bg-white/5 backdrop-blur-sm border border-white/10 rounded-xl text-white focus:outline-none focus:bg-white/10 focus:border-white/30 focus:ring-2 focus:ring-white/20 transition-all"
5918
+ class="w-full rounded-lg bg-white dark:bg-zinc-800 px-3 py-2 text-sm text-zinc-950 dark:text-white shadow-sm ring-1 ring-inset ring-zinc-950/10 dark:ring-white/10 placeholder:text-zinc-400 dark:placeholder:text-zinc-500 focus:outline-none focus:ring-2 focus:ring-zinc-950 dark:focus:ring-white transition-shadow"
5934
5919
  placeholder="Enter your username"
5935
5920
  >
5936
5921
  </div>
5937
5922
 
5938
5923
  <div>
5939
- <label class="block text-sm font-medium text-gray-300 mb-2">Email Address</label>
5940
- <input
5941
- type="email"
5942
- name="email"
5924
+ <label class="block text-sm font-medium text-zinc-950 dark:text-white mb-2">Email Address</label>
5925
+ <input
5926
+ type="email"
5927
+ name="email"
5943
5928
  value="${data.profile.email}"
5944
5929
  required
5945
- class="w-full px-4 py-3 bg-white/5 backdrop-blur-sm border border-white/10 rounded-xl text-white focus:outline-none focus:bg-white/10 focus:border-white/30 focus:ring-2 focus:ring-white/20 transition-all"
5930
+ class="w-full rounded-lg bg-white dark:bg-zinc-800 px-3 py-2 text-sm text-zinc-950 dark:text-white shadow-sm ring-1 ring-inset ring-zinc-950/10 dark:ring-white/10 placeholder:text-zinc-400 dark:placeholder:text-zinc-500 focus:outline-none focus:ring-2 focus:ring-zinc-950 dark:focus:ring-white transition-shadow"
5946
5931
  placeholder="Enter your email address"
5947
5932
  >
5948
5933
  </div>
5949
5934
 
5950
5935
  <div>
5951
- <label class="block text-sm font-medium text-gray-300 mb-2">Phone Number</label>
5952
- <input
5953
- type="tel"
5954
- name="phone"
5936
+ <label class="block text-sm font-medium text-zinc-950 dark:text-white mb-2">Phone Number</label>
5937
+ <input
5938
+ type="tel"
5939
+ name="phone"
5955
5940
  value="${data.profile.phone || ""}"
5956
- class="w-full px-4 py-3 bg-white/5 backdrop-blur-sm border border-white/10 rounded-xl text-white focus:outline-none focus:bg-white/10 focus:border-white/30 focus:ring-2 focus:ring-white/20 transition-all"
5941
+ class="w-full rounded-lg bg-white dark:bg-zinc-800 px-3 py-2 text-sm text-zinc-950 dark:text-white shadow-sm ring-1 ring-inset ring-zinc-950/10 dark:ring-white/10 placeholder:text-zinc-400 dark:placeholder:text-zinc-500 focus:outline-none focus:ring-2 focus:ring-zinc-950 dark:focus:ring-white transition-shadow"
5957
5942
  placeholder="Enter your phone number"
5958
5943
  >
5959
5944
  </div>
5960
5945
 
5961
5946
  <div>
5962
- <label class="block text-sm font-medium text-gray-300 mb-2">Bio</label>
5963
- <textarea
5964
- name="bio"
5947
+ <label class="block text-sm font-medium text-zinc-950 dark:text-white mb-2">Bio</label>
5948
+ <textarea
5949
+ name="bio"
5965
5950
  rows="3"
5966
- class="w-full px-4 py-3 bg-white/5 backdrop-blur-sm border border-white/10 rounded-xl text-white focus:outline-none focus:bg-white/10 focus:border-white/30 focus:ring-2 focus:ring-white/20 transition-all resize-none"
5951
+ class="w-full rounded-lg bg-white dark:bg-zinc-800 px-3 py-2 text-sm text-zinc-950 dark:text-white shadow-sm ring-1 ring-inset ring-zinc-950/10 dark:ring-white/10 placeholder:text-zinc-400 dark:placeholder:text-zinc-500 focus:outline-none focus:ring-2 focus:ring-zinc-950 dark:focus:ring-white transition-shadow resize-none"
5967
5952
  placeholder="Tell us about yourself..."
5968
5953
  >${data.profile.bio || ""}</textarea>
5969
5954
  </div>
5970
5955
 
5971
5956
  <!-- Preferences -->
5972
- <div class="pt-6 border-t border-white/10">
5973
- <h3 class="text-lg font-semibold text-white mb-4">Preferences</h3>
5974
-
5957
+ <div class="pt-6 border-t border-zinc-950/5 dark:border-white/5">
5958
+ <h3 class="text-base font-semibold text-zinc-950 dark:text-white mb-4">Preferences</h3>
5959
+
5975
5960
  <div class="grid grid-cols-1 md:grid-cols-2 gap-6">
5976
5961
  <div>
5977
- <label class="block text-sm font-medium text-gray-300 mb-2">Timezone</label>
5978
- <select
5979
- name="timezone"
5980
- class="w-full px-4 py-3 bg-white/5 backdrop-blur-sm border border-white/10 rounded-xl text-white focus:outline-none focus:bg-white/10 focus:border-white/30 focus:ring-2 focus:ring-white/20 transition-all"
5981
- >
5982
- ${data.timezones.map((tz) => `
5983
- <option value="${tz.value}" ${tz.value === data.profile.timezone ? "selected" : ""}>${tz.label}</option>
5984
- `).join("")}
5985
- </select>
5962
+ <label for="timezone" class="block text-sm/6 font-medium text-zinc-950 dark:text-white mb-2">Timezone</label>
5963
+ <div class="grid grid-cols-1">
5964
+ <select id="timezone" name="timezone" class="col-start-1 row-start-1 w-full appearance-none rounded-md bg-white/5 dark:bg-white/5 py-1.5 pl-3 pr-8 text-base text-zinc-950 dark:text-white outline outline-1 -outline-offset-1 outline-zinc-500/30 dark:outline-zinc-400/30 *:bg-white dark:*:bg-zinc-800 focus-visible:outline focus-visible:outline-2 focus-visible:-outline-offset-2 focus-visible:outline-zinc-500 dark:focus-visible:outline-zinc-400 sm:text-sm/6">
5965
+ ${data.timezones.map((tz) => `
5966
+ <option value="${tz.value}" ${tz.value === data.profile.timezone ? "selected" : ""}>${tz.label}</option>
5967
+ `).join("")}
5968
+ </select>
5969
+ <svg viewBox="0 0 16 16" fill="currentColor" aria-hidden="true" class="pointer-events-none col-start-1 row-start-1 mr-2 size-5 self-center justify-self-end text-zinc-600 dark:text-zinc-400 sm:size-4">
5970
+ <path d="M4.22 6.22a.75.75 0 0 1 1.06 0L8 8.94l2.72-2.72a.75.75 0 1 1 1.06 1.06l-3.25 3.25a.75.75 0 0 1-1.06 0L4.22 7.28a.75.75 0 0 1 0-1.06Z" clip-rule="evenodd" fill-rule="evenodd" />
5971
+ </svg>
5972
+ </div>
5986
5973
  </div>
5987
5974
  <div>
5988
- <label class="block text-sm font-medium text-gray-300 mb-2">Language</label>
5989
- <select
5990
- name="language"
5991
- class="w-full px-4 py-3 bg-white/5 backdrop-blur-sm border border-white/10 rounded-xl text-white focus:outline-none focus:bg-white/10 focus:border-white/30 focus:ring-2 focus:ring-white/20 transition-all"
5992
- >
5993
- ${data.languages.map((lang) => `
5994
- <option value="${lang.value}" ${lang.value === data.profile.language ? "selected" : ""}>${lang.label}</option>
5995
- `).join("")}
5996
- </select>
5975
+ <label for="language" class="block text-sm/6 font-medium text-zinc-950 dark:text-white mb-2">Language</label>
5976
+ <div class="grid grid-cols-1">
5977
+ <select id="language" name="language" class="col-start-1 row-start-1 w-full appearance-none rounded-md bg-white/5 dark:bg-white/5 py-1.5 pl-3 pr-8 text-base text-zinc-950 dark:text-white outline outline-1 -outline-offset-1 outline-zinc-500/30 dark:outline-zinc-400/30 *:bg-white dark:*:bg-zinc-800 focus-visible:outline focus-visible:outline-2 focus-visible:-outline-offset-2 focus-visible:outline-zinc-500 dark:focus-visible:outline-zinc-400 sm:text-sm/6">
5978
+ ${data.languages.map((lang) => `
5979
+ <option value="${lang.value}" ${lang.value === data.profile.language ? "selected" : ""}>${lang.label}</option>
5980
+ `).join("")}
5981
+ </select>
5982
+ <svg viewBox="0 0 16 16" fill="currentColor" aria-hidden="true" class="pointer-events-none col-start-1 row-start-1 mr-2 size-5 self-center justify-self-end text-zinc-600 dark:text-zinc-400 sm:size-4">
5983
+ <path d="M4.22 6.22a.75.75 0 0 1 1.06 0L8 8.94l2.72-2.72a.75.75 0 1 1 1.06 1.06l-3.25 3.25a.75.75 0 0 1-1.06 0L4.22 7.28a.75.75 0 0 1 0-1.06Z" clip-rule="evenodd" fill-rule="evenodd" />
5984
+ </svg>
5985
+ </div>
5997
5986
  </div>
5998
5987
  </div>
5999
5988
  </div>
6000
5989
 
6001
5990
  <!-- Notifications -->
6002
- <div class="pt-6 border-t border-white/10">
6003
- <h3 class="text-lg font-semibold text-white mb-4">Notifications</h3>
6004
-
5991
+ <div class="pt-6 border-t border-zinc-950/5 dark:border-white/5">
5992
+ <h3 class="text-base font-semibold text-zinc-950 dark:text-white mb-4">Notifications</h3>
5993
+
6005
5994
  <div class="space-y-5">
6006
5995
  <div class="flex gap-3">
6007
5996
  <div class="flex h-6 shrink-0 items-center">
@@ -6012,27 +6001,30 @@ function renderProfilePage(data) {
6012
6001
  name="email_notifications"
6013
6002
  value="1"
6014
6003
  ${data.profile.email_notifications ? "checked" : ""}
6015
- class="col-start-1 row-start-1 appearance-none rounded border border-zinc-950/10 dark:border-white/10 bg-white dark:bg-white/5 checked:border-indigo-500 checked:bg-indigo-500 indeterminate:border-indigo-500 indeterminate:bg-indigo-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-indigo-500 disabled:border-zinc-950/5 dark:disabled:border-white/5 disabled:bg-zinc-950/10 dark:disabled:bg-white/10 disabled:checked:bg-zinc-950/10 dark:disabled:checked:bg-white/10 forced-colors:appearance-auto"
6004
+ class="col-start-1 row-start-1 appearance-none rounded border border-zinc-950/10 dark:border-white/10 bg-white dark:bg-white/5 checked:border-indigo-500 checked:bg-indigo-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-indigo-500 disabled:border-zinc-950/5 dark:disabled:border-white/5 disabled:bg-zinc-950/10 dark:disabled:bg-white/10 forced-colors:appearance-auto"
6016
6005
  />
6017
6006
  <svg viewBox="0 0 14 14" fill="none" class="pointer-events-none col-start-1 row-start-1 size-3.5 self-center justify-self-center stroke-white group-has-[:disabled]:stroke-zinc-950/25 dark:group-has-[:disabled]:stroke-white/25">
6018
6007
  <path d="M3 8L6 11L11 3.5" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="opacity-0 group-has-[:checked]:opacity-100" />
6019
- <path d="M3 7H11" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="opacity-0 group-has-[:indeterminate]:opacity-100" />
6020
6008
  </svg>
6021
6009
  </div>
6022
6010
  </div>
6023
6011
  <div class="text-sm/6">
6024
6012
  <label for="email_notifications" class="font-medium text-zinc-950 dark:text-white">Email notifications</label>
6013
+ <p class="text-zinc-500 dark:text-zinc-400">Receive email updates about new features and product announcements.</p>
6025
6014
  </div>
6026
6015
  </div>
6027
6016
  </div>
6028
6017
  </div>
6029
6018
 
6030
6019
  <!-- Submit Button -->
6031
- <div class="pt-6 border-t border-white/10">
6032
- <button
6020
+ <div class="pt-6 border-t border-zinc-950/5 dark:border-white/5">
6021
+ <button
6033
6022
  type="submit"
6034
- class="w-full px-6 py-3 bg-gradient-to-r from-blue-600 to-purple-600 text-white font-semibold rounded-xl hover:from-blue-700 hover:to-purple-700 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2 focus:ring-offset-transparent transition-all"
6023
+ class="inline-flex justify-center items-center gap-x-2 rounded-lg bg-zinc-950 dark:bg-white px-4 py-2.5 text-sm font-semibold text-white dark:text-zinc-950 hover:bg-zinc-800 dark:hover:bg-zinc-100 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-zinc-950 dark:focus-visible:outline-white transition-colors"
6035
6024
  >
6025
+ <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
6026
+ <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7"/>
6027
+ </svg>
6036
6028
  Update Profile
6037
6029
  </button>
6038
6030
  </div>
@@ -6043,86 +6035,96 @@ function renderProfilePage(data) {
6043
6035
  <!-- Profile Sidebar -->
6044
6036
  <div class="lg:col-span-1 space-y-6">
6045
6037
  <!-- Avatar -->
6046
- <div class="backdrop-blur-xl bg-white/10 rounded-xl border border-white/20 shadow-2xl p-6">
6047
- <h3 class="text-lg font-semibold text-white mb-4">Profile Picture</h3>
6048
-
6038
+ <div class="rounded-xl bg-white dark:bg-zinc-900 shadow-sm ring-1 ring-zinc-950/5 dark:ring-white/10 p-6">
6039
+ <h3 class="text-base font-semibold text-zinc-950 dark:text-white mb-4">Profile Picture</h3>
6040
+
6049
6041
  <div class="text-center">
6050
- <div class="w-24 h-24 rounded-full mx-auto mb-4 overflow-hidden bg-gradient-to-br from-blue-500 to-purple-600 flex items-center justify-center">
6042
+ <div class="w-24 h-24 rounded-full mx-auto mb-4 overflow-hidden bg-gradient-to-br from-cyan-400 to-purple-400 flex items-center justify-center ring-4 ring-zinc-950/5 dark:ring-white/10">
6051
6043
  ${data.profile.avatar_url ? `<img src="${data.profile.avatar_url}" alt="Profile picture" class="w-full h-full object-cover">` : `<span class="text-2xl font-bold text-white">${data.profile.first_name.charAt(0)}${data.profile.last_name.charAt(0)}</span>`}
6052
6044
  </div>
6053
-
6045
+
6054
6046
  <form id="avatar-form" hx-post="/admin/profile/avatar" hx-target="#avatar-messages" hx-encoding="multipart/form-data">
6055
- <input
6056
- type="file"
6057
- name="avatar"
6047
+ <input
6048
+ type="file"
6049
+ name="avatar"
6058
6050
  accept="image/*"
6059
6051
  class="hidden"
6060
6052
  id="avatar-input"
6061
6053
  onchange="document.getElementById('avatar-form').dispatchEvent(new Event('submit'))"
6062
6054
  >
6063
- <label
6055
+ <label
6064
6056
  for="avatar-input"
6065
- class="inline-block px-4 py-2 bg-white/10 text-white rounded-xl border border-white/20 hover:bg-white/20 transition-all cursor-pointer"
6057
+ class="inline-flex items-center gap-x-2 rounded-lg bg-white dark:bg-zinc-800 px-4 py-2.5 text-sm font-semibold text-zinc-950 dark:text-white shadow-sm ring-1 ring-inset ring-zinc-950/10 dark:ring-white/10 hover:bg-zinc-50 dark:hover:bg-zinc-700 transition-colors cursor-pointer"
6066
6058
  >
6059
+ <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
6060
+ <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M3 9a2 2 0 012-2h.93a2 2 0 001.664-.89l.812-1.22A2 2 0 0110.07 4h3.86a2 2 0 011.664.89l.812 1.22A2 2 0 0018.07 7H19a2 2 0 012 2v9a2 2 0 01-2 2H5a2 2 0 01-2-2V9z"/>
6061
+ <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 13a3 3 0 11-6 0 3 3 0 016 0z"/>
6062
+ </svg>
6067
6063
  Change Picture
6068
6064
  </label>
6069
6065
  </form>
6070
-
6066
+
6071
6067
  <div id="avatar-messages" class="mt-3"></div>
6072
6068
  </div>
6073
6069
  </div>
6074
6070
 
6075
6071
  <!-- Account Info -->
6076
- <div class="backdrop-blur-xl bg-white/10 rounded-xl border border-white/20 shadow-2xl p-6">
6077
- <h3 class="text-lg font-semibold text-white mb-4">Account Information</h3>
6078
-
6079
- <div class="space-y-3 text-sm">
6072
+ <div class="rounded-xl bg-white dark:bg-zinc-900 shadow-sm ring-1 ring-zinc-950/5 dark:ring-white/10 p-6">
6073
+ <h3 class="text-base font-semibold text-zinc-950 dark:text-white mb-4">Account Information</h3>
6074
+
6075
+ <dl class="space-y-3 text-sm">
6080
6076
  <div>
6081
- <span class="text-gray-400">Role:</span>
6082
- <span class="text-white ml-2 capitalize">${data.profile.role}</span>
6077
+ <dt class="text-zinc-500 dark:text-zinc-400">Role</dt>
6078
+ <dd class="mt-1">
6079
+ <span class="inline-flex items-center rounded-md bg-blue-50 dark:bg-blue-500/10 px-2 py-1 text-xs font-medium text-blue-700 dark:text-blue-400 ring-1 ring-inset ring-blue-700/10 dark:ring-blue-400/20 capitalize">
6080
+ ${data.profile.role}
6081
+ </span>
6082
+ </dd>
6083
6083
  </div>
6084
6084
  <div>
6085
- <span class="text-gray-400">Member Since:</span>
6086
- <span class="text-white ml-2">${new Date(data.profile.created_at).toLocaleDateString()}</span>
6085
+ <dt class="text-zinc-500 dark:text-zinc-400">Member Since</dt>
6086
+ <dd class="mt-1 text-zinc-950 dark:text-white">${new Date(data.profile.created_at).toLocaleDateString()}</dd>
6087
6087
  </div>
6088
6088
  ${data.profile.last_login_at ? `
6089
6089
  <div>
6090
- <span class="text-gray-400">Last Login:</span>
6091
- <span class="text-white ml-2">${new Date(data.profile.last_login_at).toLocaleDateString()}</span>
6090
+ <dt class="text-zinc-500 dark:text-zinc-400">Last Login</dt>
6091
+ <dd class="mt-1 text-zinc-950 dark:text-white">${new Date(data.profile.last_login_at).toLocaleDateString()}</dd>
6092
6092
  </div>
6093
6093
  ` : ""}
6094
6094
  <div>
6095
- <span class="text-gray-400">Two-Factor Auth:</span>
6096
- <span class="text-white ml-2">${data.profile.two_factor_enabled ? "Enabled" : "Disabled"}</span>
6095
+ <dt class="text-zinc-500 dark:text-zinc-400">Two-Factor Auth</dt>
6096
+ <dd class="mt-1">
6097
+ ${data.profile.two_factor_enabled ? '<span class="inline-flex items-center rounded-md bg-green-50 dark:bg-green-500/10 px-2 py-1 text-xs font-medium text-green-700 dark:text-green-400 ring-1 ring-inset ring-green-600/20 dark:ring-green-500/20">Enabled</span>' : '<span class="inline-flex items-center rounded-md bg-zinc-50 dark:bg-zinc-800 px-2 py-1 text-xs font-medium text-zinc-600 dark:text-zinc-400 ring-1 ring-inset ring-zinc-500/10 dark:ring-zinc-400/20">Disabled</span>'}
6098
+ </dd>
6097
6099
  </div>
6098
- </div>
6100
+ </dl>
6099
6101
  </div>
6100
6102
 
6101
6103
  <!-- Security Actions -->
6102
- <div class="backdrop-blur-xl bg-white/10 rounded-xl border border-white/20 shadow-2xl p-6">
6103
- <h3 class="text-lg font-semibold text-white mb-4">Security</h3>
6104
-
6105
- <div class="space-y-3">
6106
- <button
6104
+ <div class="rounded-xl bg-white dark:bg-zinc-900 shadow-sm ring-1 ring-zinc-950/5 dark:ring-white/10 p-6">
6105
+ <h3 class="text-base font-semibold text-zinc-950 dark:text-white mb-4">Security</h3>
6106
+
6107
+ <div class="space-y-2">
6108
+ <button
6107
6109
  type="button"
6108
6110
  onclick="showChangePasswordModal()"
6109
- class="w-full text-left px-3 py-2 text-sm text-gray-300 hover:text-white hover:bg-white/10 rounded-xl transition-all"
6111
+ class="w-full text-left flex items-center gap-x-3 px-3 py-2 text-sm text-zinc-950 dark:text-white hover:bg-zinc-50 dark:hover:bg-zinc-800/50 rounded-lg transition-colors"
6110
6112
  >
6111
- <svg class="w-4 h-4 inline mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
6113
+ <svg class="w-4 h-4 text-zinc-500 dark:text-zinc-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
6112
6114
  <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 7a2 2 0 012 2m4 0a6 6 0 01-7.743 5.743L11 17H9v2H7v2H4a1 1 0 01-1-1v-3.586l4.293-4.293A6 6 0 0119 9z"/>
6113
6115
  </svg>
6114
- Change Password
6116
+ <span class="font-medium">Change Password</span>
6115
6117
  </button>
6116
-
6117
- <button
6118
+
6119
+ <button
6118
6120
  type="button"
6119
6121
  onclick="toggle2FA()"
6120
- class="w-full text-left px-3 py-2 text-sm text-gray-300 hover:text-white hover:bg-white/10 rounded-xl transition-all"
6122
+ class="w-full text-left flex items-center gap-x-3 px-3 py-2 text-sm text-zinc-950 dark:text-white hover:bg-zinc-50 dark:hover:bg-zinc-800/50 rounded-lg transition-colors"
6121
6123
  >
6122
- <svg class="w-4 h-4 inline mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
6124
+ <svg class="w-4 h-4 text-zinc-500 dark:text-zinc-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
6123
6125
  <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 15v2m-6 4h12a2 2 0 002-2v-6a2 2 0 00-2-2H6a2 2 0 00-2 2v6a2 2 0 002 2zm10-10V7a4 4 0 00-8 0v4h8z"/>
6124
6126
  </svg>
6125
- ${data.profile.two_factor_enabled ? "Disable" : "Enable"} 2FA
6127
+ <span class="font-medium">${data.profile.two_factor_enabled ? "Disable" : "Enable"} 2FA</span>
6126
6128
  </button>
6127
6129
  </div>
6128
6130
  </div>
@@ -6131,67 +6133,73 @@ function renderProfilePage(data) {
6131
6133
  </div>
6132
6134
 
6133
6135
  <!-- Change Password Modal -->
6134
- <div id="password-modal" class="fixed inset-0 bg-black/50 backdrop-blur-sm flex items-center justify-center z-50 hidden">
6135
- <div class="backdrop-blur-xl bg-white/10 rounded-xl border border-white/20 shadow-2xl w-full max-w-md mx-4">
6136
- <div class="relative px-6 py-4 border-b border-white/10">
6137
- <div class="absolute inset-0 bg-gradient-to-r from-blue-600/10 via-purple-600/10 to-pink-600/10"></div>
6138
- <div class="relative flex items-center justify-between">
6139
- <h3 class="text-lg font-semibold text-white">Change Password</h3>
6140
- <button onclick="closePasswordModal()" class="text-gray-300 hover:text-white">
6141
- <svg class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
6136
+ <div id="password-modal" class="fixed inset-0 bg-zinc-950/50 backdrop-blur-sm flex items-center justify-center z-50 hidden">
6137
+ <div class="rounded-xl bg-white dark:bg-zinc-900 shadow-2xl ring-1 ring-zinc-950/5 dark:ring-white/10 w-full max-w-md mx-4">
6138
+ <div class="px-6 py-5 border-b border-zinc-950/5 dark:border-white/5">
6139
+ <div class="flex items-center justify-between">
6140
+ <h3 class="text-base font-semibold text-zinc-950 dark:text-white">Change Password</h3>
6141
+ <button onclick="closePasswordModal()" class="text-zinc-500 dark:text-zinc-400 hover:text-zinc-950 dark:hover:text-white transition-colors">
6142
+ <svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
6142
6143
  <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12"></path>
6143
6144
  </svg>
6144
6145
  </button>
6145
6146
  </div>
6146
6147
  </div>
6147
-
6148
+
6148
6149
  <form id="password-form" hx-post="/admin/profile/password" hx-target="#password-messages" class="p-6 space-y-4">
6149
6150
  <div id="password-messages"></div>
6150
-
6151
+
6151
6152
  <div>
6152
- <label class="block text-sm font-medium text-gray-300 mb-2">Current Password</label>
6153
- <input
6154
- type="password"
6155
- name="current_password"
6153
+ <label class="block text-sm font-medium text-zinc-950 dark:text-white mb-2">Current Password</label>
6154
+ <input
6155
+ type="password"
6156
+ name="current_password"
6156
6157
  required
6157
- class="w-full px-4 py-3 bg-white/5 backdrop-blur-sm border border-white/10 rounded-xl text-white focus:outline-none focus:bg-white/10 focus:border-white/30 focus:ring-2 focus:ring-white/20 transition-all"
6158
+ class="w-full rounded-lg bg-white dark:bg-zinc-800 px-3 py-2 text-sm text-zinc-950 dark:text-white shadow-sm ring-1 ring-inset ring-zinc-950/10 dark:ring-white/10 placeholder:text-zinc-400 dark:placeholder:text-zinc-500 focus:outline-none focus:ring-2 focus:ring-zinc-950 dark:focus:ring-white transition-shadow"
6159
+ placeholder="Enter current password"
6158
6160
  >
6159
6161
  </div>
6160
6162
 
6161
6163
  <div>
6162
- <label class="block text-sm font-medium text-gray-300 mb-2">New Password</label>
6163
- <input
6164
- type="password"
6165
- name="new_password"
6164
+ <label class="block text-sm font-medium text-zinc-950 dark:text-white mb-2">New Password</label>
6165
+ <input
6166
+ type="password"
6167
+ name="new_password"
6166
6168
  required
6167
6169
  minlength="8"
6168
- class="w-full px-4 py-3 bg-white/5 backdrop-blur-sm border border-white/10 rounded-xl text-white focus:outline-none focus:bg-white/10 focus:border-white/30 focus:ring-2 focus:ring-white/20 transition-all"
6170
+ class="w-full rounded-lg bg-white dark:bg-zinc-800 px-3 py-2 text-sm text-zinc-950 dark:text-white shadow-sm ring-1 ring-inset ring-zinc-950/10 dark:ring-white/10 placeholder:text-zinc-400 dark:placeholder:text-zinc-500 focus:outline-none focus:ring-2 focus:ring-zinc-950 dark:focus:ring-white transition-shadow"
6171
+ placeholder="Enter new password"
6169
6172
  >
6173
+ <p class="mt-1 text-xs text-zinc-500 dark:text-zinc-400">Must be at least 8 characters</p>
6170
6174
  </div>
6171
6175
 
6172
6176
  <div>
6173
- <label class="block text-sm font-medium text-gray-300 mb-2">Confirm New Password</label>
6174
- <input
6175
- type="password"
6176
- name="confirm_password"
6177
+ <label class="block text-sm font-medium text-zinc-950 dark:text-white mb-2">Confirm New Password</label>
6178
+ <input
6179
+ type="password"
6180
+ name="confirm_password"
6177
6181
  required
6178
6182
  minlength="8"
6179
- class="w-full px-4 py-3 bg-white/5 backdrop-blur-sm border border-white/10 rounded-xl text-white focus:outline-none focus:bg-white/10 focus:border-white/30 focus:ring-2 focus:ring-white/20 transition-all"
6183
+ class="w-full rounded-lg bg-white dark:bg-zinc-800 px-3 py-2 text-sm text-zinc-950 dark:text-white shadow-sm ring-1 ring-inset ring-zinc-950/10 dark:ring-white/10 placeholder:text-zinc-400 dark:placeholder:text-zinc-500 focus:outline-none focus:ring-2 focus:ring-zinc-950 dark:focus:ring-white transition-shadow"
6184
+ placeholder="Confirm new password"
6180
6185
  >
6181
6186
  </div>
6182
6187
 
6183
- <div class="flex justify-end space-x-3 pt-4 border-t border-white/10">
6184
- <button
6185
- type="button"
6188
+ <div class="flex justify-end gap-x-3 pt-4 border-t border-zinc-950/5 dark:border-white/5">
6189
+ <button
6190
+ type="button"
6186
6191
  onclick="closePasswordModal()"
6187
- class="px-4 py-2 bg-white/10 text-white rounded-xl border border-white/20 hover:bg-white/20 transition-all"
6192
+ class="rounded-lg bg-white dark:bg-zinc-800 px-4 py-2.5 text-sm font-semibold text-zinc-950 dark:text-white shadow-sm ring-1 ring-inset ring-zinc-950/10 dark:ring-white/10 hover:bg-zinc-50 dark:hover:bg-zinc-700 transition-colors"
6188
6193
  >
6189
6194
  Cancel
6190
6195
  </button>
6191
- <button
6196
+ <button
6192
6197
  type="submit"
6193
- class="px-4 py-2 bg-gradient-to-r from-blue-600 to-purple-600 text-white font-medium rounded-xl hover:from-blue-700 hover:to-purple-700 transition-all"
6198
+ class="inline-flex items-center gap-x-2 rounded-lg bg-zinc-950 dark:bg-white px-4 py-2.5 text-sm font-semibold text-white dark:text-zinc-950 hover:bg-zinc-800 dark:hover:bg-zinc-100 transition-colors"
6194
6199
  >
6200
+ <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
6201
+ <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7"/>
6202
+ </svg>
6195
6203
  Update Password
6196
6204
  </button>
6197
6205
  </div>
@@ -6234,9 +6242,10 @@ function renderProfilePage(data) {
6234
6242
  pageTitle: "Profile",
6235
6243
  currentPath: "/admin/profile",
6236
6244
  user: data.user,
6245
+ version: data.version,
6237
6246
  content: pageContent
6238
6247
  };
6239
- return chunkALOS2CBJ_cjs.renderAdminLayout(layoutData);
6248
+ return chunkALOS2CBJ_cjs.renderAdminLayoutCatalyst(layoutData);
6240
6249
  }
6241
6250
 
6242
6251
  // src/templates/components/alert.template.ts
@@ -6680,7 +6689,7 @@ function renderUserEditPage(data) {
6680
6689
  <input
6681
6690
  type="text"
6682
6691
  name="first_name"
6683
- value="${chunkNK6FN5R5_cjs.escapeHtml(data.userToEdit.firstName || "")}"
6692
+ value="${chunkUL32L2KV_cjs.escapeHtml(data.userToEdit.firstName || "")}"
6684
6693
  required
6685
6694
  class="w-full rounded-lg bg-white dark:bg-zinc-800 px-3 py-2 text-sm text-zinc-950 dark:text-white shadow-sm ring-1 ring-inset ring-zinc-950/10 dark:ring-white/10 placeholder:text-zinc-400 dark:placeholder:text-zinc-500 focus:outline-none focus:ring-2 focus:ring-zinc-950 dark:focus:ring-white transition-shadow"
6686
6695
  />
@@ -6691,7 +6700,7 @@ function renderUserEditPage(data) {
6691
6700
  <input
6692
6701
  type="text"
6693
6702
  name="last_name"
6694
- value="${chunkNK6FN5R5_cjs.escapeHtml(data.userToEdit.lastName || "")}"
6703
+ value="${chunkUL32L2KV_cjs.escapeHtml(data.userToEdit.lastName || "")}"
6695
6704
  required
6696
6705
  class="w-full rounded-lg bg-white dark:bg-zinc-800 px-3 py-2 text-sm text-zinc-950 dark:text-white shadow-sm ring-1 ring-inset ring-zinc-950/10 dark:ring-white/10 placeholder:text-zinc-400 dark:placeholder:text-zinc-500 focus:outline-none focus:ring-2 focus:ring-zinc-950 dark:focus:ring-white transition-shadow"
6697
6706
  />
@@ -6702,7 +6711,7 @@ function renderUserEditPage(data) {
6702
6711
  <input
6703
6712
  type="text"
6704
6713
  name="username"
6705
- value="${chunkNK6FN5R5_cjs.escapeHtml(data.userToEdit.username || "")}"
6714
+ value="${chunkUL32L2KV_cjs.escapeHtml(data.userToEdit.username || "")}"
6706
6715
  required
6707
6716
  class="w-full rounded-lg bg-white dark:bg-zinc-800 px-3 py-2 text-sm text-zinc-950 dark:text-white shadow-sm ring-1 ring-inset ring-zinc-950/10 dark:ring-white/10 placeholder:text-zinc-400 dark:placeholder:text-zinc-500 focus:outline-none focus:ring-2 focus:ring-zinc-950 dark:focus:ring-white transition-shadow"
6708
6717
  />
@@ -6713,7 +6722,7 @@ function renderUserEditPage(data) {
6713
6722
  <input
6714
6723
  type="email"
6715
6724
  name="email"
6716
- value="${chunkNK6FN5R5_cjs.escapeHtml(data.userToEdit.email || "")}"
6725
+ value="${chunkUL32L2KV_cjs.escapeHtml(data.userToEdit.email || "")}"
6717
6726
  required
6718
6727
  class="w-full rounded-lg bg-white dark:bg-zinc-800 px-3 py-2 text-sm text-zinc-950 dark:text-white shadow-sm ring-1 ring-inset ring-zinc-950/10 dark:ring-white/10 placeholder:text-zinc-400 dark:placeholder:text-zinc-500 focus:outline-none focus:ring-2 focus:ring-zinc-950 dark:focus:ring-white transition-shadow"
6719
6728
  />
@@ -6724,7 +6733,7 @@ function renderUserEditPage(data) {
6724
6733
  <input
6725
6734
  type="tel"
6726
6735
  name="phone"
6727
- value="${chunkNK6FN5R5_cjs.escapeHtml(data.userToEdit.phone || "")}"
6736
+ value="${chunkUL32L2KV_cjs.escapeHtml(data.userToEdit.phone || "")}"
6728
6737
  class="w-full rounded-lg bg-white dark:bg-zinc-800 px-3 py-2 text-sm text-zinc-950 dark:text-white shadow-sm ring-1 ring-inset ring-zinc-950/10 dark:ring-white/10 placeholder:text-zinc-400 dark:placeholder:text-zinc-500 focus:outline-none focus:ring-2 focus:ring-zinc-950 dark:focus:ring-white transition-shadow"
6729
6738
  />
6730
6739
  </div>
@@ -6738,7 +6747,7 @@ function renderUserEditPage(data) {
6738
6747
  class="col-start-1 row-start-1 w-full appearance-none rounded-md bg-white/5 dark:bg-white/5 py-1.5 pl-3 pr-8 text-base text-zinc-950 dark:text-white outline outline-1 -outline-offset-1 outline-zinc-500/30 dark:outline-zinc-400/30 *:bg-white dark:*:bg-zinc-800 focus-visible:outline focus-visible:outline-2 focus-visible:-outline-offset-2 focus-visible:outline-zinc-500 dark:focus-visible:outline-zinc-400 sm:text-sm/6"
6739
6748
  >
6740
6749
  ${data.roles.map((role) => `
6741
- <option value="${chunkNK6FN5R5_cjs.escapeHtml(role.value)}" ${data.userToEdit.role === role.value ? "selected" : ""}>${chunkNK6FN5R5_cjs.escapeHtml(role.label)}</option>
6750
+ <option value="${chunkUL32L2KV_cjs.escapeHtml(role.value)}" ${data.userToEdit.role === role.value ? "selected" : ""}>${chunkUL32L2KV_cjs.escapeHtml(role.label)}</option>
6742
6751
  `).join("")}
6743
6752
  </select>
6744
6753
  <svg viewBox="0 0 16 16" fill="currentColor" data-slot="icon" aria-hidden="true" class="pointer-events-none col-start-1 row-start-1 mr-2 size-5 self-center justify-self-end text-zinc-600 dark:text-zinc-400 sm:size-4">
@@ -6754,7 +6763,7 @@ function renderUserEditPage(data) {
6754
6763
  name="bio"
6755
6764
  rows="3"
6756
6765
  class="w-full rounded-lg bg-white dark:bg-zinc-800 px-3 py-2 text-sm text-zinc-950 dark:text-white shadow-sm ring-1 ring-inset ring-zinc-950/10 dark:ring-white/10 placeholder:text-zinc-400 dark:placeholder:text-zinc-500 focus:outline-none focus:ring-2 focus:ring-zinc-950 dark:focus:ring-white transition-shadow"
6757
- >${chunkNK6FN5R5_cjs.escapeHtml(data.userToEdit.bio || "")}</textarea>
6766
+ >${chunkUL32L2KV_cjs.escapeHtml(data.userToEdit.bio || "")}</textarea>
6758
6767
  </div>
6759
6768
  </div>
6760
6769
 
@@ -7654,7 +7663,10 @@ function renderUsersListPage(data) {
7654
7663
 
7655
7664
  // src/routes/admin-users.ts
7656
7665
  var userRoutes = new hono.Hono();
7657
- userRoutes.use("*", chunkKM4AJFXI_cjs.requireAuth());
7666
+ userRoutes.use("*", chunk4BJGEGX5_cjs.requireAuth());
7667
+ userRoutes.get("/", (c) => {
7668
+ return c.redirect("/admin/dashboard");
7669
+ });
7658
7670
  var TIMEZONES = [
7659
7671
  { value: "UTC", label: "UTC" },
7660
7672
  { value: "America/New_York", label: "Eastern Time" },
@@ -7750,12 +7762,12 @@ userRoutes.put("/profile", async (c) => {
7750
7762
  const db = c.env.DB;
7751
7763
  try {
7752
7764
  const formData = await c.req.formData();
7753
- const firstName = chunkNK6FN5R5_cjs.sanitizeInput(formData.get("first_name")?.toString());
7754
- const lastName = chunkNK6FN5R5_cjs.sanitizeInput(formData.get("last_name")?.toString());
7755
- const username = chunkNK6FN5R5_cjs.sanitizeInput(formData.get("username")?.toString());
7765
+ const firstName = chunkUL32L2KV_cjs.sanitizeInput(formData.get("first_name")?.toString());
7766
+ const lastName = chunkUL32L2KV_cjs.sanitizeInput(formData.get("last_name")?.toString());
7767
+ const username = chunkUL32L2KV_cjs.sanitizeInput(formData.get("username")?.toString());
7756
7768
  const email = formData.get("email")?.toString()?.trim().toLowerCase() || "";
7757
- const phone = chunkNK6FN5R5_cjs.sanitizeInput(formData.get("phone")?.toString()) || null;
7758
- const bio = chunkNK6FN5R5_cjs.sanitizeInput(formData.get("bio")?.toString()) || null;
7769
+ const phone = chunkUL32L2KV_cjs.sanitizeInput(formData.get("phone")?.toString()) || null;
7770
+ const bio = chunkUL32L2KV_cjs.sanitizeInput(formData.get("bio")?.toString()) || null;
7759
7771
  const timezone = formData.get("timezone")?.toString() || "UTC";
7760
7772
  const language = formData.get("language")?.toString() || "en";
7761
7773
  const emailNotifications = formData.get("email_notifications") === "1";
@@ -7806,7 +7818,7 @@ userRoutes.put("/profile", async (c) => {
7806
7818
  Date.now(),
7807
7819
  user.userId
7808
7820
  ).run();
7809
- await chunkKM4AJFXI_cjs.logActivity(
7821
+ await chunk4BJGEGX5_cjs.logActivity(
7810
7822
  db,
7811
7823
  user.userId,
7812
7824
  "profile.update",
@@ -7865,7 +7877,7 @@ userRoutes.post("/profile/avatar", async (c) => {
7865
7877
  WHERE id = ?
7866
7878
  `);
7867
7879
  await updateStmt.bind(avatarUrl, Date.now(), user.userId).run();
7868
- await chunkKM4AJFXI_cjs.logActivity(
7880
+ await chunk4BJGEGX5_cjs.logActivity(
7869
7881
  db,
7870
7882
  user.userId,
7871
7883
  "profile.avatar_update",
@@ -7929,7 +7941,7 @@ userRoutes.post("/profile/password", async (c) => {
7929
7941
  dismissible: true
7930
7942
  }));
7931
7943
  }
7932
- const validPassword = await chunkKM4AJFXI_cjs.AuthManager.verifyPassword(currentPassword, userData.password_hash);
7944
+ const validPassword = await chunk4BJGEGX5_cjs.AuthManager.verifyPassword(currentPassword, userData.password_hash);
7933
7945
  if (!validPassword) {
7934
7946
  return c.html(renderAlert2({
7935
7947
  type: "error",
@@ -7937,7 +7949,7 @@ userRoutes.post("/profile/password", async (c) => {
7937
7949
  dismissible: true
7938
7950
  }));
7939
7951
  }
7940
- const newPasswordHash = await chunkKM4AJFXI_cjs.AuthManager.hashPassword(newPassword);
7952
+ const newPasswordHash = await chunk4BJGEGX5_cjs.AuthManager.hashPassword(newPassword);
7941
7953
  const historyStmt = db.prepare(`
7942
7954
  INSERT INTO password_history (id, user_id, password_hash, created_at)
7943
7955
  VALUES (?, ?, ?, ?)
@@ -7953,7 +7965,7 @@ userRoutes.post("/profile/password", async (c) => {
7953
7965
  WHERE id = ?
7954
7966
  `);
7955
7967
  await updateStmt.bind(newPasswordHash, Date.now(), user.userId).run();
7956
- await chunkKM4AJFXI_cjs.logActivity(
7968
+ await chunk4BJGEGX5_cjs.logActivity(
7957
7969
  db,
7958
7970
  user.userId,
7959
7971
  "profile.password_change",
@@ -7977,7 +7989,7 @@ userRoutes.post("/profile/password", async (c) => {
7977
7989
  }));
7978
7990
  }
7979
7991
  });
7980
- userRoutes.get("/users", chunkKM4AJFXI_cjs.requirePermission("users.read"), async (c) => {
7992
+ userRoutes.get("/users", chunk4BJGEGX5_cjs.requirePermission("users.read"), async (c) => {
7981
7993
  const db = c.env.DB;
7982
7994
  const user = c.get("user");
7983
7995
  try {
@@ -8020,7 +8032,7 @@ userRoutes.get("/users", chunkKM4AJFXI_cjs.requirePermission("users.read"), asyn
8020
8032
  `);
8021
8033
  const countResult = await countStmt.bind(...params).first();
8022
8034
  const totalUsers = countResult?.total || 0;
8023
- await chunkKM4AJFXI_cjs.logActivity(
8035
+ await chunk4BJGEGX5_cjs.logActivity(
8024
8036
  db,
8025
8037
  user.userId,
8026
8038
  "users.list_view",
@@ -8096,7 +8108,7 @@ userRoutes.get("/users", chunkKM4AJFXI_cjs.requirePermission("users.read"), asyn
8096
8108
  }), 500);
8097
8109
  }
8098
8110
  });
8099
- userRoutes.get("/users/new", chunkKM4AJFXI_cjs.requirePermission("users.create"), async (c) => {
8111
+ userRoutes.get("/users/new", chunk4BJGEGX5_cjs.requirePermission("users.create"), async (c) => {
8100
8112
  const user = c.get("user");
8101
8113
  try {
8102
8114
  const pageData = {
@@ -8117,17 +8129,17 @@ userRoutes.get("/users/new", chunkKM4AJFXI_cjs.requirePermission("users.create")
8117
8129
  }), 500);
8118
8130
  }
8119
8131
  });
8120
- userRoutes.post("/users/new", chunkKM4AJFXI_cjs.requirePermission("users.create"), async (c) => {
8132
+ userRoutes.post("/users/new", chunk4BJGEGX5_cjs.requirePermission("users.create"), async (c) => {
8121
8133
  const db = c.env.DB;
8122
8134
  const user = c.get("user");
8123
8135
  try {
8124
8136
  const formData = await c.req.formData();
8125
- const firstName = chunkNK6FN5R5_cjs.sanitizeInput(formData.get("first_name")?.toString());
8126
- const lastName = chunkNK6FN5R5_cjs.sanitizeInput(formData.get("last_name")?.toString());
8127
- const username = chunkNK6FN5R5_cjs.sanitizeInput(formData.get("username")?.toString());
8137
+ const firstName = chunkUL32L2KV_cjs.sanitizeInput(formData.get("first_name")?.toString());
8138
+ const lastName = chunkUL32L2KV_cjs.sanitizeInput(formData.get("last_name")?.toString());
8139
+ const username = chunkUL32L2KV_cjs.sanitizeInput(formData.get("username")?.toString());
8128
8140
  const email = formData.get("email")?.toString()?.trim().toLowerCase() || "";
8129
- const phone = chunkNK6FN5R5_cjs.sanitizeInput(formData.get("phone")?.toString()) || null;
8130
- const bio = chunkNK6FN5R5_cjs.sanitizeInput(formData.get("bio")?.toString()) || null;
8141
+ const phone = chunkUL32L2KV_cjs.sanitizeInput(formData.get("phone")?.toString()) || null;
8142
+ const bio = chunkUL32L2KV_cjs.sanitizeInput(formData.get("bio")?.toString()) || null;
8131
8143
  const role = formData.get("role")?.toString() || "viewer";
8132
8144
  const password = formData.get("password")?.toString() || "";
8133
8145
  const confirmPassword = formData.get("confirm_password")?.toString() || "";
@@ -8174,7 +8186,7 @@ userRoutes.post("/users/new", chunkKM4AJFXI_cjs.requirePermission("users.create"
8174
8186
  dismissible: true
8175
8187
  }));
8176
8188
  }
8177
- const passwordHash = await chunkKM4AJFXI_cjs.AuthManager.hashPassword(password);
8189
+ const passwordHash = await chunk4BJGEGX5_cjs.AuthManager.hashPassword(password);
8178
8190
  const userId = globalThis.crypto.randomUUID();
8179
8191
  const createStmt = db.prepare(`
8180
8192
  INSERT INTO users (
@@ -8197,7 +8209,7 @@ userRoutes.post("/users/new", chunkKM4AJFXI_cjs.requirePermission("users.create"
8197
8209
  Date.now(),
8198
8210
  Date.now()
8199
8211
  ).run();
8200
- await chunkKM4AJFXI_cjs.logActivity(
8212
+ await chunk4BJGEGX5_cjs.logActivity(
8201
8213
  db,
8202
8214
  user.userId,
8203
8215
  "user!.create",
@@ -8217,7 +8229,7 @@ userRoutes.post("/users/new", chunkKM4AJFXI_cjs.requirePermission("users.create"
8217
8229
  }));
8218
8230
  }
8219
8231
  });
8220
- userRoutes.get("/users/:id", chunkKM4AJFXI_cjs.requirePermission("users.read"), async (c) => {
8232
+ userRoutes.get("/users/:id", chunk4BJGEGX5_cjs.requirePermission("users.read"), async (c) => {
8221
8233
  if (c.req.path.endsWith("/edit")) {
8222
8234
  return c.notFound();
8223
8235
  }
@@ -8235,7 +8247,7 @@ userRoutes.get("/users/:id", chunkKM4AJFXI_cjs.requirePermission("users.read"),
8235
8247
  if (!userRecord) {
8236
8248
  return c.json({ error: "User not found" }, 404);
8237
8249
  }
8238
- await chunkKM4AJFXI_cjs.logActivity(
8250
+ await chunk4BJGEGX5_cjs.logActivity(
8239
8251
  db,
8240
8252
  user.userId,
8241
8253
  "user!.view",
@@ -8268,7 +8280,7 @@ userRoutes.get("/users/:id", chunkKM4AJFXI_cjs.requirePermission("users.read"),
8268
8280
  return c.json({ error: "Failed to fetch user" }, 500);
8269
8281
  }
8270
8282
  });
8271
- userRoutes.get("/users/:id/edit", chunkKM4AJFXI_cjs.requirePermission("users.update"), async (c) => {
8283
+ userRoutes.get("/users/:id/edit", chunk4BJGEGX5_cjs.requirePermission("users.update"), async (c) => {
8272
8284
  const db = c.env.DB;
8273
8285
  const user = c.get("user");
8274
8286
  const userId = c.req.param("id");
@@ -8322,18 +8334,18 @@ userRoutes.get("/users/:id/edit", chunkKM4AJFXI_cjs.requirePermission("users.upd
8322
8334
  }), 500);
8323
8335
  }
8324
8336
  });
8325
- userRoutes.put("/users/:id", chunkKM4AJFXI_cjs.requirePermission("users.update"), async (c) => {
8337
+ userRoutes.put("/users/:id", chunk4BJGEGX5_cjs.requirePermission("users.update"), async (c) => {
8326
8338
  const db = c.env.DB;
8327
8339
  const user = c.get("user");
8328
8340
  const userId = c.req.param("id");
8329
8341
  try {
8330
8342
  const formData = await c.req.formData();
8331
- const firstName = chunkNK6FN5R5_cjs.sanitizeInput(formData.get("first_name")?.toString());
8332
- const lastName = chunkNK6FN5R5_cjs.sanitizeInput(formData.get("last_name")?.toString());
8333
- const username = chunkNK6FN5R5_cjs.sanitizeInput(formData.get("username")?.toString());
8343
+ const firstName = chunkUL32L2KV_cjs.sanitizeInput(formData.get("first_name")?.toString());
8344
+ const lastName = chunkUL32L2KV_cjs.sanitizeInput(formData.get("last_name")?.toString());
8345
+ const username = chunkUL32L2KV_cjs.sanitizeInput(formData.get("username")?.toString());
8334
8346
  const email = formData.get("email")?.toString()?.trim().toLowerCase() || "";
8335
- const phone = chunkNK6FN5R5_cjs.sanitizeInput(formData.get("phone")?.toString()) || null;
8336
- const bio = chunkNK6FN5R5_cjs.sanitizeInput(formData.get("bio")?.toString()) || null;
8347
+ const phone = chunkUL32L2KV_cjs.sanitizeInput(formData.get("phone")?.toString()) || null;
8348
+ const bio = chunkUL32L2KV_cjs.sanitizeInput(formData.get("bio")?.toString()) || null;
8337
8349
  const role = formData.get("role")?.toString() || "viewer";
8338
8350
  const isActive = formData.get("is_active") === "1";
8339
8351
  const emailVerified = formData.get("email_verified") === "1";
@@ -8384,7 +8396,7 @@ userRoutes.put("/users/:id", chunkKM4AJFXI_cjs.requirePermission("users.update")
8384
8396
  Date.now(),
8385
8397
  userId
8386
8398
  ).run();
8387
- await chunkKM4AJFXI_cjs.logActivity(
8399
+ await chunk4BJGEGX5_cjs.logActivity(
8388
8400
  db,
8389
8401
  user.userId,
8390
8402
  "user!.update",
@@ -8408,7 +8420,7 @@ userRoutes.put("/users/:id", chunkKM4AJFXI_cjs.requirePermission("users.update")
8408
8420
  }));
8409
8421
  }
8410
8422
  });
8411
- userRoutes.delete("/users/:id", chunkKM4AJFXI_cjs.requirePermission("users.delete"), async (c) => {
8423
+ userRoutes.delete("/users/:id", chunk4BJGEGX5_cjs.requirePermission("users.delete"), async (c) => {
8412
8424
  const db = c.env.DB;
8413
8425
  const user = c.get("user");
8414
8426
  const userId = c.req.param("id");
@@ -8430,7 +8442,7 @@ userRoutes.delete("/users/:id", chunkKM4AJFXI_cjs.requirePermission("users.delet
8430
8442
  DELETE FROM users WHERE id = ?
8431
8443
  `);
8432
8444
  await deleteStmt.bind(userId).run();
8433
- await chunkKM4AJFXI_cjs.logActivity(
8445
+ await chunk4BJGEGX5_cjs.logActivity(
8434
8446
  db,
8435
8447
  user.userId,
8436
8448
  "user!.hard_delete",
@@ -8449,7 +8461,7 @@ userRoutes.delete("/users/:id", chunkKM4AJFXI_cjs.requirePermission("users.delet
8449
8461
  UPDATE users SET is_active = 0, updated_at = ? WHERE id = ?
8450
8462
  `);
8451
8463
  await deleteStmt.bind(Date.now(), userId).run();
8452
- await chunkKM4AJFXI_cjs.logActivity(
8464
+ await chunk4BJGEGX5_cjs.logActivity(
8453
8465
  db,
8454
8466
  user.userId,
8455
8467
  "user!.soft_delete",
@@ -8469,15 +8481,15 @@ userRoutes.delete("/users/:id", chunkKM4AJFXI_cjs.requirePermission("users.delet
8469
8481
  return c.json({ error: "Failed to delete user" }, 500);
8470
8482
  }
8471
8483
  });
8472
- userRoutes.post("/invite-user", chunkKM4AJFXI_cjs.requirePermission("users.create"), async (c) => {
8484
+ userRoutes.post("/invite-user", chunk4BJGEGX5_cjs.requirePermission("users.create"), async (c) => {
8473
8485
  const db = c.env.DB;
8474
8486
  const user = c.get("user");
8475
8487
  try {
8476
8488
  const formData = await c.req.formData();
8477
8489
  const email = formData.get("email")?.toString()?.trim().toLowerCase() || "";
8478
8490
  const role = formData.get("role")?.toString()?.trim() || "viewer";
8479
- const firstName = chunkNK6FN5R5_cjs.sanitizeInput(formData.get("first_name")?.toString());
8480
- const lastName = chunkNK6FN5R5_cjs.sanitizeInput(formData.get("last_name")?.toString());
8491
+ const firstName = chunkUL32L2KV_cjs.sanitizeInput(formData.get("first_name")?.toString());
8492
+ const lastName = chunkUL32L2KV_cjs.sanitizeInput(formData.get("last_name")?.toString());
8481
8493
  if (!email || !firstName || !lastName) {
8482
8494
  return c.json({ error: "Email, first name, and last name are required" }, 400);
8483
8495
  }
@@ -8516,7 +8528,7 @@ userRoutes.post("/invite-user", chunkKM4AJFXI_cjs.requirePermission("users.creat
8516
8528
  Date.now(),
8517
8529
  Date.now()
8518
8530
  ).run();
8519
- await chunkKM4AJFXI_cjs.logActivity(
8531
+ await chunk4BJGEGX5_cjs.logActivity(
8520
8532
  db,
8521
8533
  user.userId,
8522
8534
  "user!.invite_sent",
@@ -8545,7 +8557,7 @@ userRoutes.post("/invite-user", chunkKM4AJFXI_cjs.requirePermission("users.creat
8545
8557
  return c.json({ error: "Failed to send user invitation" }, 500);
8546
8558
  }
8547
8559
  });
8548
- userRoutes.post("/resend-invitation/:id", chunkKM4AJFXI_cjs.requirePermission("users.create"), async (c) => {
8560
+ userRoutes.post("/resend-invitation/:id", chunk4BJGEGX5_cjs.requirePermission("users.create"), async (c) => {
8549
8561
  const db = c.env.DB;
8550
8562
  const user = c.get("user");
8551
8563
  const userId = c.req.param("id");
@@ -8573,7 +8585,7 @@ userRoutes.post("/resend-invitation/:id", chunkKM4AJFXI_cjs.requirePermission("u
8573
8585
  Date.now(),
8574
8586
  userId
8575
8587
  ).run();
8576
- await chunkKM4AJFXI_cjs.logActivity(
8588
+ await chunk4BJGEGX5_cjs.logActivity(
8577
8589
  db,
8578
8590
  user.userId,
8579
8591
  "user!.invitation_resent",
@@ -8594,7 +8606,7 @@ userRoutes.post("/resend-invitation/:id", chunkKM4AJFXI_cjs.requirePermission("u
8594
8606
  return c.json({ error: "Failed to resend invitation" }, 500);
8595
8607
  }
8596
8608
  });
8597
- userRoutes.delete("/cancel-invitation/:id", chunkKM4AJFXI_cjs.requirePermission("users.delete"), async (c) => {
8609
+ userRoutes.delete("/cancel-invitation/:id", chunk4BJGEGX5_cjs.requirePermission("users.delete"), async (c) => {
8598
8610
  const db = c.env.DB;
8599
8611
  const user = c.get("user");
8600
8612
  const userId = c.req.param("id");
@@ -8609,7 +8621,7 @@ userRoutes.delete("/cancel-invitation/:id", chunkKM4AJFXI_cjs.requirePermission(
8609
8621
  }
8610
8622
  const deleteStmt = db.prepare(`DELETE FROM users WHERE id = ?`);
8611
8623
  await deleteStmt.bind(userId).run();
8612
- await chunkKM4AJFXI_cjs.logActivity(
8624
+ await chunk4BJGEGX5_cjs.logActivity(
8613
8625
  db,
8614
8626
  user.userId,
8615
8627
  "user!.invitation_cancelled",
@@ -8628,7 +8640,7 @@ userRoutes.delete("/cancel-invitation/:id", chunkKM4AJFXI_cjs.requirePermission(
8628
8640
  return c.json({ error: "Failed to cancel invitation" }, 500);
8629
8641
  }
8630
8642
  });
8631
- userRoutes.get("/activity-logs", chunkKM4AJFXI_cjs.requirePermission("activity.read"), async (c) => {
8643
+ userRoutes.get("/activity-logs", chunk4BJGEGX5_cjs.requirePermission("activity.read"), async (c) => {
8632
8644
  const db = c.env.DB;
8633
8645
  const user = c.get("user");
8634
8646
  try {
@@ -8692,7 +8704,7 @@ userRoutes.get("/activity-logs", chunkKM4AJFXI_cjs.requirePermission("activity.r
8692
8704
  ...log,
8693
8705
  details: log.details ? JSON.parse(log.details) : null
8694
8706
  }));
8695
- await chunkKM4AJFXI_cjs.logActivity(
8707
+ await chunk4BJGEGX5_cjs.logActivity(
8696
8708
  db,
8697
8709
  user.userId,
8698
8710
  "activity.logs_viewed",
@@ -8734,7 +8746,7 @@ userRoutes.get("/activity-logs", chunkKM4AJFXI_cjs.requirePermission("activity.r
8734
8746
  return c.html(renderActivityLogsPage(pageData));
8735
8747
  }
8736
8748
  });
8737
- userRoutes.get("/activity-logs/export", chunkKM4AJFXI_cjs.requirePermission("activity.read"), async (c) => {
8749
+ userRoutes.get("/activity-logs/export", chunk4BJGEGX5_cjs.requirePermission("activity.read"), async (c) => {
8738
8750
  const db = c.env.DB;
8739
8751
  const user = c.get("user");
8740
8752
  try {
@@ -8799,7 +8811,7 @@ userRoutes.get("/activity-logs/export", chunkKM4AJFXI_cjs.requirePermission("act
8799
8811
  csvRows.push(row.join(","));
8800
8812
  }
8801
8813
  const csvContent = csvRows.join("\n");
8802
- await chunkKM4AJFXI_cjs.logActivity(
8814
+ await chunk4BJGEGX5_cjs.logActivity(
8803
8815
  db,
8804
8816
  user.userId,
8805
8817
  "activity.logs_exported",
@@ -10135,6 +10147,7 @@ var fileValidationSchema2 = zod.z.object({
10135
10147
  // 50MB max
10136
10148
  });
10137
10149
  var adminMediaRoutes = new hono.Hono();
10150
+ adminMediaRoutes.use("*", chunk4BJGEGX5_cjs.requireAuth());
10138
10151
  adminMediaRoutes.get("/", async (c) => {
10139
10152
  try {
10140
10153
  const user = c.get("user");
@@ -12154,6 +12167,7 @@ function formatTimestamp(timestamp) {
12154
12167
 
12155
12168
  // src/routes/admin-plugins.ts
12156
12169
  var adminPluginRoutes = new hono.Hono();
12170
+ adminPluginRoutes.use("*", chunk4BJGEGX5_cjs.requireAuth());
12157
12171
  adminPluginRoutes.get("/", async (c) => {
12158
12172
  try {
12159
12173
  const user = c.get("user");
@@ -13263,10 +13277,11 @@ function renderLogConfigPage(data) {
13263
13277
 
13264
13278
  // src/routes/admin-logs.ts
13265
13279
  var adminLogsRoutes = new hono.Hono();
13280
+ adminLogsRoutes.use("*", chunk4BJGEGX5_cjs.requireAuth());
13266
13281
  adminLogsRoutes.get("/", async (c) => {
13267
13282
  try {
13268
13283
  const user = c.get("user");
13269
- const logger = chunkSRCY43RN_cjs.getLogger(c.env.DB);
13284
+ const logger = chunk3NVJ6W27_cjs.getLogger(c.env.DB);
13270
13285
  const query = c.req.query();
13271
13286
  const page = parseInt(query.page || "1");
13272
13287
  const limit = parseInt(query.limit || "50");
@@ -13346,7 +13361,7 @@ adminLogsRoutes.get("/:id", async (c) => {
13346
13361
  try {
13347
13362
  const id = c.req.param("id");
13348
13363
  const user = c.get("user");
13349
- const logger = chunkSRCY43RN_cjs.getLogger(c.env.DB);
13364
+ const logger = chunk3NVJ6W27_cjs.getLogger(c.env.DB);
13350
13365
  const { logs } = await logger.getLogs({
13351
13366
  limit: 1,
13352
13367
  offset: 0,
@@ -13383,7 +13398,7 @@ adminLogsRoutes.get("/:id", async (c) => {
13383
13398
  adminLogsRoutes.get("/config", async (c) => {
13384
13399
  try {
13385
13400
  const user = c.get("user");
13386
- const logger = chunkSRCY43RN_cjs.getLogger(c.env.DB);
13401
+ const logger = chunk3NVJ6W27_cjs.getLogger(c.env.DB);
13387
13402
  const configs = await logger.getAllConfigs();
13388
13403
  const pageData = {
13389
13404
  configs,
@@ -13407,7 +13422,7 @@ adminLogsRoutes.post("/config/:category", async (c) => {
13407
13422
  const level = formData.get("level");
13408
13423
  const retention = parseInt(formData.get("retention"));
13409
13424
  const maxSize = parseInt(formData.get("max_size"));
13410
- const logger = chunkSRCY43RN_cjs.getLogger(c.env.DB);
13425
+ const logger = chunk3NVJ6W27_cjs.getLogger(c.env.DB);
13411
13426
  await logger.updateConfig(category, {
13412
13427
  enabled,
13413
13428
  level,
@@ -13436,7 +13451,7 @@ adminLogsRoutes.get("/export", async (c) => {
13436
13451
  const category = query.category;
13437
13452
  const startDate = query.start_date;
13438
13453
  const endDate = query.end_date;
13439
- const logger = chunkSRCY43RN_cjs.getLogger(c.env.DB);
13454
+ const logger = chunk3NVJ6W27_cjs.getLogger(c.env.DB);
13440
13455
  const filter = {
13441
13456
  limit: 1e4,
13442
13457
  // Export up to 10k logs
@@ -13517,7 +13532,7 @@ adminLogsRoutes.post("/cleanup", async (c) => {
13517
13532
  error: "Unauthorized. Admin access required."
13518
13533
  }, 403);
13519
13534
  }
13520
- const logger = chunkSRCY43RN_cjs.getLogger(c.env.DB);
13535
+ const logger = chunk3NVJ6W27_cjs.getLogger(c.env.DB);
13521
13536
  await logger.cleanupByRetention();
13522
13537
  return c.html(html.html`
13523
13538
  <div class="bg-green-100 border border-green-400 text-green-700 px-4 py-3 rounded">
@@ -13539,7 +13554,7 @@ adminLogsRoutes.post("/search", async (c) => {
13539
13554
  const search = formData.get("search");
13540
13555
  const level = formData.get("level");
13541
13556
  const category = formData.get("category");
13542
- const logger = chunkSRCY43RN_cjs.getLogger(c.env.DB);
13557
+ const logger = chunk3NVJ6W27_cjs.getLogger(c.env.DB);
13543
13558
  const filter = {
13544
13559
  limit: 20,
13545
13560
  offset: 0,
@@ -15745,7 +15760,7 @@ function renderAnalyticsChart() {
15745
15760
 
15746
15761
  <!-- Hidden div to trigger HTMX polling -->
15747
15762
  <div
15748
- hx-get="/admin/api/metrics"
15763
+ hx-get="/admin/dashboard/api/metrics"
15749
15764
  hx-trigger="every 1s"
15750
15765
  hx-swap="none"
15751
15766
  style="display: none;"
@@ -15848,9 +15863,12 @@ function renderAnalyticsChart() {
15848
15863
 
15849
15864
  // Listen for metrics updates from HTMX
15850
15865
  window.addEventListener('htmx:afterRequest', function(event) {
15851
- if (event.detail.pathInfo.requestPath === '/admin/api/metrics') {
15866
+ console.log('[Dashboard] HTMX request completed:', event.detail.pathInfo.requestPath);
15867
+
15868
+ if (event.detail.pathInfo.requestPath === '/admin/dashboard/api/metrics') {
15852
15869
  try {
15853
15870
  const metrics = JSON.parse(event.detail.xhr.responseText);
15871
+ console.log('[Dashboard] Metrics received:', metrics);
15854
15872
 
15855
15873
  // Update current RPS display
15856
15874
  const rpsElement = document.getElementById('current-rps');
@@ -15871,8 +15889,9 @@ function renderAnalyticsChart() {
15871
15889
  chart.data.labels = newLabels;
15872
15890
 
15873
15891
  chart.update('none'); // Update without animation for smoother real-time updates
15892
+ console.log('[Dashboard] Chart updated with RPS:', metrics.requestsPerSecond);
15874
15893
  } catch (e) {
15875
- console.error('Error updating metrics:', e);
15894
+ console.error('[Dashboard] Error updating metrics:', e);
15876
15895
  }
15877
15896
  }
15878
15897
  });
@@ -16191,9 +16210,9 @@ function renderStorageUsage(databaseSizeBytes, mediaSizeBytes) {
16191
16210
  }
16192
16211
 
16193
16212
  // src/routes/admin-dashboard.ts
16194
- var VERSION = chunkNK6FN5R5_cjs.getCoreVersion();
16213
+ var VERSION = chunkUL32L2KV_cjs.getCoreVersion();
16195
16214
  var router = new hono.Hono();
16196
- router.use("*", chunkKM4AJFXI_cjs.requireAuth());
16215
+ router.use("*", chunk4BJGEGX5_cjs.requireAuth());
16197
16216
  router.get("/", async (c) => {
16198
16217
  const user = c.get("user");
16199
16218
  try {
@@ -16219,7 +16238,7 @@ router.get("/", async (c) => {
16219
16238
  return c.html(renderDashboardPage(pageData));
16220
16239
  }
16221
16240
  });
16222
- router.get("/dashboard/stats", async (c) => {
16241
+ router.get("/stats", async (c) => {
16223
16242
  try {
16224
16243
  const db = c.env.DB;
16225
16244
  let collectionsCount = 0;
@@ -16269,7 +16288,7 @@ router.get("/dashboard/stats", async (c) => {
16269
16288
  return c.html('<div class="text-red-500">Failed to load statistics</div>');
16270
16289
  }
16271
16290
  });
16272
- router.get("/dashboard/storage", async (c) => {
16291
+ router.get("/storage", async (c) => {
16273
16292
  try {
16274
16293
  const db = c.env.DB;
16275
16294
  let databaseSize = 0;
@@ -16294,7 +16313,7 @@ router.get("/dashboard/storage", async (c) => {
16294
16313
  return c.html('<div class="text-red-500">Failed to load storage information</div>');
16295
16314
  }
16296
16315
  });
16297
- router.get("/dashboard/recent-activity", async (c) => {
16316
+ router.get("/recent-activity", async (c) => {
16298
16317
  try {
16299
16318
  const db = c.env.DB;
16300
16319
  const limit = parseInt(c.req.query("limit") || "5");
@@ -16346,25 +16365,14 @@ router.get("/dashboard/recent-activity", async (c) => {
16346
16365
  }
16347
16366
  });
16348
16367
  router.get("/api/metrics", async (c) => {
16349
- try {
16350
- const { metricsTracker } = await import('../utils/metrics-tracker');
16351
- return c.json({
16352
- requestsPerSecond: metricsTracker.getRequestsPerSecond(),
16353
- totalRequests: metricsTracker.getTotalRequests(),
16354
- averageRPS: metricsTracker.getAverageRPS(),
16355
- timestamp: (/* @__PURE__ */ new Date()).toISOString()
16356
- });
16357
- } catch (error) {
16358
- console.error("Error fetching metrics:", error);
16359
- return c.json({
16360
- requestsPerSecond: 0,
16361
- totalRequests: 0,
16362
- averageRPS: 0,
16363
- timestamp: (/* @__PURE__ */ new Date()).toISOString()
16364
- });
16365
- }
16368
+ return c.json({
16369
+ requestsPerSecond: chunkRCQ2HIQD_cjs.metricsTracker.getRequestsPerSecond(),
16370
+ totalRequests: chunkRCQ2HIQD_cjs.metricsTracker.getTotalRequests(),
16371
+ averageRPS: Number(chunkRCQ2HIQD_cjs.metricsTracker.getAverageRPS().toFixed(2)),
16372
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
16373
+ });
16366
16374
  });
16367
- router.get("/dashboard/system-status", async (c) => {
16375
+ router.get("/system-status", async (c) => {
16368
16376
  try {
16369
16377
  const html9 = `
16370
16378
  <div class="grid grid-cols-1 sm:grid-cols-2 gap-4">
@@ -17685,7 +17693,8 @@ function renderCollectionFormPage(data) {
17685
17693
 
17686
17694
  // src/routes/admin-collections.ts
17687
17695
  var adminCollectionsRoutes = new hono.Hono();
17688
- adminCollectionsRoutes.get("/collections", async (c) => {
17696
+ adminCollectionsRoutes.use("*", chunk4BJGEGX5_cjs.requireAuth());
17697
+ adminCollectionsRoutes.get("/", async (c) => {
17689
17698
  try {
17690
17699
  const user = c.get("user");
17691
17700
  const db = c.env.DB;
@@ -17740,7 +17749,7 @@ adminCollectionsRoutes.get("/collections", async (c) => {
17740
17749
  return c.html(html.html`<p>Error loading collections</p>`);
17741
17750
  }
17742
17751
  });
17743
- adminCollectionsRoutes.get("/collections/new", (c) => {
17752
+ adminCollectionsRoutes.get("/new", (c) => {
17744
17753
  const user = c.get("user");
17745
17754
  const formData = {
17746
17755
  isEdit: false,
@@ -17753,7 +17762,7 @@ adminCollectionsRoutes.get("/collections/new", (c) => {
17753
17762
  };
17754
17763
  return c.html(renderCollectionFormPage(formData));
17755
17764
  });
17756
- adminCollectionsRoutes.post("/collections", async (c) => {
17765
+ adminCollectionsRoutes.post("/", async (c) => {
17757
17766
  try {
17758
17767
  const formData = await c.req.formData();
17759
17768
  const name = formData.get("name");
@@ -17872,7 +17881,7 @@ adminCollectionsRoutes.post("/collections", async (c) => {
17872
17881
  }
17873
17882
  }
17874
17883
  });
17875
- adminCollectionsRoutes.get("/collections/:id", async (c) => {
17884
+ adminCollectionsRoutes.get("/:id", async (c) => {
17876
17885
  try {
17877
17886
  const id = c.req.param("id");
17878
17887
  const user = c.get("user");
@@ -17940,7 +17949,7 @@ adminCollectionsRoutes.get("/collections/:id", async (c) => {
17940
17949
  return c.html(renderCollectionFormPage(formData));
17941
17950
  }
17942
17951
  });
17943
- adminCollectionsRoutes.put("/collections/:id", async (c) => {
17952
+ adminCollectionsRoutes.put("/:id", async (c) => {
17944
17953
  try {
17945
17954
  const id = c.req.param("id");
17946
17955
  const formData = await c.req.formData();
@@ -17974,7 +17983,7 @@ adminCollectionsRoutes.put("/collections/:id", async (c) => {
17974
17983
  `);
17975
17984
  }
17976
17985
  });
17977
- adminCollectionsRoutes.delete("/collections/:id", async (c) => {
17986
+ adminCollectionsRoutes.delete("/:id", async (c) => {
17978
17987
  try {
17979
17988
  const id = c.req.param("id");
17980
17989
  const db = c.env.DB;
@@ -18005,7 +18014,7 @@ adminCollectionsRoutes.delete("/collections/:id", async (c) => {
18005
18014
  `);
18006
18015
  }
18007
18016
  });
18008
- adminCollectionsRoutes.post("/collections/:id/fields", async (c) => {
18017
+ adminCollectionsRoutes.post("/:id/fields", async (c) => {
18009
18018
  try {
18010
18019
  const collectionId = c.req.param("id");
18011
18020
  const formData = await c.req.formData();
@@ -18058,7 +18067,7 @@ adminCollectionsRoutes.post("/collections/:id/fields", async (c) => {
18058
18067
  return c.json({ success: false, error: "Failed to add field." });
18059
18068
  }
18060
18069
  });
18061
- adminCollectionsRoutes.put("/collections/:collectionId/fields/:fieldId", async (c) => {
18070
+ adminCollectionsRoutes.put("/:collectionId/fields/:fieldId", async (c) => {
18062
18071
  try {
18063
18072
  const fieldId = c.req.param("fieldId");
18064
18073
  const formData = await c.req.formData();
@@ -18082,7 +18091,7 @@ adminCollectionsRoutes.put("/collections/:collectionId/fields/:fieldId", async (
18082
18091
  return c.json({ success: false, error: "Failed to update field." });
18083
18092
  }
18084
18093
  });
18085
- adminCollectionsRoutes.delete("/collections/:collectionId/fields/:fieldId", async (c) => {
18094
+ adminCollectionsRoutes.delete("/:collectionId/fields/:fieldId", async (c) => {
18086
18095
  try {
18087
18096
  const fieldId = c.req.param("fieldId");
18088
18097
  const db = c.env.DB;
@@ -18094,7 +18103,7 @@ adminCollectionsRoutes.delete("/collections/:collectionId/fields/:fieldId", asyn
18094
18103
  return c.json({ success: false, error: "Failed to delete field." });
18095
18104
  }
18096
18105
  });
18097
- adminCollectionsRoutes.post("/collections/:collectionId/fields/reorder", async (c) => {
18106
+ adminCollectionsRoutes.post("/:collectionId/fields/reorder", async (c) => {
18098
18107
  try {
18099
18108
  const body = await c.req.json();
18100
18109
  const fieldIds = body.fieldIds;
@@ -19541,6 +19550,7 @@ function renderDatabaseToolsSettings(settings) {
19541
19550
 
19542
19551
  // src/routes/admin-settings.ts
19543
19552
  var adminSettingsRoutes = new hono.Hono();
19553
+ adminSettingsRoutes.use("*", chunk4BJGEGX5_cjs.requireAuth());
19544
19554
  function getMockSettings(user) {
19545
19555
  return {
19546
19556
  general: {
@@ -19599,10 +19609,10 @@ function getMockSettings(user) {
19599
19609
  }
19600
19610
  };
19601
19611
  }
19602
- adminSettingsRoutes.get("/settings", (c) => {
19612
+ adminSettingsRoutes.get("/", (c) => {
19603
19613
  return c.redirect("/admin/settings/general");
19604
19614
  });
19605
- adminSettingsRoutes.get("/settings/general", (c) => {
19615
+ adminSettingsRoutes.get("/general", (c) => {
19606
19616
  const user = c.get("user");
19607
19617
  const pageData = {
19608
19618
  user: user ? {
@@ -19616,7 +19626,7 @@ adminSettingsRoutes.get("/settings/general", (c) => {
19616
19626
  };
19617
19627
  return c.html(renderSettingsPage(pageData));
19618
19628
  });
19619
- adminSettingsRoutes.get("/settings/appearance", (c) => {
19629
+ adminSettingsRoutes.get("/appearance", (c) => {
19620
19630
  const user = c.get("user");
19621
19631
  const pageData = {
19622
19632
  user: user ? {
@@ -19630,7 +19640,7 @@ adminSettingsRoutes.get("/settings/appearance", (c) => {
19630
19640
  };
19631
19641
  return c.html(renderSettingsPage(pageData));
19632
19642
  });
19633
- adminSettingsRoutes.get("/settings/security", (c) => {
19643
+ adminSettingsRoutes.get("/security", (c) => {
19634
19644
  const user = c.get("user");
19635
19645
  const pageData = {
19636
19646
  user: user ? {
@@ -19644,7 +19654,7 @@ adminSettingsRoutes.get("/settings/security", (c) => {
19644
19654
  };
19645
19655
  return c.html(renderSettingsPage(pageData));
19646
19656
  });
19647
- adminSettingsRoutes.get("/settings/notifications", (c) => {
19657
+ adminSettingsRoutes.get("/notifications", (c) => {
19648
19658
  const user = c.get("user");
19649
19659
  const pageData = {
19650
19660
  user: user ? {
@@ -19658,7 +19668,7 @@ adminSettingsRoutes.get("/settings/notifications", (c) => {
19658
19668
  };
19659
19669
  return c.html(renderSettingsPage(pageData));
19660
19670
  });
19661
- adminSettingsRoutes.get("/settings/storage", (c) => {
19671
+ adminSettingsRoutes.get("/storage", (c) => {
19662
19672
  const user = c.get("user");
19663
19673
  const pageData = {
19664
19674
  user: user ? {
@@ -19672,7 +19682,7 @@ adminSettingsRoutes.get("/settings/storage", (c) => {
19672
19682
  };
19673
19683
  return c.html(renderSettingsPage(pageData));
19674
19684
  });
19675
- adminSettingsRoutes.get("/settings/migrations", (c) => {
19685
+ adminSettingsRoutes.get("/migrations", (c) => {
19676
19686
  const user = c.get("user");
19677
19687
  const pageData = {
19678
19688
  user: user ? {
@@ -19686,7 +19696,7 @@ adminSettingsRoutes.get("/settings/migrations", (c) => {
19686
19696
  };
19687
19697
  return c.html(renderSettingsPage(pageData));
19688
19698
  });
19689
- adminSettingsRoutes.get("/settings/database-tools", (c) => {
19699
+ adminSettingsRoutes.get("/database-tools", (c) => {
19690
19700
  const user = c.get("user");
19691
19701
  const pageData = {
19692
19702
  user: user ? {
@@ -19759,7 +19769,7 @@ adminSettingsRoutes.get("/api/migrations/validate", async (c) => {
19759
19769
  }, 500);
19760
19770
  }
19761
19771
  });
19762
- adminSettingsRoutes.post("/settings", async (c) => {
19772
+ adminSettingsRoutes.post("/", async (c) => {
19763
19773
  try {
19764
19774
  const formData = await c.req.formData();
19765
19775
  return c.html(html.html`
@@ -19830,5 +19840,5 @@ exports.api_system_default = api_system_default;
19830
19840
  exports.auth_default = auth_default;
19831
19841
  exports.router = router;
19832
19842
  exports.userRoutes = userRoutes;
19833
- //# sourceMappingURL=chunk-5FDDDD4J.cjs.map
19834
- //# sourceMappingURL=chunk-5FDDDD4J.cjs.map
19843
+ //# sourceMappingURL=chunk-7G6XT62S.cjs.map
19844
+ //# sourceMappingURL=chunk-7G6XT62S.cjs.map