@infuro/cms-core 1.0.15 → 1.0.16
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/admin.cjs +1840 -741
- package/dist/admin.cjs.map +1 -1
- package/dist/admin.d.cts +4 -0
- package/dist/admin.d.ts +4 -0
- package/dist/admin.js +1795 -681
- package/dist/admin.js.map +1 -1
- package/dist/api.cjs +577 -29
- package/dist/api.cjs.map +1 -1
- package/dist/api.d.cts +1 -1
- package/dist/api.d.ts +1 -1
- package/dist/api.js +572 -26
- package/dist/api.js.map +1 -1
- package/dist/hooks.cjs +159 -0
- package/dist/hooks.cjs.map +1 -1
- package/dist/hooks.d.cts +24 -1
- package/dist/hooks.d.ts +24 -1
- package/dist/hooks.js +165 -0
- package/dist/hooks.js.map +1 -1
- package/dist/{index-BiagwMjV.d.ts → index-C85X7cc7.d.ts} +14 -2
- package/dist/{index-BQnqJ7EO.d.cts → index-h42MoUNq.d.cts} +14 -2
- package/dist/index.cjs +5225 -4305
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +89 -11
- package/dist/index.d.ts +89 -11
- package/dist/index.js +5220 -4317
- package/dist/index.js.map +1 -1
- package/dist/migrations/1775200000000-MediaDriveFolders.ts +38 -0
- package/package.json +10 -12
package/dist/admin.js
CHANGED
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
|
|
3
3
|
// src/admin/pages/AdminLayout.tsx
|
|
4
|
-
import React5, { useEffect as useEffect2, useState as
|
|
4
|
+
import React5, { useEffect as useEffect2, useState as useState3 } from "react";
|
|
5
5
|
import { useSession as useSession2 } from "next-auth/react";
|
|
6
6
|
import { useRouter, usePathname as usePathname3 } from "next/navigation";
|
|
7
7
|
import { Toaster } from "sonner";
|
|
8
8
|
|
|
9
9
|
// src/components/Admin/Header.tsx
|
|
10
10
|
import { signOut, useSession } from "next-auth/react";
|
|
11
|
+
import { useMemo, useState as useState2 } from "react";
|
|
11
12
|
|
|
12
13
|
// src/components/ui/button.tsx
|
|
13
14
|
import * as React from "react";
|
|
@@ -229,25 +230,44 @@ function useIsMobile() {
|
|
|
229
230
|
return !!isMobile;
|
|
230
231
|
}
|
|
231
232
|
|
|
233
|
+
// src/lib/infuro-favicon.ts
|
|
234
|
+
var INFURO_FAVICON_BASE64 = "data:image/x-icon;base64,AAABAAMAEBAAAAEAIABoBAAANgAAACAgAAABACAAKBEAAJ4EAAAwMAAAAQAgAGgmAADGFQAAKAAAABAAAAAgAAAAAQAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8V////bv///7D////R////0f///7D///9u////FQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP///wL///9s0qun7q9qYv/DkYv/6tfV///+/v///////////////+7///9r////AgAAAAAAAAAAAAAAAP///wL///+Q/////sqcl/+WOzH/ljsx/5c9M//AiYP/+/j4/////////////////v///5D///8CAAAAAAAAAAD///9s/////v/////Oo5//lz00/5Y7Mf+WOzH/ljsx/7Z3cP/9+/v////////////////+////bAAAAAD///8V////7v///////////v39//Tq6f/QqKP/m0U8/5Y7Mf+WOzH/z6ah/////////////////////+7///8V////bv///////////////////////////////+XOy/+ZQTf/ljsx/59MQ//69fX/////////////////////bv///7D/////////////////////////////////////wYyG/5Y7Mf+WOzH/4MTC/////////////////////7D////R//////////////////7+//79/f/+/f3//v39/+DGw/+WOzH/ljsx/82inf/////////////////////R////0f///////////////9Svq/+mWVH/pllR/6ZZUf+iUUj/ljsx/5Y7Mf/KnJf/////////////////////0f///7D////////////////KnJf/ljsx/5Y7Mf+WOzH/ljsx/5Y7Mf+WOzH/062p/////////////////////7D///9u////////////////0amk/6FQSP+hUEj/oVBI/6JRSP+mWVH/plpS/+7g3v////////////////////9u////Ff///+7///////////7+/v/9/Pz/9u7t/8SSjP/Dj4r/9ezr//79/f/////////////////////u////FQAAAAD///9s/////v///////////////8OPif+WOzH/ljsx/7+Jgv/////////////////////+////bAAAAAAAAAAA////Av///5D////+//////////+9hH7/ljsx/5Y7Mf+8g3z////////////////+////kP///wIAAAAAAAAAAAAAAAD///8C////bP///+7/////8OTi/7R0bP+zcmr/8OLh///////////u////bP///wIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8V////bv///7D////R////0f///7D///9u////FQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKAAAACAAAABAAAAAAQAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8C////Hf///0n///95////mf///67///+u////mf///3n///9J////Hf///wIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8I////Tf///7D////p/////v////////////////////////////////////7////p////sP///03///8IAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8C////Pfjz8r7HlpH7wY2H/86lof/iysf/9e3s///+/v//////////////////////////////////////////+////77///89////AgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////Cf///37////z9Ovq/6BORf+WOzH/ljsx/5Y8Mv+hUEf/v4iC/+rY1v/+/f3///////////////////////////////////////////H///99////CQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP///wr///+d/////P/////06+r/oE5F/5Y7Mf+WOzH/ljsx/5Y7Mf+WOzH/m0Q7/8WTjf/38PD///////////////////////////////////////////z///+d////CgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8J////nf////3///////////Tr6v+gTkX/ljsx/5Y7Mf+WOzH/ljsx/5Y7Mf+WOzH/ljsx/61mX//w4+L///////////////////////////////////////////3///+d////CQAAAAAAAAAAAAAAAAAAAAAAAAAA////Av///37////8////////////////9Ovq/6BORf+WOzH/ljsx/5Y7Mf+WOzH/ljsx/5Y7Mf+WOzH/ljsx/6daUv/v4uD///////////////////////////////////////////z///9+////AgAAAAAAAAAAAAAAAAAAAAD///89////8//////////////////////48fD/rGRc/5pCOf+YPjT/ljsx/5Y7Mf+WOzH/ljsx/5Y7Mf+WOzH/ljsx/6xkXf/37+////////////////////////////////////////////P///89AAAAAAAAAAAAAAAA////CP///77////////////////////////////////7+Pf/8eXj/+DGw/++hn//m0U8/5Y7Mf+WOzH/ljsx/5Y7Mf+WOzH/ljsx/8GLhf/9/Pz//////////////////////////////////////////77///8IAAAAAAAAAAD///9N////+/////////////////////////////////////////////////7+/v/p1tP/rGRd/5Y7Mf+WOzH/ljsx/5Y7Mf+WOzH/mkI4/+XPzf//////////////////////////////////////////+////00AAAAA////Av///7D////////////////////////////////////////////////////////////////06+r/r2pi/5Y7Mf+WOzH/ljsx/5Y7Mf+WOzH/tndw//38+///////////////////////////////////////////sP///wL///8d////6f/////////////////////////////////////////////////////////////////////x5eP/olJJ/5Y7Mf+WOzH/ljsx/5Y7Mf+aQjn/7dza///////////////////////////////////////////p////Hf///0n////+///////////////////////////////////////////////////////////////////////////Ur6v/ljwy/5Y7Mf+WOzH/ljsx/5Y7Mf/Oo5////////////////////////////////////////////7///9J////ef////////////////////////////////////////////////////////////////////////////////fw7/+jVEv/ljsx/5Y7Mf+WOzH/ljsx/7Nxav///////////////////////////////////////////////3n///+Z/////////////////////////////////////////////////////////////////////////////////////7yCfP+WOzH/ljsx/5Y7Mf+WOzH/pllQ//r29f//////////////////////////////////////////mf///67///////////////////////////////////////////79/f/9/Pz//fz8//38/P/9/Pz//fz8//38/P/9/Pz/yZuW/5Y7Mf+WOzH/ljsx/5Y7Mf+gT0b/9evr//////////////////////////////////////////+u////rv/////////////////////////////////////69vb/wo2I/7Z3cf+2d3H/tndx/7Z3cf+2d3H/tndx/7Z3cf+lV0//ljsx/5Y7Mf+WOzH/ljsx/6BORf/06+r//////////////////////////////////////////67///+Z//////////////////////////////////////Tr6v+gTkX/ljsx/5Y7Mf+WOzH/ljsx/5Y7Mf+WOzH/ljsx/5Y7Mf+WOzH/ljsx/5Y7Mf+WOzH/oE5F//Tr6v//////////////////////////////////////////mf///3n/////////////////////////////////////9Ovq/6BORf+WOzH/ljsx/5Y7Mf+WOzH/ljsx/5Y7Mf+WOzH/ljsx/5Y7Mf+WOzH/ljsx/5Y7Mf+lVk7/+fPz//////////////////////////////////////////95////Sf////7////////////////////////////////06+r/oE5F/5Y7Mf+WOzH/ljsx/5Y7Mf+WOzH/ljsx/5Y7Mf+WOzH/ljsx/5Y7Mf+WOzH/ljsx/7FuZ////v7//////////////////////////////////////v///0n///8d////6f////////////////////////////////Tr6v+gTkX/ljsx/5Y7Mf+WOzH/ljsx/5Y7Mf+WOzH/ljsx/5Y7Mf+WOzH/ljsx/5Y7Mf+WOzH/zKCb///////////////////////////////////////////p////Hf///wL///+w////////////////////////////////+PLx/7d4cf+tZl//rWZf/61mX/+tZl//rWZf/61mX/+tZl//rmdg/7Z3cP+2d3H/tndx/7h7df/w4uH//////////////////////////////////////////7D///8CAAAAAP///03////7/////////////////////////////////Pv6//z6+f/8+vn//Pr5//z6+f/z6un/48zJ/+LKx//y5+b//fz8//38/P/9/Pz//fz8///////////////////////////////////////////7////TQAAAAAAAAAA////CP///77/////////////////////////////////////////////////////4MXC/6VXTv+WPDL/ljwy/6JRSP/aubb///7+/////////////////////////////////////////////////////77///8IAAAAAAAAAAAAAAAA////Pf////P///////////////////////////////////////////Xs6/+jU0r/ljsx/5Y7Mf+WOzH/ljsx/59MQv/w5OL////////////////////////////////////////////////z////PQAAAAAAAAAAAAAAAAAAAAD///8C////fv////z/////////////////////////////////////3sK//5Y7Mf+WOzH/ljsx/5Y7Mf+WOzH/ljsx/9m5tf///////////////////////////////////////////P///37///8CAAAAAAAAAAAAAAAAAAAAAAAAAAD///8J////nf////3////////////////////////////////ZuLX/ljsx/5Y7Mf+WOzH/ljsx/5Y7Mf+WOzH/17Sw//////////////////////////////////////3///+d////CQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8K////nf////z//////////////////////////+zc2v+aQzn/ljsx/5Y7Mf+WOzH/ljsx/5pDOf/r2tj////////////////////////////////8////nf///woAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8J////fv////P//////////////////////v39/8eYkv+YPjT/ljsx/5Y7Mf+YPjT/xpSP//79/f//////////////////////////8////37///8JAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8C////Pf///77////7/////////////////fv6/+DEwf/Ekoz/wY2H/97Bvv/8+vr/////////////////////+////77///89////AgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////CP///03///+w////6f////7////////////////////////////////////+////6f///7D///9N////CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP///wL///8d////Sf///3n///+Z////rv///67///+Z////ef///0n///8d////AgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKAAAADAAAABgAAAAAQAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8E////DP///xr///80////Rv///1n///9q////gP///4D///9q////Wf///0b///80////Gv///wz///8EAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////CP///y7///9g////lP///7v////V////6P////r////8/////P////z////8////+v///+j////V////u////5T///9g////Lv///wgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP///wf///81////k////8/////v////+v////////////////////////////////////////////////////////////////////r////v////z////5P///81////BwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8G////Kv37+3zt3Nrd27y5/Nm6t//fxMH/59LQ//Dk4v/48vH//fv6//////////////////////////////////////////////////////////////////////z////d////fP///yr///8GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP///xH///9g////wvz5+ffNop3+m0U8/5c+NP+cRz7/pFVN/65oYP+8gnv/0qun/+jU0v/59fT//v7+///////////////////////////////////////////////////////////+////9////8L///9f////EQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////GP///4n////m/////fv4+P/KnJf/mUE4/5Y7Mf+WOzH/ljsx/5Y7Mf+XPTT/m0Q6/6ZaUf/BjIX/6NXT//z5+f////////////////////////////////////////////////////////////////3////k////if///xgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP///wH///8i////pP////f///////////v4+P/KnJf/mUE4/5Y7Mf+WOzH/ljsx/5Y7Mf+WOzH/ljsx/5Y7Mf+XPjT/oVFI/8yhnP/x5OP//vz8////////////////////////////////////////////////////////////////9////6T///8i////AQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP///yL///+d////8/////////////////v4+P/KnJf/mUE4/5Y7Mf+WOzH/ljsx/5Y7Mf+WOzH/ljsx/5Y7Mf+WOzH/ljsx/5tEOv+3eHL/48rH//37+/////////////////////////////////////////////////////////////////P///+d////IgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////GP///6T////z//////////////////////v4+P/KnJf/mUE4/5Y7Mf+WOzH/ljsx/5Y7Mf+WOzH/ljsx/5Y7Mf+WOzH/ljsx/5Y7Mf+YPjT/qFxT/9y+uv/9+vr////////////////////////////////////////////////////////////////z////pP///xgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8R////if////f///////////////////////////v4+P/KnJf/mUE4/5Y7Mf+WOzH/ljsx/5Y7Mf+WOzH/ljsx/5Y7Mf+WOzH/ljsx/5Y7Mf+WOzH/ljsy/6NUS//Yt7P//Pn4////////////////////////////////////////////////////////////////9////4n///8RAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP///wb///9g////5v////////////////////////////////v4+P/KnZj/mUI4/5Y7Mf+WOzH/ljsx/5Y7Mf+WOzH/ljsx/5Y7Mf+WOzH/ljsx/5Y7Mf+WOzH/ljsx/5c8Mv+pXlb/38PA//38/P///////////////////////////////////////////////////////////////+b///9g////BgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP///yr////C/////f////////////////////////////////38+//dwLz/qF1V/51JP/+bRDv/mD40/5Y7Mf+WOzH/ljsx/5Y7Mf+WOzH/ljsx/5Y7Mf+WOzH/ljsx/5Y7Mf+XPTP/qWBY/+vZ2P///v7///////////////////////////////////////////////////////////3////C////KgAAAAAAAAAAAAAAAAAAAAAAAAAA////B////3z////3///////////////////////////////////////////9+/r/9/Dv/+zc2f/dwLz/x5iT/7BrY/+eS0H/lz0z/5Y7Mf+WOzH/ljsx/5Y7Mf+WOzH/ljsx/5Y7Mf+WOzH/lzwy/7d6c//06un////////////////////////////////////////////////////////////////3////fP///wcAAAAAAAAAAAAAAAAAAAAA////Nf///93////+//////////////////////////////////////////////////////7+/v/+/v7//fz8//Hm5f/XtLH/s3Fq/5lCOP+WOzH/ljsx/5Y7Mf+WOzH/ljsx/5Y7Mf+WOzH/ljsx/51JP//Sq6b//Pn5///////////////////////////////////////////////////////////+////3f///zUAAAAAAAAAAAAAAAD///8I////k/////z////////////////////////////////////////////////////////////////////////////////9+/v/8eTj/8aVkP+dRz7/ljsx/5Y7Mf+WOzH/ljsx/5Y7Mf+WOzH/ljsx/5c8Mv+vamL/7uDf/////////////////////////////////////////////////////////////////P///5P///8IAAAAAAAAAAD///8u////z/////////////////////////////////////////////////////////////////////////////////////////////////fx8P/ImZP/nUg//5Y7Mf+WOzH/ljsx/5Y7Mf+WOzH/ljsx/5Y7Mf+ZQTj/0qyo//38/P///////////////////////////////////////////////////////////////8////8uAAAAAP///wT///9g////7//////////////////////////////////////////////////////////////////////////////////////////////////////07Or/xJGL/5hAN/+WOzH/ljsx/5Y7Mf+WOzH/ljsx/5Y7Mf+WOzH/rGRd//Tq6P///////////////////////////////////////////////////////////////+////9g////BP///wz///+U////+v////////////////////////////////////////////////////////////////////////////////////////////////////////7/8+jm/7Nya/+WPDP/ljsx/5Y7Mf+WOzH/ljsx/5Y7Mf+WOzH/mkQ7/9m3s////v7///////////////////////////////////////////////////////////r///+U////DP///xr///+7/////////////////////////////////////////////////////////////////////////////////////////////////////////////////v7+/+HHxP+hUEf/ljsx/5Y7Mf+WOzH/ljsx/5Y7Mf+WOzH/ljwy/7yBe//69/f///////////////////////////////////////////////////////////////+7////Gv///zT////V//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////bu7f+7gHr/mD40/5Y7Mf+WOzH/ljsx/5Y7Mf+WOzH/ljsx/6xkXP/u4N/////////////////////////////////////////////////////////////////V////NP///0b////o//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////38/P/XtK//nEY9/5Y7Mf+WOzH/ljsx/5Y7Mf+WOzH/ljsx/6BNRP/iycb////////////////////////////////////////////////////////////////o////Rv///1n////6///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////o1NL/pVhQ/5Y7Mf+WOzH/ljsx/5Y7Mf+WOzH/ljsx/5xGPP/Yt7L//v39///////////////////////////////////////////////////////////6////Wf///2r////8///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////06un/sW1m/5Y7Mf+WOzH/ljsx/5Y7Mf+WOzH/ljsx/5pDOf/PpKD//Pr5///////////////////////////////////////////////////////////8////av///4D////8/////////////////////////////////////////////////////////////v7//fv7//37+v/9+/r//fv6//37+v/9+/r//fv6//37+v/9+/r//fv6//37+v/06un/snBp/5Y7Mf+WOzH/ljsx/5Y7Mf+WOzH/ljsx/5lBOP/KnJj/+/j4///////////////////////////////////////////////////////////8////gP///4D////8//////////////////////////////////////////////////////79/f/s3Nr/z6ej/8uemv/Lnpr/y56a/8uemv/Lnpr/y56a/8uemv/Lnpr/y56a/8uemv/GlI//o1VM/5Y7Mf+WOzH/ljsx/5Y7Mf+WOzH/ljsx/5lBOP/KnJf/+/j4///////////////////////////////////////////////////////////8////gP///2r////8//////////////////////////////////////////////////////z5+f/Nop3/m0Q7/5Y8Mv+WPDL/ljwy/5Y8Mv+WPDL/ljwy/5Y8Mv+WPDL/ljwy/5Y8Mv+WPDL/ljsx/5Y7Mf+WOzH/ljsx/5Y7Mf+WOzH/ljsx/5lBOP/KnJf/+/j4///////////////////////////////////////////////////////////8////av///1n////6//////////////////////////////////////////////////////v4+P/KnJf/mUE4/5Y7Mf+WOzH/ljsx/5Y7Mf+WOzH/ljsx/5Y7Mf+WOzH/ljsx/5Y7Mf+WOzH/ljsx/5Y7Mf+WOzH/ljsx/5Y7Mf+WOzH/ljsx/5lCOP/KnZj/+/j4///////////////////////////////////////////////////////////6////Wf///0b////o//////////////////////////////////////////////////////v4+P/KnJf/mUE4/5Y7Mf+WOzH/ljsx/5Y7Mf+WOzH/ljsx/5Y7Mf+WOzH/ljsx/5Y7Mf+WOzH/ljsx/5Y7Mf+WOzH/ljsx/5Y7Mf+WOzH/ljsx/5pDOv/Qp6P//Pr6///////////////////////////////////////////////////////////o////Rv///zT////V//////////////////////////////////////////////////////v4+P/KnJf/mUE4/5Y7Mf+WOzH/ljsx/5Y7Mf+WOzH/ljsx/5Y7Mf+WOzH/ljsx/5Y7Mf+WOzH/ljsx/5Y7Mf+WOzH/ljsx/5Y7Mf+WOzH/ljsx/51IP//bvbr//v7+///////////////////////////////////////////////////////////V////NP///xr///+7//////////////////////////////////////////////////////v4+P/KnJf/mUE4/5Y7Mf+WOzH/ljsx/5Y7Mf+WOzH/ljsx/5Y7Mf+WOzH/ljsx/5Y7Mf+WOzH/ljsx/5Y7Mf+WOzH/ljsx/5Y7Mf+WOzH/ljsx/6RVTf/n0c////////////////////////////////////////////////////////////////+7////Gv///wz///+U////+v////////////////////////////////////////////////v4+P/KnJf/mUE4/5Y7Mf+WOzH/ljsx/5Y7Mf+WOzH/ljsx/5Y7Mf+WOzH/ljsx/5Y7Mf+WOzH/ljsx/5Y7Mf+WOzH/ljsx/5Y7Mf+WOzH/ljsx/7FuZ//z6ej///////////////////////////////////////////////////////////r///+U////DP///wT///9g////7/////////////////////////////////////////////////z4+P/LnZj/mkI5/5Y8Mv+WPDL/ljwy/5Y8Mv+WPDL/ljwy/5Y8Mv+WPDL/ljwy/5Y8Mv+WPDL/ljwy/5Y8Mv+WPDL/ljwy/5Y8Mv+WPDL/mUE3/8mblf/9+/r//////////////////////////////////////////////////////////+////9g////BAAAAAD///8u////z/////////////////////////////////////////////////38/P/iycb/v4iC/7yCfP+8gnz/vIJ8/7yCfP+8gnz/vIJ8/7yCfP+8gnz/vIJ8/7yCfP+8gnz/voR+/8qcl//Lnpr/y56a/8uemv/Lnpr/zqOf//Hl5P///v7//////////////////////////////////////////////////////////8////8uAAAAAAAAAAD///8I////k/////z////////////////////////////////////////////////9/Pz/+vf2//r39v/69/b/+vf2//r39v/69/b/+vf2//j08//07Ov/7+Df/+7f3v/z6+n/+PPy//z6+v/9+/r//fv6//37+v/9+/r//fv7///+/v///////////////////////////////////////////////////////////P///5P///8IAAAAAAAAAAAAAAAA////Nf///93////+/////////////////////////////////////////////////////////////////////////////v7/9u7t/9i3s/++hn//sW1m/7BsZf+7gnv/066q//Ln5v/+/v7////////////////////////////////////////////////////////////////////////////////+////3f///zUAAAAAAAAAAAAAAAAAAAAA////B////3z////3///////////////////////////////////////////////////////////////////////////17Ov/wo6I/55KQf+XPjT/ljsx/5Y7Mf+XPTP/nEY9/7uBe//x5eP////////////////////////////////////////////////////////////////////////////////3////fP///wcAAAAAAAAAAAAAAAAAAAAAAAAAAP///yr////C/////f////////////////////////////////////////////////////////////////37+//UsKz/nUg//5Y7Mf+WOzH/ljsx/5Y7Mf+WOzH/ljsx/5tEO//No57/+/j4//////////////////////////////////////////////////////////////////////3////C////KgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP///wb///9g////5v////////////////////////////////////////////////////////////////bv7/+5fHb/lz0z/5Y7Mf+WOzH/ljsx/5Y7Mf+WOzH/ljsx/5Y8Mv+ycGj/8ujm/////////////////////////////////////////////////////////////////////+b///9g////BgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8R////if////f//////////////////////////////////////////////////////////+3e3P+qYlr/ljsx/5Y7Mf+WOzH/ljsx/5Y7Mf+WOzH/ljsx/5Y7Mf+oXVT/6tnX////////////////////////////////////////////////////////////////9////4n///8RAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////GP///6T////z/////////////////////////////////////////////////////+vZ1/+oXVT/ljsx/5Y7Mf+WOzH/ljsx/5Y7Mf+WOzH/ljsx/5Y7Mf+nWlL/6dbU///////////////////////////////////////////////////////////z////pP///xgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP///yL///+d////8/////////////////////////////////////////////////Hm5f+wa2T/ljsx/5Y7Mf+WOzH/ljsx/5Y7Mf+WOzH/ljsx/5Y7Mf+uaGD/8OPh//////////////////////////////////////////////////////P///+d////IgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP///wH///8i////pP////f///////////////////////////////////////////r19P/CjYf/mD81/5Y7Mf+WOzH/ljsx/5Y7Mf+WOzH/ljsx/5g/Nf/BjIb/+fTz////////////////////////////////////////////////9////6T///8i////AQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////GP///4n////m/////f////////////////////////////////7+/v/m0M7/qmFZ/5c9M/+WOzH/ljsx/5Y7Mf+WOzH/lz0z/6leV//lz8z//v7+//////////////////////////////////////3////m////if///xgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP///xH///9g////wv////f////+///////////////////////////8+vr/4snG/7d4cf+iUUj/mUA3/5c+NP+gTkT/tXVu/+DFw//8+fn////////////////////////////////+////9////8L///9g////EQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8G////Kv///3z////d/////P///////////////////////////v38//Tr6v/kzcv/2726/9m6t//jysf/8uno//78/P////////////////////////////////z////d////fP///yr///8GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP///wf///81////k////8/////v////+v////////////////////////////////////////////////////////////////////r////v////z////5P///81////BwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////CP///y7///9g////lP///7v////V////6P////r////8/////P////z////8////+v///+j////V////u////5T///9g////Lv///wgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8E////DP///xr///80////Rv///1n///9q////gP///4D///9q////Wf///0b///80////Gv///wz///8EAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==";
|
|
235
|
+
|
|
232
236
|
// src/components/Admin/Header.tsx
|
|
233
237
|
import { Fragment, jsx as jsx3, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
238
|
+
var DEFAULT_ADMIN_LOGO = "/images/logo/logo.png";
|
|
234
239
|
function AdminHeader() {
|
|
235
240
|
const { data: session } = useSession();
|
|
236
241
|
const isMobile = useIsMobile();
|
|
242
|
+
const configuredLogo = process.env.NEXT_PUBLIC_ADMIN_LOGO_URL || DEFAULT_ADMIN_LOGO;
|
|
243
|
+
const [logoSrc, setLogoSrc] = useState2(configuredLogo);
|
|
244
|
+
const [logoFailed, setLogoFailed] = useState2(false);
|
|
245
|
+
const isDataLogo = useMemo(() => logoSrc.startsWith("data:"), [logoSrc]);
|
|
237
246
|
const handleLogout = () => {
|
|
238
247
|
signOut({ callbackUrl: "/admin/signin" });
|
|
239
248
|
};
|
|
240
249
|
return /* @__PURE__ */ jsx3("header", { className: "bg-white border-b border-gray-200 px-4 py-2", children: /* @__PURE__ */ jsxs2("div", { className: "flex items-center justify-between", children: [
|
|
241
|
-
/* @__PURE__ */ jsx3("div", { className: "flex items-center max-h-9 shrink-0", children: /* @__PURE__ */ jsx3(
|
|
250
|
+
/* @__PURE__ */ jsx3("div", { className: "flex items-center max-h-9 shrink-0", children: !logoFailed ? /* @__PURE__ */ jsx3(
|
|
242
251
|
Image,
|
|
243
252
|
{
|
|
244
|
-
src:
|
|
253
|
+
src: logoSrc,
|
|
245
254
|
alt: "Admin",
|
|
246
255
|
width: 120,
|
|
247
256
|
height: 34,
|
|
248
|
-
className: "max-h-9 w-auto object-contain object-left"
|
|
257
|
+
className: "max-h-9 w-auto object-contain object-left",
|
|
258
|
+
unoptimized: isDataLogo,
|
|
259
|
+
onError: () => {
|
|
260
|
+
if (logoSrc !== DEFAULT_ADMIN_LOGO) {
|
|
261
|
+
setLogoSrc(DEFAULT_ADMIN_LOGO);
|
|
262
|
+
return;
|
|
263
|
+
}
|
|
264
|
+
setLogoFailed(true);
|
|
265
|
+
}
|
|
249
266
|
}
|
|
250
|
-
)
|
|
267
|
+
) : /* @__PURE__ */ jsxs2("div", { className: "flex items-center gap-2", children: [
|
|
268
|
+
/* @__PURE__ */ jsx3(Image, { src: INFURO_FAVICON_BASE64, alt: "Infuro", width: 18, height: 18, unoptimized: true }),
|
|
269
|
+
/* @__PURE__ */ jsx3("span", { className: "text-sm font-semibold text-gray-800", children: "Infuro" })
|
|
270
|
+
] }) }),
|
|
251
271
|
/* @__PURE__ */ jsx3("div", { className: "flex items-center space-x-3", children: /* @__PURE__ */ jsxs2(DropdownMenu, { children: [
|
|
252
272
|
/* @__PURE__ */ jsx3(DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ jsxs2(
|
|
253
273
|
Button,
|
|
@@ -330,11 +350,8 @@ var defaultValue = {
|
|
|
330
350
|
};
|
|
331
351
|
var AdminConfigContext = createContext(defaultValue);
|
|
332
352
|
|
|
333
|
-
// src/lib/infuro-favicon.ts
|
|
334
|
-
var INFURO_FAVICON_BASE64 = "data:image/x-icon;base64,AAABAAMAEBAAAAEAIABoBAAANgAAACAgAAABACAAKBEAAJ4EAAAwMAAAAQAgAGgmAADGFQAAKAAAABAAAAAgAAAAAQAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8V////bv///7D////R////0f///7D///9u////FQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP///wL///9s0qun7q9qYv/DkYv/6tfV///+/v///////////////+7///9r////AgAAAAAAAAAAAAAAAP///wL///+Q/////sqcl/+WOzH/ljsx/5c9M//AiYP/+/j4/////////////////v///5D///8CAAAAAAAAAAD///9s/////v/////Oo5//lz00/5Y7Mf+WOzH/ljsx/7Z3cP/9+/v////////////////+////bAAAAAD///8V////7v///////////v39//Tq6f/QqKP/m0U8/5Y7Mf+WOzH/z6ah/////////////////////+7///8V////bv///////////////////////////////+XOy/+ZQTf/ljsx/59MQ//69fX/////////////////////bv///7D/////////////////////////////////////wYyG/5Y7Mf+WOzH/4MTC/////////////////////7D////R//////////////////7+//79/f/+/f3//v39/+DGw/+WOzH/ljsx/82inf/////////////////////R////0f///////////////9Svq/+mWVH/pllR/6ZZUf+iUUj/ljsx/5Y7Mf/KnJf/////////////////////0f///7D////////////////KnJf/ljsx/5Y7Mf+WOzH/ljsx/5Y7Mf+WOzH/062p/////////////////////7D///9u////////////////0amk/6FQSP+hUEj/oVBI/6JRSP+mWVH/plpS/+7g3v////////////////////9u////Ff///+7///////////7+/v/9/Pz/9u7t/8SSjP/Dj4r/9ezr//79/f/////////////////////u////FQAAAAD///9s/////v///////////////8OPif+WOzH/ljsx/7+Jgv/////////////////////+////bAAAAAAAAAAA////Av///5D////+//////////+9hH7/ljsx/5Y7Mf+8g3z////////////////+////kP///wIAAAAAAAAAAAAAAAD///8C////bP///+7/////8OTi/7R0bP+zcmr/8OLh///////////u////bP///wIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8V////bv///7D////R////0f///7D///9u////FQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKAAAACAAAABAAAAAAQAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8C////Hf///0n///95////mf///67///+u////mf///3n///9J////Hf///wIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8I////Tf///7D////p/////v////////////////////////////////////7////p////sP///03///8IAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8C////Pfjz8r7HlpH7wY2H/86lof/iysf/9e3s///+/v//////////////////////////////////////////+////77///89////AgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////Cf///37////z9Ovq/6BORf+WOzH/ljsx/5Y8Mv+hUEf/v4iC/+rY1v/+/f3///////////////////////////////////////////H///99////CQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP///wr///+d/////P/////06+r/oE5F/5Y7Mf+WOzH/ljsx/5Y7Mf+WOzH/m0Q7/8WTjf/38PD///////////////////////////////////////////z///+d////CgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8J////nf////3///////////Tr6v+gTkX/ljsx/5Y7Mf+WOzH/ljsx/5Y7Mf+WOzH/ljsx/61mX//w4+L///////////////////////////////////////////3///+d////CQAAAAAAAAAAAAAAAAAAAAAAAAAA////Av///37////8////////////////9Ovq/6BORf+WOzH/ljsx/5Y7Mf+WOzH/ljsx/5Y7Mf+WOzH/ljsx/6daUv/v4uD///////////////////////////////////////////z///9+////AgAAAAAAAAAAAAAAAAAAAAD///89////8//////////////////////48fD/rGRc/5pCOf+YPjT/ljsx/5Y7Mf+WOzH/ljsx/5Y7Mf+WOzH/ljsx/6xkXf/37+////////////////////////////////////////////P///89AAAAAAAAAAAAAAAA////CP///77////////////////////////////////7+Pf/8eXj/+DGw/++hn//m0U8/5Y7Mf+WOzH/ljsx/5Y7Mf+WOzH/ljsx/8GLhf/9/Pz//////////////////////////////////////////77///8IAAAAAAAAAAD///9N////+/////////////////////////////////////////////////7+/v/p1tP/rGRd/5Y7Mf+WOzH/ljsx/5Y7Mf+WOzH/mkI4/+XPzf//////////////////////////////////////////+////00AAAAA////Av///7D////////////////////////////////////////////////////////////////06+r/r2pi/5Y7Mf+WOzH/ljsx/5Y7Mf+WOzH/tndw//38+///////////////////////////////////////////sP///wL///8d////6f/////////////////////////////////////////////////////////////////////x5eP/olJJ/5Y7Mf+WOzH/ljsx/5Y7Mf+aQjn/7dza///////////////////////////////////////////p////Hf///0n////+///////////////////////////////////////////////////////////////////////////Ur6v/ljwy/5Y7Mf+WOzH/ljsx/5Y7Mf/Oo5////////////////////////////////////////////7///9J////ef////////////////////////////////////////////////////////////////////////////////fw7/+jVEv/ljsx/5Y7Mf+WOzH/ljsx/7Nxav///////////////////////////////////////////////3n///+Z/////////////////////////////////////////////////////////////////////////////////////7yCfP+WOzH/ljsx/5Y7Mf+WOzH/pllQ//r29f//////////////////////////////////////////mf///67///////////////////////////////////////////79/f/9/Pz//fz8//38/P/9/Pz//fz8//38/P/9/Pz/yZuW/5Y7Mf+WOzH/ljsx/5Y7Mf+gT0b/9evr//////////////////////////////////////////+u////rv/////////////////////////////////////69vb/wo2I/7Z3cf+2d3H/tndx/7Z3cf+2d3H/tndx/7Z3cf+lV0//ljsx/5Y7Mf+WOzH/ljsx/6BORf/06+r//////////////////////////////////////////67///+Z//////////////////////////////////////Tr6v+gTkX/ljsx/5Y7Mf+WOzH/ljsx/5Y7Mf+WOzH/ljsx/5Y7Mf+WOzH/ljsx/5Y7Mf+WOzH/oE5F//Tr6v//////////////////////////////////////////mf///3n/////////////////////////////////////9Ovq/6BORf+WOzH/ljsx/5Y7Mf+WOzH/ljsx/5Y7Mf+WOzH/ljsx/5Y7Mf+WOzH/ljsx/5Y7Mf+lVk7/+fPz//////////////////////////////////////////95////Sf////7////////////////////////////////06+r/oE5F/5Y7Mf+WOzH/ljsx/5Y7Mf+WOzH/ljsx/5Y7Mf+WOzH/ljsx/5Y7Mf+WOzH/ljsx/7FuZ////v7//////////////////////////////////////v///0n///8d////6f////////////////////////////////Tr6v+gTkX/ljsx/5Y7Mf+WOzH/ljsx/5Y7Mf+WOzH/ljsx/5Y7Mf+WOzH/ljsx/5Y7Mf+WOzH/zKCb///////////////////////////////////////////p////Hf///wL///+w////////////////////////////////+PLx/7d4cf+tZl//rWZf/61mX/+tZl//rWZf/61mX/+tZl//rmdg/7Z3cP+2d3H/tndx/7h7df/w4uH//////////////////////////////////////////7D///8CAAAAAP///03////7/////////////////////////////////Pv6//z6+f/8+vn//Pr5//z6+f/z6un/48zJ/+LKx//y5+b//fz8//38/P/9/Pz//fz8///////////////////////////////////////////7////TQAAAAAAAAAA////CP///77/////////////////////////////////////////////////////4MXC/6VXTv+WPDL/ljwy/6JRSP/aubb///7+/////////////////////////////////////////////////////77///8IAAAAAAAAAAAAAAAA////Pf////P///////////////////////////////////////////Xs6/+jU0r/ljsx/5Y7Mf+WOzH/ljsx/59MQv/w5OL////////////////////////////////////////////////z////PQAAAAAAAAAAAAAAAAAAAAD///8C////fv////z/////////////////////////////////////3sK//5Y7Mf+WOzH/ljsx/5Y7Mf+WOzH/ljsx/9m5tf///////////////////////////////////////////P///37///8CAAAAAAAAAAAAAAAAAAAAAAAAAAD///8J////nf////3////////////////////////////////ZuLX/ljsx/5Y7Mf+WOzH/ljsx/5Y7Mf+WOzH/17Sw//////////////////////////////////////3///+d////CQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8K////nf////z//////////////////////////+zc2v+aQzn/ljsx/5Y7Mf+WOzH/ljsx/5pDOf/r2tj////////////////////////////////8////nf///woAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8J////fv////P//////////////////////v39/8eYkv+YPjT/ljsx/5Y7Mf+YPjT/xpSP//79/f//////////////////////////8////37///8JAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8C////Pf///77////7/////////////////fv6/+DEwf/Ekoz/wY2H/97Bvv/8+vr/////////////////////+////77///89////AgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////CP///03///+w////6f////7////////////////////////////////////+////6f///7D///9N////CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP///wL///8d////Sf///3n///+Z////rv///67///+Z////ef///0n///8d////AgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKAAAADAAAABgAAAAAQAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8E////DP///xr///80////Rv///1n///9q////gP///4D///9q////Wf///0b///80////Gv///wz///8EAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////CP///y7///9g////lP///7v////V////6P////r////8/////P////z////8////+v///+j////V////u////5T///9g////Lv///wgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP///wf///81////k////8/////v////+v////////////////////////////////////////////////////////////////////r////v////z////5P///81////BwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8G////Kv37+3zt3Nrd27y5/Nm6t//fxMH/59LQ//Dk4v/48vH//fv6//////////////////////////////////////////////////////////////////////z////d////fP///yr///8GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP///xH///9g////wvz5+ffNop3+m0U8/5c+NP+cRz7/pFVN/65oYP+8gnv/0qun/+jU0v/59fT//v7+///////////////////////////////////////////////////////////+////9////8L///9f////EQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////GP///4n////m/////fv4+P/KnJf/mUE4/5Y7Mf+WOzH/ljsx/5Y7Mf+XPTT/m0Q6/6ZaUf/BjIX/6NXT//z5+f////////////////////////////////////////////////////////////////3////k////if///xgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP///wH///8i////pP////f///////////v4+P/KnJf/mUE4/5Y7Mf+WOzH/ljsx/5Y7Mf+WOzH/ljsx/5Y7Mf+XPjT/oVFI/8yhnP/x5OP//vz8////////////////////////////////////////////////////////////////9////6T///8i////AQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP///yL///+d////8/////////////////v4+P/KnJf/mUE4/5Y7Mf+WOzH/ljsx/5Y7Mf+WOzH/ljsx/5Y7Mf+WOzH/ljsx/5tEOv+3eHL/48rH//37+/////////////////////////////////////////////////////////////////P///+d////IgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////GP///6T////z//////////////////////v4+P/KnJf/mUE4/5Y7Mf+WOzH/ljsx/5Y7Mf+WOzH/ljsx/5Y7Mf+WOzH/ljsx/5Y7Mf+YPjT/qFxT/9y+uv/9+vr////////////////////////////////////////////////////////////////z////pP///xgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8R////if////f///////////////////////////v4+P/KnJf/mUE4/5Y7Mf+WOzH/ljsx/5Y7Mf+WOzH/ljsx/5Y7Mf+WOzH/ljsx/5Y7Mf+WOzH/ljsy/6NUS//Yt7P//Pn4////////////////////////////////////////////////////////////////9////4n///8RAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP///wb///9g////5v////////////////////////////////v4+P/KnZj/mUI4/5Y7Mf+WOzH/ljsx/5Y7Mf+WOzH/ljsx/5Y7Mf+WOzH/ljsx/5Y7Mf+WOzH/ljsx/5c8Mv+pXlb/38PA//38/P///////////////////////////////////////////////////////////////+b///9g////BgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP///yr////C/////f////////////////////////////////38+//dwLz/qF1V/51JP/+bRDv/mD40/5Y7Mf+WOzH/ljsx/5Y7Mf+WOzH/ljsx/5Y7Mf+WOzH/ljsx/5Y7Mf+XPTP/qWBY/+vZ2P///v7///////////////////////////////////////////////////////////3////C////KgAAAAAAAAAAAAAAAAAAAAAAAAAA////B////3z////3///////////////////////////////////////////9+/r/9/Dv/+zc2f/dwLz/x5iT/7BrY/+eS0H/lz0z/5Y7Mf+WOzH/ljsx/5Y7Mf+WOzH/ljsx/5Y7Mf+WOzH/lzwy/7d6c//06un////////////////////////////////////////////////////////////////3////fP///wcAAAAAAAAAAAAAAAAAAAAA////Nf///93////+//////////////////////////////////////////////////////7+/v/+/v7//fz8//Hm5f/XtLH/s3Fq/5lCOP+WOzH/ljsx/5Y7Mf+WOzH/ljsx/5Y7Mf+WOzH/ljsx/51JP//Sq6b//Pn5///////////////////////////////////////////////////////////+////3f///zUAAAAAAAAAAAAAAAD///8I////k/////z////////////////////////////////////////////////////////////////////////////////9+/v/8eTj/8aVkP+dRz7/ljsx/5Y7Mf+WOzH/ljsx/5Y7Mf+WOzH/ljsx/5c8Mv+vamL/7uDf/////////////////////////////////////////////////////////////////P///5P///8IAAAAAAAAAAD///8u////z/////////////////////////////////////////////////////////////////////////////////////////////////fx8P/ImZP/nUg//5Y7Mf+WOzH/ljsx/5Y7Mf+WOzH/ljsx/5Y7Mf+ZQTj/0qyo//38/P///////////////////////////////////////////////////////////////8////8uAAAAAP///wT///9g////7//////////////////////////////////////////////////////////////////////////////////////////////////////07Or/xJGL/5hAN/+WOzH/ljsx/5Y7Mf+WOzH/ljsx/5Y7Mf+WOzH/rGRd//Tq6P///////////////////////////////////////////////////////////////+////9g////BP///wz///+U////+v////////////////////////////////////////////////////////////////////////////////////////////////////////7/8+jm/7Nya/+WPDP/ljsx/5Y7Mf+WOzH/ljsx/5Y7Mf+WOzH/mkQ7/9m3s////v7///////////////////////////////////////////////////////////r///+U////DP///xr///+7/////////////////////////////////////////////////////////////////////////////////////////////////////////////////v7+/+HHxP+hUEf/ljsx/5Y7Mf+WOzH/ljsx/5Y7Mf+WOzH/ljwy/7yBe//69/f///////////////////////////////////////////////////////////////+7////Gv///zT////V//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////bu7f+7gHr/mD40/5Y7Mf+WOzH/ljsx/5Y7Mf+WOzH/ljsx/6xkXP/u4N/////////////////////////////////////////////////////////////////V////NP///0b////o//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////38/P/XtK//nEY9/5Y7Mf+WOzH/ljsx/5Y7Mf+WOzH/ljsx/6BNRP/iycb////////////////////////////////////////////////////////////////o////Rv///1n////6///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////o1NL/pVhQ/5Y7Mf+WOzH/ljsx/5Y7Mf+WOzH/ljsx/5xGPP/Yt7L//v39///////////////////////////////////////////////////////////6////Wf///2r////8///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////06un/sW1m/5Y7Mf+WOzH/ljsx/5Y7Mf+WOzH/ljsx/5pDOf/PpKD//Pr5///////////////////////////////////////////////////////////8////av///4D////8/////////////////////////////////////////////////////////////v7//fv7//37+v/9+/r//fv6//37+v/9+/r//fv6//37+v/9+/r//fv6//37+v/06un/snBp/5Y7Mf+WOzH/ljsx/5Y7Mf+WOzH/ljsx/5lBOP/KnJj/+/j4///////////////////////////////////////////////////////////8////gP///4D////8//////////////////////////////////////////////////////79/f/s3Nr/z6ej/8uemv/Lnpr/y56a/8uemv/Lnpr/y56a/8uemv/Lnpr/y56a/8uemv/GlI//o1VM/5Y7Mf+WOzH/ljsx/5Y7Mf+WOzH/ljsx/5lBOP/KnJf/+/j4///////////////////////////////////////////////////////////8////gP///2r////8//////////////////////////////////////////////////////z5+f/Nop3/m0Q7/5Y8Mv+WPDL/ljwy/5Y8Mv+WPDL/ljwy/5Y8Mv+WPDL/ljwy/5Y8Mv+WPDL/ljsx/5Y7Mf+WOzH/ljsx/5Y7Mf+WOzH/ljsx/5lBOP/KnJf/+/j4///////////////////////////////////////////////////////////8////av///1n////6//////////////////////////////////////////////////////v4+P/KnJf/mUE4/5Y7Mf+WOzH/ljsx/5Y7Mf+WOzH/ljsx/5Y7Mf+WOzH/ljsx/5Y7Mf+WOzH/ljsx/5Y7Mf+WOzH/ljsx/5Y7Mf+WOzH/ljsx/5lCOP/KnZj/+/j4///////////////////////////////////////////////////////////6////Wf///0b////o//////////////////////////////////////////////////////v4+P/KnJf/mUE4/5Y7Mf+WOzH/ljsx/5Y7Mf+WOzH/ljsx/5Y7Mf+WOzH/ljsx/5Y7Mf+WOzH/ljsx/5Y7Mf+WOzH/ljsx/5Y7Mf+WOzH/ljsx/5pDOv/Qp6P//Pr6///////////////////////////////////////////////////////////o////Rv///zT////V//////////////////////////////////////////////////////v4+P/KnJf/mUE4/5Y7Mf+WOzH/ljsx/5Y7Mf+WOzH/ljsx/5Y7Mf+WOzH/ljsx/5Y7Mf+WOzH/ljsx/5Y7Mf+WOzH/ljsx/5Y7Mf+WOzH/ljsx/51IP//bvbr//v7+///////////////////////////////////////////////////////////V////NP///xr///+7//////////////////////////////////////////////////////v4+P/KnJf/mUE4/5Y7Mf+WOzH/ljsx/5Y7Mf+WOzH/ljsx/5Y7Mf+WOzH/ljsx/5Y7Mf+WOzH/ljsx/5Y7Mf+WOzH/ljsx/5Y7Mf+WOzH/ljsx/6RVTf/n0c////////////////////////////////////////////////////////////////+7////Gv///wz///+U////+v////////////////////////////////////////////////v4+P/KnJf/mUE4/5Y7Mf+WOzH/ljsx/5Y7Mf+WOzH/ljsx/5Y7Mf+WOzH/ljsx/5Y7Mf+WOzH/ljsx/5Y7Mf+WOzH/ljsx/5Y7Mf+WOzH/ljsx/7FuZ//z6ej///////////////////////////////////////////////////////////r///+U////DP///wT///9g////7/////////////////////////////////////////////////z4+P/LnZj/mkI5/5Y8Mv+WPDL/ljwy/5Y8Mv+WPDL/ljwy/5Y8Mv+WPDL/ljwy/5Y8Mv+WPDL/ljwy/5Y8Mv+WPDL/ljwy/5Y8Mv+WPDL/mUE3/8mblf/9+/r//////////////////////////////////////////////////////////+////9g////BAAAAAD///8u////z/////////////////////////////////////////////////38/P/iycb/v4iC/7yCfP+8gnz/vIJ8/7yCfP+8gnz/vIJ8/7yCfP+8gnz/vIJ8/7yCfP+8gnz/voR+/8qcl//Lnpr/y56a/8uemv/Lnpr/zqOf//Hl5P///v7//////////////////////////////////////////////////////////8////8uAAAAAAAAAAD///8I////k/////z////////////////////////////////////////////////9/Pz/+vf2//r39v/69/b/+vf2//r39v/69/b/+vf2//j08//07Ov/7+Df/+7f3v/z6+n/+PPy//z6+v/9+/r//fv6//37+v/9+/r//fv7///+/v///////////////////////////////////////////////////////////P///5P///8IAAAAAAAAAAAAAAAA////Nf///93////+/////////////////////////////////////////////////////////////////////////////v7/9u7t/9i3s/++hn//sW1m/7BsZf+7gnv/066q//Ln5v/+/v7////////////////////////////////////////////////////////////////////////////////+////3f///zUAAAAAAAAAAAAAAAAAAAAA////B////3z////3///////////////////////////////////////////////////////////////////////////17Ov/wo6I/55KQf+XPjT/ljsx/5Y7Mf+XPTP/nEY9/7uBe//x5eP////////////////////////////////////////////////////////////////////////////////3////fP///wcAAAAAAAAAAAAAAAAAAAAAAAAAAP///yr////C/////f////////////////////////////////////////////////////////////////37+//UsKz/nUg//5Y7Mf+WOzH/ljsx/5Y7Mf+WOzH/ljsx/5tEO//No57/+/j4//////////////////////////////////////////////////////////////////////3////C////KgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP///wb///9g////5v////////////////////////////////////////////////////////////////bv7/+5fHb/lz0z/5Y7Mf+WOzH/ljsx/5Y7Mf+WOzH/ljsx/5Y8Mv+ycGj/8ujm/////////////////////////////////////////////////////////////////////+b///9g////BgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8R////if////f//////////////////////////////////////////////////////////+3e3P+qYlr/ljsx/5Y7Mf+WOzH/ljsx/5Y7Mf+WOzH/ljsx/5Y7Mf+oXVT/6tnX////////////////////////////////////////////////////////////////9////4n///8RAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////GP///6T////z/////////////////////////////////////////////////////+vZ1/+oXVT/ljsx/5Y7Mf+WOzH/ljsx/5Y7Mf+WOzH/ljsx/5Y7Mf+nWlL/6dbU///////////////////////////////////////////////////////////z////pP///xgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP///yL///+d////8/////////////////////////////////////////////////Hm5f+wa2T/ljsx/5Y7Mf+WOzH/ljsx/5Y7Mf+WOzH/ljsx/5Y7Mf+uaGD/8OPh//////////////////////////////////////////////////////P///+d////IgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP///wH///8i////pP////f///////////////////////////////////////////r19P/CjYf/mD81/5Y7Mf+WOzH/ljsx/5Y7Mf+WOzH/ljsx/5g/Nf/BjIb/+fTz////////////////////////////////////////////////9////6T///8i////AQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////GP///4n////m/////f////////////////////////////////7+/v/m0M7/qmFZ/5c9M/+WOzH/ljsx/5Y7Mf+WOzH/lz0z/6leV//lz8z//v7+//////////////////////////////////////3////m////if///xgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP///xH///9g////wv////f////+///////////////////////////8+vr/4snG/7d4cf+iUUj/mUA3/5c+NP+gTkT/tXVu/+DFw//8+fn////////////////////////////////+////9////8L///9g////EQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8G////Kv///3z////d/////P///////////////////////////v38//Tr6v/kzcv/2726/9m6t//jysf/8uno//78/P////////////////////////////////z////d////fP///yr///8GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP///wf///81////k////8/////v////+v////////////////////////////////////////////////////////////////////r////v////z////5P///81////BwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////CP///y7///9g////lP///7v////V////6P////r////8/////P////z////8////+v///+j////V////u////5T///9g////Lv///wgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8E////DP///xr///80////Rv///1n///9q////gP///4D///9q////Wf///0b///80////Gv///wz///8EAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==";
|
|
335
|
-
|
|
336
353
|
// src/lib/cms-version.ts
|
|
337
|
-
var CMS_VERSION = true ? "1.0.
|
|
354
|
+
var CMS_VERSION = true ? "1.0.16" : "0.0.0";
|
|
338
355
|
|
|
339
356
|
// src/components/Admin/Sidebar.tsx
|
|
340
357
|
import { jsx as jsx4, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
@@ -743,8 +760,8 @@ function AdminLayoutInner({ children }) {
|
|
|
743
760
|
const { data: session, status } = useSession2();
|
|
744
761
|
const router = useRouter();
|
|
745
762
|
const pathname = usePathname3();
|
|
746
|
-
const [loadingTimeout, setLoadingTimeout] =
|
|
747
|
-
const [moreSheetOpen, setMoreSheetOpen] =
|
|
763
|
+
const [loadingTimeout, setLoadingTimeout] = useState3(false);
|
|
764
|
+
const [moreSheetOpen, setMoreSheetOpen] = useState3(false);
|
|
748
765
|
const isMobile = useIsMobile();
|
|
749
766
|
useAdminViewSettings();
|
|
750
767
|
const isPublicPath = PUBLIC_ADMIN_PATHS.includes(pathname);
|
|
@@ -806,7 +823,7 @@ function AdminLayoutInner({ children }) {
|
|
|
806
823
|
] });
|
|
807
824
|
}
|
|
808
825
|
function useResolvedTheme(theme, themeRegistry) {
|
|
809
|
-
const [activeThemeId, setActiveThemeId] =
|
|
826
|
+
const [activeThemeId, setActiveThemeId] = useState3(null);
|
|
810
827
|
useEffect2(() => {
|
|
811
828
|
if (!themeRegistry || themeRegistry.length === 0) return;
|
|
812
829
|
fetch("/api/settings/theme").then((r) => r.ok ? r.json() : {}).then((data) => {
|
|
@@ -821,7 +838,7 @@ function useResolvedTheme(theme, themeRegistry) {
|
|
|
821
838
|
return found?.config ?? theme ?? themeRegistry[0]?.config;
|
|
822
839
|
}
|
|
823
840
|
function useStoreEnabled() {
|
|
824
|
-
const [storeEnabled, setStoreEnabled] =
|
|
841
|
+
const [storeEnabled, setStoreEnabled] = useState3(false);
|
|
825
842
|
useEffect2(() => {
|
|
826
843
|
fetch("/api/settings/store").then((r) => r.ok ? r.json() : {}).then((data) => {
|
|
827
844
|
setStoreEnabled(data?.enabled === "true");
|
|
@@ -863,10 +880,10 @@ function AdminShell({ children }) {
|
|
|
863
880
|
}
|
|
864
881
|
|
|
865
882
|
// src/components/Admin/CRUD.tsx
|
|
866
|
-
import { useEffect as useEffect6, useState as
|
|
883
|
+
import { useEffect as useEffect6, useRef as useRef3, useState as useState8 } from "react";
|
|
867
884
|
|
|
868
885
|
// src/components/Admin/CreateEditForm.tsx
|
|
869
|
-
import { useState as
|
|
886
|
+
import { useState as useState6, useEffect as useEffect4 } from "react";
|
|
870
887
|
import { X as X2 } from "lucide-react";
|
|
871
888
|
|
|
872
889
|
// src/components/ui/input.tsx
|
|
@@ -1064,7 +1081,7 @@ var Label3 = React10.forwardRef(({ className, ...props }, ref) => /* @__PURE__ *
|
|
|
1064
1081
|
Label3.displayName = LabelPrimitive.Root.displayName;
|
|
1065
1082
|
|
|
1066
1083
|
// src/components/ui/file-upload.tsx
|
|
1067
|
-
import { useState as
|
|
1084
|
+
import { useState as useState4 } from "react";
|
|
1068
1085
|
|
|
1069
1086
|
// src/components/ui/progress.tsx
|
|
1070
1087
|
import * as React11 from "react";
|
|
@@ -1093,10 +1110,10 @@ Progress.displayName = ProgressPrimitive.Root.displayName;
|
|
|
1093
1110
|
// src/components/ui/file-upload.tsx
|
|
1094
1111
|
import { jsx as jsx15, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
1095
1112
|
function FileUpload({ onUploadSuccess }) {
|
|
1096
|
-
const [selectedFile, setSelectedFile] =
|
|
1097
|
-
const [uploading, setUploading] =
|
|
1098
|
-
const [progress, setProgress] =
|
|
1099
|
-
const [fileUrl, setFileUrl] =
|
|
1113
|
+
const [selectedFile, setSelectedFile] = useState4(null);
|
|
1114
|
+
const [uploading, setUploading] = useState4(false);
|
|
1115
|
+
const [progress, setProgress] = useState4(0);
|
|
1116
|
+
const [fileUrl, setFileUrl] = useState4("");
|
|
1100
1117
|
const handleFileChange = (event) => {
|
|
1101
1118
|
setSelectedFile(event.target.files[0]);
|
|
1102
1119
|
};
|
|
@@ -1137,7 +1154,7 @@ function FileUpload({ onUploadSuccess }) {
|
|
|
1137
1154
|
}
|
|
1138
1155
|
|
|
1139
1156
|
// src/components/Admin/RelationAutocomplete.tsx
|
|
1140
|
-
import { useState as
|
|
1157
|
+
import { useState as useState5, useEffect as useEffect3, useRef, useCallback } from "react";
|
|
1141
1158
|
import { ChevronDown as ChevronDown3 } from "lucide-react";
|
|
1142
1159
|
import { jsx as jsx16, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
1143
1160
|
var DEBOUNCE_MS = 300;
|
|
@@ -1151,16 +1168,16 @@ function RelationAutocomplete({
|
|
|
1151
1168
|
placeholder = "Select\u2026",
|
|
1152
1169
|
disabled = false
|
|
1153
1170
|
}) {
|
|
1154
|
-
const [open, setOpen] =
|
|
1155
|
-
const [search, setSearch] =
|
|
1156
|
-
const [searchInput, setSearchInput] =
|
|
1157
|
-
const [items, setItems] =
|
|
1158
|
-
const [total, setTotal] =
|
|
1159
|
-
const [page, setPage] =
|
|
1160
|
-
const [loading, setLoading] =
|
|
1161
|
-
const [loadingMore, setLoadingMore] =
|
|
1162
|
-
const [selectedLabel, setSelectedLabel] =
|
|
1163
|
-
const [initialLabelLoaded, setInitialLabelLoaded] =
|
|
1171
|
+
const [open, setOpen] = useState5(false);
|
|
1172
|
+
const [search, setSearch] = useState5("");
|
|
1173
|
+
const [searchInput, setSearchInput] = useState5("");
|
|
1174
|
+
const [items, setItems] = useState5([]);
|
|
1175
|
+
const [total, setTotal] = useState5(0);
|
|
1176
|
+
const [page, setPage] = useState5(1);
|
|
1177
|
+
const [loading, setLoading] = useState5(false);
|
|
1178
|
+
const [loadingMore, setLoadingMore] = useState5(false);
|
|
1179
|
+
const [selectedLabel, setSelectedLabel] = useState5(null);
|
|
1180
|
+
const [initialLabelLoaded, setInitialLabelLoaded] = useState5(false);
|
|
1164
1181
|
const containerRef = useRef(null);
|
|
1165
1182
|
const listRef = useRef(null);
|
|
1166
1183
|
const debounceRef = useRef(null);
|
|
@@ -1207,6 +1224,12 @@ function RelationAutocomplete({
|
|
|
1207
1224
|
if (debounceRef.current) clearTimeout(debounceRef.current);
|
|
1208
1225
|
};
|
|
1209
1226
|
}, [searchInput, open]);
|
|
1227
|
+
useEffect3(() => {
|
|
1228
|
+
if (open) return;
|
|
1229
|
+
setSearchInput("");
|
|
1230
|
+
setSearch("");
|
|
1231
|
+
setPage(1);
|
|
1232
|
+
}, [open]);
|
|
1210
1233
|
const loadInitialLabel = useCallback(() => {
|
|
1211
1234
|
if (initialLabelLoaded || value == null || value === "") return;
|
|
1212
1235
|
setInitialLabelLoaded(true);
|
|
@@ -1334,8 +1357,8 @@ import { toast } from "sonner";
|
|
|
1334
1357
|
import { jsx as jsx17, jsxs as jsxs11 } from "react/jsx-runtime";
|
|
1335
1358
|
function CreateEditForm({ isOpen, onClose, apiEndpoint, columns, existingData }) {
|
|
1336
1359
|
const isMobile = useIsMobile();
|
|
1337
|
-
const [formData, setFormData] =
|
|
1338
|
-
const [errors, setErrors] =
|
|
1360
|
+
const [formData, setFormData] = useState6({});
|
|
1361
|
+
const [errors, setErrors] = useState6({});
|
|
1339
1362
|
useEffect4(() => {
|
|
1340
1363
|
if (existingData) {
|
|
1341
1364
|
setFormData(existingData);
|
|
@@ -1623,7 +1646,7 @@ var DialogContent = React14.forwardRef(({ className, children, ...props }, ref)
|
|
|
1623
1646
|
{
|
|
1624
1647
|
ref,
|
|
1625
1648
|
className: cn(
|
|
1626
|
-
"fixed left-[50%] top-[50%] z-50 grid w-
|
|
1649
|
+
"fixed left-[50%] top-[50%] z-50 grid w-[calc(100vw-1rem)] max-w-lg max-h-[calc(100vh-1rem)] translate-x-[-50%] translate-y-[-50%] gap-4 overflow-y-auto rounded-lg border bg-background p-4 shadow-lg duration-200 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-[48%] data-[state=open]:slide-in-from-left-1/2 data-[state=open]:slide-in-from-top-[48%] sm:max-h-[calc(100vh-2rem)] sm:p-6",
|
|
1627
1650
|
className
|
|
1628
1651
|
),
|
|
1629
1652
|
...props,
|
|
@@ -1659,7 +1682,7 @@ var DialogFooter = ({
|
|
|
1659
1682
|
"div",
|
|
1660
1683
|
{
|
|
1661
1684
|
className: cn(
|
|
1662
|
-
"flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2",
|
|
1685
|
+
"flex flex-col-reverse gap-2 sm:flex-row sm:justify-end sm:space-x-2 sm:gap-0 [&>button]:w-full sm:[&>button]:w-auto",
|
|
1663
1686
|
className
|
|
1664
1687
|
),
|
|
1665
1688
|
...props
|
|
@@ -1689,11 +1712,12 @@ var DialogDescription = React14.forwardRef(({ className, ...props }, ref) => /*
|
|
|
1689
1712
|
DialogDescription.displayName = DialogPrimitive.Description.displayName;
|
|
1690
1713
|
|
|
1691
1714
|
// src/components/Admin/CRUD.tsx
|
|
1692
|
-
import { Edit, Trash2,
|
|
1715
|
+
import { Edit, Trash2, Plus, Search, Check as Check3, X as X5, RefreshCw, Upload as Upload2, Download as Download2, MoreVertical, Filter } from "lucide-react";
|
|
1693
1716
|
import Link4 from "next/link";
|
|
1717
|
+
import { useRouter as useRouter2 } from "next/navigation";
|
|
1694
1718
|
|
|
1695
1719
|
// src/components/Admin/BulkUploadDialog.tsx
|
|
1696
|
-
import { useState as
|
|
1720
|
+
import { useState as useState7, useEffect as useEffect5, useRef as useRef2 } from "react";
|
|
1697
1721
|
import { Download, Upload, AlertCircle, CheckCircle2, X as X4 } from "lucide-react";
|
|
1698
1722
|
import Papa from "papaparse";
|
|
1699
1723
|
import { jsx as jsx21, jsxs as jsxs14 } from "react/jsx-runtime";
|
|
@@ -1708,16 +1732,16 @@ var AUTO_GENERATED_COLS = /* @__PURE__ */ new Set([
|
|
|
1708
1732
|
"deleted"
|
|
1709
1733
|
]);
|
|
1710
1734
|
function BulkUploadDialog({ apiEndpoint, onClose }) {
|
|
1711
|
-
const [columns, setColumns] =
|
|
1712
|
-
const [uniqueColumns, setUniqueColumns] =
|
|
1713
|
-
const [loading, setLoading] =
|
|
1714
|
-
const [importing, setImporting] =
|
|
1715
|
-
const [error, setError] =
|
|
1716
|
-
const [success, setSuccess] =
|
|
1717
|
-
const [parsedData, setParsedData] =
|
|
1718
|
-
const [parseErrors, setParseErrors] =
|
|
1719
|
-
const [upsertKey, setUpsertKey] =
|
|
1720
|
-
const [fileName, setFileName] =
|
|
1735
|
+
const [columns, setColumns] = useState7([]);
|
|
1736
|
+
const [uniqueColumns, setUniqueColumns] = useState7([]);
|
|
1737
|
+
const [loading, setLoading] = useState7(true);
|
|
1738
|
+
const [importing, setImporting] = useState7(false);
|
|
1739
|
+
const [error, setError] = useState7(null);
|
|
1740
|
+
const [success, setSuccess] = useState7(null);
|
|
1741
|
+
const [parsedData, setParsedData] = useState7([]);
|
|
1742
|
+
const [parseErrors, setParseErrors] = useState7([]);
|
|
1743
|
+
const [upsertKey, setUpsertKey] = useState7("id");
|
|
1744
|
+
const [fileName, setFileName] = useState7("");
|
|
1721
1745
|
const fileInputRef = useRef2(null);
|
|
1722
1746
|
useEffect5(() => {
|
|
1723
1747
|
fetchMetadata();
|
|
@@ -1961,6 +1985,7 @@ function BulkUploadDialog({ apiEndpoint, onClose }) {
|
|
|
1961
1985
|
}
|
|
1962
1986
|
|
|
1963
1987
|
// src/components/Admin/CRUD.tsx
|
|
1988
|
+
import { toast as toast2 } from "sonner";
|
|
1964
1989
|
import { Fragment as Fragment3, jsx as jsx22, jsxs as jsxs15 } from "react/jsx-runtime";
|
|
1965
1990
|
function getNestedValue(obj, path) {
|
|
1966
1991
|
return path.split(".").reduce((current, key) => {
|
|
@@ -1985,27 +2010,40 @@ function AdminCRUD({
|
|
|
1985
2010
|
extraListParams,
|
|
1986
2011
|
manageUserGroups
|
|
1987
2012
|
}) {
|
|
1988
|
-
const
|
|
1989
|
-
const [
|
|
1990
|
-
const [
|
|
1991
|
-
const [
|
|
1992
|
-
const [
|
|
1993
|
-
const [
|
|
1994
|
-
const [
|
|
1995
|
-
const [
|
|
1996
|
-
const [
|
|
1997
|
-
const [
|
|
1998
|
-
const [
|
|
1999
|
-
const [
|
|
2000
|
-
const [
|
|
2001
|
-
const [
|
|
2002
|
-
const [
|
|
2003
|
-
const [
|
|
2004
|
-
const [
|
|
2005
|
-
const [
|
|
2006
|
-
const [
|
|
2013
|
+
const router = useRouter2();
|
|
2014
|
+
const [data, setData] = useState8([]);
|
|
2015
|
+
const [loading, setLoading] = useState8(true);
|
|
2016
|
+
const [error, setError] = useState8(null);
|
|
2017
|
+
const [page, setPage] = useState8(1);
|
|
2018
|
+
const [totalPages, setTotalPages] = useState8(1);
|
|
2019
|
+
const [sortField, setSortField] = useState8(defaultSortField);
|
|
2020
|
+
const [sortOrder, setSortOrder] = useState8(defaultSortOrder);
|
|
2021
|
+
const [searchQuery, setSearchQuery] = useState8("");
|
|
2022
|
+
const [searchInput, setSearchInput] = useState8("");
|
|
2023
|
+
const [filterValues, setFilterValues] = useState8({});
|
|
2024
|
+
const [filterApplyKey, setFilterApplyKey] = useState8(0);
|
|
2025
|
+
const [isFormOpen, setIsFormOpen] = useState8(false);
|
|
2026
|
+
const [editingItem, setEditingItem] = useState8(null);
|
|
2027
|
+
const [deleteDialogOpen, setDeleteDialogOpen] = useState8(false);
|
|
2028
|
+
const [itemToDelete, setItemToDelete] = useState8(null);
|
|
2029
|
+
const [deleteLoading, setDeleteLoading] = useState8(false);
|
|
2030
|
+
const [refreshKey, setRefreshKey] = useState8(0);
|
|
2031
|
+
const [bulkDialogOpen, setBulkDialogOpen] = useState8(false);
|
|
2032
|
+
const [showFilters, setShowFilters] = useState8(false);
|
|
2033
|
+
const [isRefetching, setIsRefetching] = useState8(false);
|
|
2034
|
+
const [roleOptions, setRoleOptions] = useState8([]);
|
|
2035
|
+
const hasLoadedRef = useRef3(false);
|
|
2007
2036
|
const isMobile = useIsMobile();
|
|
2008
2037
|
const showGroupColumn = !!manageUserGroups && roleOptions.length > 0;
|
|
2038
|
+
useEffect6(() => {
|
|
2039
|
+
const timeoutId = setTimeout(() => {
|
|
2040
|
+
if (searchInput !== searchQuery) {
|
|
2041
|
+
setPage(1);
|
|
2042
|
+
setSearchQuery(searchInput);
|
|
2043
|
+
}
|
|
2044
|
+
}, 300);
|
|
2045
|
+
return () => clearTimeout(timeoutId);
|
|
2046
|
+
}, [searchInput, searchQuery]);
|
|
2009
2047
|
useEffect6(() => {
|
|
2010
2048
|
if (!manageUserGroups) return;
|
|
2011
2049
|
fetch("/api/admin/roles").then((r) => r.ok ? r.json() : null).then((data2) => {
|
|
@@ -2016,7 +2054,11 @@ function AdminCRUD({
|
|
|
2016
2054
|
useEffect6(() => {
|
|
2017
2055
|
async function loadData() {
|
|
2018
2056
|
try {
|
|
2019
|
-
|
|
2057
|
+
if (!hasLoadedRef.current) {
|
|
2058
|
+
setLoading(true);
|
|
2059
|
+
} else {
|
|
2060
|
+
setIsRefetching(true);
|
|
2061
|
+
}
|
|
2020
2062
|
setError(null);
|
|
2021
2063
|
const params = new URLSearchParams({
|
|
2022
2064
|
page: page.toString(),
|
|
@@ -2056,6 +2098,8 @@ function AdminCRUD({
|
|
|
2056
2098
|
setTotalPages(1);
|
|
2057
2099
|
} finally {
|
|
2058
2100
|
setLoading(false);
|
|
2101
|
+
setIsRefetching(false);
|
|
2102
|
+
hasLoadedRef.current = true;
|
|
2059
2103
|
}
|
|
2060
2104
|
}
|
|
2061
2105
|
loadData();
|
|
@@ -2066,30 +2110,67 @@ function AdminCRUD({
|
|
|
2066
2110
|
};
|
|
2067
2111
|
const handleSearch = () => {
|
|
2068
2112
|
setPage(1);
|
|
2113
|
+
setSearchQuery(searchInput);
|
|
2069
2114
|
};
|
|
2070
2115
|
const handleApplyFilters = () => {
|
|
2071
2116
|
setPage(1);
|
|
2072
2117
|
setFilterApplyKey((k) => k + 1);
|
|
2073
2118
|
};
|
|
2119
|
+
const closeDeleteDialog = () => {
|
|
2120
|
+
console.debug("[CRUD][delete] closeDeleteDialog", {
|
|
2121
|
+
open: deleteDialogOpen,
|
|
2122
|
+
itemId: itemToDelete?.id,
|
|
2123
|
+
loading: deleteLoading
|
|
2124
|
+
});
|
|
2125
|
+
setDeleteDialogOpen(false);
|
|
2126
|
+
setItemToDelete(null);
|
|
2127
|
+
setDeleteLoading(false);
|
|
2128
|
+
};
|
|
2074
2129
|
const handleDeleteClick = (item) => {
|
|
2130
|
+
console.debug("[CRUD][delete] handleDeleteClick", {
|
|
2131
|
+
itemId: item?.id,
|
|
2132
|
+
resource: resourceName
|
|
2133
|
+
});
|
|
2134
|
+
const active = typeof document !== "undefined" ? document.activeElement : null;
|
|
2135
|
+
if (active instanceof HTMLElement) {
|
|
2136
|
+
active.blur();
|
|
2137
|
+
}
|
|
2138
|
+
setDeleteLoading(false);
|
|
2075
2139
|
setItemToDelete(item);
|
|
2076
|
-
|
|
2140
|
+
window.setTimeout(() => {
|
|
2141
|
+
setDeleteDialogOpen(true);
|
|
2142
|
+
}, 0);
|
|
2077
2143
|
};
|
|
2078
2144
|
const handleDelete = async () => {
|
|
2079
|
-
if (!itemToDelete)
|
|
2145
|
+
if (!itemToDelete) {
|
|
2146
|
+
console.debug("[CRUD][delete] handleDelete blocked: no itemToDelete");
|
|
2147
|
+
return;
|
|
2148
|
+
}
|
|
2149
|
+
console.debug("[CRUD][delete] handleDelete start", {
|
|
2150
|
+
itemId: itemToDelete.id,
|
|
2151
|
+
resource: resourceName
|
|
2152
|
+
});
|
|
2080
2153
|
setDeleteLoading(true);
|
|
2081
2154
|
try {
|
|
2082
2155
|
const res = await fetch(`${apiEndpoint}/${itemToDelete.id}`, { method: "DELETE" });
|
|
2156
|
+
console.debug("[CRUD][delete] handleDelete response", {
|
|
2157
|
+
itemId: itemToDelete.id,
|
|
2158
|
+
ok: res.ok,
|
|
2159
|
+
status: res.status
|
|
2160
|
+
});
|
|
2083
2161
|
if (res.ok) {
|
|
2162
|
+
setData((prev) => prev.filter((row) => String(row.id) !== String(itemToDelete.id)));
|
|
2084
2163
|
setRefreshKey((k) => k + 1);
|
|
2085
|
-
|
|
2086
|
-
setItemToDelete(null);
|
|
2164
|
+
closeDeleteDialog();
|
|
2087
2165
|
} else {
|
|
2088
2166
|
console.error("Failed to delete item");
|
|
2089
2167
|
}
|
|
2090
2168
|
} catch (err) {
|
|
2091
2169
|
console.error("Error deleting item:", err);
|
|
2092
2170
|
} finally {
|
|
2171
|
+
console.debug("[CRUD][delete] handleDelete finally", {
|
|
2172
|
+
itemId: itemToDelete?.id
|
|
2173
|
+
});
|
|
2093
2174
|
setDeleteLoading(false);
|
|
2094
2175
|
}
|
|
2095
2176
|
};
|
|
@@ -2124,18 +2205,33 @@ function AdminCRUD({
|
|
|
2124
2205
|
}
|
|
2125
2206
|
const result = await res.json();
|
|
2126
2207
|
if (result.inviteLink) {
|
|
2127
|
-
|
|
2128
|
-
|
|
2129
|
-
Note: ${result.note}`);
|
|
2208
|
+
const note = result.note ? ` ${result.note}` : "";
|
|
2209
|
+
toast2.success(`New invite link generated.${note}`);
|
|
2130
2210
|
}
|
|
2131
2211
|
} catch (error2) {
|
|
2132
2212
|
console.error("Error regenerating invite:", error2);
|
|
2133
|
-
|
|
2213
|
+
toast2.error(error2 instanceof Error ? error2.message : "Failed to regenerate invite");
|
|
2134
2214
|
}
|
|
2135
2215
|
};
|
|
2136
2216
|
const addEditPage = addEditPageUrl && addEditPageUrl.length > 0;
|
|
2137
2217
|
const hasCustomView = customViewPageUrl && customViewPageUrl.length > 0;
|
|
2138
2218
|
const resourceName = apiEndpoint.replace("/api/", "");
|
|
2219
|
+
const hasDetailViewPage = (/* @__PURE__ */ new Set(["contacts", "form-submissions", "orders", "payments"])).has(resourceName);
|
|
2220
|
+
const getRowDestination = (item) => {
|
|
2221
|
+
if (item.id == null) return "modal";
|
|
2222
|
+
if (addEditPage) return `${addEditPageUrl}/${item.id}`;
|
|
2223
|
+
if (hasCustomView) return `${customViewPageUrl}/${item.id}`;
|
|
2224
|
+
if (hasDetailViewPage) return `/admin/${resourceName}/${item.id}/view`;
|
|
2225
|
+
return "modal";
|
|
2226
|
+
};
|
|
2227
|
+
const handleRowClick = (item) => {
|
|
2228
|
+
const destination = getRowDestination(item);
|
|
2229
|
+
if (destination === "modal") {
|
|
2230
|
+
handleEdit(item);
|
|
2231
|
+
return;
|
|
2232
|
+
}
|
|
2233
|
+
router.push(destination);
|
|
2234
|
+
};
|
|
2139
2235
|
const handleExport = async () => {
|
|
2140
2236
|
try {
|
|
2141
2237
|
const res = await fetch(`${apiEndpoint}/export?format=csv`);
|
|
@@ -2149,7 +2245,7 @@ Note: ${result.note}`);
|
|
|
2149
2245
|
URL.revokeObjectURL(url);
|
|
2150
2246
|
} catch (err) {
|
|
2151
2247
|
console.error("Export error:", err);
|
|
2152
|
-
|
|
2248
|
+
toast2.error("Failed to export data");
|
|
2153
2249
|
}
|
|
2154
2250
|
};
|
|
2155
2251
|
if (loading) {
|
|
@@ -2289,8 +2385,8 @@ Note: ${result.note}`);
|
|
|
2289
2385
|
{
|
|
2290
2386
|
type: "text",
|
|
2291
2387
|
placeholder: "Search...",
|
|
2292
|
-
value:
|
|
2293
|
-
onChange: (e) =>
|
|
2388
|
+
value: searchInput,
|
|
2389
|
+
onChange: (e) => setSearchInput(e.target.value),
|
|
2294
2390
|
onKeyDown: (e) => e.key === "Enter" && handleSearch(),
|
|
2295
2391
|
className: "border-0 focus-visible:ring-0 focus-visible:ring-offset-0 rounded-l-md rounded-r-none flex-1 min-w-0"
|
|
2296
2392
|
}
|
|
@@ -2384,6 +2480,10 @@ Note: ${result.note}`);
|
|
|
2384
2480
|
}),
|
|
2385
2481
|
/* @__PURE__ */ jsx22(Button, { variant: "outline", size: "sm", className: "h-8", onClick: handleApplyFilters, children: "Apply filters" })
|
|
2386
2482
|
] }),
|
|
2483
|
+
isRefetching && /* @__PURE__ */ jsxs15("div", { className: "mb-3 flex items-center text-xs text-gray-500", children: [
|
|
2484
|
+
/* @__PURE__ */ jsx22("div", { className: "animate-spin rounded-full h-3.5 w-3.5 border-2 border-gray-300 border-t-gray-600" }),
|
|
2485
|
+
/* @__PURE__ */ jsx22("span", { className: "ml-2", children: "Refreshing list..." })
|
|
2486
|
+
] }),
|
|
2387
2487
|
isMobile ? /* @__PURE__ */ jsx22("div", { className: "flex flex-col gap-2 min-w-0", children: data && data.length > 0 ? data.map((item, index) => {
|
|
2388
2488
|
const displayCols = columns?.slice(0, 4) ?? [];
|
|
2389
2489
|
const primary = displayCols[0];
|
|
@@ -2391,27 +2491,17 @@ Note: ${result.note}`);
|
|
|
2391
2491
|
return /* @__PURE__ */ jsxs15(
|
|
2392
2492
|
"div",
|
|
2393
2493
|
{
|
|
2394
|
-
className: "min-w-0 rounded-md border border-gray-200 bg-gray-50/50 p-2.5 flex flex-col gap-1",
|
|
2494
|
+
className: "min-w-0 rounded-md border border-gray-200 bg-gray-50/50 p-2.5 flex flex-col gap-1 cursor-pointer",
|
|
2495
|
+
onClick: () => handleRowClick(item),
|
|
2395
2496
|
children: [
|
|
2396
2497
|
/* @__PURE__ */ jsxs15("div", { className: "flex items-center justify-between gap-2", children: [
|
|
2397
2498
|
/* @__PURE__ */ jsx22("div", { className: "min-w-0 break-words flex-1 leading-tight", children: /* @__PURE__ */ jsx22("span", { className: "font-medium", children: primaryVal != null ? String(primaryVal) : "\u2014" }) }),
|
|
2398
|
-
/* @__PURE__ */ jsxs15(DropdownMenu, { children: [
|
|
2499
|
+
/* @__PURE__ */ jsx22("div", { onClick: (e) => e.stopPropagation(), children: /* @__PURE__ */ jsxs15(DropdownMenu, { children: [
|
|
2399
2500
|
/* @__PURE__ */ jsx22(DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ jsxs15(Button, { variant: "ghost", size: "icon", className: "h-8 w-8 shrink-0", children: [
|
|
2400
2501
|
/* @__PURE__ */ jsx22(MoreVertical, { className: "h-4 w-4" }),
|
|
2401
2502
|
/* @__PURE__ */ jsx22("span", { className: "sr-only", children: "Actions" })
|
|
2402
2503
|
] }) }),
|
|
2403
2504
|
/* @__PURE__ */ jsxs15(DropdownMenuContent, { align: "end", children: [
|
|
2404
|
-
/* @__PURE__ */ jsx22(DropdownMenuItem, { asChild: true, children: /* @__PURE__ */ jsxs15(
|
|
2405
|
-
Link4,
|
|
2406
|
-
{
|
|
2407
|
-
href: hasCustomView ? `${customViewPageUrl}/${item.id}` : `/admin/${resourceName}/${item.id}/view`,
|
|
2408
|
-
className: "flex items-center gap-2",
|
|
2409
|
-
children: [
|
|
2410
|
-
/* @__PURE__ */ jsx22(Eye, { className: "h-4 w-4" }),
|
|
2411
|
-
"View"
|
|
2412
|
-
]
|
|
2413
|
-
}
|
|
2414
|
-
) }),
|
|
2415
2505
|
!addEditPage && /* @__PURE__ */ jsxs15(DropdownMenuItem, { onClick: () => handleEdit(item), children: [
|
|
2416
2506
|
/* @__PURE__ */ jsx22(Edit, { className: "h-4 w-4 mr-2" }),
|
|
2417
2507
|
"Edit"
|
|
@@ -2436,7 +2526,7 @@ Note: ${result.note}`);
|
|
|
2436
2526
|
}
|
|
2437
2527
|
)
|
|
2438
2528
|
] })
|
|
2439
|
-
] })
|
|
2529
|
+
] }, `mobile-actions-${String(item.id ?? index)}-${refreshKey}`) })
|
|
2440
2530
|
] }),
|
|
2441
2531
|
displayCols.slice(1).map((col) => /* @__PURE__ */ jsxs15("div", { className: "text-sm text-gray-600 flex gap-1 min-w-0 leading-tight", children: [
|
|
2442
2532
|
/* @__PURE__ */ jsxs15("span", { className: "shrink-0", children: [
|
|
@@ -2445,7 +2535,7 @@ Note: ${result.note}`);
|
|
|
2445
2535
|
] }),
|
|
2446
2536
|
/* @__PURE__ */ jsx22("span", { className: "min-w-0 break-words", children: formatCellValue(getNestedValue(item, col.field || col.key), col) })
|
|
2447
2537
|
] }, col.field || col.key)),
|
|
2448
|
-
showGroupColumn && /* @__PURE__ */ jsxs15("div", { className: "text-sm text-gray-600 flex gap-1 items-center min-w-0", children: [
|
|
2538
|
+
showGroupColumn && /* @__PURE__ */ jsxs15("div", { className: "text-sm text-gray-600 flex gap-1 items-center min-w-0", onClick: (e) => e.stopPropagation(), children: [
|
|
2449
2539
|
/* @__PURE__ */ jsx22("span", { className: "shrink-0", children: "Group:" }),
|
|
2450
2540
|
/* @__PURE__ */ jsxs15(
|
|
2451
2541
|
"select",
|
|
@@ -2485,70 +2575,94 @@ Note: ${result.note}`);
|
|
|
2485
2575
|
showGroupColumn && /* @__PURE__ */ jsx22(TableHead, { className: "min-w-[140px]", children: "Group" }),
|
|
2486
2576
|
/* @__PURE__ */ jsx22(TableHead, { className: "w-12 text-center", children: "Actions" })
|
|
2487
2577
|
] }) }),
|
|
2488
|
-
/* @__PURE__ */ jsx22(TableBody, { children: data && data.length > 0 ? data.map((item, index) => /* @__PURE__ */ jsxs15(
|
|
2489
|
-
|
|
2490
|
-
|
|
2491
|
-
|
|
2492
|
-
|
|
2493
|
-
|
|
2494
|
-
|
|
2495
|
-
|
|
2496
|
-
|
|
2497
|
-
|
|
2498
|
-
|
|
2499
|
-
|
|
2500
|
-
|
|
2501
|
-
if (v) handleUserGroupChange(Number(item.id), Number(v));
|
|
2502
|
-
},
|
|
2503
|
-
children: [
|
|
2504
|
-
/* @__PURE__ */ jsx22("option", { value: "", children: "\u2014" }),
|
|
2505
|
-
roleOptions.map((g) => /* @__PURE__ */ jsx22("option", { value: g.id, children: g.name }, g.id))
|
|
2506
|
-
]
|
|
2507
|
-
}
|
|
2508
|
-
) }),
|
|
2509
|
-
/* @__PURE__ */ jsx22(TableCell, { className: "text-center", children: /* @__PURE__ */ jsxs15(DropdownMenu, { children: [
|
|
2510
|
-
/* @__PURE__ */ jsx22(DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ jsxs15(Button, { variant: "ghost", size: "icon", className: "h-8 w-8", children: [
|
|
2511
|
-
/* @__PURE__ */ jsx22(MoreVertical, { className: "h-4 w-4" }),
|
|
2512
|
-
/* @__PURE__ */ jsx22("span", { className: "sr-only", children: "Actions" })
|
|
2513
|
-
] }) }),
|
|
2514
|
-
/* @__PURE__ */ jsxs15(DropdownMenuContent, { align: "end", children: [
|
|
2515
|
-
/* @__PURE__ */ jsx22(DropdownMenuItem, { asChild: true, children: /* @__PURE__ */ jsxs15(
|
|
2516
|
-
Link4,
|
|
2578
|
+
/* @__PURE__ */ jsx22(TableBody, { children: data && data.length > 0 ? data.map((item, index) => /* @__PURE__ */ jsxs15(
|
|
2579
|
+
TableRow,
|
|
2580
|
+
{
|
|
2581
|
+
className: "cursor-pointer",
|
|
2582
|
+
onClick: () => handleRowClick(item),
|
|
2583
|
+
children: [
|
|
2584
|
+
columns && columns.map((col, colIndex) => {
|
|
2585
|
+
const fieldKey = col.field || col.key;
|
|
2586
|
+
const value = getNestedValue(item, fieldKey);
|
|
2587
|
+
return /* @__PURE__ */ jsx22(TableCell, { children: formatCellValue(value, col) }, `${item.id}-${colIndex}-${fieldKey}`);
|
|
2588
|
+
}),
|
|
2589
|
+
showGroupColumn && /* @__PURE__ */ jsx22(TableCell, { onClick: (e) => e.stopPropagation(), children: /* @__PURE__ */ jsxs15(
|
|
2590
|
+
"select",
|
|
2517
2591
|
{
|
|
2518
|
-
|
|
2519
|
-
|
|
2592
|
+
className: "max-w-[180px] rounded border border-gray-300 px-2 py-1 text-sm dark:border-gray-600 dark:bg-gray-800",
|
|
2593
|
+
value: item.groupId != null && roleOptions.some((g) => g.id === item.groupId) ? String(item.groupId) : "",
|
|
2594
|
+
onChange: (e) => {
|
|
2595
|
+
const v = e.target.value;
|
|
2596
|
+
if (v) handleUserGroupChange(Number(item.id), Number(v));
|
|
2597
|
+
},
|
|
2520
2598
|
children: [
|
|
2521
|
-
/* @__PURE__ */ jsx22(
|
|
2522
|
-
"
|
|
2599
|
+
/* @__PURE__ */ jsx22("option", { value: "", children: "\u2014" }),
|
|
2600
|
+
roleOptions.map((g) => /* @__PURE__ */ jsx22("option", { value: g.id, children: g.name }, g.id))
|
|
2523
2601
|
]
|
|
2524
2602
|
}
|
|
2525
2603
|
) }),
|
|
2526
|
-
|
|
2527
|
-
/* @__PURE__ */
|
|
2528
|
-
|
|
2529
|
-
|
|
2530
|
-
|
|
2531
|
-
|
|
2532
|
-
|
|
2533
|
-
|
|
2534
|
-
|
|
2535
|
-
|
|
2536
|
-
|
|
2537
|
-
|
|
2538
|
-
|
|
2539
|
-
|
|
2540
|
-
|
|
2541
|
-
|
|
2542
|
-
|
|
2543
|
-
|
|
2544
|
-
|
|
2545
|
-
"
|
|
2546
|
-
|
|
2547
|
-
|
|
2548
|
-
|
|
2549
|
-
|
|
2550
|
-
|
|
2551
|
-
|
|
2604
|
+
/* @__PURE__ */ jsx22(TableCell, { className: "text-center", onClick: (e) => e.stopPropagation(), children: /* @__PURE__ */ jsxs15("div", { className: "flex items-center justify-center gap-1", children: [
|
|
2605
|
+
!addEditPage && /* @__PURE__ */ jsxs15(
|
|
2606
|
+
Button,
|
|
2607
|
+
{
|
|
2608
|
+
variant: "outline",
|
|
2609
|
+
size: "icon",
|
|
2610
|
+
className: "h-7 w-7",
|
|
2611
|
+
onClick: () => handleEdit(item),
|
|
2612
|
+
title: "Edit",
|
|
2613
|
+
children: [
|
|
2614
|
+
/* @__PURE__ */ jsx22(Edit, { className: "h-3.5 w-3.5" }),
|
|
2615
|
+
/* @__PURE__ */ jsx22("span", { className: "sr-only", children: "Edit" })
|
|
2616
|
+
]
|
|
2617
|
+
}
|
|
2618
|
+
),
|
|
2619
|
+
addEditPage && /* @__PURE__ */ jsxs15(
|
|
2620
|
+
Button,
|
|
2621
|
+
{
|
|
2622
|
+
variant: "outline",
|
|
2623
|
+
size: "icon",
|
|
2624
|
+
className: "h-7 w-7",
|
|
2625
|
+
onClick: () => router.push(addEditPageUrl + "/" + item.id),
|
|
2626
|
+
title: "Edit",
|
|
2627
|
+
children: [
|
|
2628
|
+
/* @__PURE__ */ jsx22(Edit, { className: "h-3.5 w-3.5" }),
|
|
2629
|
+
/* @__PURE__ */ jsx22("span", { className: "sr-only", children: "Edit" })
|
|
2630
|
+
]
|
|
2631
|
+
}
|
|
2632
|
+
),
|
|
2633
|
+
resourceName === "users" && /* @__PURE__ */ jsxs15(
|
|
2634
|
+
Button,
|
|
2635
|
+
{
|
|
2636
|
+
variant: "outline",
|
|
2637
|
+
size: "icon",
|
|
2638
|
+
className: "h-7 w-7",
|
|
2639
|
+
onClick: () => handleRegenerateInvite(Number(item.id)),
|
|
2640
|
+
title: "Regenerate Invite",
|
|
2641
|
+
children: [
|
|
2642
|
+
/* @__PURE__ */ jsx22(RefreshCw, { className: "h-3.5 w-3.5" }),
|
|
2643
|
+
/* @__PURE__ */ jsx22("span", { className: "sr-only", children: "Regenerate Invite" })
|
|
2644
|
+
]
|
|
2645
|
+
}
|
|
2646
|
+
),
|
|
2647
|
+
/* @__PURE__ */ jsxs15(
|
|
2648
|
+
Button,
|
|
2649
|
+
{
|
|
2650
|
+
variant: "outline",
|
|
2651
|
+
size: "icon",
|
|
2652
|
+
className: "h-7 w-7 border-red-300 text-red-600 hover:text-red-700",
|
|
2653
|
+
onClick: () => handleDeleteClick(item),
|
|
2654
|
+
title: "Delete",
|
|
2655
|
+
children: [
|
|
2656
|
+
/* @__PURE__ */ jsx22(Trash2, { className: "h-3.5 w-3.5" }),
|
|
2657
|
+
/* @__PURE__ */ jsx22("span", { className: "sr-only", children: "Delete" })
|
|
2658
|
+
]
|
|
2659
|
+
}
|
|
2660
|
+
)
|
|
2661
|
+
] }) })
|
|
2662
|
+
]
|
|
2663
|
+
},
|
|
2664
|
+
String(item.id ?? index)
|
|
2665
|
+
)) : /* @__PURE__ */ jsx22(TableRow, { children: /* @__PURE__ */ jsx22(
|
|
2552
2666
|
TableCell,
|
|
2553
2667
|
{
|
|
2554
2668
|
colSpan: columns ? columns.length + 1 + (showGroupColumn ? 1 : 0) : 1,
|
|
@@ -2594,21 +2708,35 @@ Note: ${result.note}`);
|
|
|
2594
2708
|
existingData: editingItem
|
|
2595
2709
|
}
|
|
2596
2710
|
),
|
|
2597
|
-
/* @__PURE__ */ jsx22(
|
|
2598
|
-
|
|
2599
|
-
|
|
2600
|
-
|
|
2601
|
-
|
|
2602
|
-
|
|
2603
|
-
|
|
2604
|
-
|
|
2711
|
+
/* @__PURE__ */ jsx22(
|
|
2712
|
+
Dialog,
|
|
2713
|
+
{
|
|
2714
|
+
open: deleteDialogOpen,
|
|
2715
|
+
onOpenChange: (open) => {
|
|
2716
|
+
console.debug("[CRUD][delete] dialog onOpenChange", {
|
|
2717
|
+
nextOpen: open,
|
|
2718
|
+
itemId: itemToDelete?.id
|
|
2719
|
+
});
|
|
2720
|
+
if (!open) closeDeleteDialog();
|
|
2721
|
+
else setDeleteDialogOpen(true);
|
|
2722
|
+
},
|
|
2723
|
+
children: /* @__PURE__ */ jsxs15(DialogContent, { children: [
|
|
2724
|
+
/* @__PURE__ */ jsxs15(DialogHeader, { children: [
|
|
2725
|
+
/* @__PURE__ */ jsx22(DialogTitle, { children: "Confirm Delete" }),
|
|
2726
|
+
/* @__PURE__ */ jsx22(DialogDescription, { children: "Are you sure you want to delete this item? This action cannot be undone." }),
|
|
2727
|
+
itemToDelete && /* @__PURE__ */ jsxs15("div", { className: "mt-2 p-2 bg-gray-50 rounded", children: [
|
|
2728
|
+
/* @__PURE__ */ jsx22("strong", { children: "Item:" }),
|
|
2729
|
+
" ",
|
|
2730
|
+
String(itemToDelete.name ?? itemToDelete.title ?? itemToDelete.id ?? "")
|
|
2731
|
+
] })
|
|
2732
|
+
] }),
|
|
2733
|
+
/* @__PURE__ */ jsxs15(DialogFooter, { children: [
|
|
2734
|
+
/* @__PURE__ */ jsx22(Button, { variant: "outline", onClick: closeDeleteDialog, disabled: deleteLoading, children: "Cancel" }),
|
|
2735
|
+
/* @__PURE__ */ jsx22(Button, { variant: "destructive", onClick: handleDelete, disabled: deleteLoading, children: deleteLoading ? "Deleting..." : "Delete" })
|
|
2736
|
+
] })
|
|
2605
2737
|
] })
|
|
2606
|
-
|
|
2607
|
-
|
|
2608
|
-
/* @__PURE__ */ jsx22(Button, { variant: "outline", onClick: () => setDeleteDialogOpen(false), disabled: deleteLoading, children: "Cancel" }),
|
|
2609
|
-
/* @__PURE__ */ jsx22(Button, { variant: "destructive", onClick: handleDelete, disabled: deleteLoading, children: deleteLoading ? "Deleting..." : "Delete" })
|
|
2610
|
-
] })
|
|
2611
|
-
] }) }),
|
|
2738
|
+
}
|
|
2739
|
+
),
|
|
2612
2740
|
bulkDialogOpen && /* @__PURE__ */ jsx22(
|
|
2613
2741
|
BulkUploadDialog,
|
|
2614
2742
|
{
|
|
@@ -2624,7 +2752,7 @@ Note: ${result.note}`);
|
|
|
2624
2752
|
}
|
|
2625
2753
|
|
|
2626
2754
|
// src/components/Admin/FormBuilder.tsx
|
|
2627
|
-
import { useState as
|
|
2755
|
+
import { useState as useState10, useEffect as useEffect7, useCallback as useCallback2 } from "react";
|
|
2628
2756
|
|
|
2629
2757
|
// src/components/ui/badge.tsx
|
|
2630
2758
|
import { cva as cva4 } from "class-variance-authority";
|
|
@@ -2650,11 +2778,11 @@ function Badge({ className, variant, ...props }) {
|
|
|
2650
2778
|
}
|
|
2651
2779
|
|
|
2652
2780
|
// src/components/Admin/FormBuilder.tsx
|
|
2653
|
-
import { X as X7, Save, Plus as Plus3, Trash2 as Trash22 } from "lucide-react";
|
|
2654
|
-
import { useRouter as
|
|
2781
|
+
import { X as X7, Save, Plus as Plus3, Trash2 as Trash22, Check as Check4 } from "lucide-react";
|
|
2782
|
+
import { useRouter as useRouter3 } from "next/navigation";
|
|
2655
2783
|
|
|
2656
2784
|
// src/components/Admin/FormBuilder/FieldConfiguration.tsx
|
|
2657
|
-
import { useState as
|
|
2785
|
+
import { useState as useState9 } from "react";
|
|
2658
2786
|
import { Plus as Plus2, X as X6 } from "lucide-react";
|
|
2659
2787
|
import { jsx as jsx24, jsxs as jsxs16 } from "react/jsx-runtime";
|
|
2660
2788
|
var FIELD_TYPES = [
|
|
@@ -2675,7 +2803,7 @@ var COLUMN_WIDTHS = [
|
|
|
2675
2803
|
{ value: 12, label: "Full Width (12 cols)" }
|
|
2676
2804
|
];
|
|
2677
2805
|
function FieldConfiguration({ field, onUpdate }) {
|
|
2678
|
-
const [newOption, setNewOption] =
|
|
2806
|
+
const [newOption, setNewOption] = useState9("");
|
|
2679
2807
|
const addOption = () => {
|
|
2680
2808
|
if (newOption.trim()) {
|
|
2681
2809
|
const currentOptions = field.options || [];
|
|
@@ -2948,7 +3076,7 @@ function FieldConfiguration({ field, onUpdate }) {
|
|
|
2948
3076
|
// src/components/Admin/FormBuilder.tsx
|
|
2949
3077
|
import { jsx as jsx25, jsxs as jsxs17 } from "react/jsx-runtime";
|
|
2950
3078
|
function FormBuilder({ formId }) {
|
|
2951
|
-
const [formData, setFormData] =
|
|
3079
|
+
const [formData, setFormData] = useState10({
|
|
2952
3080
|
name: "",
|
|
2953
3081
|
description: "",
|
|
2954
3082
|
campaign: "",
|
|
@@ -2956,11 +3084,11 @@ function FormBuilder({ formId }) {
|
|
|
2956
3084
|
published: false,
|
|
2957
3085
|
fields: []
|
|
2958
3086
|
});
|
|
2959
|
-
const [errors, setErrors] =
|
|
2960
|
-
const [isLoading, setIsLoading] =
|
|
2961
|
-
const [isSaving, setIsSaving] =
|
|
2962
|
-
const [selectedField, setSelectedField] =
|
|
2963
|
-
const router =
|
|
3087
|
+
const [errors, setErrors] = useState10([]);
|
|
3088
|
+
const [isLoading, setIsLoading] = useState10(false);
|
|
3089
|
+
const [isSaving, setIsSaving] = useState10(false);
|
|
3090
|
+
const [selectedField, setSelectedField] = useState10(null);
|
|
3091
|
+
const router = useRouter3();
|
|
2964
3092
|
const loadFormData = useCallback2(async () => {
|
|
2965
3093
|
try {
|
|
2966
3094
|
setIsLoading(true);
|
|
@@ -3125,19 +3253,34 @@ function FormBuilder({ formId }) {
|
|
|
3125
3253
|
/* @__PURE__ */ jsx25("h1", { className: "text-xl font-bold text-white", children: formId ? "Edit Form" : "Create New Form" }),
|
|
3126
3254
|
/* @__PURE__ */ jsx25("p", { className: "text-xs text-gray-300 mt-0.5", children: "Design your form with drag-and-drop fields" })
|
|
3127
3255
|
] }),
|
|
3128
|
-
/* @__PURE__ */
|
|
3129
|
-
|
|
3130
|
-
|
|
3131
|
-
|
|
3132
|
-
|
|
3133
|
-
|
|
3134
|
-
|
|
3135
|
-
|
|
3136
|
-
|
|
3137
|
-
|
|
3138
|
-
|
|
3139
|
-
|
|
3140
|
-
|
|
3256
|
+
/* @__PURE__ */ jsxs17("div", { className: "flex items-center space-x-3", children: [
|
|
3257
|
+
/* @__PURE__ */ jsxs17(
|
|
3258
|
+
Button,
|
|
3259
|
+
{
|
|
3260
|
+
variant: "outline",
|
|
3261
|
+
size: "icon",
|
|
3262
|
+
className: "md:hidden h-8 w-8 bg-white text-gray-800 hover:bg-gray-100 border-0",
|
|
3263
|
+
onClick: () => router.push("/admin/forms"),
|
|
3264
|
+
children: [
|
|
3265
|
+
/* @__PURE__ */ jsx25(X7, { className: "h-4 w-4" }),
|
|
3266
|
+
/* @__PURE__ */ jsx25("span", { className: "sr-only", children: "Close" })
|
|
3267
|
+
]
|
|
3268
|
+
}
|
|
3269
|
+
),
|
|
3270
|
+
/* @__PURE__ */ jsxs17(
|
|
3271
|
+
Button,
|
|
3272
|
+
{
|
|
3273
|
+
variant: "outline",
|
|
3274
|
+
size: "sm",
|
|
3275
|
+
className: "hidden md:inline-flex bg-white text-gray-800 hover:bg-gray-100 border-0 text-xs",
|
|
3276
|
+
onClick: () => router.push("/admin/forms"),
|
|
3277
|
+
children: [
|
|
3278
|
+
/* @__PURE__ */ jsx25(X7, { className: "h-4 w-4 mr-2" }),
|
|
3279
|
+
"Close"
|
|
3280
|
+
]
|
|
3281
|
+
}
|
|
3282
|
+
)
|
|
3283
|
+
] })
|
|
3141
3284
|
] }) }),
|
|
3142
3285
|
errors.length > 0 && /* @__PURE__ */ jsx25("div", { className: "bg-red-50 border-l-4 border-red-400 p-4 mx-6 mt-4", children: /* @__PURE__ */ jsx25("div", { className: "flex", children: /* @__PURE__ */ jsxs17("div", { className: "ml-3", children: [
|
|
3143
3286
|
/* @__PURE__ */ jsx25("h3", { className: "text-sm font-medium text-red-800", children: "Please fix the following errors:" }),
|
|
@@ -3315,11 +3458,24 @@ function FormBuilder({ formId }) {
|
|
|
3315
3458
|
/* @__PURE__ */ jsx25("div", { className: "bg-gray-50 border-t border-gray-200 px-6 py-4", children: /* @__PURE__ */ jsxs17("div", { className: "flex items-center justify-between", children: [
|
|
3316
3459
|
/* @__PURE__ */ jsx25("div", { className: "text-sm text-gray-600", children: formId ? "Editing existing form" : "Creating new form" }),
|
|
3317
3460
|
/* @__PURE__ */ jsxs17("div", { className: "flex items-center space-x-3", children: [
|
|
3461
|
+
/* @__PURE__ */ jsxs17(
|
|
3462
|
+
Button,
|
|
3463
|
+
{
|
|
3464
|
+
variant: "outline",
|
|
3465
|
+
size: "icon",
|
|
3466
|
+
className: "md:hidden h-8 w-8 bg-white text-gray-800 hover:bg-gray-100 border-0",
|
|
3467
|
+
onClick: () => router.push("/admin/forms"),
|
|
3468
|
+
children: [
|
|
3469
|
+
/* @__PURE__ */ jsx25(X7, { className: "h-4 w-4" }),
|
|
3470
|
+
/* @__PURE__ */ jsx25("span", { className: "sr-only", children: "Close" })
|
|
3471
|
+
]
|
|
3472
|
+
}
|
|
3473
|
+
),
|
|
3318
3474
|
/* @__PURE__ */ jsx25(
|
|
3319
3475
|
Button,
|
|
3320
3476
|
{
|
|
3321
3477
|
variant: "outline",
|
|
3322
|
-
className: "bg-white text-gray-800 hover:bg-gray-100 border-0 text-xs",
|
|
3478
|
+
className: "hidden md:inline-flex bg-white text-gray-800 hover:bg-gray-100 border-0 text-xs",
|
|
3323
3479
|
onClick: () => router.push("/admin/forms"),
|
|
3324
3480
|
children: "Close"
|
|
3325
3481
|
}
|
|
@@ -3329,19 +3485,45 @@ function FormBuilder({ formId }) {
|
|
|
3329
3485
|
{
|
|
3330
3486
|
onClick: () => handleSave(false),
|
|
3331
3487
|
disabled: isSaving,
|
|
3332
|
-
|
|
3488
|
+
size: "icon",
|
|
3489
|
+
className: "md:hidden h-8 w-8 bg-white text-gray-800 hover:bg-gray-100 border-0",
|
|
3490
|
+
children: [
|
|
3491
|
+
/* @__PURE__ */ jsx25(Save, { className: "h-4 w-4" }),
|
|
3492
|
+
/* @__PURE__ */ jsx25("span", { className: "sr-only", children: isSaving ? "Saving..." : "Save" })
|
|
3493
|
+
]
|
|
3494
|
+
}
|
|
3495
|
+
),
|
|
3496
|
+
/* @__PURE__ */ jsxs17(
|
|
3497
|
+
Button,
|
|
3498
|
+
{
|
|
3499
|
+
onClick: () => handleSave(false),
|
|
3500
|
+
disabled: isSaving,
|
|
3501
|
+
className: "hidden md:inline-flex bg-white text-gray-800 hover:bg-gray-100 border-0 text-xs",
|
|
3333
3502
|
children: [
|
|
3334
3503
|
/* @__PURE__ */ jsx25(Save, { className: "h-4 w-4 mr-2" }),
|
|
3335
3504
|
isSaving ? "Saving..." : "Save"
|
|
3336
3505
|
]
|
|
3337
3506
|
}
|
|
3338
3507
|
),
|
|
3508
|
+
/* @__PURE__ */ jsxs17(
|
|
3509
|
+
Button,
|
|
3510
|
+
{
|
|
3511
|
+
onClick: () => handleSave(true),
|
|
3512
|
+
disabled: isSaving,
|
|
3513
|
+
size: "icon",
|
|
3514
|
+
className: "md:hidden h-8 w-8 bg-gray-800 text-white hover:bg-gray-700",
|
|
3515
|
+
children: [
|
|
3516
|
+
/* @__PURE__ */ jsx25(Check4, { className: "h-4 w-4" }),
|
|
3517
|
+
/* @__PURE__ */ jsx25("span", { className: "sr-only", children: isSaving ? "Publishing..." : "Publish" })
|
|
3518
|
+
]
|
|
3519
|
+
}
|
|
3520
|
+
),
|
|
3339
3521
|
/* @__PURE__ */ jsx25(
|
|
3340
3522
|
Button,
|
|
3341
3523
|
{
|
|
3342
3524
|
onClick: () => handleSave(true),
|
|
3343
3525
|
disabled: isSaving,
|
|
3344
|
-
className: "bg-gray-800 text-white hover:bg-gray-700 text-xs",
|
|
3526
|
+
className: "hidden md:inline-flex bg-gray-800 text-white hover:bg-gray-700 text-xs",
|
|
3345
3527
|
children: isSaving ? "Publishing..." : "Publish"
|
|
3346
3528
|
}
|
|
3347
3529
|
)
|
|
@@ -3351,10 +3533,10 @@ function FormBuilder({ formId }) {
|
|
|
3351
3533
|
}
|
|
3352
3534
|
|
|
3353
3535
|
// src/components/Admin/BlogEditorPage.tsx
|
|
3354
|
-
import { useState as
|
|
3536
|
+
import { useState as useState15, useEffect as useEffect11 } from "react";
|
|
3355
3537
|
|
|
3356
3538
|
// src/components/ui/image-upload.tsx
|
|
3357
|
-
import { useState as
|
|
3539
|
+
import { useState as useState11, useRef as useRef4, useCallback as useCallback3 } from "react";
|
|
3358
3540
|
import { Upload as Upload3, X as X8, ImageIcon as ImageIcon2, AlertCircle as AlertCircle2 } from "lucide-react";
|
|
3359
3541
|
import Image3 from "next/image";
|
|
3360
3542
|
import { jsx as jsx26, jsxs as jsxs18 } from "react/jsx-runtime";
|
|
@@ -3369,11 +3551,11 @@ function ImageUpload({
|
|
|
3369
3551
|
// 10MB default
|
|
3370
3552
|
acceptedTypes = ["image/jpeg", "image/png", "image/gif", "image/webp"]
|
|
3371
3553
|
}) {
|
|
3372
|
-
const [isDragOver, setIsDragOver] =
|
|
3373
|
-
const [isUploading, setIsUploading] =
|
|
3374
|
-
const [uploadProgress, setUploadProgress] =
|
|
3375
|
-
const [error, setError] =
|
|
3376
|
-
const fileInputRef =
|
|
3554
|
+
const [isDragOver, setIsDragOver] = useState11(false);
|
|
3555
|
+
const [isUploading, setIsUploading] = useState11(false);
|
|
3556
|
+
const [uploadProgress, setUploadProgress] = useState11(0);
|
|
3557
|
+
const [error, setError] = useState11(null);
|
|
3558
|
+
const fileInputRef = useRef4(null);
|
|
3377
3559
|
const handleFileSelect = useCallback3(async (file) => {
|
|
3378
3560
|
setError(null);
|
|
3379
3561
|
setUploadProgress(0);
|
|
@@ -3555,10 +3737,10 @@ function ImageUpload({
|
|
|
3555
3737
|
|
|
3556
3738
|
// src/components/Admin/BlogEditorPage.tsx
|
|
3557
3739
|
import { X as X12, Save as Save2, AlertCircle as AlertCircle3 } from "lucide-react";
|
|
3558
|
-
import { useRouter as
|
|
3740
|
+
import { useRouter as useRouter4 } from "next/navigation";
|
|
3559
3741
|
|
|
3560
3742
|
// src/components/Admin/TagAutocomplete.tsx
|
|
3561
|
-
import { useState as
|
|
3743
|
+
import { useState as useState12, useEffect as useEffect8, useRef as useRef5, useCallback as useCallback4 } from "react";
|
|
3562
3744
|
import { X as X9, Plus as Plus4, Search as Search2 } from "lucide-react";
|
|
3563
3745
|
import { Fragment as Fragment4, jsx as jsx27, jsxs as jsxs19 } from "react/jsx-runtime";
|
|
3564
3746
|
function TagAutocomplete({
|
|
@@ -3567,13 +3749,13 @@ function TagAutocomplete({
|
|
|
3567
3749
|
placeholder = "Search or create tags...",
|
|
3568
3750
|
className = ""
|
|
3569
3751
|
}) {
|
|
3570
|
-
const [inputValue, setInputValue] =
|
|
3571
|
-
const [suggestions, setSuggestions] =
|
|
3572
|
-
const [isLoading, setIsLoading] =
|
|
3573
|
-
const [showSuggestions, setShowSuggestions] =
|
|
3574
|
-
const [isCreating, setIsCreating] =
|
|
3575
|
-
const inputRef =
|
|
3576
|
-
const suggestionsRef =
|
|
3752
|
+
const [inputValue, setInputValue] = useState12("");
|
|
3753
|
+
const [suggestions, setSuggestions] = useState12([]);
|
|
3754
|
+
const [isLoading, setIsLoading] = useState12(false);
|
|
3755
|
+
const [showSuggestions, setShowSuggestions] = useState12(false);
|
|
3756
|
+
const [isCreating, setIsCreating] = useState12(false);
|
|
3757
|
+
const inputRef = useRef5(null);
|
|
3758
|
+
const suggestionsRef = useRef5(null);
|
|
3577
3759
|
const fetchSuggestions = useCallback4(async (query) => {
|
|
3578
3760
|
if (!query.trim()) {
|
|
3579
3761
|
setSuggestions([]);
|
|
@@ -3719,7 +3901,10 @@ function TagAutocomplete({
|
|
|
3719
3901
|
"div",
|
|
3720
3902
|
{
|
|
3721
3903
|
className: "px-4 py-2 hover:bg-gray-100 cursor-pointer text-sm",
|
|
3722
|
-
|
|
3904
|
+
onMouseDown: (e) => {
|
|
3905
|
+
e.preventDefault();
|
|
3906
|
+
handleSuggestionSelect(tag);
|
|
3907
|
+
},
|
|
3723
3908
|
children: tag.name
|
|
3724
3909
|
},
|
|
3725
3910
|
tag.id
|
|
@@ -3735,7 +3920,10 @@ function TagAutocomplete({
|
|
|
3735
3920
|
"div",
|
|
3736
3921
|
{
|
|
3737
3922
|
className: "px-4 py-2 hover:bg-gray-100 cursor-pointer text-sm text-gray-700 flex items-center",
|
|
3738
|
-
|
|
3923
|
+
onMouseDown: (e) => {
|
|
3924
|
+
e.preventDefault();
|
|
3925
|
+
handleCreateTag();
|
|
3926
|
+
},
|
|
3739
3927
|
children: [
|
|
3740
3928
|
/* @__PURE__ */ jsx27(Plus4, { className: "h-3 w-3 mr-2" }),
|
|
3741
3929
|
'Create "',
|
|
@@ -3751,7 +3939,7 @@ function TagAutocomplete({
|
|
|
3751
3939
|
|
|
3752
3940
|
// src/components/Admin/JoditRichText.tsx
|
|
3753
3941
|
import dynamic from "next/dynamic";
|
|
3754
|
-
import { useMemo } from "react";
|
|
3942
|
+
import { useMemo as useMemo2 } from "react";
|
|
3755
3943
|
import "jodit/es2021/jodit.min.css";
|
|
3756
3944
|
import { jsx as jsx28 } from "react/jsx-runtime";
|
|
3757
3945
|
var JoditEditor = dynamic(() => import("jodit-react").then((m) => m.default), {
|
|
@@ -3759,7 +3947,7 @@ var JoditEditor = dynamic(() => import("jodit-react").then((m) => m.default), {
|
|
|
3759
3947
|
loading: () => /* @__PURE__ */ jsx28("div", { className: "min-h-[300px] rounded-md border border-gray-200 bg-gray-50 animate-pulse" })
|
|
3760
3948
|
});
|
|
3761
3949
|
function JoditRichText({ value, onChange, placeholder, minHeight = 400 }) {
|
|
3762
|
-
const config =
|
|
3950
|
+
const config = useMemo2(
|
|
3763
3951
|
() => ({
|
|
3764
3952
|
readonly: false,
|
|
3765
3953
|
placeholder: placeholder ?? "",
|
|
@@ -3823,8 +4011,8 @@ function JoditRichText({ value, onChange, placeholder, minHeight = 400 }) {
|
|
|
3823
4011
|
}
|
|
3824
4012
|
|
|
3825
4013
|
// src/components/Admin/CategoryAutocomplete.tsx
|
|
3826
|
-
import { useState as
|
|
3827
|
-
import { X as X10, Plus as Plus5, Search as Search3, Check as
|
|
4014
|
+
import { useState as useState13, useEffect as useEffect9, useRef as useRef6 } from "react";
|
|
4015
|
+
import { X as X10, Plus as Plus5, Search as Search3, Check as Check5 } from "lucide-react";
|
|
3828
4016
|
import { Fragment as Fragment5, jsx as jsx29, jsxs as jsxs20 } from "react/jsx-runtime";
|
|
3829
4017
|
function CategoryAutocomplete({
|
|
3830
4018
|
selectedCategory,
|
|
@@ -3832,13 +4020,13 @@ function CategoryAutocomplete({
|
|
|
3832
4020
|
placeholder = "Search or create category...",
|
|
3833
4021
|
className = ""
|
|
3834
4022
|
}) {
|
|
3835
|
-
const [inputValue, setInputValue] =
|
|
3836
|
-
const [suggestions, setSuggestions] =
|
|
3837
|
-
const [isLoading, setIsLoading] =
|
|
3838
|
-
const [showSuggestions, setShowSuggestions] =
|
|
3839
|
-
const [isCreating, setIsCreating] =
|
|
3840
|
-
const inputRef =
|
|
3841
|
-
const suggestionsRef =
|
|
4023
|
+
const [inputValue, setInputValue] = useState13("");
|
|
4024
|
+
const [suggestions, setSuggestions] = useState13([]);
|
|
4025
|
+
const [isLoading, setIsLoading] = useState13(false);
|
|
4026
|
+
const [showSuggestions, setShowSuggestions] = useState13(false);
|
|
4027
|
+
const [isCreating, setIsCreating] = useState13(false);
|
|
4028
|
+
const inputRef = useRef6(null);
|
|
4029
|
+
const suggestionsRef = useRef6(null);
|
|
3842
4030
|
const fetchSuggestions = async (query) => {
|
|
3843
4031
|
if (!query.trim()) {
|
|
3844
4032
|
setSuggestions([]);
|
|
@@ -3979,10 +4167,13 @@ function CategoryAutocomplete({
|
|
|
3979
4167
|
"div",
|
|
3980
4168
|
{
|
|
3981
4169
|
className: "px-4 py-2 hover:bg-gray-100 cursor-pointer text-sm flex items-center justify-between",
|
|
3982
|
-
|
|
4170
|
+
onMouseDown: (e) => {
|
|
4171
|
+
e.preventDefault();
|
|
4172
|
+
handleSuggestionSelect(category);
|
|
4173
|
+
},
|
|
3983
4174
|
children: [
|
|
3984
4175
|
category.name,
|
|
3985
|
-
selectedCategory === category.name && /* @__PURE__ */ jsx29(
|
|
4176
|
+
selectedCategory === category.name && /* @__PURE__ */ jsx29(Check5, { className: "h-4 w-4 text-green-500" })
|
|
3986
4177
|
]
|
|
3987
4178
|
},
|
|
3988
4179
|
category.id
|
|
@@ -3998,7 +4189,10 @@ function CategoryAutocomplete({
|
|
|
3998
4189
|
"div",
|
|
3999
4190
|
{
|
|
4000
4191
|
className: "px-4 py-2 hover:bg-gray-100 cursor-pointer text-sm text-gray-700 flex items-center",
|
|
4001
|
-
|
|
4192
|
+
onMouseDown: (e) => {
|
|
4193
|
+
e.preventDefault();
|
|
4194
|
+
handleCreateCategory();
|
|
4195
|
+
},
|
|
4002
4196
|
children: [
|
|
4003
4197
|
/* @__PURE__ */ jsx29(Plus5, { className: "h-3 w-3 mr-2" }),
|
|
4004
4198
|
'Create "',
|
|
@@ -4013,8 +4207,8 @@ function CategoryAutocomplete({
|
|
|
4013
4207
|
}
|
|
4014
4208
|
|
|
4015
4209
|
// src/components/Admin/UserAutocomplete.tsx
|
|
4016
|
-
import { useState as
|
|
4017
|
-
import { X as X11, Search as Search4, Check as
|
|
4210
|
+
import { useState as useState14, useEffect as useEffect10, useRef as useRef7 } from "react";
|
|
4211
|
+
import { X as X11, Search as Search4, Check as Check6 } from "lucide-react";
|
|
4018
4212
|
import { jsx as jsx30, jsxs as jsxs21 } from "react/jsx-runtime";
|
|
4019
4213
|
function UserAutocomplete({
|
|
4020
4214
|
selectedUserId,
|
|
@@ -4022,12 +4216,12 @@ function UserAutocomplete({
|
|
|
4022
4216
|
placeholder = "Select author...",
|
|
4023
4217
|
className = ""
|
|
4024
4218
|
}) {
|
|
4025
|
-
const [inputValue, setInputValue] =
|
|
4026
|
-
const [suggestions, setSuggestions] =
|
|
4027
|
-
const [isLoading, setIsLoading] =
|
|
4028
|
-
const [showSuggestions, setShowSuggestions] =
|
|
4029
|
-
const inputRef =
|
|
4030
|
-
const suggestionsRef =
|
|
4219
|
+
const [inputValue, setInputValue] = useState14("");
|
|
4220
|
+
const [suggestions, setSuggestions] = useState14([]);
|
|
4221
|
+
const [isLoading, setIsLoading] = useState14(false);
|
|
4222
|
+
const [showSuggestions, setShowSuggestions] = useState14(false);
|
|
4223
|
+
const inputRef = useRef7(null);
|
|
4224
|
+
const suggestionsRef = useRef7(null);
|
|
4031
4225
|
const fetchSuggestions = async (query) => {
|
|
4032
4226
|
setIsLoading(true);
|
|
4033
4227
|
try {
|
|
@@ -4125,13 +4319,16 @@ function UserAutocomplete({
|
|
|
4125
4319
|
"div",
|
|
4126
4320
|
{
|
|
4127
4321
|
className: "px-4 py-2 hover:bg-gray-100 cursor-pointer text-sm flex items-center justify-between",
|
|
4128
|
-
|
|
4322
|
+
onMouseDown: (e) => {
|
|
4323
|
+
e.preventDefault();
|
|
4324
|
+
handleSuggestionSelect(user);
|
|
4325
|
+
},
|
|
4129
4326
|
children: [
|
|
4130
4327
|
/* @__PURE__ */ jsxs21("div", { className: "flex flex-col", children: [
|
|
4131
4328
|
/* @__PURE__ */ jsx30("span", { className: "font-medium", children: user.name }),
|
|
4132
4329
|
/* @__PURE__ */ jsx30("span", { className: "text-xs text-gray-500", children: user.email })
|
|
4133
4330
|
] }),
|
|
4134
|
-
selectedUserId === user.id && /* @__PURE__ */ jsx30(
|
|
4331
|
+
selectedUserId === user.id && /* @__PURE__ */ jsx30(Check6, { className: "h-4 w-4 text-green-500" })
|
|
4135
4332
|
]
|
|
4136
4333
|
},
|
|
4137
4334
|
user.id
|
|
@@ -4144,39 +4341,39 @@ function UserAutocomplete({
|
|
|
4144
4341
|
// src/components/Admin/BlogEditorPage.tsx
|
|
4145
4342
|
import { jsx as jsx31, jsxs as jsxs22 } from "react/jsx-runtime";
|
|
4146
4343
|
function BlogEditor({ existingBlog }) {
|
|
4147
|
-
const [title, setTitle] =
|
|
4148
|
-
const [slug, setSlug] =
|
|
4149
|
-
const [coverImage, setCoverImage] =
|
|
4344
|
+
const [title, setTitle] = useState15(existingBlog?.title || "");
|
|
4345
|
+
const [slug, setSlug] = useState15(existingBlog?.slug || "");
|
|
4346
|
+
const [coverImage, setCoverImage] = useState15(
|
|
4150
4347
|
existingBlog?.coverImage || null
|
|
4151
4348
|
);
|
|
4152
|
-
const [ogImage, setOgImage] =
|
|
4349
|
+
const [ogImage, setOgImage] = useState15(
|
|
4153
4350
|
existingBlog?.seo?.ogImage || existingBlog?.ogImage || null
|
|
4154
4351
|
);
|
|
4155
|
-
const [metaTitle, setMetaTitle] =
|
|
4156
|
-
const [metaDescription, setMetaDescription] =
|
|
4352
|
+
const [metaTitle, setMetaTitle] = useState15(existingBlog?.seo?.title || "");
|
|
4353
|
+
const [metaDescription, setMetaDescription] = useState15(
|
|
4157
4354
|
existingBlog?.seo?.description || ""
|
|
4158
4355
|
);
|
|
4159
|
-
const [metaKeywords, setMetaKeywords] =
|
|
4356
|
+
const [metaKeywords, setMetaKeywords] = useState15(
|
|
4160
4357
|
existingBlog?.seo?.keywords || ""
|
|
4161
4358
|
);
|
|
4162
|
-
const [published, setPublished] =
|
|
4163
|
-
const [tags, setTags] =
|
|
4359
|
+
const [published, setPublished] = useState15(existingBlog?.published || false);
|
|
4360
|
+
const [tags, setTags] = useState15(
|
|
4164
4361
|
existingBlog?.tags?.map((tag) => tag.name) || []
|
|
4165
4362
|
);
|
|
4166
|
-
const [category, setCategory] =
|
|
4363
|
+
const [category, setCategory] = useState15(
|
|
4167
4364
|
existingBlog?.category?.name || null
|
|
4168
4365
|
);
|
|
4169
|
-
const [authorId, setAuthorId] =
|
|
4366
|
+
const [authorId, setAuthorId] = useState15(
|
|
4170
4367
|
existingBlog?.authorId || null
|
|
4171
4368
|
);
|
|
4172
|
-
const [content, setContent] =
|
|
4173
|
-
const [createdAt, setCreatedAt] =
|
|
4369
|
+
const [content, setContent] = useState15(existingBlog?.content || "");
|
|
4370
|
+
const [createdAt, setCreatedAt] = useState15(
|
|
4174
4371
|
existingBlog?.createdAt ? new Date(existingBlog.createdAt).toISOString().slice(0, 16) : (/* @__PURE__ */ new Date()).toISOString().slice(0, 16)
|
|
4175
4372
|
);
|
|
4176
|
-
const [errors, setErrors] =
|
|
4177
|
-
const [isLoading, setIsLoading] =
|
|
4178
|
-
const [isSaving, setIsSaving] =
|
|
4179
|
-
const router =
|
|
4373
|
+
const [errors, setErrors] = useState15([]);
|
|
4374
|
+
const [isLoading, setIsLoading] = useState15(false);
|
|
4375
|
+
const [isSaving, setIsSaving] = useState15(false);
|
|
4376
|
+
const router = useRouter4();
|
|
4180
4377
|
useEffect11(() => {
|
|
4181
4378
|
if (title && !slug) {
|
|
4182
4379
|
const generatedSlug = title.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/(^-|-$)/g, "");
|
|
@@ -4302,11 +4499,25 @@ function BlogEditor({ existingBlog }) {
|
|
|
4302
4499
|
),
|
|
4303
4500
|
/* @__PURE__ */ jsx31("span", { className: "text-xs text-gray-300", children: "Published" })
|
|
4304
4501
|
] }),
|
|
4502
|
+
/* @__PURE__ */ jsxs22(
|
|
4503
|
+
Button,
|
|
4504
|
+
{
|
|
4505
|
+
size: "icon",
|
|
4506
|
+
className: "md:hidden h-8 w-8 bg-white text-gray-800 hover:bg-gray-100 border-0",
|
|
4507
|
+
onClick: () => handleSave(published),
|
|
4508
|
+
disabled: isSaving,
|
|
4509
|
+
title: isSaving ? "Saving..." : "Save",
|
|
4510
|
+
children: [
|
|
4511
|
+
/* @__PURE__ */ jsx31(Save2, { className: "h-4 w-4" }),
|
|
4512
|
+
/* @__PURE__ */ jsx31("span", { className: "sr-only", children: isSaving ? "Saving..." : "Save" })
|
|
4513
|
+
]
|
|
4514
|
+
}
|
|
4515
|
+
),
|
|
4305
4516
|
/* @__PURE__ */ jsxs22(
|
|
4306
4517
|
Button,
|
|
4307
4518
|
{
|
|
4308
4519
|
size: "sm",
|
|
4309
|
-
className: "flex items-center bg-white text-gray-800 hover:bg-gray-100 border-0 text-xs",
|
|
4520
|
+
className: "hidden md:inline-flex items-center bg-white text-gray-800 hover:bg-gray-100 border-0 text-xs",
|
|
4310
4521
|
onClick: () => handleSave(published),
|
|
4311
4522
|
disabled: isSaving,
|
|
4312
4523
|
children: [
|
|
@@ -4315,12 +4526,26 @@ function BlogEditor({ existingBlog }) {
|
|
|
4315
4526
|
]
|
|
4316
4527
|
}
|
|
4317
4528
|
),
|
|
4529
|
+
/* @__PURE__ */ jsxs22(
|
|
4530
|
+
Button,
|
|
4531
|
+
{
|
|
4532
|
+
variant: "outline",
|
|
4533
|
+
size: "icon",
|
|
4534
|
+
className: "md:hidden h-8 w-8 bg-white text-gray-800 hover:bg-gray-100 border-0",
|
|
4535
|
+
onClick: () => router.back(),
|
|
4536
|
+
title: "Close",
|
|
4537
|
+
children: [
|
|
4538
|
+
/* @__PURE__ */ jsx31(X12, { className: "h-4 w-4" }),
|
|
4539
|
+
/* @__PURE__ */ jsx31("span", { className: "sr-only", children: "Close" })
|
|
4540
|
+
]
|
|
4541
|
+
}
|
|
4542
|
+
),
|
|
4318
4543
|
/* @__PURE__ */ jsxs22(
|
|
4319
4544
|
Button,
|
|
4320
4545
|
{
|
|
4321
4546
|
variant: "outline",
|
|
4322
4547
|
size: "sm",
|
|
4323
|
-
className: "flex items-center bg-white text-gray-800 hover:bg-gray-100 border-0 text-xs",
|
|
4548
|
+
className: "hidden md:inline-flex items-center bg-white text-gray-800 hover:bg-gray-100 border-0 text-xs",
|
|
4324
4549
|
onClick: () => router.back(),
|
|
4325
4550
|
children: [
|
|
4326
4551
|
/* @__PURE__ */ jsx31(X12, { className: "h-4 w-4 mr-1" }),
|
|
@@ -4502,10 +4727,10 @@ function BlogEditor({ existingBlog }) {
|
|
|
4502
4727
|
}
|
|
4503
4728
|
|
|
4504
4729
|
// src/components/Admin/AnalyticsChart.tsx
|
|
4505
|
-
import { useEffect as useEffect12, useRef as
|
|
4730
|
+
import { useEffect as useEffect12, useRef as useRef8 } from "react";
|
|
4506
4731
|
import { jsx as jsx32, jsxs as jsxs23 } from "react/jsx-runtime";
|
|
4507
4732
|
function AnalyticsChart({ data, title, type }) {
|
|
4508
|
-
const canvasRef =
|
|
4733
|
+
const canvasRef = useRef8(null);
|
|
4509
4734
|
useEffect12(() => {
|
|
4510
4735
|
if (!canvasRef.current || !data.length) return;
|
|
4511
4736
|
const ctx = canvasRef.current.getContext("2d");
|
|
@@ -4741,14 +4966,14 @@ function AnalyticsExclusion() {
|
|
|
4741
4966
|
}
|
|
4742
4967
|
|
|
4743
4968
|
// src/components/Admin/ComponentSettings.tsx
|
|
4744
|
-
import { useState as
|
|
4969
|
+
import { useState as useState16, useEffect as useEffect14 } from "react";
|
|
4745
4970
|
import { jsx as jsx37, jsxs as jsxs28 } from "react/jsx-runtime";
|
|
4746
4971
|
function EntitySelect({
|
|
4747
4972
|
prop,
|
|
4748
4973
|
value,
|
|
4749
4974
|
onChange
|
|
4750
4975
|
}) {
|
|
4751
|
-
const [options, setOptions] =
|
|
4976
|
+
const [options, setOptions] = useState16([]);
|
|
4752
4977
|
useEffect14(() => {
|
|
4753
4978
|
if (!prop.entity) return;
|
|
4754
4979
|
fetch(`/api/${prop.entity}`).then((r) => r.ok ? r.json() : { data: [] }).then((res) => setOptions(res.data || res || [])).catch(() => {
|
|
@@ -4887,7 +5112,7 @@ function ComponentSettings({
|
|
|
4887
5112
|
}
|
|
4888
5113
|
|
|
4889
5114
|
// src/components/Admin/NavbarEditor.tsx
|
|
4890
|
-
import { useState as
|
|
5115
|
+
import { useState as useState17, useEffect as useEffect15 } from "react";
|
|
4891
5116
|
import { Plus as Plus6, Trash2 as Trash23, GripVertical, ChevronDown as ChevronDown4, ChevronRight as ChevronRight3, ArrowRight, ArrowLeft as ArrowLeft3 } from "lucide-react";
|
|
4892
5117
|
import { jsx as jsx38, jsxs as jsxs29 } from "react/jsx-runtime";
|
|
4893
5118
|
function generateId() {
|
|
@@ -4907,8 +5132,8 @@ function NavItemEditor({
|
|
|
4907
5132
|
canMoveUp,
|
|
4908
5133
|
canMoveDown
|
|
4909
5134
|
}) {
|
|
4910
|
-
const [expanded, setExpanded] =
|
|
4911
|
-
const [pages, setPages] =
|
|
5135
|
+
const [expanded, setExpanded] = useState17(false);
|
|
5136
|
+
const [pages, setPages] = useState17([]);
|
|
4912
5137
|
useEffect15(() => {
|
|
4913
5138
|
if (!expanded) return;
|
|
4914
5139
|
fetch("/api/pages").then((r) => r.ok ? r.json() : []).then((data) => {
|
|
@@ -5177,9 +5402,9 @@ function NavbarEditor({ config, onChange }) {
|
|
|
5177
5402
|
|
|
5178
5403
|
// src/admin/pages/SignInPage.tsx
|
|
5179
5404
|
import Link5 from "next/link";
|
|
5180
|
-
import { useState as
|
|
5405
|
+
import { useState as useState18, useEffect as useEffect16 } from "react";
|
|
5181
5406
|
import { signIn, useSession as useSession3 } from "next-auth/react";
|
|
5182
|
-
import { useRouter as
|
|
5407
|
+
import { useRouter as useRouter5 } from "next/navigation";
|
|
5183
5408
|
|
|
5184
5409
|
// src/components/Admin/AuthPageLayout.tsx
|
|
5185
5410
|
import Image5 from "next/image";
|
|
@@ -5237,11 +5462,11 @@ function AuthPageLayout({ children }) {
|
|
|
5237
5462
|
// src/admin/pages/SignInPage.tsx
|
|
5238
5463
|
import { jsx as jsx41, jsxs as jsxs32 } from "react/jsx-runtime";
|
|
5239
5464
|
var SigninPage = () => {
|
|
5240
|
-
const [email, setEmail] =
|
|
5241
|
-
const [password, setPassword] =
|
|
5242
|
-
const [error, setError] =
|
|
5243
|
-
const [loading, setLoading] =
|
|
5244
|
-
const router =
|
|
5465
|
+
const [email, setEmail] = useState18("");
|
|
5466
|
+
const [password, setPassword] = useState18("");
|
|
5467
|
+
const [error, setError] = useState18("");
|
|
5468
|
+
const [loading, setLoading] = useState18(false);
|
|
5469
|
+
const router = useRouter5();
|
|
5245
5470
|
const { status } = useSession3();
|
|
5246
5471
|
useEffect16(() => {
|
|
5247
5472
|
if (status === "authenticated") {
|
|
@@ -5326,13 +5551,13 @@ var SigninPage = () => {
|
|
|
5326
5551
|
var SignInPage_default = SigninPage;
|
|
5327
5552
|
|
|
5328
5553
|
// src/admin/pages/ForgotPasswordPage.tsx
|
|
5329
|
-
import { useState as
|
|
5554
|
+
import { useState as useState19 } from "react";
|
|
5330
5555
|
import Link6 from "next/link";
|
|
5331
5556
|
import { jsx as jsx42, jsxs as jsxs33 } from "react/jsx-runtime";
|
|
5332
5557
|
function ForgotPasswordPage() {
|
|
5333
|
-
const [email, setEmail] =
|
|
5334
|
-
const [loading, setLoading] =
|
|
5335
|
-
const [message, setMessage] =
|
|
5558
|
+
const [email, setEmail] = useState19("");
|
|
5559
|
+
const [loading, setLoading] = useState19(false);
|
|
5560
|
+
const [message, setMessage] = useState19("");
|
|
5336
5561
|
const handleSubmit = async (e) => {
|
|
5337
5562
|
e.preventDefault();
|
|
5338
5563
|
if (!email.trim()) return;
|
|
@@ -5374,16 +5599,16 @@ function ForgotPasswordPage() {
|
|
|
5374
5599
|
}
|
|
5375
5600
|
|
|
5376
5601
|
// src/admin/pages/ResetPasswordPage.tsx
|
|
5377
|
-
import { useState as
|
|
5602
|
+
import { useState as useState20, useEffect as useEffect17, Suspense } from "react";
|
|
5378
5603
|
import { useSearchParams } from "next/navigation";
|
|
5379
5604
|
import Link7 from "next/link";
|
|
5380
5605
|
import { jsx as jsx43, jsxs as jsxs34 } from "react/jsx-runtime";
|
|
5381
5606
|
function ResetPasswordPageContent() {
|
|
5382
5607
|
const searchParams = useSearchParams();
|
|
5383
5608
|
const token = searchParams.get("token");
|
|
5384
|
-
const [formData, setFormData] =
|
|
5385
|
-
const [loading, setLoading] =
|
|
5386
|
-
const [message, setMessage] =
|
|
5609
|
+
const [formData, setFormData] = useState20({ password: "", confirmPassword: "" });
|
|
5610
|
+
const [loading, setLoading] = useState20(false);
|
|
5611
|
+
const [message, setMessage] = useState20("");
|
|
5387
5612
|
useEffect17(() => {
|
|
5388
5613
|
if (!token) setMessage("Invalid reset link. Token is missing.");
|
|
5389
5614
|
}, [token]);
|
|
@@ -5453,18 +5678,18 @@ function ResetPasswordPage() {
|
|
|
5453
5678
|
}
|
|
5454
5679
|
|
|
5455
5680
|
// src/admin/pages/InvitePage.tsx
|
|
5456
|
-
import { useState as
|
|
5681
|
+
import { useState as useState21, useEffect as useEffect18, Suspense as Suspense2 } from "react";
|
|
5457
5682
|
import { useSearchParams as useSearchParams2 } from "next/navigation";
|
|
5458
5683
|
import { jsx as jsx44, jsxs as jsxs35 } from "react/jsx-runtime";
|
|
5459
5684
|
function InvitePageContent() {
|
|
5460
5685
|
const searchParams = useSearchParams2();
|
|
5461
5686
|
const token = searchParams.get("token");
|
|
5462
|
-
const [formData, setFormData] =
|
|
5687
|
+
const [formData, setFormData] = useState21({
|
|
5463
5688
|
password: "",
|
|
5464
5689
|
confirmPassword: ""
|
|
5465
5690
|
});
|
|
5466
|
-
const [loading, setLoading] =
|
|
5467
|
-
const [message, setMessage] =
|
|
5691
|
+
const [loading, setLoading] = useState21(false);
|
|
5692
|
+
const [message, setMessage] = useState21("");
|
|
5468
5693
|
useEffect18(() => {
|
|
5469
5694
|
if (!token) {
|
|
5470
5695
|
setMessage("Invalid invite link. Token is missing.");
|
|
@@ -5538,21 +5763,62 @@ function InvitePage() {
|
|
|
5538
5763
|
|
|
5539
5764
|
// src/admin/pages/DashboardPage.tsx
|
|
5540
5765
|
import { useSession as useSession4 } from "next-auth/react";
|
|
5541
|
-
import { useEffect as useEffect19, useState as
|
|
5542
|
-
import {
|
|
5766
|
+
import { useContext as useContext3, useEffect as useEffect19, useMemo as useMemo3, useState as useState22 } from "react";
|
|
5767
|
+
import { useRouter as useRouter6 } from "next/navigation";
|
|
5768
|
+
import { Chart as ChartJS2, ArcElement, Tooltip as Tooltip2, Legend as Legend2 } from "chart.js";
|
|
5769
|
+
import { Doughnut } from "react-chartjs-2";
|
|
5770
|
+
import { Users as Users4, Eye as Eye2, MousePointer, Globe, FileText, ClipboardList as ClipboardList2, UserCheck, TrendingUp, BarChart3, Activity } from "lucide-react";
|
|
5543
5771
|
import { Fragment as Fragment6, jsx as jsx45, jsxs as jsxs36 } from "react/jsx-runtime";
|
|
5772
|
+
ChartJS2.register(ArcElement, Tooltip2, Legend2);
|
|
5544
5773
|
function DashboardPage() {
|
|
5545
5774
|
const { data: session } = useSession4();
|
|
5546
|
-
const
|
|
5547
|
-
const
|
|
5548
|
-
const [
|
|
5549
|
-
const [
|
|
5775
|
+
const router = useRouter6();
|
|
5776
|
+
const { storeEnabled } = useContext3(AdminConfigContext);
|
|
5777
|
+
const [analyticsData, setAnalyticsData] = useState22(null);
|
|
5778
|
+
const [ecommerceData, setEcommerceData] = useState22(null);
|
|
5779
|
+
const [dashboardStats, setDashboardStats] = useState22(null);
|
|
5780
|
+
const [loading, setLoading] = useState22({ analytics: true, stats: true, ecommerce: true });
|
|
5781
|
+
const [analyticsEnabled, setAnalyticsEnabled] = useState22(false);
|
|
5782
|
+
const [days, setDays] = useState22(30);
|
|
5783
|
+
const [activeTab, setActiveTab] = useState22("overview");
|
|
5784
|
+
const formatMoney4 = useMemo3(
|
|
5785
|
+
() => (value) => new Intl.NumberFormat(void 0, {
|
|
5786
|
+
style: "currency",
|
|
5787
|
+
currency: "INR",
|
|
5788
|
+
maximumFractionDigits: 0
|
|
5789
|
+
}).format(value || 0),
|
|
5790
|
+
[]
|
|
5791
|
+
);
|
|
5792
|
+
const safePct = (v, max) => max > 0 ? Math.max(6, Math.round(v / max * 100)) : 0;
|
|
5793
|
+
const productPalette = ["#2563eb", "#0ea5e9", "#14b8a6", "#22c55e", "#eab308", "#f97316"];
|
|
5794
|
+
const salesBreakdownPalette = {
|
|
5795
|
+
sales: "#22c55e",
|
|
5796
|
+
returns: "#ef4444",
|
|
5797
|
+
replacements: "#f59e0b"
|
|
5798
|
+
};
|
|
5799
|
+
const contactTypeColor = (type) => {
|
|
5800
|
+
const t = type.trim().toLowerCase();
|
|
5801
|
+
if (t === "customer") return "#2563eb";
|
|
5802
|
+
if (t === "lead") return "#a855f7";
|
|
5803
|
+
if (t === "vendor") return "#14b8a6";
|
|
5804
|
+
return "#6b7280";
|
|
5805
|
+
};
|
|
5806
|
+
const metricBarColor = (label) => {
|
|
5807
|
+
const key = label.toLowerCase();
|
|
5808
|
+
if (key.includes("contact")) return "bg-blue-500";
|
|
5809
|
+
if (key.includes("submission")) return "bg-purple-500";
|
|
5810
|
+
if (key.includes("net sales")) return "bg-green-500";
|
|
5811
|
+
if (key.includes("gross sales")) return "bg-emerald-500";
|
|
5812
|
+
if (key.includes("return")) return "bg-red-500";
|
|
5813
|
+
return "bg-gray-600";
|
|
5814
|
+
};
|
|
5550
5815
|
useEffect19(() => {
|
|
5551
5816
|
const fetchData = async () => {
|
|
5552
|
-
const analyticsPromise = fetch(
|
|
5817
|
+
const analyticsPromise = fetch(`/api/analytics?days=${days}`);
|
|
5553
5818
|
const statsPromise = fetch("/api/dashboard/stats");
|
|
5819
|
+
const ecommercePromise = storeEnabled ? fetch(`/api/dashboard/ecommerce?days=${days}`) : Promise.resolve(null);
|
|
5554
5820
|
try {
|
|
5555
|
-
const [analyticsResponse, statsResponse] = await Promise.all([analyticsPromise, statsPromise]);
|
|
5821
|
+
const [analyticsResponse, statsResponse, ecommerceResponse] = await Promise.all([analyticsPromise, statsPromise, ecommercePromise]);
|
|
5556
5822
|
if (analyticsResponse.ok) {
|
|
5557
5823
|
const data = await analyticsResponse.json();
|
|
5558
5824
|
setAnalyticsData(data);
|
|
@@ -5570,15 +5836,22 @@ function DashboardPage() {
|
|
|
5570
5836
|
const stats = await statsResponse.json();
|
|
5571
5837
|
setDashboardStats(stats);
|
|
5572
5838
|
}
|
|
5839
|
+
if (ecommerceResponse && ecommerceResponse.ok) {
|
|
5840
|
+
const ecommerce = await ecommerceResponse.json();
|
|
5841
|
+
setEcommerceData(ecommerce);
|
|
5842
|
+
} else {
|
|
5843
|
+
setEcommerceData(null);
|
|
5844
|
+
}
|
|
5573
5845
|
} catch (error) {
|
|
5574
5846
|
setAnalyticsEnabled(false);
|
|
5847
|
+
setEcommerceData(null);
|
|
5575
5848
|
} finally {
|
|
5576
|
-
setLoading({ analytics: false, stats: false });
|
|
5849
|
+
setLoading({ analytics: false, stats: false, ecommerce: false });
|
|
5577
5850
|
}
|
|
5578
5851
|
};
|
|
5579
5852
|
fetchData();
|
|
5580
|
-
}, []);
|
|
5581
|
-
const isLoading = loading.analytics || loading.stats;
|
|
5853
|
+
}, [days, storeEnabled]);
|
|
5854
|
+
const isLoading = loading.analytics || loading.stats || storeEnabled && loading.ecommerce;
|
|
5582
5855
|
return /* @__PURE__ */ jsxs36("div", { className: "min-w-0 rounded-lg bg-white shadow-md", children: [
|
|
5583
5856
|
/* @__PURE__ */ jsx45("div", { className: "bg-gray-800 border-b border-gray-700 px-4 py-2.5 rounded-t-lg", children: /* @__PURE__ */ jsxs36("div", { className: "flex items-center justify-between", children: [
|
|
5584
5857
|
/* @__PURE__ */ jsxs36("div", { children: [
|
|
@@ -5594,13 +5867,54 @@ function DashboardPage() {
|
|
|
5594
5867
|
] }) })
|
|
5595
5868
|
] }) }),
|
|
5596
5869
|
/* @__PURE__ */ jsxs36("div", { className: "min-w-0 p-4 bg-gray-50", children: [
|
|
5597
|
-
/* @__PURE__ */ jsxs36("div", { className: "mb-
|
|
5598
|
-
/* @__PURE__ */ jsxs36("div", { className: "flex items-center
|
|
5870
|
+
/* @__PURE__ */ jsxs36("div", { className: "flex flex-wrap items-center justify-between gap-2 mb-3", children: [
|
|
5871
|
+
/* @__PURE__ */ jsxs36("div", { className: "flex items-center gap-2", children: [
|
|
5872
|
+
/* @__PURE__ */ jsx45(
|
|
5873
|
+
"button",
|
|
5874
|
+
{
|
|
5875
|
+
onClick: () => setActiveTab("overview"),
|
|
5876
|
+
className: `text-xs px-2 py-1 rounded border ${activeTab === "overview" ? "bg-gray-800 text-white border-gray-800" : "bg-white text-gray-700 border-gray-300"}`,
|
|
5877
|
+
children: "Overview"
|
|
5878
|
+
}
|
|
5879
|
+
),
|
|
5880
|
+
/* @__PURE__ */ jsx45(
|
|
5881
|
+
"button",
|
|
5882
|
+
{
|
|
5883
|
+
onClick: () => setActiveTab("crm"),
|
|
5884
|
+
className: `text-xs px-2 py-1 rounded border ${activeTab === "crm" ? "bg-gray-800 text-white border-gray-800" : "bg-white text-gray-700 border-gray-300"}`,
|
|
5885
|
+
children: "CRM / Engagement"
|
|
5886
|
+
}
|
|
5887
|
+
),
|
|
5888
|
+
storeEnabled && /* @__PURE__ */ jsx45(
|
|
5889
|
+
"button",
|
|
5890
|
+
{
|
|
5891
|
+
onClick: () => setActiveTab("sales"),
|
|
5892
|
+
className: `text-xs px-2 py-1 rounded border ${activeTab === "sales" ? "bg-gray-800 text-white border-gray-800" : "bg-white text-gray-700 border-gray-300"}`,
|
|
5893
|
+
children: "Sales"
|
|
5894
|
+
}
|
|
5895
|
+
)
|
|
5896
|
+
] }),
|
|
5897
|
+
/* @__PURE__ */ jsxs36(
|
|
5898
|
+
"select",
|
|
5899
|
+
{
|
|
5900
|
+
value: days,
|
|
5901
|
+
onChange: (e) => setDays(Number(e.target.value)),
|
|
5902
|
+
className: "border border-gray-300 text-xs rounded px-2 py-1 bg-white",
|
|
5903
|
+
children: [
|
|
5904
|
+
/* @__PURE__ */ jsx45("option", { value: 7, children: "Last 7 days" }),
|
|
5905
|
+
/* @__PURE__ */ jsx45("option", { value: 30, children: "Last 30 days" }),
|
|
5906
|
+
/* @__PURE__ */ jsx45("option", { value: 90, children: "Last 90 days" })
|
|
5907
|
+
]
|
|
5908
|
+
}
|
|
5909
|
+
)
|
|
5910
|
+
] }),
|
|
5911
|
+
activeTab === "overview" && /* @__PURE__ */ jsxs36("div", { className: "mb-5", children: [
|
|
5912
|
+
/* @__PURE__ */ jsxs36("div", { className: "flex items-center mb-3", children: [
|
|
5599
5913
|
/* @__PURE__ */ jsx45(BarChart3, { className: "w-4 h-4 text-gray-600 mr-2" }),
|
|
5600
|
-
/* @__PURE__ */ jsx45("h2", { className: "text-sm font-semibold text-gray-800", children: "
|
|
5914
|
+
/* @__PURE__ */ jsx45("h2", { className: "text-sm font-semibold text-gray-800", children: "Contacts & Forms" })
|
|
5601
5915
|
] }),
|
|
5602
|
-
/* @__PURE__ */ jsxs36("div", { className: "grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-
|
|
5603
|
-
/* @__PURE__ */ jsxs36("div", { className: "bg-white rounded border border-gray-200 p-
|
|
5916
|
+
/* @__PURE__ */ jsxs36("div", { className: "grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-4", children: [
|
|
5917
|
+
/* @__PURE__ */ jsxs36("div", { className: "bg-white rounded border border-gray-200 p-3 shadow-sm", children: [
|
|
5604
5918
|
/* @__PURE__ */ jsxs36("div", { className: "flex items-center justify-between mb-1.5", children: [
|
|
5605
5919
|
/* @__PURE__ */ jsx45("p", { className: "text-xs font-medium text-gray-600", children: "Total Contacts" }),
|
|
5606
5920
|
/* @__PURE__ */ jsx45("div", { className: "p-1 bg-gray-200 rounded", children: /* @__PURE__ */ jsx45(Users4, { className: "w-3.5 h-3.5 text-gray-600" }) })
|
|
@@ -5616,7 +5930,7 @@ function DashboardPage() {
|
|
|
5616
5930
|
] })
|
|
5617
5931
|
] })
|
|
5618
5932
|
] }),
|
|
5619
|
-
/* @__PURE__ */ jsxs36("div", { className: "bg-white rounded border border-gray-200 p-
|
|
5933
|
+
/* @__PURE__ */ jsxs36("div", { className: "bg-white rounded border border-gray-200 p-3 shadow-sm", children: [
|
|
5620
5934
|
/* @__PURE__ */ jsxs36("div", { className: "flex items-center justify-between mb-1.5", children: [
|
|
5621
5935
|
/* @__PURE__ */ jsx45("p", { className: "text-xs font-medium text-gray-600", children: "Form Submissions" }),
|
|
5622
5936
|
/* @__PURE__ */ jsx45("div", { className: "p-1 bg-gray-200 rounded", children: /* @__PURE__ */ jsx45(FileText, { className: "w-3.5 h-3.5 text-gray-600" }) })
|
|
@@ -5632,7 +5946,7 @@ function DashboardPage() {
|
|
|
5632
5946
|
] })
|
|
5633
5947
|
] })
|
|
5634
5948
|
] }),
|
|
5635
|
-
/* @__PURE__ */ jsxs36("div", { className: "bg-white rounded border border-gray-200 p-
|
|
5949
|
+
/* @__PURE__ */ jsxs36("div", { className: "bg-white rounded border border-gray-200 p-3 shadow-sm", children: [
|
|
5636
5950
|
/* @__PURE__ */ jsxs36("div", { className: "flex items-center justify-between mb-1.5", children: [
|
|
5637
5951
|
/* @__PURE__ */ jsx45("p", { className: "text-xs font-medium text-gray-600", children: "Active Forms" }),
|
|
5638
5952
|
/* @__PURE__ */ jsx45("div", { className: "p-1 bg-gray-200 rounded", children: /* @__PURE__ */ jsx45(ClipboardList2, { className: "w-3.5 h-3.5 text-gray-600" }) })
|
|
@@ -5642,7 +5956,7 @@ function DashboardPage() {
|
|
|
5642
5956
|
/* @__PURE__ */ jsx45("p", { className: "text-xs text-gray-500", children: "Total" })
|
|
5643
5957
|
] })
|
|
5644
5958
|
] }),
|
|
5645
|
-
/* @__PURE__ */ jsxs36("div", { className: "bg-white rounded border border-gray-200 p-
|
|
5959
|
+
/* @__PURE__ */ jsxs36("div", { className: "bg-white rounded border border-gray-200 p-3 shadow-sm", children: [
|
|
5646
5960
|
/* @__PURE__ */ jsxs36("div", { className: "flex items-center justify-between mb-1.5", children: [
|
|
5647
5961
|
/* @__PURE__ */ jsx45("p", { className: "text-xs font-medium text-gray-600", children: "Registered Users" }),
|
|
5648
5962
|
/* @__PURE__ */ jsx45("div", { className: "p-1 bg-gray-200 rounded", children: /* @__PURE__ */ jsx45(UserCheck, { className: "w-3.5 h-3.5 text-gray-600" }) })
|
|
@@ -5654,8 +5968,151 @@ function DashboardPage() {
|
|
|
5654
5968
|
] })
|
|
5655
5969
|
] })
|
|
5656
5970
|
] }),
|
|
5657
|
-
/* @__PURE__ */
|
|
5658
|
-
|
|
5971
|
+
activeTab === "overview" && !isLoading && /* @__PURE__ */ jsxs36("div", { className: "mb-6 bg-white rounded-lg border border-gray-200 p-4 shadow-sm", children: [
|
|
5972
|
+
/* @__PURE__ */ jsxs36("div", { className: "flex items-center mb-3", children: [
|
|
5973
|
+
/* @__PURE__ */ jsx45(Activity, { className: "w-4 h-4 text-gray-600 mr-2" }),
|
|
5974
|
+
/* @__PURE__ */ jsx45("h3", { className: "text-sm font-semibold text-gray-800", children: "Overview Snapshot" })
|
|
5975
|
+
] }),
|
|
5976
|
+
/* @__PURE__ */ jsxs36("div", { className: "grid grid-cols-1 lg:grid-cols-2 gap-6", children: [
|
|
5977
|
+
/* @__PURE__ */ jsxs36("div", { children: [
|
|
5978
|
+
/* @__PURE__ */ jsx45("h4", { className: "text-xs font-semibold text-gray-700 mb-2", children: "Contacts & Forms" }),
|
|
5979
|
+
(() => {
|
|
5980
|
+
const rows = [
|
|
5981
|
+
{ label: "Contacts (total)", value: dashboardStats?.contacts.total || 0 },
|
|
5982
|
+
{ label: "New contacts", value: dashboardStats?.contacts.recent || 0 },
|
|
5983
|
+
{ label: "Submissions", value: dashboardStats?.forms.submissions || 0 },
|
|
5984
|
+
{ label: "New submissions", value: dashboardStats?.forms.recentSubmissions || 0 }
|
|
5985
|
+
];
|
|
5986
|
+
const max = Math.max(...rows.map((r) => r.value), 0);
|
|
5987
|
+
return /* @__PURE__ */ jsx45("div", { className: "space-y-2", children: rows.map((r) => /* @__PURE__ */ jsxs36("div", { children: [
|
|
5988
|
+
/* @__PURE__ */ jsxs36("div", { className: "flex items-center justify-between text-xs mb-1", children: [
|
|
5989
|
+
/* @__PURE__ */ jsx45("span", { className: "text-gray-600", children: r.label }),
|
|
5990
|
+
/* @__PURE__ */ jsx45("span", { className: "font-semibold text-gray-900", children: r.value })
|
|
5991
|
+
] }),
|
|
5992
|
+
/* @__PURE__ */ jsx45("div", { className: "h-2 rounded bg-gray-100 overflow-hidden", children: /* @__PURE__ */ jsx45("div", { className: `h-2 rounded ${metricBarColor(r.label)}`, style: { width: `${safePct(r.value, max)}%` } }) })
|
|
5993
|
+
] }, r.label)) });
|
|
5994
|
+
})()
|
|
5995
|
+
] }),
|
|
5996
|
+
storeEnabled && ecommerceData && /* @__PURE__ */ jsxs36("div", { children: [
|
|
5997
|
+
/* @__PURE__ */ jsx45("h4", { className: "text-xs font-semibold text-gray-700 mb-2", children: "Sales, Returns & Products" }),
|
|
5998
|
+
(() => {
|
|
5999
|
+
const salesBase = Math.max(ecommerceData.kpis.grossSales, 1);
|
|
6000
|
+
const rows = [
|
|
6001
|
+
{ label: "Net sales", value: ecommerceData.kpis.netSales, display: formatMoney4(ecommerceData.kpis.netSales) },
|
|
6002
|
+
{ label: "Gross sales", value: ecommerceData.kpis.grossSales, display: formatMoney4(ecommerceData.kpis.grossSales) },
|
|
6003
|
+
{ label: "Return value", value: ecommerceData.kpis.returnValue, display: formatMoney4(ecommerceData.kpis.returnValue) },
|
|
6004
|
+
{ label: "Return rate", value: ecommerceData.kpis.returnRate, display: `${ecommerceData.kpis.returnRate.toFixed(1)}%` }
|
|
6005
|
+
];
|
|
6006
|
+
const topProduct = ecommerceData.topProducts[0];
|
|
6007
|
+
return /* @__PURE__ */ jsxs36("div", { className: "space-y-2", children: [
|
|
6008
|
+
rows.map((r) => /* @__PURE__ */ jsxs36("div", { children: [
|
|
6009
|
+
/* @__PURE__ */ jsxs36("div", { className: "flex items-center justify-between text-xs mb-1", children: [
|
|
6010
|
+
/* @__PURE__ */ jsx45("span", { className: "text-gray-600", children: r.label }),
|
|
6011
|
+
/* @__PURE__ */ jsx45("span", { className: "font-semibold text-gray-900", children: r.display })
|
|
6012
|
+
] }),
|
|
6013
|
+
/* @__PURE__ */ jsx45("div", { className: "h-2 rounded bg-gray-100 overflow-hidden", children: /* @__PURE__ */ jsx45(
|
|
6014
|
+
"div",
|
|
6015
|
+
{
|
|
6016
|
+
className: `h-2 rounded ${metricBarColor(r.label)}`,
|
|
6017
|
+
style: { width: `${r.label === "Return rate" ? Math.max(6, Math.round(r.value)) : safePct(r.value, salesBase)}%` }
|
|
6018
|
+
}
|
|
6019
|
+
) })
|
|
6020
|
+
] }, r.label)),
|
|
6021
|
+
topProduct && /* @__PURE__ */ jsxs36("div", { className: "pt-1 text-xs text-gray-600", children: [
|
|
6022
|
+
"Top product: ",
|
|
6023
|
+
/* @__PURE__ */ jsx45("span", { className: "font-medium text-gray-900", children: topProduct.name }),
|
|
6024
|
+
" (",
|
|
6025
|
+
topProduct.units,
|
|
6026
|
+
" units)"
|
|
6027
|
+
] })
|
|
6028
|
+
] });
|
|
6029
|
+
})()
|
|
6030
|
+
] })
|
|
6031
|
+
] })
|
|
6032
|
+
] }),
|
|
6033
|
+
activeTab === "overview" && !isLoading && /* @__PURE__ */ jsxs36("div", { className: "grid grid-cols-1 lg:grid-cols-3 gap-6 mb-7", children: [
|
|
6034
|
+
storeEnabled && ecommerceData && /* @__PURE__ */ jsxs36("div", { className: "bg-white rounded-lg border border-gray-200 p-4 shadow-sm", children: [
|
|
6035
|
+
/* @__PURE__ */ jsx45("h3", { className: "text-sm font-semibold text-gray-800 mb-3", children: "Sales vs Returns vs Replacements" }),
|
|
6036
|
+
/* @__PURE__ */ jsx45("div", { className: "h-56", children: /* @__PURE__ */ jsx45(
|
|
6037
|
+
Doughnut,
|
|
6038
|
+
{
|
|
6039
|
+
data: {
|
|
6040
|
+
labels: ["Sales", "Returns", "Replacements"],
|
|
6041
|
+
datasets: [
|
|
6042
|
+
{
|
|
6043
|
+
data: [
|
|
6044
|
+
ecommerceData.salesBreakdown?.sales.value ?? ecommerceData.kpis.grossSales,
|
|
6045
|
+
ecommerceData.salesBreakdown?.returns.value ?? ecommerceData.kpis.returnValue,
|
|
6046
|
+
ecommerceData.salesBreakdown?.replacements.value ?? 0
|
|
6047
|
+
],
|
|
6048
|
+
backgroundColor: [
|
|
6049
|
+
salesBreakdownPalette.sales,
|
|
6050
|
+
salesBreakdownPalette.returns,
|
|
6051
|
+
salesBreakdownPalette.replacements
|
|
6052
|
+
],
|
|
6053
|
+
borderWidth: 0
|
|
6054
|
+
}
|
|
6055
|
+
]
|
|
6056
|
+
},
|
|
6057
|
+
options: {
|
|
6058
|
+
maintainAspectRatio: false,
|
|
6059
|
+
plugins: {
|
|
6060
|
+
legend: { position: "bottom" }
|
|
6061
|
+
}
|
|
6062
|
+
}
|
|
6063
|
+
}
|
|
6064
|
+
) })
|
|
6065
|
+
] }),
|
|
6066
|
+
storeEnabled && ecommerceData && /* @__PURE__ */ jsxs36("div", { className: "bg-white rounded-lg border border-gray-200 p-4 shadow-sm", children: [
|
|
6067
|
+
/* @__PURE__ */ jsx45("h3", { className: "text-sm font-semibold text-gray-800 mb-3", children: "Product-wise Sales (Top)" }),
|
|
6068
|
+
/* @__PURE__ */ jsx45("div", { className: "h-56", children: /* @__PURE__ */ jsx45(
|
|
6069
|
+
Doughnut,
|
|
6070
|
+
{
|
|
6071
|
+
data: {
|
|
6072
|
+
labels: ecommerceData.topProducts.map((p) => p.name),
|
|
6073
|
+
datasets: [
|
|
6074
|
+
{
|
|
6075
|
+
data: ecommerceData.topProducts.map((p) => p.sales),
|
|
6076
|
+
backgroundColor: productPalette.slice(0, Math.max(3, ecommerceData.topProducts.length)),
|
|
6077
|
+
borderWidth: 0
|
|
6078
|
+
}
|
|
6079
|
+
]
|
|
6080
|
+
},
|
|
6081
|
+
options: {
|
|
6082
|
+
maintainAspectRatio: false,
|
|
6083
|
+
plugins: {
|
|
6084
|
+
legend: { position: "bottom" }
|
|
6085
|
+
}
|
|
6086
|
+
}
|
|
6087
|
+
}
|
|
6088
|
+
) })
|
|
6089
|
+
] }),
|
|
6090
|
+
/* @__PURE__ */ jsxs36("div", { className: "bg-white rounded-lg border border-gray-200 p-4 shadow-sm", children: [
|
|
6091
|
+
/* @__PURE__ */ jsx45("h3", { className: "text-sm font-semibold text-gray-800 mb-3", children: "Contact Distribution" }),
|
|
6092
|
+
/* @__PURE__ */ jsx45("div", { className: "h-56", children: /* @__PURE__ */ jsx45(
|
|
6093
|
+
Doughnut,
|
|
6094
|
+
{
|
|
6095
|
+
data: {
|
|
6096
|
+
labels: (dashboardStats?.contactTypes?.length ? dashboardStats.contactTypes : [{ type: "unknown", count: dashboardStats?.contacts.total || 0 }]).map((c) => c.type),
|
|
6097
|
+
datasets: [
|
|
6098
|
+
{
|
|
6099
|
+
data: (dashboardStats?.contactTypes?.length ? dashboardStats.contactTypes : [{ type: "unknown", count: dashboardStats?.contacts.total || 0 }]).map((c) => c.count),
|
|
6100
|
+
backgroundColor: (dashboardStats?.contactTypes?.length ? dashboardStats.contactTypes : [{ type: "unknown", count: dashboardStats?.contacts.total || 0 }]).map((c) => contactTypeColor(c.type)),
|
|
6101
|
+
borderWidth: 0
|
|
6102
|
+
}
|
|
6103
|
+
]
|
|
6104
|
+
},
|
|
6105
|
+
options: {
|
|
6106
|
+
maintainAspectRatio: false,
|
|
6107
|
+
plugins: {
|
|
6108
|
+
legend: { position: "bottom" }
|
|
6109
|
+
}
|
|
6110
|
+
}
|
|
6111
|
+
}
|
|
6112
|
+
) })
|
|
6113
|
+
] })
|
|
6114
|
+
] }),
|
|
6115
|
+
activeTab === "overview" && analyticsEnabled && !isLoading && analyticsData && /* @__PURE__ */ jsxs36(Fragment6, { children: [
|
|
5659
6116
|
/* @__PURE__ */ jsxs36("div", { className: "mb-4", children: [
|
|
5660
6117
|
/* @__PURE__ */ jsxs36("div", { className: "flex items-center mb-2", children: [
|
|
5661
6118
|
/* @__PURE__ */ jsx45(Globe, { className: "w-4 h-4 text-gray-600 mr-2" }),
|
|
@@ -5678,7 +6135,7 @@ function DashboardPage() {
|
|
|
5678
6135
|
title: "Page Views",
|
|
5679
6136
|
value: analyticsData.pageViews.toLocaleString(),
|
|
5680
6137
|
subtitle: "Last 30 days",
|
|
5681
|
-
icon: /* @__PURE__ */ jsx45(
|
|
6138
|
+
icon: /* @__PURE__ */ jsx45(Eye2, { className: "w-5 h-5" }),
|
|
5682
6139
|
trend: { value: 8.2, isPositive: true }
|
|
5683
6140
|
}
|
|
5684
6141
|
),
|
|
@@ -5741,33 +6198,281 @@ function DashboardPage() {
|
|
|
5741
6198
|
/* @__PURE__ */ jsx45("div", { className: "border-t-2 border-dotted border-gray-200 my-6" }),
|
|
5742
6199
|
/* @__PURE__ */ jsx45("div", { className: "mb-6", children: /* @__PURE__ */ jsx45(GeographicMap, { data: analyticsData.geographicData }) })
|
|
5743
6200
|
] }),
|
|
6201
|
+
activeTab === "crm" && !isLoading && /* @__PURE__ */ jsxs36(Fragment6, { children: [
|
|
6202
|
+
/* @__PURE__ */ jsxs36("div", { className: "mb-4", children: [
|
|
6203
|
+
/* @__PURE__ */ jsxs36("div", { className: "flex items-center mb-2", children: [
|
|
6204
|
+
/* @__PURE__ */ jsx45(Users4, { className: "w-4 h-4 text-gray-600 mr-2" }),
|
|
6205
|
+
/* @__PURE__ */ jsx45("h2", { className: "text-sm font-semibold text-gray-800", children: "CRM Activity" })
|
|
6206
|
+
] }),
|
|
6207
|
+
/* @__PURE__ */ jsxs36("div", { className: "grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-3", children: [
|
|
6208
|
+
/* @__PURE__ */ jsxs36("button", { onClick: () => router.push("/admin/contacts"), className: "text-left bg-white rounded border border-gray-200 p-2.5 shadow-sm", children: [
|
|
6209
|
+
/* @__PURE__ */ jsx45("p", { className: "text-xs text-gray-600", children: "Contacts" }),
|
|
6210
|
+
/* @__PURE__ */ jsx45("p", { className: "text-lg font-bold text-gray-900", children: dashboardStats?.contacts.total || 0 }),
|
|
6211
|
+
/* @__PURE__ */ jsxs36("p", { className: "text-xs text-green-600", children: [
|
|
6212
|
+
"+",
|
|
6213
|
+
dashboardStats?.contacts.recent || 0,
|
|
6214
|
+
" recent"
|
|
6215
|
+
] })
|
|
6216
|
+
] }),
|
|
6217
|
+
/* @__PURE__ */ jsxs36("button", { onClick: () => router.push("/admin/forms"), className: "text-left bg-white rounded border border-gray-200 p-2.5 shadow-sm", children: [
|
|
6218
|
+
/* @__PURE__ */ jsx45("p", { className: "text-xs text-gray-600", children: "Active Forms" }),
|
|
6219
|
+
/* @__PURE__ */ jsx45("p", { className: "text-lg font-bold text-gray-900", children: dashboardStats?.forms.total || 0 })
|
|
6220
|
+
] }),
|
|
6221
|
+
/* @__PURE__ */ jsxs36("button", { onClick: () => router.push("/admin/submissions"), className: "text-left bg-white rounded border border-gray-200 p-2.5 shadow-sm", children: [
|
|
6222
|
+
/* @__PURE__ */ jsx45("p", { className: "text-xs text-gray-600", children: "Form Submissions" }),
|
|
6223
|
+
/* @__PURE__ */ jsx45("p", { className: "text-lg font-bold text-gray-900", children: dashboardStats?.forms.submissions || 0 }),
|
|
6224
|
+
/* @__PURE__ */ jsxs36("p", { className: "text-xs text-green-600", children: [
|
|
6225
|
+
"+",
|
|
6226
|
+
dashboardStats?.forms.recentSubmissions || 0,
|
|
6227
|
+
" recent"
|
|
6228
|
+
] })
|
|
6229
|
+
] }),
|
|
6230
|
+
/* @__PURE__ */ jsxs36("button", { onClick: () => router.push("/admin/blogs"), className: "text-left bg-white rounded border border-gray-200 p-2.5 shadow-sm", children: [
|
|
6231
|
+
/* @__PURE__ */ jsx45("p", { className: "text-xs text-gray-600", children: "Blogs" }),
|
|
6232
|
+
/* @__PURE__ */ jsx45("p", { className: "text-lg font-bold text-gray-900", children: dashboardStats?.blogs || 0 })
|
|
6233
|
+
] })
|
|
6234
|
+
] })
|
|
6235
|
+
] }),
|
|
6236
|
+
/* @__PURE__ */ jsxs36("div", { className: "grid grid-cols-1 lg:grid-cols-2 gap-6 mb-6", children: [
|
|
6237
|
+
/* @__PURE__ */ jsxs36("div", { className: "bg-white rounded-lg border border-gray-100 p-4 shadow-sm", children: [
|
|
6238
|
+
/* @__PURE__ */ jsx45("h3", { className: "text-base font-semibold text-gray-800 mb-3", children: "Engagement Funnel" }),
|
|
6239
|
+
(() => {
|
|
6240
|
+
const contacts = dashboardStats?.contacts.total || 0;
|
|
6241
|
+
const submissions = dashboardStats?.forms.submissions || 0;
|
|
6242
|
+
const visitors = analyticsData?.visitors || 0;
|
|
6243
|
+
const base = Math.max(visitors, contacts, submissions, 1);
|
|
6244
|
+
const rows = [
|
|
6245
|
+
{ label: "Visitors", value: visitors },
|
|
6246
|
+
{ label: "Contacts", value: contacts },
|
|
6247
|
+
{ label: "Submissions", value: submissions }
|
|
6248
|
+
];
|
|
6249
|
+
return /* @__PURE__ */ jsxs36("div", { className: "space-y-3", children: [
|
|
6250
|
+
rows.map((r) => /* @__PURE__ */ jsxs36("div", { children: [
|
|
6251
|
+
/* @__PURE__ */ jsxs36("div", { className: "flex items-center justify-between text-xs mb-1", children: [
|
|
6252
|
+
/* @__PURE__ */ jsx45("span", { className: "text-gray-600", children: r.label }),
|
|
6253
|
+
/* @__PURE__ */ jsx45("span", { className: "font-semibold text-gray-900", children: r.value.toLocaleString() })
|
|
6254
|
+
] }),
|
|
6255
|
+
/* @__PURE__ */ jsx45("div", { className: "h-2 rounded bg-gray-100 overflow-hidden", children: /* @__PURE__ */ jsx45("div", { className: "h-2 bg-gray-700 rounded", style: { width: `${safePct(r.value, base)}%` } }) })
|
|
6256
|
+
] }, r.label)),
|
|
6257
|
+
/* @__PURE__ */ jsxs36("div", { className: "pt-1 text-xs text-gray-600", children: [
|
|
6258
|
+
"Contact rate:",
|
|
6259
|
+
" ",
|
|
6260
|
+
/* @__PURE__ */ jsxs36("span", { className: "font-semibold text-gray-900", children: [
|
|
6261
|
+
visitors > 0 ? (contacts / visitors * 100).toFixed(1) : "0.0",
|
|
6262
|
+
"%"
|
|
6263
|
+
] }),
|
|
6264
|
+
" ",
|
|
6265
|
+
" | Submission rate:",
|
|
6266
|
+
" ",
|
|
6267
|
+
/* @__PURE__ */ jsxs36("span", { className: "font-semibold text-gray-900", children: [
|
|
6268
|
+
visitors > 0 ? (submissions / visitors * 100).toFixed(1) : "0.0",
|
|
6269
|
+
"%"
|
|
6270
|
+
] })
|
|
6271
|
+
] })
|
|
6272
|
+
] });
|
|
6273
|
+
})()
|
|
6274
|
+
] }),
|
|
6275
|
+
/* @__PURE__ */ jsxs36("div", { className: "bg-white rounded-lg border border-gray-100 p-4 shadow-sm", children: [
|
|
6276
|
+
/* @__PURE__ */ jsx45("h3", { className: "text-base font-semibold text-gray-800 mb-3", children: "CRM Distribution" }),
|
|
6277
|
+
(() => {
|
|
6278
|
+
const contacts = dashboardStats?.contacts.total || 0;
|
|
6279
|
+
const forms = dashboardStats?.forms.total || 0;
|
|
6280
|
+
const blogs = dashboardStats?.blogs || 0;
|
|
6281
|
+
const users = dashboardStats?.users || 0;
|
|
6282
|
+
const base = Math.max(contacts, forms, blogs, users, 1);
|
|
6283
|
+
const rows = [
|
|
6284
|
+
{ label: "Contacts", value: contacts },
|
|
6285
|
+
{ label: "Forms", value: forms },
|
|
6286
|
+
{ label: "Blogs", value: blogs },
|
|
6287
|
+
{ label: "Users", value: users }
|
|
6288
|
+
];
|
|
6289
|
+
return /* @__PURE__ */ jsx45("div", { className: "space-y-2", children: rows.map((r) => /* @__PURE__ */ jsxs36("div", { children: [
|
|
6290
|
+
/* @__PURE__ */ jsxs36("div", { className: "flex items-center justify-between text-xs mb-1", children: [
|
|
6291
|
+
/* @__PURE__ */ jsx45("span", { className: "text-gray-600", children: r.label }),
|
|
6292
|
+
/* @__PURE__ */ jsx45("span", { className: "font-semibold text-gray-900", children: r.value })
|
|
6293
|
+
] }),
|
|
6294
|
+
/* @__PURE__ */ jsx45("div", { className: "h-2 rounded bg-gray-100 overflow-hidden", children: /* @__PURE__ */ jsx45("div", { className: "h-2 bg-gray-700 rounded", style: { width: `${safePct(r.value, base)}%` } }) })
|
|
6295
|
+
] }, r.label)) });
|
|
6296
|
+
})()
|
|
6297
|
+
] })
|
|
6298
|
+
] }),
|
|
6299
|
+
analyticsEnabled && analyticsData && /* @__PURE__ */ jsxs36("div", { className: "bg-white rounded-lg border border-gray-100 p-4 shadow-sm mb-2", children: [
|
|
6300
|
+
/* @__PURE__ */ jsx45("h3", { className: "text-base font-semibold text-gray-800 mb-3", children: "Top Content & Sources" }),
|
|
6301
|
+
/* @__PURE__ */ jsxs36("div", { className: "grid grid-cols-1 lg:grid-cols-2 gap-6", children: [
|
|
6302
|
+
/* @__PURE__ */ jsxs36("div", { children: [
|
|
6303
|
+
/* @__PURE__ */ jsx45("p", { className: "text-xs font-semibold text-gray-700 mb-2", children: "Top Pages" }),
|
|
6304
|
+
/* @__PURE__ */ jsx45("div", { className: "space-y-1", children: analyticsData.topPages.slice(0, 5).map((page, index) => /* @__PURE__ */ jsxs36("div", { className: "flex items-center justify-between text-xs", children: [
|
|
6305
|
+
/* @__PURE__ */ jsx45("span", { className: "text-gray-600 truncate max-w-[75%]", children: page.page }),
|
|
6306
|
+
/* @__PURE__ */ jsx45("span", { className: "font-semibold text-gray-900", children: page.views.toLocaleString() })
|
|
6307
|
+
] }, index)) })
|
|
6308
|
+
] }),
|
|
6309
|
+
/* @__PURE__ */ jsxs36("div", { children: [
|
|
6310
|
+
/* @__PURE__ */ jsx45("p", { className: "text-xs font-semibold text-gray-700 mb-2", children: "Traffic Sources" }),
|
|
6311
|
+
/* @__PURE__ */ jsx45("div", { className: "space-y-1", children: analyticsData.trafficSources.slice(0, 5).map((source, index) => /* @__PURE__ */ jsxs36("div", { className: "flex items-center justify-between text-xs", children: [
|
|
6312
|
+
/* @__PURE__ */ jsx45("span", { className: "text-gray-600", children: source.source }),
|
|
6313
|
+
/* @__PURE__ */ jsx45("span", { className: "font-semibold text-gray-900", children: source.sessions.toLocaleString() })
|
|
6314
|
+
] }, index)) })
|
|
6315
|
+
] })
|
|
6316
|
+
] })
|
|
6317
|
+
] })
|
|
6318
|
+
] }),
|
|
6319
|
+
activeTab === "sales" && !isLoading && storeEnabled && ecommerceData && /* @__PURE__ */ jsxs36(Fragment6, { children: [
|
|
6320
|
+
/* @__PURE__ */ jsx45("div", { className: "border-t-2 border-dotted border-gray-200 my-6" }),
|
|
6321
|
+
/* @__PURE__ */ jsxs36("div", { className: "mb-4", children: [
|
|
6322
|
+
/* @__PURE__ */ jsxs36("div", { className: "flex items-center mb-2", children: [
|
|
6323
|
+
/* @__PURE__ */ jsx45(BarChart3, { className: "w-4 h-4 text-gray-600 mr-2" }),
|
|
6324
|
+
/* @__PURE__ */ jsx45("h2", { className: "text-sm font-semibold text-gray-800", children: "Store Analytics" })
|
|
6325
|
+
] }),
|
|
6326
|
+
/* @__PURE__ */ jsxs36("div", { className: "grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-3", children: [
|
|
6327
|
+
/* @__PURE__ */ jsxs36("button", { onClick: () => router.push("/admin/orders"), className: "text-left bg-white rounded border border-gray-200 p-2.5 shadow-sm", children: [
|
|
6328
|
+
/* @__PURE__ */ jsx45("p", { className: "text-xs text-gray-600", children: "Net Sales" }),
|
|
6329
|
+
/* @__PURE__ */ jsx45("p", { className: "text-lg font-bold text-gray-900", children: formatMoney4(ecommerceData.kpis.netSales) })
|
|
6330
|
+
] }),
|
|
6331
|
+
/* @__PURE__ */ jsxs36("button", { onClick: () => router.push("/admin/orders"), className: "text-left bg-white rounded border border-gray-200 p-2.5 shadow-sm", children: [
|
|
6332
|
+
/* @__PURE__ */ jsx45("p", { className: "text-xs text-gray-600", children: "Orders" }),
|
|
6333
|
+
/* @__PURE__ */ jsx45("p", { className: "text-lg font-bold text-gray-900", children: ecommerceData.kpis.ordersPlaced })
|
|
6334
|
+
] }),
|
|
6335
|
+
/* @__PURE__ */ jsxs36("button", { onClick: () => router.push("/admin/orders"), className: "text-left bg-white rounded border border-gray-200 p-2.5 shadow-sm", children: [
|
|
6336
|
+
/* @__PURE__ */ jsx45("p", { className: "text-xs text-gray-600", children: "AOV" }),
|
|
6337
|
+
/* @__PURE__ */ jsx45("p", { className: "text-lg font-bold text-gray-900", children: formatMoney4(ecommerceData.kpis.averageOrderValue) })
|
|
6338
|
+
] }),
|
|
6339
|
+
/* @__PURE__ */ jsxs36("button", { onClick: () => router.push("/admin/contacts"), className: "text-left bg-white rounded border border-gray-200 p-2.5 shadow-sm", children: [
|
|
6340
|
+
/* @__PURE__ */ jsx45("p", { className: "text-xs text-gray-600", children: "Returning Customer Rate" }),
|
|
6341
|
+
/* @__PURE__ */ jsxs36("p", { className: "text-lg font-bold text-gray-900", children: [
|
|
6342
|
+
ecommerceData.kpis.returningCustomerRate.toFixed(1),
|
|
6343
|
+
"%"
|
|
6344
|
+
] })
|
|
6345
|
+
] }),
|
|
6346
|
+
/* @__PURE__ */ jsxs36("button", { onClick: () => router.push("/admin/orders"), className: "text-left bg-white rounded border border-gray-200 p-2.5 shadow-sm", children: [
|
|
6347
|
+
/* @__PURE__ */ jsx45("p", { className: "text-xs text-gray-600", children: "Return Rate" }),
|
|
6348
|
+
/* @__PURE__ */ jsxs36("p", { className: "text-lg font-bold text-gray-900", children: [
|
|
6349
|
+
ecommerceData.kpis.returnRate.toFixed(1),
|
|
6350
|
+
"%"
|
|
6351
|
+
] })
|
|
6352
|
+
] }),
|
|
6353
|
+
/* @__PURE__ */ jsxs36("button", { onClick: () => router.push("/admin/payments"), className: "text-left bg-white rounded border border-gray-200 p-2.5 shadow-sm", children: [
|
|
6354
|
+
/* @__PURE__ */ jsx45("p", { className: "text-xs text-gray-600", children: "Payment Success" }),
|
|
6355
|
+
/* @__PURE__ */ jsxs36("p", { className: "text-lg font-bold text-gray-900", children: [
|
|
6356
|
+
ecommerceData.kpis.paymentSuccessRate.toFixed(1),
|
|
6357
|
+
"%"
|
|
6358
|
+
] })
|
|
6359
|
+
] })
|
|
6360
|
+
] })
|
|
6361
|
+
] }),
|
|
6362
|
+
/* @__PURE__ */ jsxs36("div", { className: "grid grid-cols-1 lg:grid-cols-2 gap-6 mb-6", children: [
|
|
6363
|
+
/* @__PURE__ */ jsxs36("div", { className: "bg-white rounded-lg border border-gray-100 p-4 shadow-sm", children: [
|
|
6364
|
+
/* @__PURE__ */ jsx45("h3", { className: "text-base font-semibold text-gray-800 mb-3", children: "Sales Over Time" }),
|
|
6365
|
+
/* @__PURE__ */ jsx45("div", { className: "space-y-2 max-h-64 overflow-auto", children: ecommerceData.salesOverTime.slice(-10).map((point) => /* @__PURE__ */ jsxs36("div", { className: "flex items-center justify-between text-xs", children: [
|
|
6366
|
+
/* @__PURE__ */ jsx45("span", { className: "text-gray-600", children: point.date }),
|
|
6367
|
+
/* @__PURE__ */ jsxs36("span", { className: "font-semibold text-gray-900", children: [
|
|
6368
|
+
formatMoney4(point.value),
|
|
6369
|
+
" (",
|
|
6370
|
+
point.orders,
|
|
6371
|
+
")"
|
|
6372
|
+
] })
|
|
6373
|
+
] }, point.date)) })
|
|
6374
|
+
] }),
|
|
6375
|
+
/* @__PURE__ */ jsxs36("div", { className: "bg-white rounded-lg border border-gray-100 p-4 shadow-sm", children: [
|
|
6376
|
+
/* @__PURE__ */ jsx45("h3", { className: "text-base font-semibold text-gray-800 mb-3", children: "Top Products" }),
|
|
6377
|
+
/* @__PURE__ */ jsx45("div", { className: "space-y-2", children: ecommerceData.topProducts.map((p, idx) => /* @__PURE__ */ jsxs36(
|
|
6378
|
+
"button",
|
|
6379
|
+
{
|
|
6380
|
+
onClick: () => router.push("/admin/products"),
|
|
6381
|
+
className: "w-full text-left flex items-center justify-between p-2 bg-gray-50 rounded-lg",
|
|
6382
|
+
children: [
|
|
6383
|
+
/* @__PURE__ */ jsx45("span", { className: "text-xs text-gray-700 truncate max-w-[70%]", children: p.name }),
|
|
6384
|
+
/* @__PURE__ */ jsxs36("span", { className: "text-xs font-semibold text-gray-900", children: [
|
|
6385
|
+
p.units,
|
|
6386
|
+
" / ",
|
|
6387
|
+
formatMoney4(p.sales)
|
|
6388
|
+
] })
|
|
6389
|
+
]
|
|
6390
|
+
},
|
|
6391
|
+
`${p.name}-${idx}`
|
|
6392
|
+
)) })
|
|
6393
|
+
] })
|
|
6394
|
+
] }),
|
|
6395
|
+
/* @__PURE__ */ jsxs36("div", { className: "grid grid-cols-1 lg:grid-cols-3 gap-6 mb-2", children: [
|
|
6396
|
+
/* @__PURE__ */ jsxs36("div", { className: "bg-white rounded-lg border border-gray-100 p-4 shadow-sm", children: [
|
|
6397
|
+
/* @__PURE__ */ jsx45("h3", { className: "text-base font-semibold text-gray-800 mb-2", children: "Customer Mix" }),
|
|
6398
|
+
/* @__PURE__ */ jsxs36("p", { className: "text-xs text-gray-700", children: [
|
|
6399
|
+
"New: ",
|
|
6400
|
+
ecommerceData.customerMix.newCustomers
|
|
6401
|
+
] }),
|
|
6402
|
+
/* @__PURE__ */ jsxs36("p", { className: "text-xs text-gray-700", children: [
|
|
6403
|
+
"Returning: ",
|
|
6404
|
+
ecommerceData.customerMix.returningCustomers
|
|
6405
|
+
] }),
|
|
6406
|
+
/* @__PURE__ */ jsxs36("p", { className: "text-xs text-gray-700", children: [
|
|
6407
|
+
"Repeat rate: ",
|
|
6408
|
+
ecommerceData.customerMix.repeatPurchaseRate.toFixed(1),
|
|
6409
|
+
"%"
|
|
6410
|
+
] })
|
|
6411
|
+
] }),
|
|
6412
|
+
/* @__PURE__ */ jsxs36("div", { className: "bg-white rounded-lg border border-gray-100 p-4 shadow-sm", children: [
|
|
6413
|
+
/* @__PURE__ */ jsx45("h3", { className: "text-base font-semibold text-gray-800 mb-2", children: "Returns Trend" }),
|
|
6414
|
+
/* @__PURE__ */ jsxs36("p", { className: "text-xs text-gray-700", children: [
|
|
6415
|
+
"Return value: ",
|
|
6416
|
+
formatMoney4(ecommerceData.kpis.returnValue)
|
|
6417
|
+
] }),
|
|
6418
|
+
/* @__PURE__ */ jsxs36("p", { className: "text-xs text-gray-700", children: [
|
|
6419
|
+
"Return orders: ",
|
|
6420
|
+
ecommerceData.returnsTrend.reduce((s, r) => s + r.count, 0)
|
|
6421
|
+
] }),
|
|
6422
|
+
/* @__PURE__ */ jsxs36("p", { className: "text-xs text-gray-700", children: [
|
|
6423
|
+
"Return rate: ",
|
|
6424
|
+
ecommerceData.kpis.returnRate.toFixed(1),
|
|
6425
|
+
"%"
|
|
6426
|
+
] })
|
|
6427
|
+
] }),
|
|
6428
|
+
/* @__PURE__ */ jsxs36("div", { className: "bg-white rounded-lg border border-gray-100 p-4 shadow-sm", children: [
|
|
6429
|
+
/* @__PURE__ */ jsx45("h3", { className: "text-base font-semibold text-gray-800 mb-2", children: "Inventory Risk" }),
|
|
6430
|
+
/* @__PURE__ */ jsxs36("p", { className: "text-xs text-gray-700", children: [
|
|
6431
|
+
"Out of stock: ",
|
|
6432
|
+
ecommerceData.inventoryRisk.outOfStockCount
|
|
6433
|
+
] }),
|
|
6434
|
+
/* @__PURE__ */ jsxs36("p", { className: "text-xs text-gray-700", children: [
|
|
6435
|
+
"Low stock: ",
|
|
6436
|
+
ecommerceData.inventoryRisk.lowStockCount
|
|
6437
|
+
] }),
|
|
6438
|
+
/* @__PURE__ */ jsxs36("p", { className: "text-xs text-gray-700", children: [
|
|
6439
|
+
"Total units: ",
|
|
6440
|
+
ecommerceData.inventoryRisk.totalInventory
|
|
6441
|
+
] })
|
|
6442
|
+
] })
|
|
6443
|
+
] })
|
|
6444
|
+
] }),
|
|
5744
6445
|
isLoading && /* @__PURE__ */ jsxs36("div", { className: "flex items-center justify-center py-8", children: [
|
|
5745
6446
|
/* @__PURE__ */ jsx45("div", { className: "animate-spin rounded-full h-5 w-5 border-2 border-gray-300 border-t-gray-600" }),
|
|
5746
6447
|
/* @__PURE__ */ jsx45("span", { className: "ml-2 text-sm text-gray-600", children: "Loading dashboard data..." })
|
|
5747
6448
|
] }),
|
|
5748
|
-
!isLoading && !analyticsEnabled && /* @__PURE__ */ jsxs36("div", { className: "text-center py-8", children: [
|
|
6449
|
+
!isLoading && activeTab === "overview" && !analyticsEnabled && /* @__PURE__ */ jsxs36("div", { className: "text-center py-8", children: [
|
|
5749
6450
|
/* @__PURE__ */ jsx45(Globe, { className: "w-10 h-10 text-gray-400 mx-auto mb-3" }),
|
|
5750
6451
|
/* @__PURE__ */ jsx45("h3", { className: "text-base font-medium text-gray-600 mb-1", children: "Analytics Not Configured" }),
|
|
5751
6452
|
/* @__PURE__ */ jsx45("p", { className: "text-xs text-gray-500", children: "Google Analytics integration is required to view website analytics." })
|
|
6453
|
+
] }),
|
|
6454
|
+
!isLoading && activeTab === "sales" && !storeEnabled && /* @__PURE__ */ jsxs36("div", { className: "text-center py-8", children: [
|
|
6455
|
+
/* @__PURE__ */ jsx45("h3", { className: "text-base font-medium text-gray-600 mb-1", children: "Store analytics unavailable" }),
|
|
6456
|
+
/* @__PURE__ */ jsx45("p", { className: "text-xs text-gray-500", children: "Enable store/ecomm to view sales reports." })
|
|
5752
6457
|
] })
|
|
5753
6458
|
] })
|
|
5754
6459
|
] });
|
|
5755
6460
|
}
|
|
5756
6461
|
|
|
5757
6462
|
// src/admin/pages/AdminPageResolver.tsx
|
|
5758
|
-
import { useState as
|
|
5759
|
-
import { useRouter as
|
|
6463
|
+
import { useState as useState36, useEffect as useEffect33, useContext as useContext7, useMemo as useMemo4 } from "react";
|
|
6464
|
+
import { useRouter as useRouter15 } from "next/navigation";
|
|
5760
6465
|
|
|
5761
6466
|
// src/admin/pages/SubmissionDetailPage.tsx
|
|
5762
|
-
import { useEffect as useEffect20, useState as
|
|
6467
|
+
import { useEffect as useEffect20, useState as useState23 } from "react";
|
|
5763
6468
|
import Link9 from "next/link";
|
|
5764
6469
|
import { ArrowLeft as ArrowLeft5 } from "lucide-react";
|
|
5765
6470
|
|
|
5766
6471
|
// src/components/Admin/DetailPageHeader.tsx
|
|
5767
6472
|
import Link8 from "next/link";
|
|
5768
|
-
import { useRouter as
|
|
5769
|
-
import { ArrowLeft as ArrowLeft4,
|
|
5770
|
-
import { jsx as jsx46, jsxs as jsxs37 } from "react/jsx-runtime";
|
|
6473
|
+
import { useRouter as useRouter7 } from "next/navigation";
|
|
6474
|
+
import { ArrowLeft as ArrowLeft4, X as X13 } from "lucide-react";
|
|
6475
|
+
import { Fragment as Fragment7, jsx as jsx46, jsxs as jsxs37 } from "react/jsx-runtime";
|
|
5771
6476
|
function DetailPageHeader({
|
|
5772
6477
|
title,
|
|
5773
6478
|
subtitle,
|
|
@@ -5777,7 +6482,7 @@ function DetailPageHeader({
|
|
|
5777
6482
|
onClose,
|
|
5778
6483
|
menuItems = []
|
|
5779
6484
|
}) {
|
|
5780
|
-
const router =
|
|
6485
|
+
const router = useRouter7();
|
|
5781
6486
|
const handleClose = () => {
|
|
5782
6487
|
if (onClose) onClose();
|
|
5783
6488
|
else if (closeHref) router.push(closeHref);
|
|
@@ -5802,20 +6507,32 @@ function DetailPageHeader({
|
|
|
5802
6507
|
] })
|
|
5803
6508
|
] }),
|
|
5804
6509
|
/* @__PURE__ */ jsxs37("div", { className: "flex items-center gap-2 shrink-0", children: [
|
|
5805
|
-
menuItems.length > 0 && /* @__PURE__ */ jsxs37(
|
|
5806
|
-
/* @__PURE__ */ jsx46(
|
|
5807
|
-
|
|
5808
|
-
|
|
5809
|
-
|
|
5810
|
-
|
|
5811
|
-
|
|
5812
|
-
|
|
5813
|
-
|
|
5814
|
-
|
|
5815
|
-
|
|
5816
|
-
|
|
5817
|
-
|
|
5818
|
-
|
|
6510
|
+
menuItems.length > 0 && /* @__PURE__ */ jsxs37(Fragment7, { children: [
|
|
6511
|
+
/* @__PURE__ */ jsx46("div", { className: "flex items-center gap-2 md:hidden", children: menuItems.map((item, i) => {
|
|
6512
|
+
const Icon2 = item.icon;
|
|
6513
|
+
return /* @__PURE__ */ jsxs37(
|
|
6514
|
+
Button,
|
|
6515
|
+
{
|
|
6516
|
+
variant: item.variant ?? "outline",
|
|
6517
|
+
size: "icon",
|
|
6518
|
+
className: "h-8 w-8 border border-gray-600 bg-transparent text-white hover:bg-gray-700",
|
|
6519
|
+
onClick: item.onClick,
|
|
6520
|
+
title: item.label,
|
|
6521
|
+
children: [
|
|
6522
|
+
/* @__PURE__ */ jsx46(Icon2, { className: "h-4 w-4" }),
|
|
6523
|
+
/* @__PURE__ */ jsx46("span", { className: "sr-only", children: item.label })
|
|
6524
|
+
]
|
|
6525
|
+
},
|
|
6526
|
+
i
|
|
6527
|
+
);
|
|
6528
|
+
}) }),
|
|
6529
|
+
/* @__PURE__ */ jsx46("div", { className: "hidden md:flex items-center gap-2", children: menuItems.map((item, i) => {
|
|
6530
|
+
const Icon2 = item.icon;
|
|
6531
|
+
return /* @__PURE__ */ jsxs37(Button, { variant: item.variant ?? "outline", size: "sm", onClick: item.onClick, children: [
|
|
6532
|
+
/* @__PURE__ */ jsx46(Icon2, { className: "h-4 w-4 mr-1" }),
|
|
6533
|
+
item.label
|
|
6534
|
+
] }, i);
|
|
6535
|
+
}) })
|
|
5819
6536
|
] }),
|
|
5820
6537
|
/* @__PURE__ */ jsxs37(
|
|
5821
6538
|
Button,
|
|
@@ -5837,9 +6554,9 @@ function DetailPageHeader({
|
|
|
5837
6554
|
// src/admin/pages/SubmissionDetailPage.tsx
|
|
5838
6555
|
import { jsx as jsx47, jsxs as jsxs38 } from "react/jsx-runtime";
|
|
5839
6556
|
function SubmissionDetailPage({ submissionId }) {
|
|
5840
|
-
const [submission, setSubmission] =
|
|
5841
|
-
const [loading, setLoading] =
|
|
5842
|
-
const [error, setError] =
|
|
6557
|
+
const [submission, setSubmission] = useState23(null);
|
|
6558
|
+
const [loading, setLoading] = useState23(true);
|
|
6559
|
+
const [error, setError] = useState23(null);
|
|
5843
6560
|
useEffect20(() => {
|
|
5844
6561
|
async function load() {
|
|
5845
6562
|
try {
|
|
@@ -5948,10 +6665,10 @@ function SubmissionDetailPage({ submissionId }) {
|
|
|
5948
6665
|
}
|
|
5949
6666
|
|
|
5950
6667
|
// src/admin/pages/OrderDetailPage.tsx
|
|
5951
|
-
import { useEffect as useEffect21, useState as
|
|
6668
|
+
import { useEffect as useEffect21, useState as useState24 } from "react";
|
|
5952
6669
|
import Link10 from "next/link";
|
|
5953
|
-
import { useRouter as
|
|
5954
|
-
import { X as X14 } from "lucide-react";
|
|
6670
|
+
import { useRouter as useRouter8 } from "next/navigation";
|
|
6671
|
+
import { X as X14, RefreshCw as RefreshCw2 } from "lucide-react";
|
|
5955
6672
|
|
|
5956
6673
|
// src/components/Admin/DetailPageLayout.tsx
|
|
5957
6674
|
import { jsx as jsx48, jsxs as jsxs39 } from "react/jsx-runtime";
|
|
@@ -5969,7 +6686,7 @@ function DetailPageLayout({
|
|
|
5969
6686
|
}
|
|
5970
6687
|
|
|
5971
6688
|
// src/admin/pages/OrderDetailPage.tsx
|
|
5972
|
-
import { Fragment as
|
|
6689
|
+
import { Fragment as Fragment8, jsx as jsx49, jsxs as jsxs40 } from "react/jsx-runtime";
|
|
5973
6690
|
function formatMoney(amount, currency = "INR") {
|
|
5974
6691
|
return new Intl.NumberFormat("en-IN", {
|
|
5975
6692
|
style: "currency",
|
|
@@ -5992,12 +6709,12 @@ function formatAddress(a) {
|
|
|
5992
6709
|
return parts.join(", ") || "\u2014";
|
|
5993
6710
|
}
|
|
5994
6711
|
function OrderDetailPage({ orderId }) {
|
|
5995
|
-
const router =
|
|
5996
|
-
const [order, setOrder] =
|
|
5997
|
-
const [loading, setLoading] =
|
|
5998
|
-
const [error, setError] =
|
|
5999
|
-
const [erpEnabled, setErpEnabled] =
|
|
6000
|
-
const [reposting, setReposting] =
|
|
6712
|
+
const router = useRouter8();
|
|
6713
|
+
const [order, setOrder] = useState24(null);
|
|
6714
|
+
const [loading, setLoading] = useState24(true);
|
|
6715
|
+
const [error, setError] = useState24(null);
|
|
6716
|
+
const [erpEnabled, setErpEnabled] = useState24(false);
|
|
6717
|
+
const [reposting, setReposting] = useState24(false);
|
|
6001
6718
|
useEffect21(() => {
|
|
6002
6719
|
async function load() {
|
|
6003
6720
|
try {
|
|
@@ -6077,13 +6794,13 @@ function OrderDetailPage({ orderId }) {
|
|
|
6077
6794
|
title: `Order ${order.orderNumber}`,
|
|
6078
6795
|
subtitle: /* @__PURE__ */ jsx49("span", { className: "text-sm text-gray-400", children: formatDateTime(order.createdAt) }),
|
|
6079
6796
|
closeHref: "/admin/orders",
|
|
6080
|
-
menuItems: erpEnabled ? [{ label: reposting ? "Reposting..." : "Repost to ERP", onClick: handleRepostToErp }] : void 0
|
|
6797
|
+
menuItems: erpEnabled ? [{ label: reposting ? "Reposting..." : "Repost to ERP", icon: RefreshCw2, onClick: handleRepostToErp }] : void 0
|
|
6081
6798
|
}
|
|
6082
6799
|
),
|
|
6083
6800
|
/* @__PURE__ */ jsx49(
|
|
6084
6801
|
DetailPageLayout,
|
|
6085
6802
|
{
|
|
6086
|
-
main: /* @__PURE__ */ jsxs40(
|
|
6803
|
+
main: /* @__PURE__ */ jsxs40(Fragment8, { children: [
|
|
6087
6804
|
/* @__PURE__ */ jsxs40("section", { children: [
|
|
6088
6805
|
/* @__PURE__ */ jsx49("h2", { className: "text-xs font-semibold text-gray-400 uppercase tracking-wider mb-2", children: "Order details" }),
|
|
6089
6806
|
/* @__PURE__ */ jsx49("div", { className: "min-w-0 overflow-hidden border border-gray-200 rounded-lg p-4 bg-gray-50/50", children: /* @__PURE__ */ jsxs40("dl", { className: "min-w-0 grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-3 text-sm", children: [
|
|
@@ -6115,7 +6832,7 @@ function OrderDetailPage({ orderId }) {
|
|
|
6115
6832
|
/* @__PURE__ */ jsx49("dt", { className: "text-gray-500", children: "Total" }),
|
|
6116
6833
|
/* @__PURE__ */ jsx49("dd", { className: "font-medium text-gray-900", children: formatMoney(Number(order.total), currency) })
|
|
6117
6834
|
] }),
|
|
6118
|
-
(order.orderKind || order.parentOrderId != null) && /* @__PURE__ */ jsxs40(
|
|
6835
|
+
(order.orderKind || order.parentOrderId != null) && /* @__PURE__ */ jsxs40(Fragment8, { children: [
|
|
6119
6836
|
/* @__PURE__ */ jsxs40("div", { className: "min-w-0", children: [
|
|
6120
6837
|
/* @__PURE__ */ jsx49("dt", { className: "text-gray-500", children: "Kind" }),
|
|
6121
6838
|
/* @__PURE__ */ jsx49("dd", { className: "font-medium text-gray-900 capitalize", children: order.orderKind ?? "sale" })
|
|
@@ -6238,7 +6955,7 @@ function OrderDetailPage({ orderId }) {
|
|
|
6238
6955
|
] })
|
|
6239
6956
|
] }) })
|
|
6240
6957
|
] }),
|
|
6241
|
-
sidebar: /* @__PURE__ */ jsxs40(
|
|
6958
|
+
sidebar: /* @__PURE__ */ jsxs40(Fragment8, { children: [
|
|
6242
6959
|
contact && /* @__PURE__ */ jsxs40("section", { children: [
|
|
6243
6960
|
/* @__PURE__ */ jsx49("h2", { className: "text-xs font-semibold text-gray-400 uppercase tracking-wider mb-2", children: "Customer" }),
|
|
6244
6961
|
/* @__PURE__ */ jsx49("div", { className: "min-w-0 overflow-hidden border border-gray-200 rounded-lg p-4 bg-gray-50/50", children: /* @__PURE__ */ jsxs40("dl", { className: "min-w-0 grid grid-cols-1 sm:grid-cols-3 gap-3 text-sm", children: [
|
|
@@ -6317,11 +7034,11 @@ function OrderDetailPage({ orderId }) {
|
|
|
6317
7034
|
}
|
|
6318
7035
|
|
|
6319
7036
|
// src/admin/pages/PaymentDetailPage.tsx
|
|
6320
|
-
import { useEffect as useEffect22, useState as
|
|
7037
|
+
import { useEffect as useEffect22, useState as useState25 } from "react";
|
|
6321
7038
|
import Link11 from "next/link";
|
|
6322
|
-
import { useRouter as
|
|
7039
|
+
import { useRouter as useRouter9 } from "next/navigation";
|
|
6323
7040
|
import { X as X15 } from "lucide-react";
|
|
6324
|
-
import { Fragment as
|
|
7041
|
+
import { Fragment as Fragment9, jsx as jsx50, jsxs as jsxs41 } from "react/jsx-runtime";
|
|
6325
7042
|
function formatMoney2(amount, currency = "INR") {
|
|
6326
7043
|
return new Intl.NumberFormat("en-IN", {
|
|
6327
7044
|
style: "currency",
|
|
@@ -6330,10 +7047,10 @@ function formatMoney2(amount, currency = "INR") {
|
|
|
6330
7047
|
}).format(Number(amount));
|
|
6331
7048
|
}
|
|
6332
7049
|
function PaymentDetailPage({ paymentId }) {
|
|
6333
|
-
const router =
|
|
6334
|
-
const [payment, setPayment] =
|
|
6335
|
-
const [loading, setLoading] =
|
|
6336
|
-
const [error, setError] =
|
|
7050
|
+
const router = useRouter9();
|
|
7051
|
+
const [payment, setPayment] = useState25(null);
|
|
7052
|
+
const [loading, setLoading] = useState25(true);
|
|
7053
|
+
const [error, setError] = useState25(null);
|
|
6337
7054
|
useEffect22(() => {
|
|
6338
7055
|
async function load() {
|
|
6339
7056
|
try {
|
|
@@ -6383,7 +7100,7 @@ function PaymentDetailPage({ paymentId }) {
|
|
|
6383
7100
|
/* @__PURE__ */ jsx50(
|
|
6384
7101
|
DetailPageLayout,
|
|
6385
7102
|
{
|
|
6386
|
-
main: /* @__PURE__ */ jsxs41(
|
|
7103
|
+
main: /* @__PURE__ */ jsxs41(Fragment9, { children: [
|
|
6387
7104
|
/* @__PURE__ */ jsxs41("section", { children: [
|
|
6388
7105
|
/* @__PURE__ */ jsx50("h2", { className: "text-xs font-semibold text-gray-400 uppercase tracking-wider mb-2", children: "Payment details" }),
|
|
6389
7106
|
/* @__PURE__ */ jsx50("div", { className: "min-w-0 overflow-hidden border border-gray-200 rounded-lg p-4 bg-gray-50/50", children: /* @__PURE__ */ jsxs41("dl", { className: "min-w-0 grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-3 text-sm", children: [
|
|
@@ -6446,7 +7163,7 @@ function PaymentDetailPage({ paymentId }) {
|
|
|
6446
7163
|
] })
|
|
6447
7164
|
] })
|
|
6448
7165
|
] }),
|
|
6449
|
-
sidebar: /* @__PURE__ */ jsx50(
|
|
7166
|
+
sidebar: /* @__PURE__ */ jsx50(Fragment9, { children: customer && /* @__PURE__ */ jsxs41("section", { children: [
|
|
6450
7167
|
/* @__PURE__ */ jsx50("h2", { className: "text-xs font-semibold text-gray-400 uppercase tracking-wider mb-2", children: "Customer" }),
|
|
6451
7168
|
/* @__PURE__ */ jsx50("div", { className: "min-w-0 overflow-hidden border border-gray-200 rounded-lg p-4 bg-gray-50/50", children: /* @__PURE__ */ jsxs41("dl", { className: "min-w-0 grid grid-cols-1 sm:grid-cols-3 gap-3 text-sm", children: [
|
|
6452
7169
|
/* @__PURE__ */ jsxs41("div", { className: "min-w-0", children: [
|
|
@@ -6476,11 +7193,11 @@ function PaymentDetailPage({ paymentId }) {
|
|
|
6476
7193
|
}
|
|
6477
7194
|
|
|
6478
7195
|
// src/admin/pages/ContactDetailPage.tsx
|
|
6479
|
-
import { useEffect as useEffect23, useState as
|
|
7196
|
+
import { useEffect as useEffect23, useState as useState26 } from "react";
|
|
6480
7197
|
import Link12 from "next/link";
|
|
6481
|
-
import { useRouter as
|
|
7198
|
+
import { useRouter as useRouter10 } from "next/navigation";
|
|
6482
7199
|
import { Plus as Plus7, X as X16 } from "lucide-react";
|
|
6483
|
-
import { Fragment as
|
|
7200
|
+
import { Fragment as Fragment10, jsx as jsx51, jsxs as jsxs42 } from "react/jsx-runtime";
|
|
6484
7201
|
function formatMoney3(amount, currency = "INR") {
|
|
6485
7202
|
return new Intl.NumberFormat("en-IN", {
|
|
6486
7203
|
style: "currency",
|
|
@@ -6494,13 +7211,13 @@ function formatAddress2(a) {
|
|
|
6494
7211
|
}
|
|
6495
7212
|
var ADDRESS_TAGS = [{ value: "", label: "\u2014" }, { value: "default", label: "Default" }, { value: "billing", label: "Billing" }, { value: "shipping", label: "Shipping" }];
|
|
6496
7213
|
function ContactDetailPage({ contactId }) {
|
|
6497
|
-
const router =
|
|
6498
|
-
const [contact, setContact] =
|
|
6499
|
-
const [loading, setLoading] =
|
|
6500
|
-
const [error, setError] =
|
|
6501
|
-
const [addAddressOpen, setAddAddressOpen] =
|
|
6502
|
-
const [addAddressSaving, setAddAddressSaving] =
|
|
6503
|
-
const [addAddressForm, setAddAddressForm] =
|
|
7214
|
+
const router = useRouter10();
|
|
7215
|
+
const [contact, setContact] = useState26(null);
|
|
7216
|
+
const [loading, setLoading] = useState26(true);
|
|
7217
|
+
const [error, setError] = useState26(null);
|
|
7218
|
+
const [addAddressOpen, setAddAddressOpen] = useState26(false);
|
|
7219
|
+
const [addAddressSaving, setAddAddressSaving] = useState26(false);
|
|
7220
|
+
const [addAddressForm, setAddAddressForm] = useState26({
|
|
6504
7221
|
tag: "",
|
|
6505
7222
|
line1: "",
|
|
6506
7223
|
line2: "",
|
|
@@ -6592,7 +7309,7 @@ function ContactDetailPage({ contactId }) {
|
|
|
6592
7309
|
/* @__PURE__ */ jsx51(
|
|
6593
7310
|
DetailPageLayout,
|
|
6594
7311
|
{
|
|
6595
|
-
main: /* @__PURE__ */ jsxs42(
|
|
7312
|
+
main: /* @__PURE__ */ jsxs42(Fragment10, { children: [
|
|
6596
7313
|
/* @__PURE__ */ jsxs42("section", { children: [
|
|
6597
7314
|
/* @__PURE__ */ jsx51("h2", { className: "text-xs font-semibold text-gray-400 uppercase tracking-wider mb-2", children: "Contact details" }),
|
|
6598
7315
|
/* @__PURE__ */ jsx51("div", { className: "min-w-0 overflow-hidden border border-gray-200 rounded-lg p-4 bg-gray-50/50", children: /* @__PURE__ */ jsxs42("dl", { className: "min-w-0 grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-3 text-sm", children: [
|
|
@@ -6608,7 +7325,7 @@ function ContactDetailPage({ contactId }) {
|
|
|
6608
7325
|
/* @__PURE__ */ jsx51("dt", { className: "text-gray-500", children: "Phone" }),
|
|
6609
7326
|
/* @__PURE__ */ jsx51("dd", { className: "font-medium text-gray-900 break-words", children: contact.phone ?? "\u2014" })
|
|
6610
7327
|
] }),
|
|
6611
|
-
(contact.type ?? contact.company ?? contact.taxId) && /* @__PURE__ */ jsxs42(
|
|
7328
|
+
(contact.type ?? contact.company ?? contact.taxId) && /* @__PURE__ */ jsxs42(Fragment10, { children: [
|
|
6612
7329
|
contact.type && /* @__PURE__ */ jsxs42("div", { className: "min-w-0", children: [
|
|
6613
7330
|
/* @__PURE__ */ jsx51("dt", { className: "text-gray-500", children: "Type" }),
|
|
6614
7331
|
/* @__PURE__ */ jsx51("dd", { className: "font-medium text-gray-900 break-words", children: contact.type })
|
|
@@ -6662,7 +7379,7 @@ function ContactDetailPage({ contactId }) {
|
|
|
6662
7379
|
] }) })
|
|
6663
7380
|
] })
|
|
6664
7381
|
] }),
|
|
6665
|
-
sidebar: /* @__PURE__ */ jsxs42(
|
|
7382
|
+
sidebar: /* @__PURE__ */ jsxs42(Fragment10, { children: [
|
|
6666
7383
|
/* @__PURE__ */ jsxs42("section", { children: [
|
|
6667
7384
|
/* @__PURE__ */ jsx51("h2", { className: "text-xs font-semibold text-gray-400 uppercase tracking-wider mb-2", children: "Summary" }),
|
|
6668
7385
|
/* @__PURE__ */ jsx51("div", { className: "min-w-0 overflow-hidden border border-gray-200 rounded-lg p-4 bg-gray-50/50", children: /* @__PURE__ */ jsxs42("dl", { className: "min-w-0 grid grid-cols-1 sm:grid-cols-3 gap-3 text-sm", children: [
|
|
@@ -6848,11 +7565,11 @@ function ContactDetailPage({ contactId }) {
|
|
|
6848
7565
|
}
|
|
6849
7566
|
|
|
6850
7567
|
// src/admin/pages/SettingsPage.tsx
|
|
6851
|
-
import { useState as
|
|
7568
|
+
import { useState as useState27, useEffect as useEffect24, useContext as useContext4 } from "react";
|
|
6852
7569
|
import { useSearchParams as useSearchParams3 } from "next/navigation";
|
|
6853
|
-
import { toast as
|
|
7570
|
+
import { toast as toast3 } from "sonner";
|
|
6854
7571
|
import { Save as Save3, RotateCcw } from "lucide-react";
|
|
6855
|
-
import { Fragment as
|
|
7572
|
+
import { Fragment as Fragment11, jsx as jsx52, jsxs as jsxs43 } from "react/jsx-runtime";
|
|
6856
7573
|
var DEFAULTS = {
|
|
6857
7574
|
primaryColor: "#313996",
|
|
6858
7575
|
secondaryColor: "#6366f1",
|
|
@@ -6876,22 +7593,22 @@ function hexToHsl(hex) {
|
|
|
6876
7593
|
function SettingsPage() {
|
|
6877
7594
|
const searchParams = useSearchParams3();
|
|
6878
7595
|
const tabParam = searchParams.get("tab");
|
|
6879
|
-
const { theme, themeRegistry } =
|
|
6880
|
-
const [tab, setTab] =
|
|
7596
|
+
const { theme, themeRegistry } = useContext4(AdminConfigContext);
|
|
7597
|
+
const [tab, setTab] = useState27(
|
|
6881
7598
|
tabParam === "navbar" ? "navbar" : tabParam === "store" ? "store" : "appearance"
|
|
6882
7599
|
);
|
|
6883
7600
|
useEffect24(() => {
|
|
6884
7601
|
if (tabParam === "navbar") setTab("navbar");
|
|
6885
7602
|
else if (tabParam === "store") setTab("store");
|
|
6886
7603
|
}, [tabParam]);
|
|
6887
|
-
const [settings, setSettings] =
|
|
6888
|
-
const [loading, setLoading] =
|
|
6889
|
-
const [saving, setSaving] =
|
|
6890
|
-
const [activeThemeId, setActiveThemeId] =
|
|
6891
|
-
const [navbarConfig, setNavbarConfig] =
|
|
6892
|
-
const [themeSettingsLoading, setThemeSettingsLoading] =
|
|
6893
|
-
const [storeEnabled, setStoreEnabled] =
|
|
6894
|
-
const [storeSettingsLoading, setStoreSettingsLoading] =
|
|
7604
|
+
const [settings, setSettings] = useState27(DEFAULTS);
|
|
7605
|
+
const [loading, setLoading] = useState27(true);
|
|
7606
|
+
const [saving, setSaving] = useState27(false);
|
|
7607
|
+
const [activeThemeId, setActiveThemeId] = useState27("");
|
|
7608
|
+
const [navbarConfig, setNavbarConfig] = useState27({ logo: "", items: [], ctaLabel: "", ctaUrl: "" });
|
|
7609
|
+
const [themeSettingsLoading, setThemeSettingsLoading] = useState27(true);
|
|
7610
|
+
const [storeEnabled, setStoreEnabled] = useState27(false);
|
|
7611
|
+
const [storeSettingsLoading, setStoreSettingsLoading] = useState27(true);
|
|
6895
7612
|
useEffect24(() => {
|
|
6896
7613
|
fetch("/api/settings/admin_view").then((r) => r.ok ? r.json() : {}).then((data) => {
|
|
6897
7614
|
setSettings({
|
|
@@ -6937,9 +7654,9 @@ function SettingsPage() {
|
|
|
6937
7654
|
document.documentElement.style.setProperty("--secondary", hexToHsl(settings.secondaryColor));
|
|
6938
7655
|
if (settings.compactView === "true") document.documentElement.classList.add("compact");
|
|
6939
7656
|
else document.documentElement.classList.remove("compact");
|
|
6940
|
-
|
|
7657
|
+
toast3.success("Settings saved");
|
|
6941
7658
|
} catch {
|
|
6942
|
-
|
|
7659
|
+
toast3.error("Failed to save settings");
|
|
6943
7660
|
} finally {
|
|
6944
7661
|
setSaving(false);
|
|
6945
7662
|
}
|
|
@@ -6953,10 +7670,10 @@ function SettingsPage() {
|
|
|
6953
7670
|
headers: { "Content-Type": "application/json" },
|
|
6954
7671
|
body: JSON.stringify({ activeThemeId: { value: id, type: "public" } })
|
|
6955
7672
|
});
|
|
6956
|
-
|
|
7673
|
+
toast3.success("Theme updated");
|
|
6957
7674
|
window.location.reload();
|
|
6958
7675
|
} catch {
|
|
6959
|
-
|
|
7676
|
+
toast3.error("Failed to save theme");
|
|
6960
7677
|
} finally {
|
|
6961
7678
|
setSaving(false);
|
|
6962
7679
|
}
|
|
@@ -6969,9 +7686,9 @@ function SettingsPage() {
|
|
|
6969
7686
|
headers: { "Content-Type": "application/json" },
|
|
6970
7687
|
body: JSON.stringify({ navbar: { value: JSON.stringify(navbarConfig), type: "public" } })
|
|
6971
7688
|
});
|
|
6972
|
-
|
|
7689
|
+
toast3.success("Navbar saved");
|
|
6973
7690
|
} catch {
|
|
6974
|
-
|
|
7691
|
+
toast3.error("Failed to save");
|
|
6975
7692
|
} finally {
|
|
6976
7693
|
setSaving(false);
|
|
6977
7694
|
}
|
|
@@ -6984,10 +7701,10 @@ function SettingsPage() {
|
|
|
6984
7701
|
headers: { "Content-Type": "application/json" },
|
|
6985
7702
|
body: JSON.stringify({ enabled: { value: storeEnabled ? "true" : "false", type: "public" } })
|
|
6986
7703
|
});
|
|
6987
|
-
|
|
7704
|
+
toast3.success("Store settings saved");
|
|
6988
7705
|
window.location.reload();
|
|
6989
7706
|
} catch {
|
|
6990
|
-
|
|
7707
|
+
toast3.error("Failed to save store settings");
|
|
6991
7708
|
} finally {
|
|
6992
7709
|
setSaving(false);
|
|
6993
7710
|
}
|
|
@@ -7063,7 +7780,7 @@ function SettingsPage() {
|
|
|
7063
7780
|
/* @__PURE__ */ jsx52("span", { className: "text-[11px] text-gray-400", children: "Smaller spacing in admin" })
|
|
7064
7781
|
] }) })
|
|
7065
7782
|
] }),
|
|
7066
|
-
tab === "navbar" && /* @__PURE__ */ jsx52("div", { className: "space-y-6", children: themeSettingsLoading ? /* @__PURE__ */ jsx52("div", { className: "flex items-center gap-2 text-gray-500", children: "Loading..." }) : /* @__PURE__ */ jsxs43(
|
|
7783
|
+
tab === "navbar" && /* @__PURE__ */ jsx52("div", { className: "space-y-6", children: themeSettingsLoading ? /* @__PURE__ */ jsx52("div", { className: "flex items-center gap-2 text-gray-500", children: "Loading..." }) : /* @__PURE__ */ jsxs43(Fragment11, { children: [
|
|
7067
7784
|
/* @__PURE__ */ jsxs43("div", { children: [
|
|
7068
7785
|
/* @__PURE__ */ jsx52("h2", { className: "text-lg font-semibold text-gray-900 mb-2", children: "Navbar & pages" }),
|
|
7069
7786
|
/* @__PURE__ */ jsx52("p", { className: "text-sm text-gray-500 mb-4", children: "Set logo and menu items. Use parent/child (indent/outdent) for hierarchy. Each item can link to a page or a custom URL." }),
|
|
@@ -7071,7 +7788,7 @@ function SettingsPage() {
|
|
|
7071
7788
|
] }),
|
|
7072
7789
|
/* @__PURE__ */ jsx52(Button, { onClick: handleSaveNavbar, disabled: saving, children: saving ? "Saving..." : "Save navbar" })
|
|
7073
7790
|
] }) }),
|
|
7074
|
-
tab === "store" && /* @__PURE__ */ jsx52("div", { className: "space-y-6", children: storeSettingsLoading ? /* @__PURE__ */ jsx52("div", { className: "flex items-center gap-2 text-gray-500", children: "Loading..." }) : /* @__PURE__ */ jsxs43(
|
|
7791
|
+
tab === "store" && /* @__PURE__ */ jsx52("div", { className: "space-y-6", children: storeSettingsLoading ? /* @__PURE__ */ jsx52("div", { className: "flex items-center gap-2 text-gray-500", children: "Loading..." }) : /* @__PURE__ */ jsxs43(Fragment11, { children: [
|
|
7075
7792
|
/* @__PURE__ */ jsxs43("div", { children: [
|
|
7076
7793
|
/* @__PURE__ */ jsx52("h2", { className: "text-lg font-semibold text-gray-900 mb-2", children: "Store / E-commerce" }),
|
|
7077
7794
|
/* @__PURE__ */ jsx52("p", { className: "text-sm text-gray-500 mb-4", children: "Enable e-commerce functionality to manage products, orders, payments, and more." }),
|
|
@@ -7103,11 +7820,39 @@ function SettingsPage() {
|
|
|
7103
7820
|
}
|
|
7104
7821
|
|
|
7105
7822
|
// src/admin/pages/MediaLibraryPage.tsx
|
|
7106
|
-
import { useState as
|
|
7107
|
-
|
|
7108
|
-
|
|
7109
|
-
import {
|
|
7110
|
-
|
|
7823
|
+
import React17, { useState as useState28, useEffect as useEffect25, useCallback as useCallback5, useRef as useRef9 } from "react";
|
|
7824
|
+
|
|
7825
|
+
// src/lib/media-zip-extract.ts
|
|
7826
|
+
import { IsNull } from "typeorm";
|
|
7827
|
+
var ZIP_MIME_TYPES = /* @__PURE__ */ new Set(["application/zip", "application/x-zip-compressed"]);
|
|
7828
|
+
var MAX_TOTAL_UNCOMPRESSED = 80 * 1024 * 1024;
|
|
7829
|
+
function isZipMedia(mime, filename) {
|
|
7830
|
+
if (mime && ZIP_MIME_TYPES.has(mime)) return true;
|
|
7831
|
+
return filename.toLowerCase().endsWith(".zip");
|
|
7832
|
+
}
|
|
7833
|
+
|
|
7834
|
+
// src/admin/pages/MediaLibraryPage.tsx
|
|
7835
|
+
import {
|
|
7836
|
+
Upload as Upload4,
|
|
7837
|
+
Search as Search5,
|
|
7838
|
+
Image as ImageIcon3,
|
|
7839
|
+
FileText as FileText2,
|
|
7840
|
+
Film,
|
|
7841
|
+
File as File3,
|
|
7842
|
+
Copy,
|
|
7843
|
+
Trash2 as Trash24,
|
|
7844
|
+
Edit2,
|
|
7845
|
+
Folder,
|
|
7846
|
+
FolderPlus,
|
|
7847
|
+
Archive,
|
|
7848
|
+
LayoutGrid,
|
|
7849
|
+
List
|
|
7850
|
+
} from "lucide-react";
|
|
7851
|
+
import { toast as toast4 } from "sonner";
|
|
7852
|
+
import { Fragment as Fragment12, jsx as jsx53, jsxs as jsxs44 } from "react/jsx-runtime";
|
|
7853
|
+
function getTypeCategory(mime, kind, filename) {
|
|
7854
|
+
if (kind === "folder" || mime === "inode/directory") return "folder";
|
|
7855
|
+
if (isZipMedia(mime, filename ?? "")) return "zip";
|
|
7111
7856
|
if (!mime) return "other";
|
|
7112
7857
|
if (mime.startsWith("image/")) return "image";
|
|
7113
7858
|
if (mime.startsWith("video/")) return "video";
|
|
@@ -7115,56 +7860,66 @@ function getTypeCategory(mime) {
|
|
|
7115
7860
|
if (mime === "application/pdf" || mime.startsWith("application/")) return "document";
|
|
7116
7861
|
return "other";
|
|
7117
7862
|
}
|
|
7118
|
-
function getTypeLabel(mime) {
|
|
7119
|
-
|
|
7863
|
+
function getTypeLabel(mime, kind, filename) {
|
|
7864
|
+
if (kind === "folder" || mime === "inode/directory") return "Folder";
|
|
7865
|
+
if (isZipMedia(mime, filename ?? "")) return "Zip";
|
|
7866
|
+
const c = getTypeCategory(mime, kind, filename);
|
|
7120
7867
|
const labels = {
|
|
7121
7868
|
image: "Image",
|
|
7122
7869
|
video: "Video",
|
|
7123
7870
|
audio: "Audio",
|
|
7124
7871
|
document: "Document",
|
|
7872
|
+
folder: "Folder",
|
|
7873
|
+
zip: "Zip",
|
|
7125
7874
|
other: "Other"
|
|
7126
7875
|
};
|
|
7127
7876
|
return labels[c] || "Other";
|
|
7128
7877
|
}
|
|
7129
|
-
function TypeIcon({ mimeType }) {
|
|
7130
|
-
|
|
7878
|
+
function TypeIcon({ mimeType, kind, filename }) {
|
|
7879
|
+
if (kind === "folder" || mimeType === "inode/directory") {
|
|
7880
|
+
return /* @__PURE__ */ jsx53(Folder, { className: "h-10 w-10 text-amber-500" });
|
|
7881
|
+
}
|
|
7882
|
+
if (isZipMedia(mimeType, filename ?? "")) {
|
|
7883
|
+
return /* @__PURE__ */ jsx53(Archive, { className: "h-10 w-10 text-violet-600" });
|
|
7884
|
+
}
|
|
7885
|
+
const c = getTypeCategory(mimeType, kind, filename);
|
|
7131
7886
|
if (c === "image") return /* @__PURE__ */ jsx53(ImageIcon3, { className: "h-8 w-8 text-gray-400" });
|
|
7132
7887
|
if (c === "video") return /* @__PURE__ */ jsx53(Film, { className: "h-8 w-8 text-gray-400" });
|
|
7133
7888
|
if (c === "document") return /* @__PURE__ */ jsx53(FileText2, { className: "h-8 w-8 text-gray-400" });
|
|
7134
7889
|
return /* @__PURE__ */ jsx53(File3, { className: "h-8 w-8 text-gray-400" });
|
|
7135
7890
|
}
|
|
7136
|
-
function groupByMonth(items) {
|
|
7137
|
-
const groups = {};
|
|
7138
|
-
items.forEach((item) => {
|
|
7139
|
-
const d = new Date(item.createdAt);
|
|
7140
|
-
const key = `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, "0")}`;
|
|
7141
|
-
const label = d.toLocaleDateString("en-US", { year: "numeric", month: "long" });
|
|
7142
|
-
if (!groups[label]) groups[label] = [];
|
|
7143
|
-
groups[label].push(item);
|
|
7144
|
-
});
|
|
7145
|
-
return groups;
|
|
7146
|
-
}
|
|
7147
7891
|
function MediaLibraryPage() {
|
|
7148
|
-
const [data, setData] =
|
|
7149
|
-
const [loading, setLoading] =
|
|
7150
|
-
const [page, setPage] =
|
|
7151
|
-
const [totalPages, setTotalPages] =
|
|
7152
|
-
const [search, setSearch] =
|
|
7153
|
-
const [searchInput, setSearchInput] =
|
|
7154
|
-
const [typeFilter, setTypeFilter] =
|
|
7155
|
-
const [
|
|
7156
|
-
const [
|
|
7157
|
-
const [
|
|
7158
|
-
const [
|
|
7159
|
-
const
|
|
7892
|
+
const [data, setData] = useState28([]);
|
|
7893
|
+
const [loading, setLoading] = useState28(true);
|
|
7894
|
+
const [page, setPage] = useState28(1);
|
|
7895
|
+
const [totalPages, setTotalPages] = useState28(1);
|
|
7896
|
+
const [search, setSearch] = useState28("");
|
|
7897
|
+
const [searchInput, setSearchInput] = useState28("");
|
|
7898
|
+
const [typeFilter, setTypeFilter] = useState28("");
|
|
7899
|
+
const [sortField, setSortField] = useState28("filename");
|
|
7900
|
+
const [sortOrder, setSortOrder] = useState28("asc");
|
|
7901
|
+
const [viewMode, setViewMode] = useState28("grid");
|
|
7902
|
+
const [uploading, setUploading] = useState28(false);
|
|
7903
|
+
const [currentParentId, setCurrentParentId] = useState28(null);
|
|
7904
|
+
const [crumb, setCrumb] = useState28([]);
|
|
7905
|
+
const [newFolderOpen, setNewFolderOpen] = useState28(false);
|
|
7906
|
+
const [newFolderName, setNewFolderName] = useState28("");
|
|
7907
|
+
const [editModal, setEditModal] = useState28(null);
|
|
7908
|
+
const [deleteTarget, setDeleteTarget] = useState28(null);
|
|
7909
|
+
const [editAlt, setEditAlt] = useState28("");
|
|
7910
|
+
const [editPublic, setEditPublic] = useState28(false);
|
|
7911
|
+
const [editFilename, setEditFilename] = useState28("");
|
|
7912
|
+
const [extractingId, setExtractingId] = useState28(null);
|
|
7913
|
+
const fileInputRef = useRef9(null);
|
|
7160
7914
|
const load = useCallback5(async () => {
|
|
7161
7915
|
setLoading(true);
|
|
7162
7916
|
const params = new URLSearchParams({
|
|
7163
7917
|
page: String(page),
|
|
7164
7918
|
limit: "24",
|
|
7165
|
-
sortField
|
|
7166
|
-
sortOrder
|
|
7919
|
+
sortField,
|
|
7920
|
+
sortOrder
|
|
7167
7921
|
});
|
|
7922
|
+
params.set("parentId", currentParentId === null ? "" : String(currentParentId));
|
|
7168
7923
|
if (search) params.set("search", search);
|
|
7169
7924
|
if (typeFilter) params.set("type", typeFilter);
|
|
7170
7925
|
try {
|
|
@@ -7179,11 +7934,33 @@ function MediaLibraryPage() {
|
|
|
7179
7934
|
} finally {
|
|
7180
7935
|
setLoading(false);
|
|
7181
7936
|
}
|
|
7182
|
-
}, [page, search, typeFilter]);
|
|
7937
|
+
}, [page, search, typeFilter, currentParentId, sortField, sortOrder]);
|
|
7183
7938
|
useEffect25(() => {
|
|
7184
7939
|
load();
|
|
7185
7940
|
}, [load]);
|
|
7186
7941
|
const handleSearch = () => setSearch(searchInput.trim());
|
|
7942
|
+
const goRoot = useCallback5(() => {
|
|
7943
|
+
setPage(1);
|
|
7944
|
+
setCurrentParentId(null);
|
|
7945
|
+
setCrumb([]);
|
|
7946
|
+
}, []);
|
|
7947
|
+
const goCrumb = useCallback5((index) => {
|
|
7948
|
+
setPage(1);
|
|
7949
|
+
if (index < 0) {
|
|
7950
|
+
goRoot();
|
|
7951
|
+
return;
|
|
7952
|
+
}
|
|
7953
|
+
const slice = crumb.slice(0, index + 1);
|
|
7954
|
+
setCrumb(slice);
|
|
7955
|
+
const last = slice[slice.length - 1];
|
|
7956
|
+
setCurrentParentId(last.id);
|
|
7957
|
+
}, [crumb, goRoot]);
|
|
7958
|
+
const enterFolder = (item) => {
|
|
7959
|
+
if (item.kind !== "folder") return;
|
|
7960
|
+
setPage(1);
|
|
7961
|
+
setCurrentParentId(item.id);
|
|
7962
|
+
setCrumb((c) => [...c, { id: item.id, name: item.filename }]);
|
|
7963
|
+
};
|
|
7187
7964
|
const handleUpload = async (e) => {
|
|
7188
7965
|
const file = e.target.files?.[0];
|
|
7189
7966
|
if (!file) return;
|
|
@@ -7191,6 +7968,7 @@ function MediaLibraryPage() {
|
|
|
7191
7968
|
try {
|
|
7192
7969
|
const formData = new FormData();
|
|
7193
7970
|
formData.append("file", file);
|
|
7971
|
+
if (currentParentId != null) formData.append("parentId", String(currentParentId));
|
|
7194
7972
|
const uploadRes = await fetch("/api/upload", { method: "POST", body: formData });
|
|
7195
7973
|
const uploadJson = await uploadRes.json();
|
|
7196
7974
|
if (!uploadRes.ok) throw new Error(uploadJson.error || "Upload failed");
|
|
@@ -7200,69 +7978,134 @@ function MediaLibraryPage() {
|
|
|
7200
7978
|
method: "POST",
|
|
7201
7979
|
headers: { "Content-Type": "application/json" },
|
|
7202
7980
|
body: JSON.stringify({
|
|
7981
|
+
kind: "file",
|
|
7203
7982
|
filename: file.name,
|
|
7204
7983
|
url: filePath.startsWith("http") ? filePath : filePath,
|
|
7205
7984
|
mimeType: file.type || "application/octet-stream",
|
|
7206
7985
|
size: file.size,
|
|
7207
7986
|
alt: null,
|
|
7208
|
-
isPublic: false
|
|
7987
|
+
isPublic: false,
|
|
7988
|
+
parentId: currentParentId
|
|
7209
7989
|
})
|
|
7210
7990
|
});
|
|
7211
7991
|
if (!createRes.ok) throw new Error("Failed to create media record");
|
|
7212
|
-
|
|
7992
|
+
toast4.success("File uploaded");
|
|
7213
7993
|
load();
|
|
7214
7994
|
} catch (err) {
|
|
7215
|
-
|
|
7995
|
+
toast4.error(err instanceof Error ? err.message : "Upload failed");
|
|
7216
7996
|
} finally {
|
|
7217
7997
|
setUploading(false);
|
|
7218
7998
|
e.target.value = "";
|
|
7219
7999
|
}
|
|
7220
8000
|
};
|
|
7221
|
-
const
|
|
7222
|
-
|
|
8001
|
+
const createFolder = async () => {
|
|
8002
|
+
const name = newFolderName.trim();
|
|
8003
|
+
if (!name) {
|
|
8004
|
+
toast4.error("Enter a folder name");
|
|
8005
|
+
return;
|
|
8006
|
+
}
|
|
8007
|
+
try {
|
|
8008
|
+
const res = await fetch("/api/media", {
|
|
8009
|
+
method: "POST",
|
|
8010
|
+
headers: { "Content-Type": "application/json" },
|
|
8011
|
+
body: JSON.stringify({
|
|
8012
|
+
kind: "folder",
|
|
8013
|
+
filename: name,
|
|
8014
|
+
parentId: currentParentId
|
|
8015
|
+
})
|
|
8016
|
+
});
|
|
8017
|
+
const j = await res.json().catch(() => ({}));
|
|
8018
|
+
if (!res.ok) throw new Error(j.error || "Failed to create folder");
|
|
8019
|
+
toast4.success("Folder created");
|
|
8020
|
+
setNewFolderOpen(false);
|
|
8021
|
+
setNewFolderName("");
|
|
8022
|
+
load();
|
|
8023
|
+
} catch (err) {
|
|
8024
|
+
toast4.error(err instanceof Error ? err.message : "Failed");
|
|
8025
|
+
}
|
|
8026
|
+
};
|
|
8027
|
+
const handleExtractZip = async (id) => {
|
|
8028
|
+
setExtractingId(id);
|
|
8029
|
+
try {
|
|
8030
|
+
const res = await fetch(`/api/media/extract/${id}`, { method: "POST" });
|
|
8031
|
+
const j = await res.json().catch(() => ({}));
|
|
8032
|
+
if (!res.ok) throw new Error(j.error || "Extract failed");
|
|
8033
|
+
toast4.success(
|
|
8034
|
+
`Extracted ${j.files ?? 0} file(s)` + (j.folderEntries ? `, ${j.folderEntries} folder path(s)` : "")
|
|
8035
|
+
);
|
|
8036
|
+
load();
|
|
8037
|
+
} catch (e) {
|
|
8038
|
+
toast4.error(e instanceof Error ? e.message : "Extract failed");
|
|
8039
|
+
} finally {
|
|
8040
|
+
setExtractingId(null);
|
|
8041
|
+
}
|
|
8042
|
+
};
|
|
8043
|
+
const handleDelete = async (item) => {
|
|
7223
8044
|
try {
|
|
7224
|
-
const res = await fetch(`/api/media/${id}`, { method: "DELETE" });
|
|
8045
|
+
const res = await fetch(`/api/media/${item.id}`, { method: "DELETE" });
|
|
7225
8046
|
if (!res.ok) throw new Error("Delete failed");
|
|
7226
|
-
|
|
8047
|
+
toast4.success("Deleted");
|
|
8048
|
+
setDeleteTarget(null);
|
|
7227
8049
|
load();
|
|
7228
8050
|
} catch {
|
|
7229
|
-
|
|
8051
|
+
toast4.error("Delete failed");
|
|
7230
8052
|
}
|
|
7231
8053
|
};
|
|
7232
8054
|
const handleSaveEdit = async () => {
|
|
7233
8055
|
if (!editModal) return;
|
|
7234
8056
|
try {
|
|
8057
|
+
const isFolder = editModal.kind === "folder";
|
|
8058
|
+
const body = isFolder ? { filename: editFilename.trim() || editModal.filename } : { alt: editAlt || null, isPublic: editPublic };
|
|
8059
|
+
if (isFolder && !body.filename) {
|
|
8060
|
+
toast4.error("Name required");
|
|
8061
|
+
return;
|
|
8062
|
+
}
|
|
7235
8063
|
const res = await fetch(`/api/media/${editModal.id}`, {
|
|
7236
8064
|
method: "PUT",
|
|
7237
8065
|
headers: { "Content-Type": "application/json" },
|
|
7238
|
-
body: JSON.stringify(
|
|
8066
|
+
body: JSON.stringify(body)
|
|
7239
8067
|
});
|
|
7240
8068
|
if (!res.ok) throw new Error("Update failed");
|
|
7241
|
-
|
|
8069
|
+
toast4.success("Updated");
|
|
7242
8070
|
setEditModal(null);
|
|
7243
8071
|
load();
|
|
7244
8072
|
} catch {
|
|
7245
|
-
|
|
8073
|
+
toast4.error("Update failed");
|
|
7246
8074
|
}
|
|
7247
8075
|
};
|
|
7248
8076
|
const copyUrl = (url) => {
|
|
7249
8077
|
const full = url.startsWith("http") ? url : `${typeof window !== "undefined" ? window.location.origin : ""}${url}`;
|
|
7250
8078
|
navigator.clipboard.writeText(full);
|
|
7251
|
-
|
|
8079
|
+
toast4.success("URL copied");
|
|
7252
8080
|
};
|
|
7253
8081
|
const openEdit = (item) => {
|
|
7254
8082
|
setEditModal(item);
|
|
7255
8083
|
setEditAlt(item.alt || "");
|
|
7256
8084
|
setEditPublic(item.isPublic);
|
|
8085
|
+
setEditFilename(item.filename);
|
|
7257
8086
|
};
|
|
7258
|
-
const
|
|
7259
|
-
const
|
|
8087
|
+
const isImage = (mime, kind, filename) => kind !== "folder" && getTypeCategory(mime, kind, filename) === "image";
|
|
8088
|
+
const listViewData = React17.useMemo(() => {
|
|
8089
|
+
const sorted = [...data];
|
|
8090
|
+
const byDateDesc = (a, b) => new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime();
|
|
8091
|
+
const folders = sorted.filter((x) => x.kind === "folder").sort(byDateDesc);
|
|
8092
|
+
const files = sorted.filter((x) => x.kind !== "folder").sort(byDateDesc);
|
|
8093
|
+
return [...folders, ...files];
|
|
8094
|
+
}, [data]);
|
|
7260
8095
|
return /* @__PURE__ */ jsxs44("div", { className: "min-w-0 rounded-lg bg-white shadow-md", children: [
|
|
7261
8096
|
/* @__PURE__ */ jsxs44("div", { className: "bg-gray-800 border-b border-gray-700 px-4 py-2.5 rounded-t-lg", children: [
|
|
7262
8097
|
/* @__PURE__ */ jsx53("h1", { className: "text-base font-semibold text-white", children: "Media Library" }),
|
|
7263
|
-
/* @__PURE__ */ jsx53("p", { className: "text-xs text-gray-300 mt-0.5", children: "
|
|
8098
|
+
/* @__PURE__ */ jsx53("p", { className: "text-xs text-gray-300 mt-0.5", children: "Folders and files (Google Drive\u2013style). Storage mirrors the folder tree under uploads/." })
|
|
7264
8099
|
] }),
|
|
7265
8100
|
/* @__PURE__ */ jsxs44("div", { className: "min-w-0 p-4 space-y-3", children: [
|
|
8101
|
+
/* @__PURE__ */ jsxs44("div", { className: "flex flex-wrap items-center gap-2 text-sm text-gray-700", children: [
|
|
8102
|
+
/* @__PURE__ */ jsx53("span", { className: "font-medium text-gray-600", children: "Location:" }),
|
|
8103
|
+
/* @__PURE__ */ jsx53("button", { type: "button", className: "text-blue-600 hover:underline", onClick: () => goCrumb(-1), children: "Media" }),
|
|
8104
|
+
crumb.map((c, i) => /* @__PURE__ */ jsxs44("span", { className: "flex items-center gap-1", children: [
|
|
8105
|
+
/* @__PURE__ */ jsx53("span", { className: "text-gray-400", children: "/" }),
|
|
8106
|
+
/* @__PURE__ */ jsx53("button", { type: "button", className: "text-blue-600 hover:underline", onClick: () => goCrumb(i), children: c.name })
|
|
8107
|
+
] }, `${c.id}-${i}`))
|
|
8108
|
+
] }),
|
|
7266
8109
|
/* @__PURE__ */ jsxs44("div", { className: "flex flex-wrap items-center gap-3", children: [
|
|
7267
8110
|
/* @__PURE__ */ jsx53(
|
|
7268
8111
|
"input",
|
|
@@ -7272,7 +8115,7 @@ function MediaLibraryPage() {
|
|
|
7272
8115
|
className: "hidden",
|
|
7273
8116
|
onChange: handleUpload,
|
|
7274
8117
|
disabled: uploading,
|
|
7275
|
-
accept: "image/*,video/*,audio/*,.pdf,.doc,.docx"
|
|
8118
|
+
accept: "image/*,video/*,audio/*,.pdf,.doc,.docx,.zip"
|
|
7276
8119
|
}
|
|
7277
8120
|
),
|
|
7278
8121
|
/* @__PURE__ */ jsxs44(
|
|
@@ -7288,11 +8131,15 @@ function MediaLibraryPage() {
|
|
|
7288
8131
|
]
|
|
7289
8132
|
}
|
|
7290
8133
|
),
|
|
8134
|
+
/* @__PURE__ */ jsxs44(Button, { type: "button", variant: "secondary", className: "flex items-center gap-2", onClick: () => setNewFolderOpen(true), children: [
|
|
8135
|
+
/* @__PURE__ */ jsx53(FolderPlus, { className: "h-4 w-4" }),
|
|
8136
|
+
"New folder"
|
|
8137
|
+
] }),
|
|
7291
8138
|
/* @__PURE__ */ jsxs44("div", { className: "flex items-center gap-2 flex-1 min-w-[200px]", children: [
|
|
7292
8139
|
/* @__PURE__ */ jsx53(
|
|
7293
8140
|
Input,
|
|
7294
8141
|
{
|
|
7295
|
-
placeholder: "Search by
|
|
8142
|
+
placeholder: "Search by name...",
|
|
7296
8143
|
value: searchInput,
|
|
7297
8144
|
onChange: (e) => setSearchInput(e.target.value),
|
|
7298
8145
|
onKeyDown: (e) => e.key === "Enter" && handleSearch()
|
|
@@ -7314,61 +8161,192 @@ function MediaLibraryPage() {
|
|
|
7314
8161
|
/* @__PURE__ */ jsx53("option", { value: "application", children: "Documents" })
|
|
7315
8162
|
]
|
|
7316
8163
|
}
|
|
7317
|
-
)
|
|
8164
|
+
),
|
|
8165
|
+
/* @__PURE__ */ jsxs44(
|
|
8166
|
+
"select",
|
|
8167
|
+
{
|
|
8168
|
+
className: "border rounded-md px-3 py-2 text-sm bg-white max-w-[200px]",
|
|
8169
|
+
value: `${sortField}:${sortOrder}`,
|
|
8170
|
+
onChange: (e) => {
|
|
8171
|
+
const [f, o] = e.target.value.split(":");
|
|
8172
|
+
setSortField(f);
|
|
8173
|
+
setSortOrder(o);
|
|
8174
|
+
setPage(1);
|
|
8175
|
+
},
|
|
8176
|
+
children: [
|
|
8177
|
+
/* @__PURE__ */ jsx53("option", { value: "filename:asc", children: "Name A\u2013Z" }),
|
|
8178
|
+
/* @__PURE__ */ jsx53("option", { value: "filename:desc", children: "Name Z\u2013A" }),
|
|
8179
|
+
/* @__PURE__ */ jsx53("option", { value: "createdAt:desc", children: "Newest first" }),
|
|
8180
|
+
/* @__PURE__ */ jsx53("option", { value: "createdAt:asc", children: "Oldest first" })
|
|
8181
|
+
]
|
|
8182
|
+
}
|
|
8183
|
+
),
|
|
8184
|
+
/* @__PURE__ */ jsxs44("div", { className: "inline-flex rounded-md border border-gray-300 overflow-hidden bg-white", children: [
|
|
8185
|
+
/* @__PURE__ */ jsxs44(
|
|
8186
|
+
"button",
|
|
8187
|
+
{
|
|
8188
|
+
type: "button",
|
|
8189
|
+
className: `px-2.5 py-2 text-xs inline-flex items-center gap-1 ${viewMode === "grid" ? "bg-gray-100 text-gray-900" : "text-gray-600"}`,
|
|
8190
|
+
onClick: () => setViewMode("grid"),
|
|
8191
|
+
title: "Grid view",
|
|
8192
|
+
children: [
|
|
8193
|
+
/* @__PURE__ */ jsx53(LayoutGrid, { className: "h-4 w-4" }),
|
|
8194
|
+
"Grid"
|
|
8195
|
+
]
|
|
8196
|
+
}
|
|
8197
|
+
),
|
|
8198
|
+
/* @__PURE__ */ jsxs44(
|
|
8199
|
+
"button",
|
|
8200
|
+
{
|
|
8201
|
+
type: "button",
|
|
8202
|
+
className: `px-2.5 py-2 text-xs inline-flex items-center gap-1 border-l border-gray-300 ${viewMode === "list" ? "bg-gray-100 text-gray-900" : "text-gray-600"}`,
|
|
8203
|
+
onClick: () => setViewMode("list"),
|
|
8204
|
+
title: "List view",
|
|
8205
|
+
children: [
|
|
8206
|
+
/* @__PURE__ */ jsx53(List, { className: "h-4 w-4" }),
|
|
8207
|
+
"List"
|
|
8208
|
+
]
|
|
8209
|
+
}
|
|
8210
|
+
)
|
|
8211
|
+
] })
|
|
7318
8212
|
] }),
|
|
7319
|
-
loading ? /* @__PURE__ */ jsx53("div", { className: "flex justify-center py-12", children: /* @__PURE__ */ jsx53("div", { className: "animate-spin rounded-full h-8 w-8 border-2 border-gray-300 border-t-gray-600" }) }) : data.length === 0 ? /* @__PURE__ */ jsx53("div", { className: "text-center py-12 text-gray-500", children: "
|
|
7320
|
-
|
|
7321
|
-
|
|
8213
|
+
loading ? /* @__PURE__ */ jsx53("div", { className: "flex justify-center py-12", children: /* @__PURE__ */ jsx53("div", { className: "animate-spin rounded-full h-8 w-8 border-2 border-gray-300 border-t-gray-600" }) }) : data.length === 0 ? /* @__PURE__ */ jsx53("div", { className: "text-center py-12 text-gray-500", children: "This folder is empty. Create a folder or upload a file." }) : viewMode === "grid" ? /* @__PURE__ */ jsx53("div", { className: "grid grid-cols-2 sm:grid-cols-3 md:grid-cols-4 lg:grid-cols-6 gap-4", children: data.map((item) => {
|
|
8214
|
+
const isF = item.kind === "folder";
|
|
8215
|
+
return /* @__PURE__ */ jsxs44(
|
|
7322
8216
|
"div",
|
|
7323
8217
|
{
|
|
7324
8218
|
className: "border rounded-lg overflow-hidden bg-gray-50 hover:bg-gray-100 transition-colors group",
|
|
7325
8219
|
children: [
|
|
7326
|
-
/* @__PURE__ */ jsxs44(
|
|
7327
|
-
|
|
7328
|
-
|
|
7329
|
-
|
|
7330
|
-
|
|
7331
|
-
|
|
7332
|
-
|
|
7333
|
-
|
|
7334
|
-
|
|
7335
|
-
|
|
7336
|
-
|
|
7337
|
-
|
|
7338
|
-
|
|
7339
|
-
|
|
7340
|
-
|
|
7341
|
-
|
|
7342
|
-
|
|
7343
|
-
|
|
7344
|
-
|
|
7345
|
-
|
|
7346
|
-
|
|
7347
|
-
|
|
7348
|
-
|
|
7349
|
-
|
|
7350
|
-
|
|
7351
|
-
|
|
7352
|
-
|
|
7353
|
-
|
|
7354
|
-
|
|
7355
|
-
|
|
7356
|
-
|
|
7357
|
-
|
|
7358
|
-
|
|
8220
|
+
/* @__PURE__ */ jsxs44(
|
|
8221
|
+
"button",
|
|
8222
|
+
{
|
|
8223
|
+
type: "button",
|
|
8224
|
+
className: "w-full aspect-square flex items-center justify-center bg-gray-200 relative cursor-pointer",
|
|
8225
|
+
onClick: () => isF && enterFolder(item),
|
|
8226
|
+
children: [
|
|
8227
|
+
isImage(item.mimeType, item.kind, item.filename) ? /* @__PURE__ */ jsx53(
|
|
8228
|
+
"img",
|
|
8229
|
+
{
|
|
8230
|
+
src: item.url,
|
|
8231
|
+
alt: item.alt || item.filename,
|
|
8232
|
+
className: "w-full h-full object-cover"
|
|
8233
|
+
}
|
|
8234
|
+
) : /* @__PURE__ */ jsx53(TypeIcon, { mimeType: item.mimeType, kind: item.kind, filename: item.filename }),
|
|
8235
|
+
/* @__PURE__ */ jsxs44("div", { className: "absolute inset-0 bg-black/0 group-hover:bg-black/40 transition-colors flex items-center justify-center gap-1 opacity-0 group-hover:opacity-100 flex-wrap", children: [
|
|
8236
|
+
!isF && isZipMedia(item.mimeType, item.filename) ? /* @__PURE__ */ jsx53(
|
|
8237
|
+
Button,
|
|
8238
|
+
{
|
|
8239
|
+
size: "icon",
|
|
8240
|
+
variant: "outline",
|
|
8241
|
+
className: "h-8 w-8",
|
|
8242
|
+
title: "Extract zip into this folder",
|
|
8243
|
+
disabled: extractingId === item.id,
|
|
8244
|
+
onClick: (e) => {
|
|
8245
|
+
e.stopPropagation();
|
|
8246
|
+
handleExtractZip(item.id);
|
|
8247
|
+
},
|
|
8248
|
+
children: /* @__PURE__ */ jsx53(Archive, { className: "h-3 w-3" })
|
|
8249
|
+
}
|
|
8250
|
+
) : null,
|
|
8251
|
+
!isF && item.url ? /* @__PURE__ */ jsx53(
|
|
8252
|
+
Button,
|
|
8253
|
+
{
|
|
8254
|
+
size: "icon",
|
|
8255
|
+
variant: "outline",
|
|
8256
|
+
className: "h-8 w-8",
|
|
8257
|
+
onClick: (e) => {
|
|
8258
|
+
e.stopPropagation();
|
|
8259
|
+
copyUrl(item.url);
|
|
8260
|
+
},
|
|
8261
|
+
children: /* @__PURE__ */ jsx53(Copy, { className: "h-3 w-3" })
|
|
8262
|
+
}
|
|
8263
|
+
) : null,
|
|
8264
|
+
/* @__PURE__ */ jsx53(
|
|
8265
|
+
Button,
|
|
8266
|
+
{
|
|
8267
|
+
size: "icon",
|
|
8268
|
+
variant: "outline",
|
|
8269
|
+
className: "h-8 w-8",
|
|
8270
|
+
onClick: (e) => {
|
|
8271
|
+
e.stopPropagation();
|
|
8272
|
+
openEdit(item);
|
|
8273
|
+
},
|
|
8274
|
+
children: /* @__PURE__ */ jsx53(Edit2, { className: "h-3 w-3" })
|
|
8275
|
+
}
|
|
8276
|
+
),
|
|
8277
|
+
/* @__PURE__ */ jsx53(
|
|
8278
|
+
Button,
|
|
8279
|
+
{
|
|
8280
|
+
size: "icon",
|
|
8281
|
+
variant: "outline",
|
|
8282
|
+
className: "h-8 w-8 border-red-300 text-red-600 hover:text-red-700",
|
|
8283
|
+
onClick: (e) => {
|
|
8284
|
+
e.stopPropagation();
|
|
8285
|
+
setDeleteTarget(item);
|
|
8286
|
+
},
|
|
8287
|
+
children: /* @__PURE__ */ jsx53(Trash24, { className: "h-3 w-3" })
|
|
8288
|
+
}
|
|
8289
|
+
)
|
|
8290
|
+
] })
|
|
8291
|
+
]
|
|
8292
|
+
}
|
|
8293
|
+
),
|
|
7359
8294
|
/* @__PURE__ */ jsxs44("div", { className: "p-2", children: [
|
|
7360
|
-
/* @__PURE__ */ jsx53("p", { className: "text-xs font-medium text-gray-900 truncate", title: item.filename, children: item.filename }),
|
|
8295
|
+
/* @__PURE__ */ jsx53("p", { className: "text-xs font-medium text-gray-900 truncate text-left", title: item.filename, children: item.filename }),
|
|
7361
8296
|
/* @__PURE__ */ jsxs44("div", { className: "flex items-center justify-between mt-1", children: [
|
|
7362
8297
|
/* @__PURE__ */ jsx53("span", { className: "text-xs text-gray-500", children: formatDate(item.createdAt) }),
|
|
7363
|
-
/* @__PURE__ */ jsx53("span", { className: "text-xs px-1.5 py-0.5 rounded bg-gray-200 text-gray-600", children: getTypeLabel(item.mimeType) })
|
|
8298
|
+
/* @__PURE__ */ jsx53("span", { className: "text-xs px-1.5 py-0.5 rounded bg-gray-200 text-gray-600", children: getTypeLabel(item.mimeType, item.kind, item.filename) })
|
|
7364
8299
|
] }),
|
|
7365
|
-
item.isPublic && /* @__PURE__ */ jsx53("span", { className: "text-xs text-green-600 mt-0.5 block", children: "Public" })
|
|
8300
|
+
item.isPublic && !isF && /* @__PURE__ */ jsx53("span", { className: "text-xs text-green-600 mt-0.5 block", children: "Public" }),
|
|
8301
|
+
isF && /* @__PURE__ */ jsx53(
|
|
8302
|
+
"button",
|
|
8303
|
+
{
|
|
8304
|
+
type: "button",
|
|
8305
|
+
className: "text-xs text-blue-600 mt-1 hover:underline",
|
|
8306
|
+
onClick: () => enterFolder(item),
|
|
8307
|
+
children: "Open"
|
|
8308
|
+
}
|
|
8309
|
+
)
|
|
7366
8310
|
] })
|
|
7367
8311
|
]
|
|
7368
8312
|
},
|
|
7369
8313
|
item.id
|
|
7370
|
-
)
|
|
7371
|
-
|
|
8314
|
+
);
|
|
8315
|
+
}) }) : /* @__PURE__ */ jsx53("div", { className: "overflow-x-auto rounded-md border border-gray-200 bg-white", children: /* @__PURE__ */ jsxs44("table", { className: "w-full text-sm", children: [
|
|
8316
|
+
/* @__PURE__ */ jsx53("thead", { children: /* @__PURE__ */ jsxs44("tr", { className: "border-b bg-gray-50", children: [
|
|
8317
|
+
/* @__PURE__ */ jsx53("th", { className: "p-3 text-left font-medium", children: "Name" }),
|
|
8318
|
+
/* @__PURE__ */ jsx53("th", { className: "p-3 text-left font-medium", children: "Type" }),
|
|
8319
|
+
/* @__PURE__ */ jsx53("th", { className: "p-3 text-left font-medium", children: "Created" }),
|
|
8320
|
+
/* @__PURE__ */ jsx53("th", { className: "p-3 text-left font-medium", children: "Size" }),
|
|
8321
|
+
/* @__PURE__ */ jsx53("th", { className: "p-3 text-right font-medium", children: "Actions" })
|
|
8322
|
+
] }) }),
|
|
8323
|
+
/* @__PURE__ */ jsx53("tbody", { children: listViewData.map((item) => {
|
|
8324
|
+
const isF = item.kind === "folder";
|
|
8325
|
+
return /* @__PURE__ */ jsxs44("tr", { className: "border-b border-gray-100 hover:bg-gray-50", children: [
|
|
8326
|
+
/* @__PURE__ */ jsx53("td", { className: "p-3", children: /* @__PURE__ */ jsxs44(
|
|
8327
|
+
"button",
|
|
8328
|
+
{
|
|
8329
|
+
type: "button",
|
|
8330
|
+
className: `inline-flex items-center gap-2 ${isF ? "text-blue-600 hover:underline" : "text-gray-900"}`,
|
|
8331
|
+
onClick: () => isF && enterFolder(item),
|
|
8332
|
+
children: [
|
|
8333
|
+
/* @__PURE__ */ jsx53(TypeIcon, { mimeType: item.mimeType, kind: item.kind, filename: item.filename }),
|
|
8334
|
+
/* @__PURE__ */ jsx53("span", { className: "truncate max-w-[260px]", title: item.filename, children: item.filename })
|
|
8335
|
+
]
|
|
8336
|
+
}
|
|
8337
|
+
) }),
|
|
8338
|
+
/* @__PURE__ */ jsx53("td", { className: "p-3 text-gray-600", children: getTypeLabel(item.mimeType, item.kind, item.filename) }),
|
|
8339
|
+
/* @__PURE__ */ jsx53("td", { className: "p-3 text-gray-600", children: formatDate(item.createdAt) }),
|
|
8340
|
+
/* @__PURE__ */ jsx53("td", { className: "p-3 text-gray-600", children: isF ? "\u2014" : `${Math.round((item.size || 0) / 1024)} KB` }),
|
|
8341
|
+
/* @__PURE__ */ jsx53("td", { className: "p-3", children: /* @__PURE__ */ jsxs44("div", { className: "flex items-center justify-end gap-1", children: [
|
|
8342
|
+
!isF && isZipMedia(item.mimeType, item.filename) && /* @__PURE__ */ jsx53(Button, { size: "icon", variant: "outline", className: "h-8 w-8", onClick: () => handleExtractZip(item.id), disabled: extractingId === item.id, children: /* @__PURE__ */ jsx53(Archive, { className: "h-3 w-3" }) }),
|
|
8343
|
+
!isF && item.url && /* @__PURE__ */ jsx53(Button, { size: "icon", variant: "outline", className: "h-8 w-8", onClick: () => copyUrl(item.url), children: /* @__PURE__ */ jsx53(Copy, { className: "h-3 w-3" }) }),
|
|
8344
|
+
/* @__PURE__ */ jsx53(Button, { size: "icon", variant: "outline", className: "h-8 w-8", onClick: () => openEdit(item), children: /* @__PURE__ */ jsx53(Edit2, { className: "h-3 w-3" }) }),
|
|
8345
|
+
/* @__PURE__ */ jsx53(Button, { size: "icon", variant: "outline", className: "h-8 w-8 border-red-300 text-red-600 hover:text-red-700", onClick: () => setDeleteTarget(item), children: /* @__PURE__ */ jsx53(Trash24, { className: "h-3 w-3" }) })
|
|
8346
|
+
] }) })
|
|
8347
|
+
] }, item.id);
|
|
8348
|
+
}) })
|
|
8349
|
+
] }) }),
|
|
7372
8350
|
totalPages > 1 && /* @__PURE__ */ jsx53(Pagination, { className: "mt-6", children: /* @__PURE__ */ jsxs44(PaginationContent, { children: [
|
|
7373
8351
|
/* @__PURE__ */ jsx53(PaginationItem, { children: /* @__PURE__ */ jsx53(
|
|
7374
8352
|
PaginationPrevious,
|
|
@@ -7390,9 +8368,28 @@ function MediaLibraryPage() {
|
|
|
7390
8368
|
) })
|
|
7391
8369
|
] }) })
|
|
7392
8370
|
] }),
|
|
8371
|
+
/* @__PURE__ */ jsx53(Dialog, { open: newFolderOpen, onOpenChange: setNewFolderOpen, children: /* @__PURE__ */ jsxs44(DialogContent, { children: [
|
|
8372
|
+
/* @__PURE__ */ jsx53(DialogHeader, { children: /* @__PURE__ */ jsx53(DialogTitle, { children: "New folder" }) }),
|
|
8373
|
+
/* @__PURE__ */ jsx53(
|
|
8374
|
+
Input,
|
|
8375
|
+
{
|
|
8376
|
+
placeholder: "Folder name",
|
|
8377
|
+
value: newFolderName,
|
|
8378
|
+
onChange: (e) => setNewFolderName(e.target.value),
|
|
8379
|
+
onKeyDown: (e) => e.key === "Enter" && createFolder()
|
|
8380
|
+
}
|
|
8381
|
+
),
|
|
8382
|
+
/* @__PURE__ */ jsxs44(DialogFooter, { children: [
|
|
8383
|
+
/* @__PURE__ */ jsx53(Button, { variant: "outline", onClick: () => setNewFolderOpen(false), children: "Cancel" }),
|
|
8384
|
+
/* @__PURE__ */ jsx53(Button, { onClick: createFolder, children: "Create" })
|
|
8385
|
+
] })
|
|
8386
|
+
] }) }),
|
|
7393
8387
|
/* @__PURE__ */ jsx53(Dialog, { open: !!editModal, onOpenChange: (open) => !open && setEditModal(null), children: /* @__PURE__ */ jsxs44(DialogContent, { children: [
|
|
7394
|
-
/* @__PURE__ */ jsx53(DialogHeader, { children: /* @__PURE__ */ jsx53(DialogTitle, { children: "Edit media" }) }),
|
|
7395
|
-
editModal && /* @__PURE__ */
|
|
8388
|
+
/* @__PURE__ */ jsx53(DialogHeader, { children: /* @__PURE__ */ jsx53(DialogTitle, { children: editModal?.kind === "folder" ? "Rename folder" : "Edit media" }) }),
|
|
8389
|
+
editModal && /* @__PURE__ */ jsx53("div", { className: "space-y-4 py-2", children: editModal.kind === "folder" ? /* @__PURE__ */ jsxs44("div", { children: [
|
|
8390
|
+
/* @__PURE__ */ jsx53("label", { className: "text-sm font-medium", children: "Name" }),
|
|
8391
|
+
/* @__PURE__ */ jsx53(Input, { value: editFilename, onChange: (e) => setEditFilename(e.target.value), className: "mt-1" })
|
|
8392
|
+
] }) : /* @__PURE__ */ jsxs44(Fragment12, { children: [
|
|
7396
8393
|
/* @__PURE__ */ jsxs44("div", { children: [
|
|
7397
8394
|
/* @__PURE__ */ jsx53("label", { className: "text-sm font-medium", children: "Alt text" }),
|
|
7398
8395
|
/* @__PURE__ */ jsx53(
|
|
@@ -7417,20 +8414,37 @@ function MediaLibraryPage() {
|
|
|
7417
8414
|
),
|
|
7418
8415
|
/* @__PURE__ */ jsx53("label", { htmlFor: "edit-public", className: "text-sm", children: "Public (visible on site)" })
|
|
7419
8416
|
] })
|
|
7420
|
-
] }),
|
|
8417
|
+
] }) }),
|
|
7421
8418
|
/* @__PURE__ */ jsxs44(DialogFooter, { children: [
|
|
7422
8419
|
/* @__PURE__ */ jsx53(Button, { variant: "outline", onClick: () => setEditModal(null), children: "Cancel" }),
|
|
7423
8420
|
/* @__PURE__ */ jsx53(Button, { onClick: handleSaveEdit, children: "Save" })
|
|
7424
8421
|
] })
|
|
8422
|
+
] }) }),
|
|
8423
|
+
/* @__PURE__ */ jsx53(Dialog, { open: !!deleteTarget, onOpenChange: (open) => !open && setDeleteTarget(null), children: /* @__PURE__ */ jsxs44(DialogContent, { children: [
|
|
8424
|
+
/* @__PURE__ */ jsx53(DialogHeader, { children: /* @__PURE__ */ jsx53(DialogTitle, { children: "Confirm Delete" }) }),
|
|
8425
|
+
/* @__PURE__ */ jsx53("p", { className: "text-sm text-gray-600", children: deleteTarget?.kind === "folder" ? "Delete this folder and everything inside it?" : "Delete this file?" }),
|
|
8426
|
+
/* @__PURE__ */ jsxs44(DialogFooter, { children: [
|
|
8427
|
+
/* @__PURE__ */ jsx53(Button, { variant: "outline", onClick: () => setDeleteTarget(null), children: "Cancel" }),
|
|
8428
|
+
/* @__PURE__ */ jsx53(
|
|
8429
|
+
Button,
|
|
8430
|
+
{
|
|
8431
|
+
variant: "destructive",
|
|
8432
|
+
onClick: () => {
|
|
8433
|
+
if (deleteTarget) handleDelete(deleteTarget);
|
|
8434
|
+
},
|
|
8435
|
+
children: "Delete"
|
|
8436
|
+
}
|
|
8437
|
+
)
|
|
8438
|
+
] })
|
|
7425
8439
|
] }) })
|
|
7426
8440
|
] });
|
|
7427
8441
|
}
|
|
7428
8442
|
|
|
7429
8443
|
// src/admin/pages/PageBuilderPage.tsx
|
|
7430
|
-
import { useState as
|
|
8444
|
+
import { useState as useState29, useEffect as useEffect26, useContext as useContext5, useRef as useRef10 } from "react";
|
|
7431
8445
|
import { Editor, Frame, Element, useEditor, useNode } from "@craftjs/core";
|
|
7432
8446
|
import { Save as Save4, X as X17, ChevronDown as ChevronDown5, ChevronRight as ChevronRight4, LayoutDashboard as LayoutDashboard3, Layers as Layers2, Box, SlidersHorizontal } from "lucide-react";
|
|
7433
|
-
import { useRouter as
|
|
8447
|
+
import { useRouter as useRouter11 } from "next/navigation";
|
|
7434
8448
|
|
|
7435
8449
|
// src/theme/registry.ts
|
|
7436
8450
|
function buildResolver(theme) {
|
|
@@ -7456,7 +8470,7 @@ function getCatalog(theme) {
|
|
|
7456
8470
|
// src/admin/pages/PageBuilderPage.tsx
|
|
7457
8471
|
import * as LucideIcons from "lucide-react";
|
|
7458
8472
|
import React18 from "react";
|
|
7459
|
-
import { Fragment as
|
|
8473
|
+
import { Fragment as Fragment13, jsx as jsx54, jsxs as jsxs45 } from "react/jsx-runtime";
|
|
7460
8474
|
function createSelectable(Comp) {
|
|
7461
8475
|
function SelectableWrapper(props) {
|
|
7462
8476
|
const { id, connectors, displayName, isHovered } = useNode((node) => ({
|
|
@@ -7500,7 +8514,7 @@ function DraggableCatalogItem({
|
|
|
7500
8514
|
Icon: Icon2,
|
|
7501
8515
|
description
|
|
7502
8516
|
}) {
|
|
7503
|
-
const elRef =
|
|
8517
|
+
const elRef = useRef10(null);
|
|
7504
8518
|
useEffect26(() => {
|
|
7505
8519
|
if (!elRef.current) return;
|
|
7506
8520
|
if (meta.canContainChildren) {
|
|
@@ -7528,7 +8542,7 @@ function DraggableCatalogItem({
|
|
|
7528
8542
|
function ComponentPickerContent({ theme, resolver }) {
|
|
7529
8543
|
const { connectors } = useEditor();
|
|
7530
8544
|
const catalog = getCatalog(theme);
|
|
7531
|
-
const [collapsed, setCollapsed] =
|
|
8545
|
+
const [collapsed, setCollapsed] = useState29({});
|
|
7532
8546
|
const toggleCategory = (cat) => {
|
|
7533
8547
|
setCollapsed((prev) => ({ ...prev, [cat]: !prev[cat] }));
|
|
7534
8548
|
};
|
|
@@ -7733,7 +8747,7 @@ function LayersPanelContent() {
|
|
|
7733
8747
|
nodes: state.nodes,
|
|
7734
8748
|
selectedSet: state.events.selected
|
|
7735
8749
|
}));
|
|
7736
|
-
const [expanded, setExpanded] =
|
|
8750
|
+
const [expanded, setExpanded] = useState29({});
|
|
7737
8751
|
const nodeMap = nodes || {};
|
|
7738
8752
|
const rootId = (() => {
|
|
7739
8753
|
const ids = Object.keys(nodeMap);
|
|
@@ -7855,10 +8869,10 @@ function CollapsibleSection({
|
|
|
7855
8869
|
] });
|
|
7856
8870
|
}
|
|
7857
8871
|
function RightSidebar({ theme, resolver, activeTab, setActiveTab, seoProps }) {
|
|
7858
|
-
const [componentsOpen, setComponentsOpen] =
|
|
7859
|
-
const [propertiesOpen, setPropertiesOpen] =
|
|
7860
|
-
const [layoutOpen, setLayoutOpen] =
|
|
7861
|
-
const [layersOpen, setLayersOpen] =
|
|
8872
|
+
const [componentsOpen, setComponentsOpen] = useState29(true);
|
|
8873
|
+
const [propertiesOpen, setPropertiesOpen] = useState29(true);
|
|
8874
|
+
const [layoutOpen, setLayoutOpen] = useState29(true);
|
|
8875
|
+
const [layersOpen, setLayersOpen] = useState29(true);
|
|
7862
8876
|
return /* @__PURE__ */ jsxs45("div", { className: "flex flex-col flex-1 overflow-hidden", children: [
|
|
7863
8877
|
/* @__PURE__ */ jsx54("div", { className: "flex border-b flex-shrink-0", children: ["designer", "seo"].map((tab) => /* @__PURE__ */ jsx54(
|
|
7864
8878
|
"button",
|
|
@@ -7870,7 +8884,7 @@ function RightSidebar({ theme, resolver, activeTab, setActiveTab, seoProps }) {
|
|
|
7870
8884
|
tab
|
|
7871
8885
|
)) }),
|
|
7872
8886
|
/* @__PURE__ */ jsxs45("div", { className: "flex-1 overflow-y-auto flex flex-col min-h-0", children: [
|
|
7873
|
-
activeTab === "designer" && /* @__PURE__ */ jsxs45(
|
|
8887
|
+
activeTab === "designer" && /* @__PURE__ */ jsxs45(Fragment13, { children: [
|
|
7874
8888
|
/* @__PURE__ */ jsx54(
|
|
7875
8889
|
CollapsibleSection,
|
|
7876
8890
|
{
|
|
@@ -7926,7 +8940,7 @@ function SaveButton({
|
|
|
7926
8940
|
className
|
|
7927
8941
|
}) {
|
|
7928
8942
|
const { query } = useEditor();
|
|
7929
|
-
const [saving, setSaving] =
|
|
8943
|
+
const [saving, setSaving] = useState29(false);
|
|
7930
8944
|
const handleSave = async () => {
|
|
7931
8945
|
setSaving(true);
|
|
7932
8946
|
try {
|
|
@@ -7998,21 +9012,21 @@ function SaveButton({
|
|
|
7998
9012
|
);
|
|
7999
9013
|
}
|
|
8000
9014
|
function PageBuilderPage({ pageId }) {
|
|
8001
|
-
const { theme } =
|
|
8002
|
-
const router =
|
|
8003
|
-
const [title, setTitle] =
|
|
8004
|
-
const [slug, setSlug] =
|
|
8005
|
-
const [published, setPublished] =
|
|
8006
|
-
const [initialContent, setInitialContent] =
|
|
8007
|
-
const [loading, setLoading] =
|
|
8008
|
-
const [rightTab, setRightTab] =
|
|
8009
|
-
const [seoTitle, setSeoTitle] =
|
|
8010
|
-
const [seoDescription, setSeoDescription] =
|
|
8011
|
-
const [seoKeywords, setSeoKeywords] =
|
|
8012
|
-
const [seoOgTitle, setSeoOgTitle] =
|
|
8013
|
-
const [seoOgDescription, setSeoOgDescription] =
|
|
8014
|
-
const [seoOgImage, setSeoOgImage] =
|
|
8015
|
-
const [pageSeoId, setPageSeoId] =
|
|
9015
|
+
const { theme } = useContext5(AdminConfigContext);
|
|
9016
|
+
const router = useRouter11();
|
|
9017
|
+
const [title, setTitle] = useState29("");
|
|
9018
|
+
const [slug, setSlug] = useState29("");
|
|
9019
|
+
const [published, setPublished] = useState29(false);
|
|
9020
|
+
const [initialContent, setInitialContent] = useState29(null);
|
|
9021
|
+
const [loading, setLoading] = useState29(!!pageId);
|
|
9022
|
+
const [rightTab, setRightTab] = useState29("designer");
|
|
9023
|
+
const [seoTitle, setSeoTitle] = useState29("");
|
|
9024
|
+
const [seoDescription, setSeoDescription] = useState29("");
|
|
9025
|
+
const [seoKeywords, setSeoKeywords] = useState29("");
|
|
9026
|
+
const [seoOgTitle, setSeoOgTitle] = useState29("");
|
|
9027
|
+
const [seoOgDescription, setSeoOgDescription] = useState29("");
|
|
9028
|
+
const [seoOgImage, setSeoOgImage] = useState29("");
|
|
9029
|
+
const [pageSeoId, setPageSeoId] = useState29(null);
|
|
8016
9030
|
useEffect26(() => {
|
|
8017
9031
|
if (!pageId) {
|
|
8018
9032
|
setInitialContent(null);
|
|
@@ -8087,19 +9101,49 @@ function PageBuilderPage({ pageId }) {
|
|
|
8087
9101
|
onSaved: (id) => {
|
|
8088
9102
|
if (!pageId) router.replace(`/admin/pages/${id}`);
|
|
8089
9103
|
},
|
|
8090
|
-
className: "
|
|
9104
|
+
className: "md:hidden h-8 w-8 p-0 bg-white text-gray-800 hover:bg-gray-100 border-0",
|
|
9105
|
+
children: [
|
|
9106
|
+
/* @__PURE__ */ jsx54(Save4, { className: "h-4 w-4" }),
|
|
9107
|
+
/* @__PURE__ */ jsx54("span", { className: "sr-only", children: "Save" })
|
|
9108
|
+
]
|
|
9109
|
+
}
|
|
9110
|
+
),
|
|
9111
|
+
/* @__PURE__ */ jsxs45(
|
|
9112
|
+
SaveButton,
|
|
9113
|
+
{
|
|
9114
|
+
pageId,
|
|
9115
|
+
existingSeoId: pageSeoId,
|
|
9116
|
+
onSeoIdChange: setPageSeoId,
|
|
9117
|
+
pageData: { title, slug, published, seoTitle, seoDescription, seoKeywords, seoOgTitle, seoOgDescription, seoOgImage },
|
|
9118
|
+
onSaved: (id) => {
|
|
9119
|
+
if (!pageId) router.replace(`/admin/pages/${id}`);
|
|
9120
|
+
},
|
|
9121
|
+
className: "hidden md:inline-flex items-center bg-white text-gray-800 hover:bg-gray-100 border-0 text-xs",
|
|
8091
9122
|
children: [
|
|
8092
9123
|
/* @__PURE__ */ jsx54(Save4, { className: "h-4 w-4 mr-1" }),
|
|
8093
9124
|
" Save"
|
|
8094
9125
|
]
|
|
8095
9126
|
}
|
|
8096
9127
|
),
|
|
9128
|
+
/* @__PURE__ */ jsxs45(
|
|
9129
|
+
Button,
|
|
9130
|
+
{
|
|
9131
|
+
variant: "outline",
|
|
9132
|
+
size: "icon",
|
|
9133
|
+
className: "md:hidden h-8 w-8 bg-white text-gray-800 hover:bg-gray-100 border-0",
|
|
9134
|
+
onClick: () => router.push("/admin/pages"),
|
|
9135
|
+
children: [
|
|
9136
|
+
/* @__PURE__ */ jsx54(X17, { className: "h-4 w-4" }),
|
|
9137
|
+
/* @__PURE__ */ jsx54("span", { className: "sr-only", children: "Close" })
|
|
9138
|
+
]
|
|
9139
|
+
}
|
|
9140
|
+
),
|
|
8097
9141
|
/* @__PURE__ */ jsxs45(
|
|
8098
9142
|
Button,
|
|
8099
9143
|
{
|
|
8100
9144
|
variant: "outline",
|
|
8101
9145
|
size: "sm",
|
|
8102
|
-
className: "flex items-center bg-white text-gray-800 hover:bg-gray-100 border-0 text-xs",
|
|
9146
|
+
className: "hidden md:inline-flex items-center bg-white text-gray-800 hover:bg-gray-100 border-0 text-xs",
|
|
8103
9147
|
onClick: () => router.push("/admin/pages"),
|
|
8104
9148
|
children: [
|
|
8105
9149
|
/* @__PURE__ */ jsx54(X17, { className: "h-4 w-4 mr-1" }),
|
|
@@ -8160,7 +9204,7 @@ function PageBuilderPage({ pageId }) {
|
|
|
8160
9204
|
}
|
|
8161
9205
|
|
|
8162
9206
|
// src/admin/pages/PluginsPage.tsx
|
|
8163
|
-
import { useContext as
|
|
9207
|
+
import { useContext as useContext6, useState as useState30, useEffect as useEffect27 } from "react";
|
|
8164
9208
|
import { HardDrive, Mail, CreditCard as CreditCard2, MessageCircle, BarChart3 as BarChart32, Building2 as Building22, Puzzle as Puzzle2, CheckCircle2 as CheckCircle22, XCircle, Save as Save5, X as X18, Plus as Plus8, Smartphone } from "lucide-react";
|
|
8165
9209
|
|
|
8166
9210
|
// src/lib/email-recipients.ts
|
|
@@ -8185,7 +9229,7 @@ function serializeEmailRecipients(emails) {
|
|
|
8185
9229
|
// src/components/ui/checkbox.tsx
|
|
8186
9230
|
import * as React19 from "react";
|
|
8187
9231
|
import * as CheckboxPrimitive from "@radix-ui/react-checkbox";
|
|
8188
|
-
import { Check as
|
|
9232
|
+
import { Check as Check7 } from "lucide-react";
|
|
8189
9233
|
import { jsx as jsx55 } from "react/jsx-runtime";
|
|
8190
9234
|
var Checkbox = React19.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx55(
|
|
8191
9235
|
CheckboxPrimitive.Root,
|
|
@@ -8200,7 +9244,7 @@ var Checkbox = React19.forwardRef(({ className, ...props }, ref) => /* @__PURE__
|
|
|
8200
9244
|
CheckboxPrimitive.Indicator,
|
|
8201
9245
|
{
|
|
8202
9246
|
className: cn("flex items-center justify-center text-current"),
|
|
8203
|
-
children: /* @__PURE__ */ jsx55(
|
|
9247
|
+
children: /* @__PURE__ */ jsx55(Check7, { className: "h-4 w-4" })
|
|
8204
9248
|
}
|
|
8205
9249
|
)
|
|
8206
9250
|
}
|
|
@@ -8208,8 +9252,8 @@ var Checkbox = React19.forwardRef(({ className, ...props }, ref) => /* @__PURE__
|
|
|
8208
9252
|
Checkbox.displayName = CheckboxPrimitive.Root.displayName;
|
|
8209
9253
|
|
|
8210
9254
|
// src/admin/pages/PluginsPage.tsx
|
|
8211
|
-
import { toast as
|
|
8212
|
-
import { Fragment as
|
|
9255
|
+
import { toast as toast5 } from "sonner";
|
|
9256
|
+
import { Fragment as Fragment14, jsx as jsx56, jsxs as jsxs46 } from "react/jsx-runtime";
|
|
8213
9257
|
function normalizeChatMode(raw) {
|
|
8214
9258
|
if (raw === "external" || raw === "llm") return raw;
|
|
8215
9259
|
return "whatsapp";
|
|
@@ -8274,7 +9318,7 @@ function EmailRecipientTags({
|
|
|
8274
9318
|
onChange,
|
|
8275
9319
|
placeholder
|
|
8276
9320
|
}) {
|
|
8277
|
-
const [draft, setDraft] =
|
|
9321
|
+
const [draft, setDraft] = useState30("");
|
|
8278
9322
|
const commitDraft = () => {
|
|
8279
9323
|
const parts = splitInputToEmails(draft);
|
|
8280
9324
|
if (!parts.length) return;
|
|
@@ -8350,35 +9394,35 @@ function PluginSettingsPanel({
|
|
|
8350
9394
|
const isEmail = settingsGroup === "email";
|
|
8351
9395
|
const isErp = settingsGroup === "erp";
|
|
8352
9396
|
const isSms = settingsGroup === "sms";
|
|
8353
|
-
const [enabled, setEnabled] =
|
|
8354
|
-
const [botName, setBotName] =
|
|
8355
|
-
const [icon, setIcon] =
|
|
8356
|
-
const [iconImageUrl, setIconImageUrl] =
|
|
8357
|
-
const [iconBackgroundColor, setIconBackgroundColor] =
|
|
8358
|
-
const [headerColor, setHeaderColor] =
|
|
8359
|
-
const [salesTeamEmails, setSalesTeamEmails] =
|
|
8360
|
-
const [fulfilmentTeamEmails, setFulfilmentTeamEmails] =
|
|
8361
|
-
const [crmEmails, setCrmEmails] =
|
|
8362
|
-
const [logoUrl, setLogoUrl] =
|
|
8363
|
-
const [companyName, setCompanyName] =
|
|
8364
|
-
const [supportEmail, setSupportEmail] =
|
|
8365
|
-
const [supportPhone, setSupportPhone] =
|
|
8366
|
-
const [followUsTitle, setFollowUsTitle] =
|
|
8367
|
-
const [socialLinkRows, setSocialLinkRows] =
|
|
8368
|
-
const [footerDisclaimer, setFooterDisclaimer] =
|
|
8369
|
-
const [chatMode, setChatMode] =
|
|
8370
|
-
const [whatsappPhone, setWhatsappPhone] =
|
|
8371
|
-
const [externalChatSnippet, setExternalChatSnippet] =
|
|
8372
|
-
const [erpPipelineName, setErpPipelineName] =
|
|
8373
|
-
const [erpPipelineStageName, setErpPipelineStageName] =
|
|
8374
|
-
const [erpFormsCatalog, setErpFormsCatalog] =
|
|
8375
|
-
const [erpOpportunityFormIds, setErpOpportunityFormIds] =
|
|
8376
|
-
const [erpOpportunityIdsKeyPresent, setErpOpportunityIdsKeyPresent] =
|
|
8377
|
-
const [smsProviderChoice, setSmsProviderChoice] =
|
|
8378
|
-
const [msg91ApiMode, setMsg91ApiMode] =
|
|
8379
|
-
const [smsTplItems, setSmsTplItems] =
|
|
8380
|
-
const [loading, setLoading] =
|
|
8381
|
-
const [saving, setSaving] =
|
|
9397
|
+
const [enabled, setEnabled] = useState30(true);
|
|
9398
|
+
const [botName, setBotName] = useState30("");
|
|
9399
|
+
const [icon, setIcon] = useState30("");
|
|
9400
|
+
const [iconImageUrl, setIconImageUrl] = useState30("");
|
|
9401
|
+
const [iconBackgroundColor, setIconBackgroundColor] = useState30("#6366f1");
|
|
9402
|
+
const [headerColor, setHeaderColor] = useState30("#6366f1");
|
|
9403
|
+
const [salesTeamEmails, setSalesTeamEmails] = useState30([]);
|
|
9404
|
+
const [fulfilmentTeamEmails, setFulfilmentTeamEmails] = useState30([]);
|
|
9405
|
+
const [crmEmails, setCrmEmails] = useState30([]);
|
|
9406
|
+
const [logoUrl, setLogoUrl] = useState30("");
|
|
9407
|
+
const [companyName, setCompanyName] = useState30("");
|
|
9408
|
+
const [supportEmail, setSupportEmail] = useState30("");
|
|
9409
|
+
const [supportPhone, setSupportPhone] = useState30("");
|
|
9410
|
+
const [followUsTitle, setFollowUsTitle] = useState30("Follow Us");
|
|
9411
|
+
const [socialLinkRows, setSocialLinkRows] = useState30([{ ...EMPTY_SOCIAL_ROW }]);
|
|
9412
|
+
const [footerDisclaimer, setFooterDisclaimer] = useState30("");
|
|
9413
|
+
const [chatMode, setChatMode] = useState30("whatsapp");
|
|
9414
|
+
const [whatsappPhone, setWhatsappPhone] = useState30("");
|
|
9415
|
+
const [externalChatSnippet, setExternalChatSnippet] = useState30("");
|
|
9416
|
+
const [erpPipelineName, setErpPipelineName] = useState30("");
|
|
9417
|
+
const [erpPipelineStageName, setErpPipelineStageName] = useState30("");
|
|
9418
|
+
const [erpFormsCatalog, setErpFormsCatalog] = useState30([]);
|
|
9419
|
+
const [erpOpportunityFormIds, setErpOpportunityFormIds] = useState30([]);
|
|
9420
|
+
const [erpOpportunityIdsKeyPresent, setErpOpportunityIdsKeyPresent] = useState30(false);
|
|
9421
|
+
const [smsProviderChoice, setSmsProviderChoice] = useState30("auto");
|
|
9422
|
+
const [msg91ApiMode, setMsg91ApiMode] = useState30("auto");
|
|
9423
|
+
const [smsTplItems, setSmsTplItems] = useState30([]);
|
|
9424
|
+
const [loading, setLoading] = useState30(true);
|
|
9425
|
+
const [saving, setSaving] = useState30(false);
|
|
8382
9426
|
useEffect27(() => {
|
|
8383
9427
|
setLoading(true);
|
|
8384
9428
|
fetch(`/api/settings/${settingsGroup}`).then((r) => r.ok ? r.json() : {}).then(async (data) => {
|
|
@@ -8520,10 +9564,10 @@ function PluginSettingsPanel({
|
|
|
8520
9564
|
});
|
|
8521
9565
|
if (!res2.ok) throw new Error();
|
|
8522
9566
|
}
|
|
8523
|
-
|
|
9567
|
+
toast5.success("Settings saved");
|
|
8524
9568
|
onSaved?.();
|
|
8525
9569
|
} catch {
|
|
8526
|
-
|
|
9570
|
+
toast5.error("Failed to save");
|
|
8527
9571
|
} finally {
|
|
8528
9572
|
setSaving(false);
|
|
8529
9573
|
}
|
|
@@ -8968,7 +10012,7 @@ function PluginSettingsPanel({
|
|
|
8968
10012
|
),
|
|
8969
10013
|
/* @__PURE__ */ jsx56("p", { className: "text-xs text-gray-500 dark:text-gray-400", children: "Only paste code from sources you trust." })
|
|
8970
10014
|
] }),
|
|
8971
|
-
chatMode === "llm" && /* @__PURE__ */ jsxs46(
|
|
10015
|
+
chatMode === "llm" && /* @__PURE__ */ jsxs46(Fragment14, { children: [
|
|
8972
10016
|
/* @__PURE__ */ jsxs46("div", { className: "space-y-1", children: [
|
|
8973
10017
|
/* @__PURE__ */ jsx56(Label3, { htmlFor: `${settingsGroup}-botName`, className: "text-sm", children: "Name" }),
|
|
8974
10018
|
/* @__PURE__ */ jsx56(
|
|
@@ -9139,9 +10183,9 @@ function PluginListItem({
|
|
|
9139
10183
|
);
|
|
9140
10184
|
}
|
|
9141
10185
|
function PluginsPage() {
|
|
9142
|
-
const { pluginDescriptors = [] } =
|
|
9143
|
-
const [selectedName, setSelectedName] =
|
|
9144
|
-
const [enabledMap, setEnabledMap] =
|
|
10186
|
+
const { pluginDescriptors = [] } = useContext6(AdminConfigContext);
|
|
10187
|
+
const [selectedName, setSelectedName] = useState30(null);
|
|
10188
|
+
const [enabledMap, setEnabledMap] = useState30({});
|
|
9145
10189
|
useEffect27(() => {
|
|
9146
10190
|
pluginDescriptors.forEach((p) => {
|
|
9147
10191
|
if (!p.settingsGroup) return;
|
|
@@ -9182,7 +10226,7 @@ function PluginsPage() {
|
|
|
9182
10226
|
/* @__PURE__ */ jsx56("div", { className: "min-w-0 flex-1", children: !selectedName ? /* @__PURE__ */ jsxs46("div", { className: "flex flex-col items-center justify-center py-12 text-center", children: [
|
|
9183
10227
|
/* @__PURE__ */ jsx56(Puzzle2, { className: "h-10 w-10 text-gray-300 dark:text-gray-600" }),
|
|
9184
10228
|
/* @__PURE__ */ jsx56("p", { className: "mt-3 text-sm text-gray-500 dark:text-gray-400", children: "Select a plugin to view or edit its configuration." })
|
|
9185
|
-
] }) : /* @__PURE__ */ jsx56("div", { className: "rounded-lg border border-gray-200 bg-gray-50/50 p-5 dark:border-gray-700 dark:bg-gray-800/50", children: selectedDescriptor?.settingsGroup ? /* @__PURE__ */ jsxs46(
|
|
10229
|
+
] }) : /* @__PURE__ */ jsx56("div", { className: "rounded-lg border border-gray-200 bg-gray-50/50 p-5 dark:border-gray-700 dark:bg-gray-800/50", children: selectedDescriptor?.settingsGroup ? /* @__PURE__ */ jsxs46(Fragment14, { children: [
|
|
9186
10230
|
/* @__PURE__ */ jsxs46("h2", { className: "text-sm font-medium text-gray-700 dark:text-gray-300 mb-4", children: [
|
|
9187
10231
|
selectedDescriptor.label || selectedDescriptor.name,
|
|
9188
10232
|
" \u2014 Configuration"
|
|
@@ -9203,9 +10247,9 @@ function PluginsPage() {
|
|
|
9203
10247
|
}
|
|
9204
10248
|
|
|
9205
10249
|
// src/admin/pages/BrandEditPage.tsx
|
|
9206
|
-
import { useState as
|
|
9207
|
-
import { useRouter as
|
|
9208
|
-
import { AlertCircle as AlertCircle4 } from "lucide-react";
|
|
10250
|
+
import { useState as useState31, useEffect as useEffect28 } from "react";
|
|
10251
|
+
import { useRouter as useRouter12 } from "next/navigation";
|
|
10252
|
+
import { AlertCircle as AlertCircle4, Save as Save6, Power } from "lucide-react";
|
|
9209
10253
|
|
|
9210
10254
|
// src/components/Admin/SeoSection.tsx
|
|
9211
10255
|
import { jsx as jsx57, jsxs as jsxs47 } from "react/jsx-runtime";
|
|
@@ -9296,22 +10340,22 @@ async function fetchSeo(seoId) {
|
|
|
9296
10340
|
}
|
|
9297
10341
|
|
|
9298
10342
|
// src/admin/pages/BrandEditPage.tsx
|
|
9299
|
-
import { Fragment as
|
|
10343
|
+
import { Fragment as Fragment15, jsx as jsx58, jsxs as jsxs48 } from "react/jsx-runtime";
|
|
9300
10344
|
var isCreate = (id) => id === "create";
|
|
9301
10345
|
function BrandEditPage({ brandId }) {
|
|
9302
|
-
const router =
|
|
10346
|
+
const router = useRouter12();
|
|
9303
10347
|
const create = isCreate(brandId);
|
|
9304
|
-
const [loading, setLoading] =
|
|
9305
|
-
const [saving, setSaving] =
|
|
9306
|
-
const [errors, setErrors] =
|
|
9307
|
-
const [name, setName] =
|
|
9308
|
-
const [slug, setSlug] =
|
|
9309
|
-
const [description, setDescription] =
|
|
9310
|
-
const [logo, setLogo] =
|
|
9311
|
-
const [active, setActive] =
|
|
9312
|
-
const [sortOrder, setSortOrder] =
|
|
9313
|
-
const [seoId, setSeoId] =
|
|
9314
|
-
const [seo, setSeo] =
|
|
10348
|
+
const [loading, setLoading] = useState31(!create);
|
|
10349
|
+
const [saving, setSaving] = useState31(false);
|
|
10350
|
+
const [errors, setErrors] = useState31([]);
|
|
10351
|
+
const [name, setName] = useState31("");
|
|
10352
|
+
const [slug, setSlug] = useState31("");
|
|
10353
|
+
const [description, setDescription] = useState31("");
|
|
10354
|
+
const [logo, setLogo] = useState31("");
|
|
10355
|
+
const [active, setActive] = useState31(true);
|
|
10356
|
+
const [sortOrder, setSortOrder] = useState31(0);
|
|
10357
|
+
const [seoId, setSeoId] = useState31(null);
|
|
10358
|
+
const [seo, setSeo] = useState31({ seoTitle: "", seoDescription: "", seoKeywords: "", seoOgTitle: "", seoOgDescription: "", seoOgImage: "" });
|
|
9315
10359
|
useEffect28(() => {
|
|
9316
10360
|
if (create) return;
|
|
9317
10361
|
let cancelled = false;
|
|
@@ -9392,8 +10436,8 @@ function BrandEditPage({ brandId }) {
|
|
|
9392
10436
|
subtitle: create ? "Create a new brand" : "Update brand details",
|
|
9393
10437
|
closeHref: "/admin/brands",
|
|
9394
10438
|
menuItems: [
|
|
9395
|
-
{ label: saving ? "Saving..." : "Save", onClick: handleSave },
|
|
9396
|
-
{ label: active ? "Deactivate" : "Activate", onClick: () => setActive(!active) }
|
|
10439
|
+
{ label: saving ? "Saving..." : "Save", icon: Save6, onClick: handleSave },
|
|
10440
|
+
{ label: active ? "Deactivate" : "Activate", icon: Power, onClick: () => setActive(!active) }
|
|
9397
10441
|
]
|
|
9398
10442
|
}
|
|
9399
10443
|
),
|
|
@@ -9407,7 +10451,7 @@ function BrandEditPage({ brandId }) {
|
|
|
9407
10451
|
/* @__PURE__ */ jsx58(
|
|
9408
10452
|
DetailPageLayout,
|
|
9409
10453
|
{
|
|
9410
|
-
main: /* @__PURE__ */ jsxs48(
|
|
10454
|
+
main: /* @__PURE__ */ jsxs48(Fragment15, { children: [
|
|
9411
10455
|
/* @__PURE__ */ jsxs48("section", { children: [
|
|
9412
10456
|
/* @__PURE__ */ jsx58("h2", { className: "text-xs font-semibold text-gray-400 uppercase tracking-wider mb-2", children: "Basic info" }),
|
|
9413
10457
|
/* @__PURE__ */ jsxs48("div", { className: "min-w-0 overflow-hidden border border-gray-200 rounded-lg p-4 bg-gray-50/50 space-y-4", children: [
|
|
@@ -9480,7 +10524,7 @@ function BrandEditPage({ brandId }) {
|
|
|
9480
10524
|
/* @__PURE__ */ jsx58("div", { className: "min-w-0 overflow-hidden border border-gray-200 rounded-lg p-4 bg-gray-50/50", children: /* @__PURE__ */ jsx58(SeoSection, { values: seo, onChange: (field, value) => setSeo((s) => ({ ...s, [field]: value })) }) })
|
|
9481
10525
|
] })
|
|
9482
10526
|
] }),
|
|
9483
|
-
sidebar: /* @__PURE__ */ jsx58(
|
|
10527
|
+
sidebar: /* @__PURE__ */ jsx58(Fragment15, { children: /* @__PURE__ */ jsxs48("section", { children: [
|
|
9484
10528
|
/* @__PURE__ */ jsx58("h2", { className: "text-xs font-semibold text-gray-400 uppercase tracking-wider mb-2", children: "Status" }),
|
|
9485
10529
|
/* @__PURE__ */ jsx58("div", { className: "min-w-0 overflow-hidden border border-gray-200 rounded-lg p-4 bg-gray-50/50", children: /* @__PURE__ */ jsxs48("label", { className: "flex items-center gap-2 cursor-pointer", children: [
|
|
9486
10530
|
/* @__PURE__ */ jsx58(
|
|
@@ -9501,12 +10545,12 @@ function BrandEditPage({ brandId }) {
|
|
|
9501
10545
|
}
|
|
9502
10546
|
|
|
9503
10547
|
// src/admin/pages/ProductEditPage.tsx
|
|
9504
|
-
import { useState as
|
|
9505
|
-
import { useRouter as
|
|
9506
|
-
import { AlertCircle as AlertCircle5, Plus as Plus9, Trash2 as Trash25, Star } from "lucide-react";
|
|
10548
|
+
import { useState as useState33, useEffect as useEffect30 } from "react";
|
|
10549
|
+
import { useRouter as useRouter13 } from "next/navigation";
|
|
10550
|
+
import { AlertCircle as AlertCircle5, Plus as Plus9, Trash2 as Trash25, Star, Save as Save7 } from "lucide-react";
|
|
9507
10551
|
|
|
9508
10552
|
// src/components/Admin/AttributeFacetNameInput.tsx
|
|
9509
|
-
import { useState as
|
|
10553
|
+
import { useState as useState32, useEffect as useEffect29, useRef as useRef11 } from "react";
|
|
9510
10554
|
import { jsx as jsx59, jsxs as jsxs49 } from "react/jsx-runtime";
|
|
9511
10555
|
function slugFromName(name) {
|
|
9512
10556
|
const s = name.toLowerCase().trim().replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "");
|
|
@@ -9517,12 +10561,15 @@ function AttributeFacetNameInput({
|
|
|
9517
10561
|
onChange,
|
|
9518
10562
|
inputClassName
|
|
9519
10563
|
}) {
|
|
9520
|
-
const [draft, setDraft] =
|
|
9521
|
-
const [open, setOpen] =
|
|
9522
|
-
const [list, setList] =
|
|
10564
|
+
const [draft, setDraft] = useState32(value);
|
|
10565
|
+
const [open, setOpen] = useState32(false);
|
|
10566
|
+
const [list, setList] = useState32([]);
|
|
10567
|
+
const isFocusedRef = useRef11(false);
|
|
9523
10568
|
useEffect29(() => {
|
|
9524
|
-
|
|
9525
|
-
|
|
10569
|
+
if (!isFocusedRef.current && value !== draft) {
|
|
10570
|
+
setDraft(value);
|
|
10571
|
+
}
|
|
10572
|
+
}, [value, draft]);
|
|
9526
10573
|
useEffect29(() => {
|
|
9527
10574
|
const q = draft.trim();
|
|
9528
10575
|
if (!q) {
|
|
@@ -9585,8 +10632,12 @@ function AttributeFacetNameInput({
|
|
|
9585
10632
|
setDraft(e.target.value);
|
|
9586
10633
|
setOpen(true);
|
|
9587
10634
|
},
|
|
9588
|
-
onFocus: () =>
|
|
10635
|
+
onFocus: () => {
|
|
10636
|
+
setOpen(true);
|
|
10637
|
+
isFocusedRef.current = true;
|
|
10638
|
+
},
|
|
9589
10639
|
onBlur: () => setTimeout(() => {
|
|
10640
|
+
isFocusedRef.current = false;
|
|
9590
10641
|
setOpen(false);
|
|
9591
10642
|
onChange(draft.trim());
|
|
9592
10643
|
}, 200),
|
|
@@ -9640,7 +10691,7 @@ function AttributeFacetNameInput({
|
|
|
9640
10691
|
}
|
|
9641
10692
|
|
|
9642
10693
|
// src/admin/pages/ProductEditPage.tsx
|
|
9643
|
-
import { Fragment as
|
|
10694
|
+
import { Fragment as Fragment16, jsx as jsx60, jsxs as jsxs50 } from "react/jsx-runtime";
|
|
9644
10695
|
var isCreate2 = (id) => id === "create";
|
|
9645
10696
|
var sectionCls = "min-w-0 overflow-hidden border border-gray-200 rounded-lg p-4 bg-gray-50/50";
|
|
9646
10697
|
var labelCls = "block text-xs font-medium text-gray-600 mb-1";
|
|
@@ -9674,37 +10725,37 @@ function pickOtherMetadata(m) {
|
|
|
9674
10725
|
return rest;
|
|
9675
10726
|
}
|
|
9676
10727
|
function ProductEditPage({ productId }) {
|
|
9677
|
-
const router =
|
|
10728
|
+
const router = useRouter13();
|
|
9678
10729
|
const create = isCreate2(productId);
|
|
9679
|
-
const [loading, setLoading] =
|
|
9680
|
-
const [saving, setSaving] =
|
|
9681
|
-
const [errors, setErrors] =
|
|
9682
|
-
const [collections, setCollections] =
|
|
9683
|
-
const [brands, setBrands] =
|
|
9684
|
-
const [categories, setCategories] =
|
|
9685
|
-
const [name, setName] =
|
|
9686
|
-
const [productSlug, setProductSlug] =
|
|
9687
|
-
const [sku, setSku] =
|
|
9688
|
-
const [hsn, setHsn] =
|
|
9689
|
-
const [uom, setUom] =
|
|
9690
|
-
const [productType, setProductType] =
|
|
9691
|
-
const [collectionId, setCollectionId] =
|
|
9692
|
-
const [brandId, setBrandId] =
|
|
9693
|
-
const [categoryId, setCategoryId] =
|
|
9694
|
-
const [price, setPrice] =
|
|
9695
|
-
const [compareAtPrice, setCompareAtPrice] =
|
|
9696
|
-
const [quantity, setQuantity] =
|
|
9697
|
-
const [status, setStatus] =
|
|
9698
|
-
const [featured, setFeatured] =
|
|
9699
|
-
const [description, setDescription] =
|
|
9700
|
-
const [images, setImages] =
|
|
9701
|
-
const [specifications, setSpecifications] =
|
|
9702
|
-
const [otherMetadata, setOtherMetadata] =
|
|
9703
|
-
const [facetRows, setFacetRows] =
|
|
9704
|
-
const [taxMasterList, setTaxMasterList] =
|
|
9705
|
-
const [taxRows, setTaxRows] =
|
|
9706
|
-
const [seoId, setSeoId] =
|
|
9707
|
-
const [seo, setSeo] =
|
|
10730
|
+
const [loading, setLoading] = useState33(!create);
|
|
10731
|
+
const [saving, setSaving] = useState33(false);
|
|
10732
|
+
const [errors, setErrors] = useState33([]);
|
|
10733
|
+
const [collections, setCollections] = useState33([]);
|
|
10734
|
+
const [brands, setBrands] = useState33([]);
|
|
10735
|
+
const [categories, setCategories] = useState33([]);
|
|
10736
|
+
const [name, setName] = useState33("");
|
|
10737
|
+
const [productSlug, setProductSlug] = useState33("");
|
|
10738
|
+
const [sku, setSku] = useState33("");
|
|
10739
|
+
const [hsn, setHsn] = useState33("");
|
|
10740
|
+
const [uom, setUom] = useState33("");
|
|
10741
|
+
const [productType, setProductType] = useState33("product");
|
|
10742
|
+
const [collectionId, setCollectionId] = useState33(null);
|
|
10743
|
+
const [brandId, setBrandId] = useState33(null);
|
|
10744
|
+
const [categoryId, setCategoryId] = useState33(null);
|
|
10745
|
+
const [price, setPrice] = useState33("");
|
|
10746
|
+
const [compareAtPrice, setCompareAtPrice] = useState33("");
|
|
10747
|
+
const [quantity, setQuantity] = useState33(1);
|
|
10748
|
+
const [status, setStatus] = useState33("draft");
|
|
10749
|
+
const [featured, setFeatured] = useState33(false);
|
|
10750
|
+
const [description, setDescription] = useState33("");
|
|
10751
|
+
const [images, setImages] = useState33([{ url: "", alt: "", isDefault: true }]);
|
|
10752
|
+
const [specifications, setSpecifications] = useState33([{ key: "", value: "" }]);
|
|
10753
|
+
const [otherMetadata, setOtherMetadata] = useState33({});
|
|
10754
|
+
const [facetRows, setFacetRows] = useState33([{ name: "", value: "" }]);
|
|
10755
|
+
const [taxMasterList, setTaxMasterList] = useState33([]);
|
|
10756
|
+
const [taxRows, setTaxRows] = useState33([{ taxId: "", rate: "" }]);
|
|
10757
|
+
const [seoId, setSeoId] = useState33(null);
|
|
10758
|
+
const [seo, setSeo] = useState33({
|
|
9708
10759
|
seoTitle: "",
|
|
9709
10760
|
seoDescription: "",
|
|
9710
10761
|
seoKeywords: "",
|
|
@@ -10042,8 +11093,8 @@ function ProductEditPage({ productId }) {
|
|
|
10042
11093
|
subtitle: create ? "Create a new product" : "Update product details",
|
|
10043
11094
|
closeHref: "/admin/products",
|
|
10044
11095
|
menuItems: [
|
|
10045
|
-
{ label: saving ? "Saving..." : "Save", onClick: handleSave },
|
|
10046
|
-
{ label: featured ? "Unfeature" : "Feature", onClick: () => setFeatured(!featured) }
|
|
11096
|
+
{ label: saving ? "Saving..." : "Save", icon: Save7, onClick: handleSave },
|
|
11097
|
+
{ label: featured ? "Unfeature" : "Feature", icon: Star, onClick: () => setFeatured(!featured) }
|
|
10047
11098
|
]
|
|
10048
11099
|
}
|
|
10049
11100
|
),
|
|
@@ -10057,7 +11108,7 @@ function ProductEditPage({ productId }) {
|
|
|
10057
11108
|
/* @__PURE__ */ jsx60(
|
|
10058
11109
|
DetailPageLayout,
|
|
10059
11110
|
{
|
|
10060
|
-
main: /* @__PURE__ */ jsxs50(
|
|
11111
|
+
main: /* @__PURE__ */ jsxs50(Fragment16, { children: [
|
|
10061
11112
|
/* @__PURE__ */ jsxs50("section", { children: [
|
|
10062
11113
|
/* @__PURE__ */ jsx60("h2", { className: "text-xs font-semibold text-gray-400 uppercase tracking-wider mb-2", children: "Product details" }),
|
|
10063
11114
|
/* @__PURE__ */ jsxs50("div", { className: `${sectionCls} space-y-4`, children: [
|
|
@@ -10361,10 +11412,10 @@ function ProductEditPage({ productId }) {
|
|
|
10361
11412
|
}
|
|
10362
11413
|
|
|
10363
11414
|
// src/admin/pages/CollectionEditPage.tsx
|
|
10364
|
-
import { useState as
|
|
10365
|
-
import { useRouter as
|
|
10366
|
-
import { AlertCircle as AlertCircle6, Plus as Plus10, Trash2 as Trash26, ChevronDown as ChevronDown6, ChevronUp as ChevronUp2 } from "lucide-react";
|
|
10367
|
-
import { Fragment as
|
|
11415
|
+
import { useState as useState34, useEffect as useEffect31 } from "react";
|
|
11416
|
+
import { useRouter as useRouter14 } from "next/navigation";
|
|
11417
|
+
import { AlertCircle as AlertCircle6, Plus as Plus10, Trash2 as Trash26, ChevronDown as ChevronDown6, ChevronUp as ChevronUp2, Save as Save8, Power as Power2 } from "lucide-react";
|
|
11418
|
+
import { Fragment as Fragment17, jsx as jsx61, jsxs as jsxs51 } from "react/jsx-runtime";
|
|
10368
11419
|
var isCreate3 = (id) => id === "create";
|
|
10369
11420
|
var emptySlide = () => ({ url: "", type: "image", caption: "" });
|
|
10370
11421
|
var emptyVariant = () => ({ name: "", price: "", extraSpecs: [] });
|
|
@@ -10372,29 +11423,29 @@ var sectionCls2 = "min-w-0 overflow-hidden border border-gray-200 rounded-lg p-4
|
|
|
10372
11423
|
var labelCls2 = "block text-xs font-medium text-gray-600 mb-1";
|
|
10373
11424
|
var inputCls2 = "w-full rounded-md border border-gray-300 px-2 py-1.5 text-sm";
|
|
10374
11425
|
function CollectionEditPage({ collectionId }) {
|
|
10375
|
-
const router =
|
|
11426
|
+
const router = useRouter14();
|
|
10376
11427
|
const create = isCreate3(collectionId);
|
|
10377
|
-
const [loading, setLoading] =
|
|
10378
|
-
const [saving, setSaving] =
|
|
10379
|
-
const [errors, setErrors] =
|
|
10380
|
-
const [categories, setCategories] =
|
|
10381
|
-
const [brands, setBrands] =
|
|
10382
|
-
const [name, setName] =
|
|
10383
|
-
const [slug, setSlug] =
|
|
10384
|
-
const [hsn, setHsn] =
|
|
10385
|
-
const [categoryId, setCategoryId] =
|
|
10386
|
-
const [brandId, setBrandId] =
|
|
10387
|
-
const [description, setDescription] =
|
|
10388
|
-
const [image, setImage] =
|
|
10389
|
-
const [active, setActive] =
|
|
10390
|
-
const [sortOrder, setSortOrder] =
|
|
10391
|
-
const [advancedOpen, setAdvancedOpen] =
|
|
10392
|
-
const [heroSlides, setHeroSlides] =
|
|
10393
|
-
const [variants, setVariants] =
|
|
10394
|
-
const [experienceDescription, setExperienceDescription] =
|
|
10395
|
-
const [brochureUrl, setBrochureUrl] =
|
|
10396
|
-
const [seoId, setSeoId] =
|
|
10397
|
-
const [seo, setSeo] =
|
|
11428
|
+
const [loading, setLoading] = useState34(!create);
|
|
11429
|
+
const [saving, setSaving] = useState34(false);
|
|
11430
|
+
const [errors, setErrors] = useState34([]);
|
|
11431
|
+
const [categories, setCategories] = useState34([]);
|
|
11432
|
+
const [brands, setBrands] = useState34([]);
|
|
11433
|
+
const [name, setName] = useState34("");
|
|
11434
|
+
const [slug, setSlug] = useState34("");
|
|
11435
|
+
const [hsn, setHsn] = useState34("");
|
|
11436
|
+
const [categoryId, setCategoryId] = useState34(null);
|
|
11437
|
+
const [brandId, setBrandId] = useState34(null);
|
|
11438
|
+
const [description, setDescription] = useState34("");
|
|
11439
|
+
const [image, setImage] = useState34("");
|
|
11440
|
+
const [active, setActive] = useState34(true);
|
|
11441
|
+
const [sortOrder, setSortOrder] = useState34(0);
|
|
11442
|
+
const [advancedOpen, setAdvancedOpen] = useState34(false);
|
|
11443
|
+
const [heroSlides, setHeroSlides] = useState34([emptySlide()]);
|
|
11444
|
+
const [variants, setVariants] = useState34([emptyVariant()]);
|
|
11445
|
+
const [experienceDescription, setExperienceDescription] = useState34("");
|
|
11446
|
+
const [brochureUrl, setBrochureUrl] = useState34("");
|
|
11447
|
+
const [seoId, setSeoId] = useState34(null);
|
|
11448
|
+
const [seo, setSeo] = useState34({
|
|
10398
11449
|
seoTitle: "",
|
|
10399
11450
|
seoDescription: "",
|
|
10400
11451
|
seoKeywords: "",
|
|
@@ -10575,8 +11626,8 @@ function CollectionEditPage({ collectionId }) {
|
|
|
10575
11626
|
subtitle: create ? "Create a new collection" : "Update collection and page content",
|
|
10576
11627
|
closeHref: "/admin/collections",
|
|
10577
11628
|
menuItems: [
|
|
10578
|
-
{ label: saving ? "Saving..." : "Save", onClick: handleSave },
|
|
10579
|
-
{ label: active ? "Deactivate" : "Activate", onClick: () => setActive(!active) }
|
|
11629
|
+
{ label: saving ? "Saving..." : "Save", icon: Save8, onClick: handleSave },
|
|
11630
|
+
{ label: active ? "Deactivate" : "Activate", icon: Power2, onClick: () => setActive(!active) }
|
|
10580
11631
|
]
|
|
10581
11632
|
}
|
|
10582
11633
|
),
|
|
@@ -10590,7 +11641,7 @@ function CollectionEditPage({ collectionId }) {
|
|
|
10590
11641
|
/* @__PURE__ */ jsx61(
|
|
10591
11642
|
DetailPageLayout,
|
|
10592
11643
|
{
|
|
10593
|
-
main: /* @__PURE__ */ jsxs51(
|
|
11644
|
+
main: /* @__PURE__ */ jsxs51(Fragment17, { children: [
|
|
10594
11645
|
/* @__PURE__ */ jsxs51("section", { children: [
|
|
10595
11646
|
/* @__PURE__ */ jsx61("h2", { className: "text-xs font-semibold text-gray-400 uppercase tracking-wider mb-2", children: "Basic info" }),
|
|
10596
11647
|
/* @__PURE__ */ jsxs51("div", { className: `${sectionCls2} space-y-4`, children: [
|
|
@@ -10700,7 +11751,7 @@ function CollectionEditPage({ collectionId }) {
|
|
|
10700
11751
|
] })
|
|
10701
11752
|
] })
|
|
10702
11753
|
] }),
|
|
10703
|
-
sidebar: /* @__PURE__ */ jsxs51(
|
|
11754
|
+
sidebar: /* @__PURE__ */ jsxs51(Fragment17, { children: [
|
|
10704
11755
|
/* @__PURE__ */ jsxs51("section", { children: [
|
|
10705
11756
|
/* @__PURE__ */ jsx61("h2", { className: "text-xs font-semibold text-gray-400 uppercase tracking-wider mb-2", children: "Status" }),
|
|
10706
11757
|
/* @__PURE__ */ jsx61("div", { className: sectionCls2, children: /* @__PURE__ */ jsxs51("label", { className: "flex items-center gap-2 cursor-pointer", children: [
|
|
@@ -10719,9 +11770,9 @@ function CollectionEditPage({ collectionId }) {
|
|
|
10719
11770
|
}
|
|
10720
11771
|
|
|
10721
11772
|
// src/admin/pages/RolesPage.tsx
|
|
10722
|
-
import { useCallback as useCallback7, useEffect as useEffect32, useState as
|
|
11773
|
+
import { useCallback as useCallback7, useEffect as useEffect32, useState as useState35 } from "react";
|
|
10723
11774
|
import { useSession as useSession5 } from "next-auth/react";
|
|
10724
|
-
import { Shield as Shield2, Save as
|
|
11775
|
+
import { Shield as Shield2, Save as Save9, Trash2 as Trash27 } from "lucide-react";
|
|
10725
11776
|
|
|
10726
11777
|
// src/auth/permission-entities.ts
|
|
10727
11778
|
var ADMIN_GROUP_NAME = "Administrator";
|
|
@@ -10754,14 +11805,15 @@ function RolesPage() {
|
|
|
10754
11805
|
const { data: session, status } = useSession5();
|
|
10755
11806
|
const u = session?.user;
|
|
10756
11807
|
const canManage = !!u?.isRBACAdmin;
|
|
10757
|
-
const [entities, setEntities] =
|
|
10758
|
-
const [groups, setGroups] =
|
|
10759
|
-
const [selectedId, setSelectedId] =
|
|
10760
|
-
const [matrix, setMatrix] =
|
|
10761
|
-
const [loading, setLoading] =
|
|
10762
|
-
const [saving, setSaving] =
|
|
10763
|
-
const [newName, setNewName] =
|
|
10764
|
-
const [
|
|
11808
|
+
const [entities, setEntities] = useState35([]);
|
|
11809
|
+
const [groups, setGroups] = useState35([]);
|
|
11810
|
+
const [selectedId, setSelectedId] = useState35(null);
|
|
11811
|
+
const [matrix, setMatrix] = useState35({});
|
|
11812
|
+
const [loading, setLoading] = useState35(true);
|
|
11813
|
+
const [saving, setSaving] = useState35(false);
|
|
11814
|
+
const [newName, setNewName] = useState35("");
|
|
11815
|
+
const [deleteRoleOpen, setDeleteRoleOpen] = useState35(false);
|
|
11816
|
+
const [error, setError] = useState35(null);
|
|
10765
11817
|
const load = useCallback7(async () => {
|
|
10766
11818
|
setLoading(true);
|
|
10767
11819
|
setError(null);
|
|
@@ -10816,6 +11868,45 @@ function RolesPage() {
|
|
|
10816
11868
|
[entity]: { ...prev[entity], [key]: !prev[entity][key] }
|
|
10817
11869
|
}));
|
|
10818
11870
|
};
|
|
11871
|
+
const PERM_KEYS = [
|
|
11872
|
+
"canCreate",
|
|
11873
|
+
"canRead",
|
|
11874
|
+
"canUpdate",
|
|
11875
|
+
"canDelete"
|
|
11876
|
+
];
|
|
11877
|
+
const isColumnAllChecked = (key) => entities.length > 0 && entities.every((entity) => matrix[entity]?.[key]);
|
|
11878
|
+
const toggleColumn = (key) => {
|
|
11879
|
+
const nextValue = !isColumnAllChecked(key);
|
|
11880
|
+
setMatrix((prev) => {
|
|
11881
|
+
const next = { ...prev };
|
|
11882
|
+
for (const entity of entities) {
|
|
11883
|
+
if (!next[entity]) continue;
|
|
11884
|
+
next[entity] = { ...next[entity], [key]: nextValue };
|
|
11885
|
+
}
|
|
11886
|
+
return next;
|
|
11887
|
+
});
|
|
11888
|
+
};
|
|
11889
|
+
const isAllChecked = entities.length > 0 && entities.every((entity) => {
|
|
11890
|
+
const row = matrix[entity];
|
|
11891
|
+
return row ? PERM_KEYS.every((k) => row[k]) : false;
|
|
11892
|
+
});
|
|
11893
|
+
const toggleAll = () => {
|
|
11894
|
+
const nextValue = !isAllChecked;
|
|
11895
|
+
setMatrix((prev) => {
|
|
11896
|
+
const next = { ...prev };
|
|
11897
|
+
for (const entity of entities) {
|
|
11898
|
+
if (!next[entity]) continue;
|
|
11899
|
+
next[entity] = {
|
|
11900
|
+
...next[entity],
|
|
11901
|
+
canCreate: nextValue,
|
|
11902
|
+
canRead: nextValue,
|
|
11903
|
+
canUpdate: nextValue,
|
|
11904
|
+
canDelete: nextValue
|
|
11905
|
+
};
|
|
11906
|
+
}
|
|
11907
|
+
return next;
|
|
11908
|
+
});
|
|
11909
|
+
};
|
|
10819
11910
|
const saveMatrix = async () => {
|
|
10820
11911
|
if (!selectedId) return;
|
|
10821
11912
|
setSaving(true);
|
|
@@ -10864,7 +11955,6 @@ function RolesPage() {
|
|
|
10864
11955
|
};
|
|
10865
11956
|
const deleteGroup = async () => {
|
|
10866
11957
|
if (!selectedId || !selected || isSuperAdminGroupName(selected.name)) return;
|
|
10867
|
-
if (!confirm(`Delete group "${selected.name}"?`)) return;
|
|
10868
11958
|
try {
|
|
10869
11959
|
const res = await fetch(`/api/admin/roles/${selectedId}`, { method: "DELETE" });
|
|
10870
11960
|
if (!res.ok) {
|
|
@@ -10873,6 +11963,7 @@ function RolesPage() {
|
|
|
10873
11963
|
return;
|
|
10874
11964
|
}
|
|
10875
11965
|
setSelectedId(null);
|
|
11966
|
+
setDeleteRoleOpen(false);
|
|
10876
11967
|
await load();
|
|
10877
11968
|
} catch {
|
|
10878
11969
|
setError("Delete failed");
|
|
@@ -10923,21 +12014,36 @@ function RolesPage() {
|
|
|
10923
12014
|
" \u2014 Permissions"
|
|
10924
12015
|
] }),
|
|
10925
12016
|
/* @__PURE__ */ jsxs52(Button, { size: "sm", onClick: saveMatrix, disabled: saving, className: "gap-1", children: [
|
|
10926
|
-
/* @__PURE__ */ jsx62(
|
|
12017
|
+
/* @__PURE__ */ jsx62(Save9, { className: "h-3.5 w-3.5" }),
|
|
10927
12018
|
saving ? "Saving\u2026" : "Save"
|
|
10928
12019
|
] }),
|
|
10929
|
-
selected && !isSuperAdminGroupName(selected.name) && /* @__PURE__ */ jsxs52(Button, { size: "sm", variant: "outline", className: "gap-1 text-red-600", onClick:
|
|
12020
|
+
selected && !isSuperAdminGroupName(selected.name) && /* @__PURE__ */ jsxs52(Button, { size: "sm", variant: "outline", className: "gap-1 text-red-600", onClick: () => setDeleteRoleOpen(true), children: [
|
|
10930
12021
|
/* @__PURE__ */ jsx62(Trash27, { className: "h-3.5 w-3.5" }),
|
|
10931
12022
|
"Delete role"
|
|
10932
12023
|
] })
|
|
10933
12024
|
] }),
|
|
10934
12025
|
entities.length > 0 && /* @__PURE__ */ jsx62("div", { className: "overflow-x-auto rounded-md border border-gray-200 dark:border-gray-600", children: /* @__PURE__ */ jsxs52("table", { className: "w-full text-sm", children: [
|
|
10935
12026
|
/* @__PURE__ */ jsx62("thead", { children: /* @__PURE__ */ jsxs52("tr", { className: "border-b bg-gray-50 dark:bg-gray-900/50", children: [
|
|
10936
|
-
/* @__PURE__ */ jsx62("th", { className: "p-3 text-left font-medium", children: "
|
|
10937
|
-
|
|
10938
|
-
|
|
10939
|
-
|
|
10940
|
-
/* @__PURE__ */ jsx62("th", { className: "p-2", children: "
|
|
12027
|
+
/* @__PURE__ */ jsx62("th", { className: "p-3 text-left font-medium", children: /* @__PURE__ */ jsxs52("div", { className: "flex items-center gap-2", children: [
|
|
12028
|
+
/* @__PURE__ */ jsx62("input", { type: "checkbox", checked: isAllChecked, onChange: toggleAll }),
|
|
12029
|
+
/* @__PURE__ */ jsx62("span", { children: "Resource" })
|
|
12030
|
+
] }) }),
|
|
12031
|
+
/* @__PURE__ */ jsx62("th", { className: "p-2", children: /* @__PURE__ */ jsxs52("div", { className: "flex items-center justify-center gap-1", children: [
|
|
12032
|
+
/* @__PURE__ */ jsx62("span", { children: "C" }),
|
|
12033
|
+
/* @__PURE__ */ jsx62("input", { type: "checkbox", checked: isColumnAllChecked("canCreate"), onChange: () => toggleColumn("canCreate") })
|
|
12034
|
+
] }) }),
|
|
12035
|
+
/* @__PURE__ */ jsx62("th", { className: "p-2", children: /* @__PURE__ */ jsxs52("div", { className: "flex items-center justify-center gap-1", children: [
|
|
12036
|
+
/* @__PURE__ */ jsx62("span", { children: "R" }),
|
|
12037
|
+
/* @__PURE__ */ jsx62("input", { type: "checkbox", checked: isColumnAllChecked("canRead"), onChange: () => toggleColumn("canRead") })
|
|
12038
|
+
] }) }),
|
|
12039
|
+
/* @__PURE__ */ jsx62("th", { className: "p-2", children: /* @__PURE__ */ jsxs52("div", { className: "flex items-center justify-center gap-1", children: [
|
|
12040
|
+
/* @__PURE__ */ jsx62("span", { children: "U" }),
|
|
12041
|
+
/* @__PURE__ */ jsx62("input", { type: "checkbox", checked: isColumnAllChecked("canUpdate"), onChange: () => toggleColumn("canUpdate") })
|
|
12042
|
+
] }) }),
|
|
12043
|
+
/* @__PURE__ */ jsx62("th", { className: "p-2", children: /* @__PURE__ */ jsxs52("div", { className: "flex items-center justify-center gap-1", children: [
|
|
12044
|
+
/* @__PURE__ */ jsx62("span", { children: "D" }),
|
|
12045
|
+
/* @__PURE__ */ jsx62("input", { type: "checkbox", checked: isColumnAllChecked("canDelete"), onChange: () => toggleColumn("canDelete") })
|
|
12046
|
+
] }) })
|
|
10941
12047
|
] }) }),
|
|
10942
12048
|
/* @__PURE__ */ jsx62("tbody", { children: entities.map((entity) => {
|
|
10943
12049
|
const row = matrix[entity];
|
|
@@ -10961,7 +12067,15 @@ function RolesPage() {
|
|
|
10961
12067
|
/* @__PURE__ */ jsx62(Input, { placeholder: "New role name", value: newName, onChange: (e) => setNewName(e.target.value), onKeyDown: (e) => e.key === "Enter" && createGroup() }),
|
|
10962
12068
|
/* @__PURE__ */ jsx62(Button, { type: "button", onClick: createGroup, children: "Add role" })
|
|
10963
12069
|
] })
|
|
10964
|
-
] })
|
|
12070
|
+
] }),
|
|
12071
|
+
/* @__PURE__ */ jsx62(Dialog, { open: deleteRoleOpen, onOpenChange: setDeleteRoleOpen, children: /* @__PURE__ */ jsxs52(DialogContent, { children: [
|
|
12072
|
+
/* @__PURE__ */ jsx62(DialogHeader, { children: /* @__PURE__ */ jsx62(DialogTitle, { children: "Delete Role" }) }),
|
|
12073
|
+
/* @__PURE__ */ jsx62("p", { className: "text-sm text-gray-600", children: selected ? `Delete group "${selected.name}"?` : "Delete selected role?" }),
|
|
12074
|
+
/* @__PURE__ */ jsxs52(DialogFooter, { children: [
|
|
12075
|
+
/* @__PURE__ */ jsx62(Button, { variant: "outline", onClick: () => setDeleteRoleOpen(false), children: "Cancel" }),
|
|
12076
|
+
/* @__PURE__ */ jsx62(Button, { variant: "destructive", onClick: deleteGroup, children: "Delete" })
|
|
12077
|
+
] })
|
|
12078
|
+
] }) })
|
|
10965
12079
|
] });
|
|
10966
12080
|
}
|
|
10967
12081
|
|
|
@@ -11239,8 +12353,8 @@ var CRUD_CONFIGS = {
|
|
|
11239
12353
|
}
|
|
11240
12354
|
};
|
|
11241
12355
|
function BlogEditorWrapper({ blogId }) {
|
|
11242
|
-
const [blog, setBlog] =
|
|
11243
|
-
const [loading, setLoading] =
|
|
12356
|
+
const [blog, setBlog] = useState36(null);
|
|
12357
|
+
const [loading, setLoading] = useState36(!!blogId);
|
|
11244
12358
|
useEffect33(() => {
|
|
11245
12359
|
if (!blogId) return;
|
|
11246
12360
|
fetch(`/api/blogs/${blogId}`).then((res) => res.ok ? res.json() : null).then((data) => setBlog(data)).finally(() => setLoading(false));
|
|
@@ -11254,8 +12368,8 @@ function BlogEditorWrapper({ blogId }) {
|
|
|
11254
12368
|
return /* @__PURE__ */ jsx63(BlogEditor, { existingBlog: blog });
|
|
11255
12369
|
}
|
|
11256
12370
|
function AdminPageResolver({ slug }) {
|
|
11257
|
-
const router =
|
|
11258
|
-
const { customCrudConfigs, storeEnabled } =
|
|
12371
|
+
const router = useRouter15();
|
|
12372
|
+
const { customCrudConfigs, storeEnabled } = useContext7(AdminConfigContext);
|
|
11259
12373
|
const key = slug?.[0] || "dashboard";
|
|
11260
12374
|
useEffect33(() => {
|
|
11261
12375
|
if (key === "layout-settings") {
|
|
@@ -11317,7 +12431,7 @@ function AdminPageResolver({ slug }) {
|
|
|
11317
12431
|
{ field: "orderCount", displayName: "Orders" },
|
|
11318
12432
|
{ field: "totalPaid", displayName: "Total paid" }
|
|
11319
12433
|
] : crud.columns;
|
|
11320
|
-
const extraListParams =
|
|
12434
|
+
const extraListParams = useMemo4(
|
|
11321
12435
|
() => isContactsWithStore ? { includeSummary: "1" } : void 0,
|
|
11322
12436
|
[isContactsWithStore]
|
|
11323
12437
|
);
|
|
@@ -11340,21 +12454,21 @@ function AdminPageResolver({ slug }) {
|
|
|
11340
12454
|
}
|
|
11341
12455
|
|
|
11342
12456
|
// src/admin/pages/LayoutSettingsPage.tsx
|
|
11343
|
-
import { useState as
|
|
11344
|
-
import { Save as
|
|
12457
|
+
import { useState as useState37, useEffect as useEffect34, useContext as useContext8 } from "react";
|
|
12458
|
+
import { Save as Save10 } from "lucide-react";
|
|
11345
12459
|
import { jsx as jsx64, jsxs as jsxs54 } from "react/jsx-runtime";
|
|
11346
12460
|
function LayoutSettingsPage() {
|
|
11347
|
-
const { theme } =
|
|
11348
|
-
const [activeTab, setActiveTab] =
|
|
11349
|
-
const [navbarConfig, setNavbarConfig] =
|
|
12461
|
+
const { theme } = useContext8(AdminConfigContext);
|
|
12462
|
+
const [activeTab, setActiveTab] = useState37("navbar");
|
|
12463
|
+
const [navbarConfig, setNavbarConfig] = useState37({
|
|
11350
12464
|
logo: "",
|
|
11351
12465
|
items: [],
|
|
11352
12466
|
ctaLabel: "",
|
|
11353
12467
|
ctaUrl: ""
|
|
11354
12468
|
});
|
|
11355
|
-
const [footerValues, setFooterValues] =
|
|
11356
|
-
const [saving, setSaving] =
|
|
11357
|
-
const [loading, setLoading] =
|
|
12469
|
+
const [footerValues, setFooterValues] = useState37({});
|
|
12470
|
+
const [saving, setSaving] = useState37(false);
|
|
12471
|
+
const [loading, setLoading] = useState37(true);
|
|
11358
12472
|
useEffect34(() => {
|
|
11359
12473
|
fetch("/api/settings/theme").then((r) => r.ok ? r.json() : null).then((data) => {
|
|
11360
12474
|
if (!data) return;
|
|
@@ -11413,7 +12527,7 @@ function LayoutSettingsPage() {
|
|
|
11413
12527
|
disabled: saving,
|
|
11414
12528
|
className: "bg-white text-gray-800 hover:bg-gray-100 border-0 text-xs",
|
|
11415
12529
|
children: [
|
|
11416
|
-
/* @__PURE__ */ jsx64(
|
|
12530
|
+
/* @__PURE__ */ jsx64(Save10, { className: "h-4 w-4 mr-2" }),
|
|
11417
12531
|
saving ? "Saving..." : "Save"
|
|
11418
12532
|
]
|
|
11419
12533
|
}
|