@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.
- package/dist/{chunk-SRCY43RN.cjs → chunk-3NVJ6W27.cjs} +2 -2
- package/dist/chunk-3NVJ6W27.cjs.map +1 -0
- package/dist/chunk-4BJGEGX5.cjs +236 -0
- package/dist/chunk-4BJGEGX5.cjs.map +1 -0
- package/dist/{chunk-5FDDDD4J.cjs → chunk-7G6XT62S.cjs} +321 -311
- package/dist/chunk-7G6XT62S.cjs.map +1 -0
- package/dist/chunk-ALOS2CBJ.cjs.map +1 -1
- package/dist/chunk-CDBVZEWR.js.map +1 -1
- package/dist/{chunk-BITQ4MFX.js → chunk-EAELJXRV.js} +93 -115
- package/dist/chunk-EAELJXRV.js.map +1 -0
- package/dist/chunk-FICTAGD4.js +59 -0
- package/dist/chunk-FICTAGD4.js.map +1 -0
- package/dist/{chunk-FVMV5DKA.cjs → chunk-HJZOA2O5.cjs} +93 -115
- package/dist/chunk-HJZOA2O5.cjs.map +1 -0
- package/dist/chunk-LEG4KNFP.cjs.map +1 -1
- package/dist/{chunk-5XTB4FE5.js → chunk-LH4Z7QID.js} +2 -2
- package/dist/chunk-LH4Z7QID.js.map +1 -0
- package/dist/chunk-M6FPVS7E.js +214 -0
- package/dist/chunk-M6FPVS7E.js.map +1 -0
- package/dist/chunk-O46XKBFM.js.map +1 -1
- package/dist/chunk-RCQ2HIQD.cjs +61 -0
- package/dist/chunk-RCQ2HIQD.cjs.map +1 -0
- package/dist/{chunk-QSF34IYQ.js → chunk-SGGHTIWV.js} +218 -208
- package/dist/chunk-SGGHTIWV.js.map +1 -0
- package/dist/{chunk-NK6FN5R5.cjs → chunk-UL32L2KV.cjs} +3 -60
- package/dist/chunk-UL32L2KV.cjs.map +1 -0
- package/dist/{chunk-OL2OE3VJ.js → chunk-XJETEIRU.js} +4 -60
- package/dist/chunk-XJETEIRU.js.map +1 -0
- package/dist/index.cjs +134 -119
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +16 -12
- package/dist/index.js.map +1 -1
- package/dist/middleware.cjs +26 -21
- package/dist/middleware.js +2 -1
- package/dist/plugins.cjs +7 -7
- package/dist/plugins.js +1 -1
- package/dist/routes.cjs +25 -24
- package/dist/routes.js +5 -4
- package/dist/services.cjs +7 -7
- package/dist/services.js +1 -1
- package/dist/utils.cjs +16 -15
- package/dist/utils.js +2 -1
- package/package.json +1 -1
- package/dist/chunk-5FDDDD4J.cjs.map +0 -1
- package/dist/chunk-5XTB4FE5.js.map +0 -1
- package/dist/chunk-BITQ4MFX.js.map +0 -1
- package/dist/chunk-FVMV5DKA.cjs.map +0 -1
- package/dist/chunk-KM4AJFXI.cjs +0 -101
- package/dist/chunk-KM4AJFXI.cjs.map +0 -1
- package/dist/chunk-NK6FN5R5.cjs.map +0 -1
- package/dist/chunk-OL2OE3VJ.js.map +0 -1
- package/dist/chunk-QSF34IYQ.js.map +0 -1
- package/dist/chunk-SRCY43RN.cjs.map +0 -1
- package/dist/chunk-TY3NHEBN.js +0 -80
- package/dist/chunk-TY3NHEBN.js.map +0 -1
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
import { getCacheService, CACHE_CONFIGS, getLogger } from './chunk-
|
|
2
|
-
import { requireAuth, isPluginActive, requireRole, AuthManager, logActivity, requirePermission } from './chunk-
|
|
1
|
+
import { getCacheService, CACHE_CONFIGS, getLogger } from './chunk-LH4Z7QID.js';
|
|
2
|
+
import { requireAuth, isPluginActive, requireRole, AuthManager, logActivity, requirePermission } from './chunk-M6FPVS7E.js';
|
|
3
3
|
import { PluginService, MigrationService } from './chunk-CDBVZEWR.js';
|
|
4
4
|
import { init_admin_layout_catalyst_template, renderDesignPage, renderCheckboxPage, renderFAQList, renderTestimonialsList, renderCodeExamplesList, renderAlert, renderTable, renderPagination, renderConfirmationDialog, getConfirmationDialogScript, renderAdminLayoutCatalyst, renderAdminLayout, adminLayoutV2, renderForm } from './chunk-O46XKBFM.js';
|
|
5
|
-
import { QueryFilterBuilder, sanitizeInput, getCoreVersion, escapeHtml } from './chunk-
|
|
5
|
+
import { QueryFilterBuilder, sanitizeInput, getCoreVersion, escapeHtml } from './chunk-XJETEIRU.js';
|
|
6
|
+
import { metricsTracker } from './chunk-FICTAGD4.js';
|
|
6
7
|
import { Hono } from 'hono';
|
|
7
8
|
import { cors } from 'hono/cors';
|
|
8
9
|
import { z } from 'zod';
|
|
@@ -4704,6 +4705,7 @@ var isPluginActive2 = () => false;
|
|
|
4704
4705
|
|
|
4705
4706
|
// src/routes/admin-content.ts
|
|
4706
4707
|
var adminContentRoutes = new Hono();
|
|
4708
|
+
adminContentRoutes.use("*", requireAuth());
|
|
4707
4709
|
async function getCollectionFields(db, collectionId) {
|
|
4708
4710
|
const cache = getCacheService(CACHE_CONFIGS.collection);
|
|
4709
4711
|
return cache.getOrSet(
|
|
@@ -5836,170 +5838,157 @@ ${JSON.stringify(data, null, 2)}
|
|
|
5836
5838
|
var admin_content_default = adminContentRoutes;
|
|
5837
5839
|
|
|
5838
5840
|
// src/templates/pages/admin-profile.template.ts
|
|
5841
|
+
init_admin_layout_catalyst_template();
|
|
5839
5842
|
function renderProfilePage(data) {
|
|
5840
5843
|
const pageContent = `
|
|
5841
|
-
<div class="
|
|
5844
|
+
<div class="space-y-8">
|
|
5842
5845
|
<!-- Header -->
|
|
5843
|
-
<div class="
|
|
5846
|
+
<div class="sm:flex sm:items-center sm:justify-between">
|
|
5844
5847
|
<div>
|
|
5845
|
-
<h1 class="text-2xl font-semibold text-white">User Profile</h1>
|
|
5846
|
-
<p class="mt-2 text-sm text-
|
|
5848
|
+
<h1 class="text-2xl/8 font-semibold text-zinc-950 dark:text-white sm:text-xl/8">User Profile</h1>
|
|
5849
|
+
<p class="mt-2 text-sm/6 text-zinc-500 dark:text-zinc-400">
|
|
5850
|
+
Manage your account settings and preferences
|
|
5851
|
+
</p>
|
|
5847
5852
|
</div>
|
|
5848
5853
|
</div>
|
|
5849
5854
|
|
|
5850
|
-
<!-- Breadcrumb -->
|
|
5851
|
-
<nav class="flex mb-6" aria-label="Breadcrumb">
|
|
5852
|
-
<ol class="flex items-center space-x-3">
|
|
5853
|
-
<li>
|
|
5854
|
-
<a href="/admin" class="text-gray-300 hover:text-white transition-colors">
|
|
5855
|
-
<svg class="h-5 w-5" fill="currentColor" viewBox="0 0 20 20">
|
|
5856
|
-
<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"/>
|
|
5857
|
-
</svg>
|
|
5858
|
-
</a>
|
|
5859
|
-
</li>
|
|
5860
|
-
<li class="flex items-center">
|
|
5861
|
-
<svg class="h-5 w-5 text-gray-400 mx-2" fill="currentColor" viewBox="0 0 20 20">
|
|
5862
|
-
<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"/>
|
|
5863
|
-
</svg>
|
|
5864
|
-
<span class="text-sm font-medium text-gray-200">Profile</span>
|
|
5865
|
-
</li>
|
|
5866
|
-
</ol>
|
|
5867
|
-
</nav>
|
|
5868
|
-
|
|
5869
5855
|
<!-- Alert Messages -->
|
|
5870
5856
|
${data.error ? renderAlert({ type: "error", message: data.error, dismissible: true }) : ""}
|
|
5871
5857
|
${data.success ? renderAlert({ type: "success", message: data.success, dismissible: true }) : ""}
|
|
5872
5858
|
|
|
5873
5859
|
<!-- Profile Form -->
|
|
5874
|
-
<div class="grid grid-cols-1 lg:grid-cols-3 gap-
|
|
5860
|
+
<div class="grid grid-cols-1 lg:grid-cols-3 gap-8">
|
|
5875
5861
|
<!-- Main Profile Form -->
|
|
5876
5862
|
<div class="lg:col-span-2">
|
|
5877
|
-
<div class="
|
|
5863
|
+
<div class="rounded-xl bg-white dark:bg-zinc-900 shadow-sm ring-1 ring-zinc-950/5 dark:ring-white/10">
|
|
5878
5864
|
<!-- Form Header -->
|
|
5879
|
-
<div class="
|
|
5880
|
-
<div class="
|
|
5881
|
-
|
|
5882
|
-
|
|
5883
|
-
<svg class="w-6 h-6 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
5865
|
+
<div class="px-6 py-5 border-b border-zinc-950/5 dark:border-white/5">
|
|
5866
|
+
<div class="flex items-center gap-x-3">
|
|
5867
|
+
<div class="flex h-10 w-10 items-center justify-center rounded-lg bg-zinc-950 dark:bg-white">
|
|
5868
|
+
<svg class="h-5 w-5 text-white dark:text-zinc-950" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
5884
5869
|
<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"/>
|
|
5885
5870
|
</svg>
|
|
5886
5871
|
</div>
|
|
5887
5872
|
<div>
|
|
5888
|
-
<h2 class="text-
|
|
5889
|
-
<p class="text-sm text-
|
|
5873
|
+
<h2 class="text-base font-semibold text-zinc-950 dark:text-white">Profile Information</h2>
|
|
5874
|
+
<p class="text-sm text-zinc-500 dark:text-zinc-400">Update your account details</p>
|
|
5890
5875
|
</div>
|
|
5891
5876
|
</div>
|
|
5892
5877
|
</div>
|
|
5893
5878
|
|
|
5894
5879
|
<!-- Form Content -->
|
|
5895
|
-
<form id="profile-form" hx-put="/admin/profile" hx-target="#form-messages" class="p-
|
|
5880
|
+
<form id="profile-form" hx-put="/admin/profile" hx-target="#form-messages" class="p-6 space-y-6">
|
|
5896
5881
|
<div id="form-messages"></div>
|
|
5897
5882
|
|
|
5898
5883
|
<!-- Basic Information -->
|
|
5899
5884
|
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
|
|
5900
5885
|
<div>
|
|
5901
|
-
<label class="block text-sm font-medium text-
|
|
5902
|
-
<input
|
|
5903
|
-
type="text"
|
|
5904
|
-
name="first_name"
|
|
5886
|
+
<label class="block text-sm font-medium text-zinc-950 dark:text-white mb-2">First Name</label>
|
|
5887
|
+
<input
|
|
5888
|
+
type="text"
|
|
5889
|
+
name="first_name"
|
|
5905
5890
|
value="${data.profile.first_name}"
|
|
5906
5891
|
required
|
|
5907
|
-
class="w-full px-
|
|
5892
|
+
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"
|
|
5908
5893
|
placeholder="Enter your first name"
|
|
5909
5894
|
>
|
|
5910
5895
|
</div>
|
|
5911
5896
|
<div>
|
|
5912
|
-
<label class="block text-sm font-medium text-
|
|
5913
|
-
<input
|
|
5914
|
-
type="text"
|
|
5915
|
-
name="last_name"
|
|
5897
|
+
<label class="block text-sm font-medium text-zinc-950 dark:text-white mb-2">Last Name</label>
|
|
5898
|
+
<input
|
|
5899
|
+
type="text"
|
|
5900
|
+
name="last_name"
|
|
5916
5901
|
value="${data.profile.last_name}"
|
|
5917
5902
|
required
|
|
5918
|
-
class="w-full px-
|
|
5903
|
+
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"
|
|
5919
5904
|
placeholder="Enter your last name"
|
|
5920
5905
|
>
|
|
5921
5906
|
</div>
|
|
5922
5907
|
</div>
|
|
5923
5908
|
|
|
5924
5909
|
<div>
|
|
5925
|
-
<label class="block text-sm font-medium text-
|
|
5926
|
-
<input
|
|
5927
|
-
type="text"
|
|
5928
|
-
name="username"
|
|
5910
|
+
<label class="block text-sm font-medium text-zinc-950 dark:text-white mb-2">Username</label>
|
|
5911
|
+
<input
|
|
5912
|
+
type="text"
|
|
5913
|
+
name="username"
|
|
5929
5914
|
value="${data.profile.username}"
|
|
5930
5915
|
required
|
|
5931
|
-
class="w-full px-
|
|
5916
|
+
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"
|
|
5932
5917
|
placeholder="Enter your username"
|
|
5933
5918
|
>
|
|
5934
5919
|
</div>
|
|
5935
5920
|
|
|
5936
5921
|
<div>
|
|
5937
|
-
<label class="block text-sm font-medium text-
|
|
5938
|
-
<input
|
|
5939
|
-
type="email"
|
|
5940
|
-
name="email"
|
|
5922
|
+
<label class="block text-sm font-medium text-zinc-950 dark:text-white mb-2">Email Address</label>
|
|
5923
|
+
<input
|
|
5924
|
+
type="email"
|
|
5925
|
+
name="email"
|
|
5941
5926
|
value="${data.profile.email}"
|
|
5942
5927
|
required
|
|
5943
|
-
class="w-full px-
|
|
5928
|
+
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"
|
|
5944
5929
|
placeholder="Enter your email address"
|
|
5945
5930
|
>
|
|
5946
5931
|
</div>
|
|
5947
5932
|
|
|
5948
5933
|
<div>
|
|
5949
|
-
<label class="block text-sm font-medium text-
|
|
5950
|
-
<input
|
|
5951
|
-
type="tel"
|
|
5952
|
-
name="phone"
|
|
5934
|
+
<label class="block text-sm font-medium text-zinc-950 dark:text-white mb-2">Phone Number</label>
|
|
5935
|
+
<input
|
|
5936
|
+
type="tel"
|
|
5937
|
+
name="phone"
|
|
5953
5938
|
value="${data.profile.phone || ""}"
|
|
5954
|
-
class="w-full px-
|
|
5939
|
+
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"
|
|
5955
5940
|
placeholder="Enter your phone number"
|
|
5956
5941
|
>
|
|
5957
5942
|
</div>
|
|
5958
5943
|
|
|
5959
5944
|
<div>
|
|
5960
|
-
<label class="block text-sm font-medium text-
|
|
5961
|
-
<textarea
|
|
5962
|
-
name="bio"
|
|
5945
|
+
<label class="block text-sm font-medium text-zinc-950 dark:text-white mb-2">Bio</label>
|
|
5946
|
+
<textarea
|
|
5947
|
+
name="bio"
|
|
5963
5948
|
rows="3"
|
|
5964
|
-
class="w-full px-
|
|
5949
|
+
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"
|
|
5965
5950
|
placeholder="Tell us about yourself..."
|
|
5966
5951
|
>${data.profile.bio || ""}</textarea>
|
|
5967
5952
|
</div>
|
|
5968
5953
|
|
|
5969
5954
|
<!-- Preferences -->
|
|
5970
|
-
<div class="pt-6 border-t border-white/
|
|
5971
|
-
<h3 class="text-
|
|
5972
|
-
|
|
5955
|
+
<div class="pt-6 border-t border-zinc-950/5 dark:border-white/5">
|
|
5956
|
+
<h3 class="text-base font-semibold text-zinc-950 dark:text-white mb-4">Preferences</h3>
|
|
5957
|
+
|
|
5973
5958
|
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
|
|
5974
5959
|
<div>
|
|
5975
|
-
<label class="block text-sm font-medium text-
|
|
5976
|
-
<
|
|
5977
|
-
name="timezone"
|
|
5978
|
-
|
|
5979
|
-
|
|
5980
|
-
|
|
5981
|
-
|
|
5982
|
-
|
|
5983
|
-
|
|
5960
|
+
<label for="timezone" class="block text-sm/6 font-medium text-zinc-950 dark:text-white mb-2">Timezone</label>
|
|
5961
|
+
<div class="grid grid-cols-1">
|
|
5962
|
+
<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">
|
|
5963
|
+
${data.timezones.map((tz) => `
|
|
5964
|
+
<option value="${tz.value}" ${tz.value === data.profile.timezone ? "selected" : ""}>${tz.label}</option>
|
|
5965
|
+
`).join("")}
|
|
5966
|
+
</select>
|
|
5967
|
+
<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">
|
|
5968
|
+
<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" />
|
|
5969
|
+
</svg>
|
|
5970
|
+
</div>
|
|
5984
5971
|
</div>
|
|
5985
5972
|
<div>
|
|
5986
|
-
<label class="block text-sm font-medium text-
|
|
5987
|
-
<
|
|
5988
|
-
name="language"
|
|
5989
|
-
|
|
5990
|
-
|
|
5991
|
-
|
|
5992
|
-
|
|
5993
|
-
|
|
5994
|
-
|
|
5973
|
+
<label for="language" class="block text-sm/6 font-medium text-zinc-950 dark:text-white mb-2">Language</label>
|
|
5974
|
+
<div class="grid grid-cols-1">
|
|
5975
|
+
<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">
|
|
5976
|
+
${data.languages.map((lang) => `
|
|
5977
|
+
<option value="${lang.value}" ${lang.value === data.profile.language ? "selected" : ""}>${lang.label}</option>
|
|
5978
|
+
`).join("")}
|
|
5979
|
+
</select>
|
|
5980
|
+
<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">
|
|
5981
|
+
<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" />
|
|
5982
|
+
</svg>
|
|
5983
|
+
</div>
|
|
5995
5984
|
</div>
|
|
5996
5985
|
</div>
|
|
5997
5986
|
</div>
|
|
5998
5987
|
|
|
5999
5988
|
<!-- Notifications -->
|
|
6000
|
-
<div class="pt-6 border-t border-white/
|
|
6001
|
-
<h3 class="text-
|
|
6002
|
-
|
|
5989
|
+
<div class="pt-6 border-t border-zinc-950/5 dark:border-white/5">
|
|
5990
|
+
<h3 class="text-base font-semibold text-zinc-950 dark:text-white mb-4">Notifications</h3>
|
|
5991
|
+
|
|
6003
5992
|
<div class="space-y-5">
|
|
6004
5993
|
<div class="flex gap-3">
|
|
6005
5994
|
<div class="flex h-6 shrink-0 items-center">
|
|
@@ -6010,27 +5999,30 @@ function renderProfilePage(data) {
|
|
|
6010
5999
|
name="email_notifications"
|
|
6011
6000
|
value="1"
|
|
6012
6001
|
${data.profile.email_notifications ? "checked" : ""}
|
|
6013
|
-
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
|
|
6002
|
+
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"
|
|
6014
6003
|
/>
|
|
6015
6004
|
<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">
|
|
6016
6005
|
<path d="M3 8L6 11L11 3.5" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="opacity-0 group-has-[:checked]:opacity-100" />
|
|
6017
|
-
<path d="M3 7H11" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="opacity-0 group-has-[:indeterminate]:opacity-100" />
|
|
6018
6006
|
</svg>
|
|
6019
6007
|
</div>
|
|
6020
6008
|
</div>
|
|
6021
6009
|
<div class="text-sm/6">
|
|
6022
6010
|
<label for="email_notifications" class="font-medium text-zinc-950 dark:text-white">Email notifications</label>
|
|
6011
|
+
<p class="text-zinc-500 dark:text-zinc-400">Receive email updates about new features and product announcements.</p>
|
|
6023
6012
|
</div>
|
|
6024
6013
|
</div>
|
|
6025
6014
|
</div>
|
|
6026
6015
|
</div>
|
|
6027
6016
|
|
|
6028
6017
|
<!-- Submit Button -->
|
|
6029
|
-
<div class="pt-6 border-t border-white/
|
|
6030
|
-
<button
|
|
6018
|
+
<div class="pt-6 border-t border-zinc-950/5 dark:border-white/5">
|
|
6019
|
+
<button
|
|
6031
6020
|
type="submit"
|
|
6032
|
-
class="
|
|
6021
|
+
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"
|
|
6033
6022
|
>
|
|
6023
|
+
<svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
6024
|
+
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7"/>
|
|
6025
|
+
</svg>
|
|
6034
6026
|
Update Profile
|
|
6035
6027
|
</button>
|
|
6036
6028
|
</div>
|
|
@@ -6041,86 +6033,96 @@ function renderProfilePage(data) {
|
|
|
6041
6033
|
<!-- Profile Sidebar -->
|
|
6042
6034
|
<div class="lg:col-span-1 space-y-6">
|
|
6043
6035
|
<!-- Avatar -->
|
|
6044
|
-
<div class="
|
|
6045
|
-
<h3 class="text-
|
|
6046
|
-
|
|
6036
|
+
<div class="rounded-xl bg-white dark:bg-zinc-900 shadow-sm ring-1 ring-zinc-950/5 dark:ring-white/10 p-6">
|
|
6037
|
+
<h3 class="text-base font-semibold text-zinc-950 dark:text-white mb-4">Profile Picture</h3>
|
|
6038
|
+
|
|
6047
6039
|
<div class="text-center">
|
|
6048
|
-
<div class="w-24 h-24 rounded-full mx-auto mb-4 overflow-hidden bg-gradient-to-br from-
|
|
6040
|
+
<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">
|
|
6049
6041
|
${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>`}
|
|
6050
6042
|
</div>
|
|
6051
|
-
|
|
6043
|
+
|
|
6052
6044
|
<form id="avatar-form" hx-post="/admin/profile/avatar" hx-target="#avatar-messages" hx-encoding="multipart/form-data">
|
|
6053
|
-
<input
|
|
6054
|
-
type="file"
|
|
6055
|
-
name="avatar"
|
|
6045
|
+
<input
|
|
6046
|
+
type="file"
|
|
6047
|
+
name="avatar"
|
|
6056
6048
|
accept="image/*"
|
|
6057
6049
|
class="hidden"
|
|
6058
6050
|
id="avatar-input"
|
|
6059
6051
|
onchange="document.getElementById('avatar-form').dispatchEvent(new Event('submit'))"
|
|
6060
6052
|
>
|
|
6061
|
-
<label
|
|
6053
|
+
<label
|
|
6062
6054
|
for="avatar-input"
|
|
6063
|
-
class="inline-
|
|
6055
|
+
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"
|
|
6064
6056
|
>
|
|
6057
|
+
<svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
6058
|
+
<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"/>
|
|
6059
|
+
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 13a3 3 0 11-6 0 3 3 0 016 0z"/>
|
|
6060
|
+
</svg>
|
|
6065
6061
|
Change Picture
|
|
6066
6062
|
</label>
|
|
6067
6063
|
</form>
|
|
6068
|
-
|
|
6064
|
+
|
|
6069
6065
|
<div id="avatar-messages" class="mt-3"></div>
|
|
6070
6066
|
</div>
|
|
6071
6067
|
</div>
|
|
6072
6068
|
|
|
6073
6069
|
<!-- Account Info -->
|
|
6074
|
-
<div class="
|
|
6075
|
-
<h3 class="text-
|
|
6076
|
-
|
|
6077
|
-
<
|
|
6070
|
+
<div class="rounded-xl bg-white dark:bg-zinc-900 shadow-sm ring-1 ring-zinc-950/5 dark:ring-white/10 p-6">
|
|
6071
|
+
<h3 class="text-base font-semibold text-zinc-950 dark:text-white mb-4">Account Information</h3>
|
|
6072
|
+
|
|
6073
|
+
<dl class="space-y-3 text-sm">
|
|
6078
6074
|
<div>
|
|
6079
|
-
<
|
|
6080
|
-
<
|
|
6075
|
+
<dt class="text-zinc-500 dark:text-zinc-400">Role</dt>
|
|
6076
|
+
<dd class="mt-1">
|
|
6077
|
+
<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">
|
|
6078
|
+
${data.profile.role}
|
|
6079
|
+
</span>
|
|
6080
|
+
</dd>
|
|
6081
6081
|
</div>
|
|
6082
6082
|
<div>
|
|
6083
|
-
<
|
|
6084
|
-
<
|
|
6083
|
+
<dt class="text-zinc-500 dark:text-zinc-400">Member Since</dt>
|
|
6084
|
+
<dd class="mt-1 text-zinc-950 dark:text-white">${new Date(data.profile.created_at).toLocaleDateString()}</dd>
|
|
6085
6085
|
</div>
|
|
6086
6086
|
${data.profile.last_login_at ? `
|
|
6087
6087
|
<div>
|
|
6088
|
-
<
|
|
6089
|
-
<
|
|
6088
|
+
<dt class="text-zinc-500 dark:text-zinc-400">Last Login</dt>
|
|
6089
|
+
<dd class="mt-1 text-zinc-950 dark:text-white">${new Date(data.profile.last_login_at).toLocaleDateString()}</dd>
|
|
6090
6090
|
</div>
|
|
6091
6091
|
` : ""}
|
|
6092
6092
|
<div>
|
|
6093
|
-
<
|
|
6094
|
-
<
|
|
6093
|
+
<dt class="text-zinc-500 dark:text-zinc-400">Two-Factor Auth</dt>
|
|
6094
|
+
<dd class="mt-1">
|
|
6095
|
+
${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>'}
|
|
6096
|
+
</dd>
|
|
6095
6097
|
</div>
|
|
6096
|
-
</
|
|
6098
|
+
</dl>
|
|
6097
6099
|
</div>
|
|
6098
6100
|
|
|
6099
6101
|
<!-- Security Actions -->
|
|
6100
|
-
<div class="
|
|
6101
|
-
<h3 class="text-
|
|
6102
|
-
|
|
6103
|
-
<div class="space-y-
|
|
6104
|
-
<button
|
|
6102
|
+
<div class="rounded-xl bg-white dark:bg-zinc-900 shadow-sm ring-1 ring-zinc-950/5 dark:ring-white/10 p-6">
|
|
6103
|
+
<h3 class="text-base font-semibold text-zinc-950 dark:text-white mb-4">Security</h3>
|
|
6104
|
+
|
|
6105
|
+
<div class="space-y-2">
|
|
6106
|
+
<button
|
|
6105
6107
|
type="button"
|
|
6106
6108
|
onclick="showChangePasswordModal()"
|
|
6107
|
-
class="w-full text-left px-3 py-2 text-sm text-
|
|
6109
|
+
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"
|
|
6108
6110
|
>
|
|
6109
|
-
<svg class="w-4 h-4
|
|
6111
|
+
<svg class="w-4 h-4 text-zinc-500 dark:text-zinc-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
6110
6112
|
<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"/>
|
|
6111
6113
|
</svg>
|
|
6112
|
-
Change Password
|
|
6114
|
+
<span class="font-medium">Change Password</span>
|
|
6113
6115
|
</button>
|
|
6114
|
-
|
|
6115
|
-
<button
|
|
6116
|
+
|
|
6117
|
+
<button
|
|
6116
6118
|
type="button"
|
|
6117
6119
|
onclick="toggle2FA()"
|
|
6118
|
-
class="w-full text-left px-3 py-2 text-sm text-
|
|
6120
|
+
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"
|
|
6119
6121
|
>
|
|
6120
|
-
<svg class="w-4 h-4
|
|
6122
|
+
<svg class="w-4 h-4 text-zinc-500 dark:text-zinc-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
6121
6123
|
<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"/>
|
|
6122
6124
|
</svg>
|
|
6123
|
-
|
|
6125
|
+
<span class="font-medium">${data.profile.two_factor_enabled ? "Disable" : "Enable"} 2FA</span>
|
|
6124
6126
|
</button>
|
|
6125
6127
|
</div>
|
|
6126
6128
|
</div>
|
|
@@ -6129,67 +6131,73 @@ function renderProfilePage(data) {
|
|
|
6129
6131
|
</div>
|
|
6130
6132
|
|
|
6131
6133
|
<!-- Change Password Modal -->
|
|
6132
|
-
<div id="password-modal" class="fixed inset-0 bg-
|
|
6133
|
-
<div class="
|
|
6134
|
-
<div class="
|
|
6135
|
-
<div class="
|
|
6136
|
-
|
|
6137
|
-
<
|
|
6138
|
-
|
|
6139
|
-
<svg class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
6134
|
+
<div id="password-modal" class="fixed inset-0 bg-zinc-950/50 backdrop-blur-sm flex items-center justify-center z-50 hidden">
|
|
6135
|
+
<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">
|
|
6136
|
+
<div class="px-6 py-5 border-b border-zinc-950/5 dark:border-white/5">
|
|
6137
|
+
<div class="flex items-center justify-between">
|
|
6138
|
+
<h3 class="text-base font-semibold text-zinc-950 dark:text-white">Change Password</h3>
|
|
6139
|
+
<button onclick="closePasswordModal()" class="text-zinc-500 dark:text-zinc-400 hover:text-zinc-950 dark:hover:text-white transition-colors">
|
|
6140
|
+
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
6140
6141
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12"></path>
|
|
6141
6142
|
</svg>
|
|
6142
6143
|
</button>
|
|
6143
6144
|
</div>
|
|
6144
6145
|
</div>
|
|
6145
|
-
|
|
6146
|
+
|
|
6146
6147
|
<form id="password-form" hx-post="/admin/profile/password" hx-target="#password-messages" class="p-6 space-y-4">
|
|
6147
6148
|
<div id="password-messages"></div>
|
|
6148
|
-
|
|
6149
|
+
|
|
6149
6150
|
<div>
|
|
6150
|
-
<label class="block text-sm font-medium text-
|
|
6151
|
-
<input
|
|
6152
|
-
type="password"
|
|
6153
|
-
name="current_password"
|
|
6151
|
+
<label class="block text-sm font-medium text-zinc-950 dark:text-white mb-2">Current Password</label>
|
|
6152
|
+
<input
|
|
6153
|
+
type="password"
|
|
6154
|
+
name="current_password"
|
|
6154
6155
|
required
|
|
6155
|
-
class="w-full px-
|
|
6156
|
+
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"
|
|
6157
|
+
placeholder="Enter current password"
|
|
6156
6158
|
>
|
|
6157
6159
|
</div>
|
|
6158
6160
|
|
|
6159
6161
|
<div>
|
|
6160
|
-
<label class="block text-sm font-medium text-
|
|
6161
|
-
<input
|
|
6162
|
-
type="password"
|
|
6163
|
-
name="new_password"
|
|
6162
|
+
<label class="block text-sm font-medium text-zinc-950 dark:text-white mb-2">New Password</label>
|
|
6163
|
+
<input
|
|
6164
|
+
type="password"
|
|
6165
|
+
name="new_password"
|
|
6164
6166
|
required
|
|
6165
6167
|
minlength="8"
|
|
6166
|
-
class="w-full px-
|
|
6168
|
+
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"
|
|
6169
|
+
placeholder="Enter new password"
|
|
6167
6170
|
>
|
|
6171
|
+
<p class="mt-1 text-xs text-zinc-500 dark:text-zinc-400">Must be at least 8 characters</p>
|
|
6168
6172
|
</div>
|
|
6169
6173
|
|
|
6170
6174
|
<div>
|
|
6171
|
-
<label class="block text-sm font-medium text-
|
|
6172
|
-
<input
|
|
6173
|
-
type="password"
|
|
6174
|
-
name="confirm_password"
|
|
6175
|
+
<label class="block text-sm font-medium text-zinc-950 dark:text-white mb-2">Confirm New Password</label>
|
|
6176
|
+
<input
|
|
6177
|
+
type="password"
|
|
6178
|
+
name="confirm_password"
|
|
6175
6179
|
required
|
|
6176
6180
|
minlength="8"
|
|
6177
|
-
class="w-full px-
|
|
6181
|
+
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"
|
|
6182
|
+
placeholder="Confirm new password"
|
|
6178
6183
|
>
|
|
6179
6184
|
</div>
|
|
6180
6185
|
|
|
6181
|
-
<div class="flex justify-end
|
|
6182
|
-
<button
|
|
6183
|
-
type="button"
|
|
6186
|
+
<div class="flex justify-end gap-x-3 pt-4 border-t border-zinc-950/5 dark:border-white/5">
|
|
6187
|
+
<button
|
|
6188
|
+
type="button"
|
|
6184
6189
|
onclick="closePasswordModal()"
|
|
6185
|
-
class="px-4 py-2
|
|
6190
|
+
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"
|
|
6186
6191
|
>
|
|
6187
6192
|
Cancel
|
|
6188
6193
|
</button>
|
|
6189
|
-
<button
|
|
6194
|
+
<button
|
|
6190
6195
|
type="submit"
|
|
6191
|
-
class="
|
|
6196
|
+
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"
|
|
6192
6197
|
>
|
|
6198
|
+
<svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
6199
|
+
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7"/>
|
|
6200
|
+
</svg>
|
|
6193
6201
|
Update Password
|
|
6194
6202
|
</button>
|
|
6195
6203
|
</div>
|
|
@@ -6232,9 +6240,10 @@ function renderProfilePage(data) {
|
|
|
6232
6240
|
pageTitle: "Profile",
|
|
6233
6241
|
currentPath: "/admin/profile",
|
|
6234
6242
|
user: data.user,
|
|
6243
|
+
version: data.version,
|
|
6235
6244
|
content: pageContent
|
|
6236
6245
|
};
|
|
6237
|
-
return
|
|
6246
|
+
return renderAdminLayoutCatalyst(layoutData);
|
|
6238
6247
|
}
|
|
6239
6248
|
|
|
6240
6249
|
// src/templates/components/alert.template.ts
|
|
@@ -7653,6 +7662,9 @@ function renderUsersListPage(data) {
|
|
|
7653
7662
|
// src/routes/admin-users.ts
|
|
7654
7663
|
var userRoutes = new Hono();
|
|
7655
7664
|
userRoutes.use("*", requireAuth());
|
|
7665
|
+
userRoutes.get("/", (c) => {
|
|
7666
|
+
return c.redirect("/admin/dashboard");
|
|
7667
|
+
});
|
|
7656
7668
|
var TIMEZONES = [
|
|
7657
7669
|
{ value: "UTC", label: "UTC" },
|
|
7658
7670
|
{ value: "America/New_York", label: "Eastern Time" },
|
|
@@ -10133,6 +10145,7 @@ var fileValidationSchema2 = z.object({
|
|
|
10133
10145
|
// 50MB max
|
|
10134
10146
|
});
|
|
10135
10147
|
var adminMediaRoutes = new Hono();
|
|
10148
|
+
adminMediaRoutes.use("*", requireAuth());
|
|
10136
10149
|
adminMediaRoutes.get("/", async (c) => {
|
|
10137
10150
|
try {
|
|
10138
10151
|
const user = c.get("user");
|
|
@@ -12152,6 +12165,7 @@ function formatTimestamp(timestamp) {
|
|
|
12152
12165
|
|
|
12153
12166
|
// src/routes/admin-plugins.ts
|
|
12154
12167
|
var adminPluginRoutes = new Hono();
|
|
12168
|
+
adminPluginRoutes.use("*", requireAuth());
|
|
12155
12169
|
adminPluginRoutes.get("/", async (c) => {
|
|
12156
12170
|
try {
|
|
12157
12171
|
const user = c.get("user");
|
|
@@ -13261,6 +13275,7 @@ function renderLogConfigPage(data) {
|
|
|
13261
13275
|
|
|
13262
13276
|
// src/routes/admin-logs.ts
|
|
13263
13277
|
var adminLogsRoutes = new Hono();
|
|
13278
|
+
adminLogsRoutes.use("*", requireAuth());
|
|
13264
13279
|
adminLogsRoutes.get("/", async (c) => {
|
|
13265
13280
|
try {
|
|
13266
13281
|
const user = c.get("user");
|
|
@@ -15743,7 +15758,7 @@ function renderAnalyticsChart() {
|
|
|
15743
15758
|
|
|
15744
15759
|
<!-- Hidden div to trigger HTMX polling -->
|
|
15745
15760
|
<div
|
|
15746
|
-
hx-get="/admin/api/metrics"
|
|
15761
|
+
hx-get="/admin/dashboard/api/metrics"
|
|
15747
15762
|
hx-trigger="every 1s"
|
|
15748
15763
|
hx-swap="none"
|
|
15749
15764
|
style="display: none;"
|
|
@@ -15846,9 +15861,12 @@ function renderAnalyticsChart() {
|
|
|
15846
15861
|
|
|
15847
15862
|
// Listen for metrics updates from HTMX
|
|
15848
15863
|
window.addEventListener('htmx:afterRequest', function(event) {
|
|
15849
|
-
|
|
15864
|
+
console.log('[Dashboard] HTMX request completed:', event.detail.pathInfo.requestPath);
|
|
15865
|
+
|
|
15866
|
+
if (event.detail.pathInfo.requestPath === '/admin/dashboard/api/metrics') {
|
|
15850
15867
|
try {
|
|
15851
15868
|
const metrics = JSON.parse(event.detail.xhr.responseText);
|
|
15869
|
+
console.log('[Dashboard] Metrics received:', metrics);
|
|
15852
15870
|
|
|
15853
15871
|
// Update current RPS display
|
|
15854
15872
|
const rpsElement = document.getElementById('current-rps');
|
|
@@ -15869,8 +15887,9 @@ function renderAnalyticsChart() {
|
|
|
15869
15887
|
chart.data.labels = newLabels;
|
|
15870
15888
|
|
|
15871
15889
|
chart.update('none'); // Update without animation for smoother real-time updates
|
|
15890
|
+
console.log('[Dashboard] Chart updated with RPS:', metrics.requestsPerSecond);
|
|
15872
15891
|
} catch (e) {
|
|
15873
|
-
console.error('Error updating metrics:', e);
|
|
15892
|
+
console.error('[Dashboard] Error updating metrics:', e);
|
|
15874
15893
|
}
|
|
15875
15894
|
}
|
|
15876
15895
|
});
|
|
@@ -16217,7 +16236,7 @@ router.get("/", async (c) => {
|
|
|
16217
16236
|
return c.html(renderDashboardPage(pageData));
|
|
16218
16237
|
}
|
|
16219
16238
|
});
|
|
16220
|
-
router.get("/
|
|
16239
|
+
router.get("/stats", async (c) => {
|
|
16221
16240
|
try {
|
|
16222
16241
|
const db = c.env.DB;
|
|
16223
16242
|
let collectionsCount = 0;
|
|
@@ -16267,7 +16286,7 @@ router.get("/dashboard/stats", async (c) => {
|
|
|
16267
16286
|
return c.html('<div class="text-red-500">Failed to load statistics</div>');
|
|
16268
16287
|
}
|
|
16269
16288
|
});
|
|
16270
|
-
router.get("/
|
|
16289
|
+
router.get("/storage", async (c) => {
|
|
16271
16290
|
try {
|
|
16272
16291
|
const db = c.env.DB;
|
|
16273
16292
|
let databaseSize = 0;
|
|
@@ -16292,7 +16311,7 @@ router.get("/dashboard/storage", async (c) => {
|
|
|
16292
16311
|
return c.html('<div class="text-red-500">Failed to load storage information</div>');
|
|
16293
16312
|
}
|
|
16294
16313
|
});
|
|
16295
|
-
router.get("/
|
|
16314
|
+
router.get("/recent-activity", async (c) => {
|
|
16296
16315
|
try {
|
|
16297
16316
|
const db = c.env.DB;
|
|
16298
16317
|
const limit = parseInt(c.req.query("limit") || "5");
|
|
@@ -16344,25 +16363,14 @@ router.get("/dashboard/recent-activity", async (c) => {
|
|
|
16344
16363
|
}
|
|
16345
16364
|
});
|
|
16346
16365
|
router.get("/api/metrics", async (c) => {
|
|
16347
|
-
|
|
16348
|
-
|
|
16349
|
-
|
|
16350
|
-
|
|
16351
|
-
|
|
16352
|
-
|
|
16353
|
-
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
16354
|
-
});
|
|
16355
|
-
} catch (error) {
|
|
16356
|
-
console.error("Error fetching metrics:", error);
|
|
16357
|
-
return c.json({
|
|
16358
|
-
requestsPerSecond: 0,
|
|
16359
|
-
totalRequests: 0,
|
|
16360
|
-
averageRPS: 0,
|
|
16361
|
-
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
16362
|
-
});
|
|
16363
|
-
}
|
|
16366
|
+
return c.json({
|
|
16367
|
+
requestsPerSecond: metricsTracker.getRequestsPerSecond(),
|
|
16368
|
+
totalRequests: metricsTracker.getTotalRequests(),
|
|
16369
|
+
averageRPS: Number(metricsTracker.getAverageRPS().toFixed(2)),
|
|
16370
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
16371
|
+
});
|
|
16364
16372
|
});
|
|
16365
|
-
router.get("/
|
|
16373
|
+
router.get("/system-status", async (c) => {
|
|
16366
16374
|
try {
|
|
16367
16375
|
const html9 = `
|
|
16368
16376
|
<div class="grid grid-cols-1 sm:grid-cols-2 gap-4">
|
|
@@ -17683,7 +17691,8 @@ function renderCollectionFormPage(data) {
|
|
|
17683
17691
|
|
|
17684
17692
|
// src/routes/admin-collections.ts
|
|
17685
17693
|
var adminCollectionsRoutes = new Hono();
|
|
17686
|
-
adminCollectionsRoutes.
|
|
17694
|
+
adminCollectionsRoutes.use("*", requireAuth());
|
|
17695
|
+
adminCollectionsRoutes.get("/", async (c) => {
|
|
17687
17696
|
try {
|
|
17688
17697
|
const user = c.get("user");
|
|
17689
17698
|
const db = c.env.DB;
|
|
@@ -17738,7 +17747,7 @@ adminCollectionsRoutes.get("/collections", async (c) => {
|
|
|
17738
17747
|
return c.html(html`<p>Error loading collections</p>`);
|
|
17739
17748
|
}
|
|
17740
17749
|
});
|
|
17741
|
-
adminCollectionsRoutes.get("/
|
|
17750
|
+
adminCollectionsRoutes.get("/new", (c) => {
|
|
17742
17751
|
const user = c.get("user");
|
|
17743
17752
|
const formData = {
|
|
17744
17753
|
isEdit: false,
|
|
@@ -17751,7 +17760,7 @@ adminCollectionsRoutes.get("/collections/new", (c) => {
|
|
|
17751
17760
|
};
|
|
17752
17761
|
return c.html(renderCollectionFormPage(formData));
|
|
17753
17762
|
});
|
|
17754
|
-
adminCollectionsRoutes.post("/
|
|
17763
|
+
adminCollectionsRoutes.post("/", async (c) => {
|
|
17755
17764
|
try {
|
|
17756
17765
|
const formData = await c.req.formData();
|
|
17757
17766
|
const name = formData.get("name");
|
|
@@ -17870,7 +17879,7 @@ adminCollectionsRoutes.post("/collections", async (c) => {
|
|
|
17870
17879
|
}
|
|
17871
17880
|
}
|
|
17872
17881
|
});
|
|
17873
|
-
adminCollectionsRoutes.get("
|
|
17882
|
+
adminCollectionsRoutes.get("/:id", async (c) => {
|
|
17874
17883
|
try {
|
|
17875
17884
|
const id = c.req.param("id");
|
|
17876
17885
|
const user = c.get("user");
|
|
@@ -17938,7 +17947,7 @@ adminCollectionsRoutes.get("/collections/:id", async (c) => {
|
|
|
17938
17947
|
return c.html(renderCollectionFormPage(formData));
|
|
17939
17948
|
}
|
|
17940
17949
|
});
|
|
17941
|
-
adminCollectionsRoutes.put("
|
|
17950
|
+
adminCollectionsRoutes.put("/:id", async (c) => {
|
|
17942
17951
|
try {
|
|
17943
17952
|
const id = c.req.param("id");
|
|
17944
17953
|
const formData = await c.req.formData();
|
|
@@ -17972,7 +17981,7 @@ adminCollectionsRoutes.put("/collections/:id", async (c) => {
|
|
|
17972
17981
|
`);
|
|
17973
17982
|
}
|
|
17974
17983
|
});
|
|
17975
|
-
adminCollectionsRoutes.delete("
|
|
17984
|
+
adminCollectionsRoutes.delete("/:id", async (c) => {
|
|
17976
17985
|
try {
|
|
17977
17986
|
const id = c.req.param("id");
|
|
17978
17987
|
const db = c.env.DB;
|
|
@@ -18003,7 +18012,7 @@ adminCollectionsRoutes.delete("/collections/:id", async (c) => {
|
|
|
18003
18012
|
`);
|
|
18004
18013
|
}
|
|
18005
18014
|
});
|
|
18006
|
-
adminCollectionsRoutes.post("
|
|
18015
|
+
adminCollectionsRoutes.post("/:id/fields", async (c) => {
|
|
18007
18016
|
try {
|
|
18008
18017
|
const collectionId = c.req.param("id");
|
|
18009
18018
|
const formData = await c.req.formData();
|
|
@@ -18056,7 +18065,7 @@ adminCollectionsRoutes.post("/collections/:id/fields", async (c) => {
|
|
|
18056
18065
|
return c.json({ success: false, error: "Failed to add field." });
|
|
18057
18066
|
}
|
|
18058
18067
|
});
|
|
18059
|
-
adminCollectionsRoutes.put("
|
|
18068
|
+
adminCollectionsRoutes.put("/:collectionId/fields/:fieldId", async (c) => {
|
|
18060
18069
|
try {
|
|
18061
18070
|
const fieldId = c.req.param("fieldId");
|
|
18062
18071
|
const formData = await c.req.formData();
|
|
@@ -18080,7 +18089,7 @@ adminCollectionsRoutes.put("/collections/:collectionId/fields/:fieldId", async (
|
|
|
18080
18089
|
return c.json({ success: false, error: "Failed to update field." });
|
|
18081
18090
|
}
|
|
18082
18091
|
});
|
|
18083
|
-
adminCollectionsRoutes.delete("
|
|
18092
|
+
adminCollectionsRoutes.delete("/:collectionId/fields/:fieldId", async (c) => {
|
|
18084
18093
|
try {
|
|
18085
18094
|
const fieldId = c.req.param("fieldId");
|
|
18086
18095
|
const db = c.env.DB;
|
|
@@ -18092,7 +18101,7 @@ adminCollectionsRoutes.delete("/collections/:collectionId/fields/:fieldId", asyn
|
|
|
18092
18101
|
return c.json({ success: false, error: "Failed to delete field." });
|
|
18093
18102
|
}
|
|
18094
18103
|
});
|
|
18095
|
-
adminCollectionsRoutes.post("
|
|
18104
|
+
adminCollectionsRoutes.post("/:collectionId/fields/reorder", async (c) => {
|
|
18096
18105
|
try {
|
|
18097
18106
|
const body = await c.req.json();
|
|
18098
18107
|
const fieldIds = body.fieldIds;
|
|
@@ -19539,6 +19548,7 @@ function renderDatabaseToolsSettings(settings) {
|
|
|
19539
19548
|
|
|
19540
19549
|
// src/routes/admin-settings.ts
|
|
19541
19550
|
var adminSettingsRoutes = new Hono();
|
|
19551
|
+
adminSettingsRoutes.use("*", requireAuth());
|
|
19542
19552
|
function getMockSettings(user) {
|
|
19543
19553
|
return {
|
|
19544
19554
|
general: {
|
|
@@ -19597,10 +19607,10 @@ function getMockSettings(user) {
|
|
|
19597
19607
|
}
|
|
19598
19608
|
};
|
|
19599
19609
|
}
|
|
19600
|
-
adminSettingsRoutes.get("/
|
|
19610
|
+
adminSettingsRoutes.get("/", (c) => {
|
|
19601
19611
|
return c.redirect("/admin/settings/general");
|
|
19602
19612
|
});
|
|
19603
|
-
adminSettingsRoutes.get("/
|
|
19613
|
+
adminSettingsRoutes.get("/general", (c) => {
|
|
19604
19614
|
const user = c.get("user");
|
|
19605
19615
|
const pageData = {
|
|
19606
19616
|
user: user ? {
|
|
@@ -19614,7 +19624,7 @@ adminSettingsRoutes.get("/settings/general", (c) => {
|
|
|
19614
19624
|
};
|
|
19615
19625
|
return c.html(renderSettingsPage(pageData));
|
|
19616
19626
|
});
|
|
19617
|
-
adminSettingsRoutes.get("/
|
|
19627
|
+
adminSettingsRoutes.get("/appearance", (c) => {
|
|
19618
19628
|
const user = c.get("user");
|
|
19619
19629
|
const pageData = {
|
|
19620
19630
|
user: user ? {
|
|
@@ -19628,7 +19638,7 @@ adminSettingsRoutes.get("/settings/appearance", (c) => {
|
|
|
19628
19638
|
};
|
|
19629
19639
|
return c.html(renderSettingsPage(pageData));
|
|
19630
19640
|
});
|
|
19631
|
-
adminSettingsRoutes.get("/
|
|
19641
|
+
adminSettingsRoutes.get("/security", (c) => {
|
|
19632
19642
|
const user = c.get("user");
|
|
19633
19643
|
const pageData = {
|
|
19634
19644
|
user: user ? {
|
|
@@ -19642,7 +19652,7 @@ adminSettingsRoutes.get("/settings/security", (c) => {
|
|
|
19642
19652
|
};
|
|
19643
19653
|
return c.html(renderSettingsPage(pageData));
|
|
19644
19654
|
});
|
|
19645
|
-
adminSettingsRoutes.get("/
|
|
19655
|
+
adminSettingsRoutes.get("/notifications", (c) => {
|
|
19646
19656
|
const user = c.get("user");
|
|
19647
19657
|
const pageData = {
|
|
19648
19658
|
user: user ? {
|
|
@@ -19656,7 +19666,7 @@ adminSettingsRoutes.get("/settings/notifications", (c) => {
|
|
|
19656
19666
|
};
|
|
19657
19667
|
return c.html(renderSettingsPage(pageData));
|
|
19658
19668
|
});
|
|
19659
|
-
adminSettingsRoutes.get("/
|
|
19669
|
+
adminSettingsRoutes.get("/storage", (c) => {
|
|
19660
19670
|
const user = c.get("user");
|
|
19661
19671
|
const pageData = {
|
|
19662
19672
|
user: user ? {
|
|
@@ -19670,7 +19680,7 @@ adminSettingsRoutes.get("/settings/storage", (c) => {
|
|
|
19670
19680
|
};
|
|
19671
19681
|
return c.html(renderSettingsPage(pageData));
|
|
19672
19682
|
});
|
|
19673
|
-
adminSettingsRoutes.get("/
|
|
19683
|
+
adminSettingsRoutes.get("/migrations", (c) => {
|
|
19674
19684
|
const user = c.get("user");
|
|
19675
19685
|
const pageData = {
|
|
19676
19686
|
user: user ? {
|
|
@@ -19684,7 +19694,7 @@ adminSettingsRoutes.get("/settings/migrations", (c) => {
|
|
|
19684
19694
|
};
|
|
19685
19695
|
return c.html(renderSettingsPage(pageData));
|
|
19686
19696
|
});
|
|
19687
|
-
adminSettingsRoutes.get("/
|
|
19697
|
+
adminSettingsRoutes.get("/database-tools", (c) => {
|
|
19688
19698
|
const user = c.get("user");
|
|
19689
19699
|
const pageData = {
|
|
19690
19700
|
user: user ? {
|
|
@@ -19757,7 +19767,7 @@ adminSettingsRoutes.get("/api/migrations/validate", async (c) => {
|
|
|
19757
19767
|
}, 500);
|
|
19758
19768
|
}
|
|
19759
19769
|
});
|
|
19760
|
-
adminSettingsRoutes.post("/
|
|
19770
|
+
adminSettingsRoutes.post("/", async (c) => {
|
|
19761
19771
|
try {
|
|
19762
19772
|
const formData = await c.req.formData();
|
|
19763
19773
|
return c.html(html`
|
|
@@ -19809,5 +19819,5 @@ var ROUTES_INFO = {
|
|
|
19809
19819
|
};
|
|
19810
19820
|
|
|
19811
19821
|
export { ROUTES_INFO, adminCheckboxRoutes, adminCollectionsRoutes, adminDesignRoutes, adminLogsRoutes, adminMediaRoutes, adminPluginRoutes, adminSettingsRoutes, admin_api_default, admin_code_examples_default, admin_content_default, admin_faq_default, admin_testimonials_default, api_content_crud_default, api_default, api_media_default, api_system_default, auth_default, router, userRoutes };
|
|
19812
|
-
//# sourceMappingURL=chunk-
|
|
19813
|
-
//# sourceMappingURL=chunk-
|
|
19822
|
+
//# sourceMappingURL=chunk-SGGHTIWV.js.map
|
|
19823
|
+
//# sourceMappingURL=chunk-SGGHTIWV.js.map
|