@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 CHANGED
@@ -73,13 +73,14 @@ __export(admin_exports, {
73
73
  module.exports = __toCommonJS(admin_exports);
74
74
 
75
75
  // src/admin/pages/AdminLayout.tsx
76
- var import_react6 = __toESM(require("react"), 1);
77
- var import_react7 = require("next-auth/react");
76
+ var import_react7 = __toESM(require("react"), 1);
77
+ var import_react8 = require("next-auth/react");
78
78
  var import_navigation3 = require("next/navigation");
79
79
  var import_sonner = require("sonner");
80
80
 
81
81
  // src/components/Admin/Header.tsx
82
82
  var import_react2 = require("next-auth/react");
83
+ var import_react3 = require("react");
83
84
 
84
85
  // src/components/ui/button.tsx
85
86
  var React = __toESM(require("react"), 1);
@@ -301,25 +302,44 @@ function useIsMobile() {
301
302
  return !!isMobile;
302
303
  }
303
304
 
305
+ // src/lib/infuro-favicon.ts
306
+ 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==";
307
+
304
308
  // src/components/Admin/Header.tsx
305
309
  var import_jsx_runtime3 = require("react/jsx-runtime");
310
+ var DEFAULT_ADMIN_LOGO = "/images/logo/logo.png";
306
311
  function AdminHeader() {
307
312
  const { data: session } = (0, import_react2.useSession)();
308
313
  const isMobile = useIsMobile();
314
+ const configuredLogo = process.env.NEXT_PUBLIC_ADMIN_LOGO_URL || DEFAULT_ADMIN_LOGO;
315
+ const [logoSrc, setLogoSrc] = (0, import_react3.useState)(configuredLogo);
316
+ const [logoFailed, setLogoFailed] = (0, import_react3.useState)(false);
317
+ const isDataLogo = (0, import_react3.useMemo)(() => logoSrc.startsWith("data:"), [logoSrc]);
309
318
  const handleLogout = () => {
310
319
  (0, import_react2.signOut)({ callbackUrl: "/admin/signin" });
311
320
  };
312
321
  return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("header", { className: "bg-white border-b border-gray-200 px-4 py-2", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "flex items-center justify-between", children: [
313
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "flex items-center max-h-9 shrink-0", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
322
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "flex items-center max-h-9 shrink-0", children: !logoFailed ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
314
323
  import_image.default,
315
324
  {
316
- src: process.env.NEXT_PUBLIC_ADMIN_LOGO_URL || "/images/logo/logo.png",
325
+ src: logoSrc,
317
326
  alt: "Admin",
318
327
  width: 120,
319
328
  height: 34,
320
- className: "max-h-9 w-auto object-contain object-left"
329
+ className: "max-h-9 w-auto object-contain object-left",
330
+ unoptimized: isDataLogo,
331
+ onError: () => {
332
+ if (logoSrc !== DEFAULT_ADMIN_LOGO) {
333
+ setLogoSrc(DEFAULT_ADMIN_LOGO);
334
+ return;
335
+ }
336
+ setLogoFailed(true);
337
+ }
321
338
  }
322
- ) }),
339
+ ) : /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "flex items-center gap-2", children: [
340
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_image.default, { src: INFURO_FAVICON_BASE64, alt: "Infuro", width: 18, height: 18, unoptimized: true }),
341
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "text-sm font-semibold text-gray-800", children: "Infuro" })
342
+ ] }) }),
323
343
  /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "flex items-center space-x-3", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(DropdownMenu, { children: [
324
344
  /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
325
345
  Button,
@@ -368,23 +388,20 @@ function AdminHeader() {
368
388
  var import_link2 = __toESM(require("next/link"), 1);
369
389
  var import_image2 = __toESM(require("next/image"), 1);
370
390
  var import_navigation = require("next/navigation");
371
- var import_react4 = require("react");
391
+ var import_react5 = require("react");
372
392
  var import_lucide_react3 = require("lucide-react");
373
393
 
374
394
  // src/admin/admin-config-context.tsx
375
- var import_react3 = require("react");
395
+ var import_react4 = require("react");
376
396
  var defaultValue = {
377
397
  customNavItems: [],
378
398
  customNavSections: [],
379
399
  customCrudConfigs: {}
380
400
  };
381
- var AdminConfigContext = (0, import_react3.createContext)(defaultValue);
382
-
383
- // src/lib/infuro-favicon.ts
384
- 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==";
401
+ var AdminConfigContext = (0, import_react4.createContext)(defaultValue);
385
402
 
386
403
  // src/lib/cms-version.ts
387
- var CMS_VERSION = true ? "1.0.15" : "0.0.0";
404
+ var CMS_VERSION = true ? "1.0.16" : "0.0.0";
388
405
 
389
406
  // src/components/Admin/Sidebar.tsx
390
407
  var import_jsx_runtime4 = require("react/jsx-runtime");
@@ -404,7 +421,7 @@ function getIconForItem(iconName) {
404
421
  }
405
422
  function AdminSidebar({ variant = "sidebar" }) {
406
423
  const pathname = (0, import_navigation.usePathname)();
407
- const { customNavItems, customNavSections = [], storeEnabled } = (0, import_react4.useContext)(AdminConfigContext);
424
+ const { customNavItems, customNavSections = [], storeEnabled } = (0, import_react5.useContext)(AdminConfigContext);
408
425
  const isDrawer = variant === "drawer";
409
426
  const isActive = (path) => {
410
427
  if (path === "/admin/dashboard") {
@@ -565,12 +582,12 @@ function AdminSidebar({ variant = "sidebar" }) {
565
582
  // src/components/Admin/MobileBottomNav.tsx
566
583
  var import_link3 = __toESM(require("next/link"), 1);
567
584
  var import_navigation2 = require("next/navigation");
568
- var import_react5 = require("react");
585
+ var import_react6 = require("react");
569
586
  var import_lucide_react4 = require("lucide-react");
570
587
  var import_jsx_runtime5 = require("react/jsx-runtime");
571
588
  function MobileBottomNav({ onOpenMore }) {
572
589
  const pathname = (0, import_navigation2.usePathname)();
573
- const { storeEnabled } = (0, import_react5.useContext)(AdminConfigContext);
590
+ const { storeEnabled } = (0, import_react6.useContext)(AdminConfigContext);
574
591
  const isActive = (path) => {
575
592
  if (path === "/admin/dashboard") return pathname === path;
576
593
  return pathname.startsWith(path);
@@ -770,7 +787,7 @@ var PUBLIC_ADMIN_PATHS = [
770
787
  ];
771
788
  var AdminStyle = () => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("style", { dangerouslySetInnerHTML: { __html: ADMIN_THEME_CSS } });
772
789
  function useAdminViewSettings() {
773
- (0, import_react6.useEffect)(() => {
790
+ (0, import_react7.useEffect)(() => {
774
791
  fetch("/api/settings/admin_view").then((r) => r.ok ? r.json() : null).then((data) => {
775
792
  if (!data) return;
776
793
  const root = document.getElementById("admin-root");
@@ -781,18 +798,18 @@ function useAdminViewSettings() {
781
798
  }, []);
782
799
  }
783
800
  function AdminLayoutInner({ children }) {
784
- const { data: session, status } = (0, import_react7.useSession)();
801
+ const { data: session, status } = (0, import_react8.useSession)();
785
802
  const router = (0, import_navigation3.useRouter)();
786
803
  const pathname = (0, import_navigation3.usePathname)();
787
- const [loadingTimeout, setLoadingTimeout] = (0, import_react6.useState)(false);
788
- const [moreSheetOpen, setMoreSheetOpen] = (0, import_react6.useState)(false);
804
+ const [loadingTimeout, setLoadingTimeout] = (0, import_react7.useState)(false);
805
+ const [moreSheetOpen, setMoreSheetOpen] = (0, import_react7.useState)(false);
789
806
  const isMobile = useIsMobile();
790
807
  useAdminViewSettings();
791
808
  const isPublicPath = PUBLIC_ADMIN_PATHS.includes(pathname);
792
- (0, import_react6.useEffect)(() => {
809
+ (0, import_react7.useEffect)(() => {
793
810
  if (isMobile) setMoreSheetOpen(false);
794
811
  }, [isMobile, pathname]);
795
- (0, import_react6.useEffect)(() => {
812
+ (0, import_react7.useEffect)(() => {
796
813
  if (isPublicPath) return;
797
814
  if (status === "loading") {
798
815
  const timeout = setTimeout(() => setLoadingTimeout(true), 1e4);
@@ -847,8 +864,8 @@ function AdminLayoutInner({ children }) {
847
864
  ] });
848
865
  }
849
866
  function useResolvedTheme(theme, themeRegistry) {
850
- const [activeThemeId, setActiveThemeId] = (0, import_react6.useState)(null);
851
- (0, import_react6.useEffect)(() => {
867
+ const [activeThemeId, setActiveThemeId] = (0, import_react7.useState)(null);
868
+ (0, import_react7.useEffect)(() => {
852
869
  if (!themeRegistry || themeRegistry.length === 0) return;
853
870
  fetch("/api/settings/theme").then((r) => r.ok ? r.json() : {}).then((data) => {
854
871
  const id2 = data?.activeThemeId?.trim();
@@ -862,8 +879,8 @@ function useResolvedTheme(theme, themeRegistry) {
862
879
  return found?.config ?? theme ?? themeRegistry[0]?.config;
863
880
  }
864
881
  function useStoreEnabled() {
865
- const [storeEnabled, setStoreEnabled] = (0, import_react6.useState)(false);
866
- (0, import_react6.useEffect)(() => {
882
+ const [storeEnabled, setStoreEnabled] = (0, import_react7.useState)(false);
883
+ (0, import_react7.useEffect)(() => {
867
884
  fetch("/api/settings/store").then((r) => r.ok ? r.json() : {}).then((data) => {
868
885
  setStoreEnabled(data?.enabled === "true");
869
886
  }).catch(() => {
@@ -874,7 +891,7 @@ function useStoreEnabled() {
874
891
  function AdminLayout({ children, customNavItems = [], customNavSections = [], customCrudConfigs = {}, theme, themeRegistry, pluginDescriptors = [] }) {
875
892
  const resolvedTheme = useResolvedTheme(theme, themeRegistry);
876
893
  const storeEnabled = useStoreEnabled();
877
- const configValue = import_react6.default.useMemo(
894
+ const configValue = import_react7.default.useMemo(
878
895
  () => ({
879
896
  customNavItems,
880
897
  customNavSections,
@@ -904,10 +921,10 @@ function AdminShell({ children }) {
904
921
  }
905
922
 
906
923
  // src/components/Admin/CRUD.tsx
907
- var import_react12 = require("react");
924
+ var import_react13 = require("react");
908
925
 
909
926
  // src/components/Admin/CreateEditForm.tsx
910
- var import_react10 = require("react");
927
+ var import_react11 = require("react");
911
928
  var import_lucide_react8 = require("lucide-react");
912
929
 
913
930
  // src/components/ui/input.tsx
@@ -1105,7 +1122,7 @@ var Label3 = React10.forwardRef(({ className, ...props }, ref) => /* @__PURE__ *
1105
1122
  Label3.displayName = LabelPrimitive.Root.displayName;
1106
1123
 
1107
1124
  // src/components/ui/file-upload.tsx
1108
- var import_react8 = require("react");
1125
+ var import_react9 = require("react");
1109
1126
 
1110
1127
  // src/components/ui/progress.tsx
1111
1128
  var React11 = __toESM(require("react"), 1);
@@ -1134,10 +1151,10 @@ Progress.displayName = ProgressPrimitive.Root.displayName;
1134
1151
  // src/components/ui/file-upload.tsx
1135
1152
  var import_jsx_runtime15 = require("react/jsx-runtime");
1136
1153
  function FileUpload({ onUploadSuccess }) {
1137
- const [selectedFile, setSelectedFile] = (0, import_react8.useState)(null);
1138
- const [uploading, setUploading] = (0, import_react8.useState)(false);
1139
- const [progress, setProgress] = (0, import_react8.useState)(0);
1140
- const [fileUrl, setFileUrl] = (0, import_react8.useState)("");
1154
+ const [selectedFile, setSelectedFile] = (0, import_react9.useState)(null);
1155
+ const [uploading, setUploading] = (0, import_react9.useState)(false);
1156
+ const [progress, setProgress] = (0, import_react9.useState)(0);
1157
+ const [fileUrl, setFileUrl] = (0, import_react9.useState)("");
1141
1158
  const handleFileChange = (event) => {
1142
1159
  setSelectedFile(event.target.files[0]);
1143
1160
  };
@@ -1178,7 +1195,7 @@ function FileUpload({ onUploadSuccess }) {
1178
1195
  }
1179
1196
 
1180
1197
  // src/components/Admin/RelationAutocomplete.tsx
1181
- var import_react9 = require("react");
1198
+ var import_react10 = require("react");
1182
1199
  var import_lucide_react7 = require("lucide-react");
1183
1200
  var import_jsx_runtime16 = require("react/jsx-runtime");
1184
1201
  var DEBOUNCE_MS = 300;
@@ -1192,21 +1209,21 @@ function RelationAutocomplete({
1192
1209
  placeholder = "Select\u2026",
1193
1210
  disabled = false
1194
1211
  }) {
1195
- const [open, setOpen] = (0, import_react9.useState)(false);
1196
- const [search, setSearch] = (0, import_react9.useState)("");
1197
- const [searchInput, setSearchInput] = (0, import_react9.useState)("");
1198
- const [items, setItems] = (0, import_react9.useState)([]);
1199
- const [total, setTotal] = (0, import_react9.useState)(0);
1200
- const [page, setPage] = (0, import_react9.useState)(1);
1201
- const [loading, setLoading] = (0, import_react9.useState)(false);
1202
- const [loadingMore, setLoadingMore] = (0, import_react9.useState)(false);
1203
- const [selectedLabel, setSelectedLabel] = (0, import_react9.useState)(null);
1204
- const [initialLabelLoaded, setInitialLabelLoaded] = (0, import_react9.useState)(false);
1205
- const containerRef = (0, import_react9.useRef)(null);
1206
- const listRef = (0, import_react9.useRef)(null);
1207
- const debounceRef = (0, import_react9.useRef)(null);
1212
+ const [open, setOpen] = (0, import_react10.useState)(false);
1213
+ const [search, setSearch] = (0, import_react10.useState)("");
1214
+ const [searchInput, setSearchInput] = (0, import_react10.useState)("");
1215
+ const [items, setItems] = (0, import_react10.useState)([]);
1216
+ const [total, setTotal] = (0, import_react10.useState)(0);
1217
+ const [page, setPage] = (0, import_react10.useState)(1);
1218
+ const [loading, setLoading] = (0, import_react10.useState)(false);
1219
+ const [loadingMore, setLoadingMore] = (0, import_react10.useState)(false);
1220
+ const [selectedLabel, setSelectedLabel] = (0, import_react10.useState)(null);
1221
+ const [initialLabelLoaded, setInitialLabelLoaded] = (0, import_react10.useState)(false);
1222
+ const containerRef = (0, import_react10.useRef)(null);
1223
+ const listRef = (0, import_react10.useRef)(null);
1224
+ const debounceRef = (0, import_react10.useRef)(null);
1208
1225
  const hasMore = items.length < total;
1209
- const fetchPage = (0, import_react9.useCallback)(
1226
+ const fetchPage = (0, import_react10.useCallback)(
1210
1227
  async (pageNum, searchQ, append) => {
1211
1228
  const params = new URLSearchParams({
1212
1229
  page: String(pageNum),
@@ -1227,13 +1244,13 @@ function RelationAutocomplete({
1227
1244
  },
1228
1245
  [apiEndpoint]
1229
1246
  );
1230
- (0, import_react9.useEffect)(() => {
1247
+ (0, import_react10.useEffect)(() => {
1231
1248
  if (!open) return;
1232
1249
  setPage(1);
1233
1250
  setLoading(true);
1234
1251
  fetchPage(1, search, false).finally(() => setLoading(false));
1235
1252
  }, [open, search, fetchPage]);
1236
- (0, import_react9.useEffect)(() => {
1253
+ (0, import_react10.useEffect)(() => {
1237
1254
  if (!open) return;
1238
1255
  const onSearchInput = () => {
1239
1256
  if (debounceRef.current) clearTimeout(debounceRef.current);
@@ -1248,7 +1265,13 @@ function RelationAutocomplete({
1248
1265
  if (debounceRef.current) clearTimeout(debounceRef.current);
1249
1266
  };
1250
1267
  }, [searchInput, open]);
1251
- const loadInitialLabel = (0, import_react9.useCallback)(() => {
1268
+ (0, import_react10.useEffect)(() => {
1269
+ if (open) return;
1270
+ setSearchInput("");
1271
+ setSearch("");
1272
+ setPage(1);
1273
+ }, [open]);
1274
+ const loadInitialLabel = (0, import_react10.useCallback)(() => {
1252
1275
  if (initialLabelLoaded || value == null || value === "") return;
1253
1276
  setInitialLabelLoaded(true);
1254
1277
  fetch(`${apiEndpoint}/${value}`).then((r) => r.ok ? r.json() : null).then((item) => {
@@ -1258,14 +1281,14 @@ function RelationAutocomplete({
1258
1281
  }).catch(() => {
1259
1282
  });
1260
1283
  }, [apiEndpoint, value, labelField, initialLabelLoaded]);
1261
- (0, import_react9.useEffect)(() => {
1284
+ (0, import_react10.useEffect)(() => {
1262
1285
  if (value != null && value !== "") loadInitialLabel();
1263
1286
  else {
1264
1287
  setSelectedLabel(null);
1265
1288
  setInitialLabelLoaded(false);
1266
1289
  }
1267
1290
  }, [value, loadInitialLabel]);
1268
- (0, import_react9.useEffect)(() => {
1291
+ (0, import_react10.useEffect)(() => {
1269
1292
  if (!open) return;
1270
1293
  const el = listRef.current;
1271
1294
  if (!el) return;
@@ -1281,7 +1304,7 @@ function RelationAutocomplete({
1281
1304
  el.addEventListener("scroll", onScroll);
1282
1305
  return () => el.removeEventListener("scroll", onScroll);
1283
1306
  }, [open, hasMore, page, search, loadingMore, fetchPage]);
1284
- (0, import_react9.useEffect)(() => {
1307
+ (0, import_react10.useEffect)(() => {
1285
1308
  if (!open) return;
1286
1309
  const onPointerDown = (e) => {
1287
1310
  if (containerRef.current && !containerRef.current.contains(e.target)) {
@@ -1375,9 +1398,9 @@ var import_sonner3 = require("sonner");
1375
1398
  var import_jsx_runtime17 = require("react/jsx-runtime");
1376
1399
  function CreateEditForm({ isOpen, onClose, apiEndpoint, columns, existingData }) {
1377
1400
  const isMobile = useIsMobile();
1378
- const [formData, setFormData] = (0, import_react10.useState)({});
1379
- const [errors, setErrors] = (0, import_react10.useState)({});
1380
- (0, import_react10.useEffect)(() => {
1401
+ const [formData, setFormData] = (0, import_react11.useState)({});
1402
+ const [errors, setErrors] = (0, import_react11.useState)({});
1403
+ (0, import_react11.useEffect)(() => {
1381
1404
  if (existingData) {
1382
1405
  setFormData(existingData);
1383
1406
  } else {
@@ -1664,7 +1687,7 @@ var DialogContent = React14.forwardRef(({ className, children, ...props }, ref)
1664
1687
  {
1665
1688
  ref,
1666
1689
  className: cn(
1667
- "fixed left-[50%] top-[50%] z-50 grid w-full max-w-lg translate-x-[-50%] translate-y-[-50%] gap-4 border bg-background p-6 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:rounded-lg",
1690
+ "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",
1668
1691
  className
1669
1692
  ),
1670
1693
  ...props,
@@ -1700,7 +1723,7 @@ var DialogFooter = ({
1700
1723
  "div",
1701
1724
  {
1702
1725
  className: cn(
1703
- "flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2",
1726
+ "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",
1704
1727
  className
1705
1728
  ),
1706
1729
  ...props
@@ -1732,9 +1755,10 @@ DialogDescription.displayName = DialogPrimitive.Description.displayName;
1732
1755
  // src/components/Admin/CRUD.tsx
1733
1756
  var import_lucide_react12 = require("lucide-react");
1734
1757
  var import_link4 = __toESM(require("next/link"), 1);
1758
+ var import_navigation4 = require("next/navigation");
1735
1759
 
1736
1760
  // src/components/Admin/BulkUploadDialog.tsx
1737
- var import_react11 = require("react");
1761
+ var import_react12 = require("react");
1738
1762
  var import_lucide_react11 = require("lucide-react");
1739
1763
  var import_papaparse = __toESM(require("papaparse"), 1);
1740
1764
  var import_jsx_runtime21 = require("react/jsx-runtime");
@@ -1749,18 +1773,18 @@ var AUTO_GENERATED_COLS = /* @__PURE__ */ new Set([
1749
1773
  "deleted"
1750
1774
  ]);
1751
1775
  function BulkUploadDialog({ apiEndpoint, onClose }) {
1752
- const [columns, setColumns] = (0, import_react11.useState)([]);
1753
- const [uniqueColumns, setUniqueColumns] = (0, import_react11.useState)([]);
1754
- const [loading, setLoading] = (0, import_react11.useState)(true);
1755
- const [importing, setImporting] = (0, import_react11.useState)(false);
1756
- const [error, setError] = (0, import_react11.useState)(null);
1757
- const [success, setSuccess] = (0, import_react11.useState)(null);
1758
- const [parsedData, setParsedData] = (0, import_react11.useState)([]);
1759
- const [parseErrors, setParseErrors] = (0, import_react11.useState)([]);
1760
- const [upsertKey, setUpsertKey] = (0, import_react11.useState)("id");
1761
- const [fileName, setFileName] = (0, import_react11.useState)("");
1762
- const fileInputRef = (0, import_react11.useRef)(null);
1763
- (0, import_react11.useEffect)(() => {
1776
+ const [columns, setColumns] = (0, import_react12.useState)([]);
1777
+ const [uniqueColumns, setUniqueColumns] = (0, import_react12.useState)([]);
1778
+ const [loading, setLoading] = (0, import_react12.useState)(true);
1779
+ const [importing, setImporting] = (0, import_react12.useState)(false);
1780
+ const [error, setError] = (0, import_react12.useState)(null);
1781
+ const [success, setSuccess] = (0, import_react12.useState)(null);
1782
+ const [parsedData, setParsedData] = (0, import_react12.useState)([]);
1783
+ const [parseErrors, setParseErrors] = (0, import_react12.useState)([]);
1784
+ const [upsertKey, setUpsertKey] = (0, import_react12.useState)("id");
1785
+ const [fileName, setFileName] = (0, import_react12.useState)("");
1786
+ const fileInputRef = (0, import_react12.useRef)(null);
1787
+ (0, import_react12.useEffect)(() => {
1764
1788
  fetchMetadata();
1765
1789
  }, [apiEndpoint]);
1766
1790
  const fetchMetadata = async () => {
@@ -2002,6 +2026,7 @@ function BulkUploadDialog({ apiEndpoint, onClose }) {
2002
2026
  }
2003
2027
 
2004
2028
  // src/components/Admin/CRUD.tsx
2029
+ var import_sonner4 = require("sonner");
2005
2030
  var import_jsx_runtime22 = require("react/jsx-runtime");
2006
2031
  function getNestedValue(obj, path) {
2007
2032
  return path.split(".").reduce((current, key) => {
@@ -2026,38 +2051,55 @@ function AdminCRUD({
2026
2051
  extraListParams,
2027
2052
  manageUserGroups
2028
2053
  }) {
2029
- const [data, setData] = (0, import_react12.useState)([]);
2030
- const [loading, setLoading] = (0, import_react12.useState)(true);
2031
- const [error, setError] = (0, import_react12.useState)(null);
2032
- const [page, setPage] = (0, import_react12.useState)(1);
2033
- const [totalPages, setTotalPages] = (0, import_react12.useState)(1);
2034
- const [sortField, setSortField] = (0, import_react12.useState)(defaultSortField);
2035
- const [sortOrder, setSortOrder] = (0, import_react12.useState)(defaultSortOrder);
2036
- const [searchQuery, setSearchQuery] = (0, import_react12.useState)("");
2037
- const [filterValues, setFilterValues] = (0, import_react12.useState)({});
2038
- const [filterApplyKey, setFilterApplyKey] = (0, import_react12.useState)(0);
2039
- const [isFormOpen, setIsFormOpen] = (0, import_react12.useState)(false);
2040
- const [editingItem, setEditingItem] = (0, import_react12.useState)(null);
2041
- const [deleteDialogOpen, setDeleteDialogOpen] = (0, import_react12.useState)(false);
2042
- const [itemToDelete, setItemToDelete] = (0, import_react12.useState)(null);
2043
- const [deleteLoading, setDeleteLoading] = (0, import_react12.useState)(false);
2044
- const [refreshKey, setRefreshKey] = (0, import_react12.useState)(0);
2045
- const [bulkDialogOpen, setBulkDialogOpen] = (0, import_react12.useState)(false);
2046
- const [showFilters, setShowFilters] = (0, import_react12.useState)(false);
2047
- const [roleOptions, setRoleOptions] = (0, import_react12.useState)([]);
2054
+ const router = (0, import_navigation4.useRouter)();
2055
+ const [data, setData] = (0, import_react13.useState)([]);
2056
+ const [loading, setLoading] = (0, import_react13.useState)(true);
2057
+ const [error, setError] = (0, import_react13.useState)(null);
2058
+ const [page, setPage] = (0, import_react13.useState)(1);
2059
+ const [totalPages, setTotalPages] = (0, import_react13.useState)(1);
2060
+ const [sortField, setSortField] = (0, import_react13.useState)(defaultSortField);
2061
+ const [sortOrder, setSortOrder] = (0, import_react13.useState)(defaultSortOrder);
2062
+ const [searchQuery, setSearchQuery] = (0, import_react13.useState)("");
2063
+ const [searchInput, setSearchInput] = (0, import_react13.useState)("");
2064
+ const [filterValues, setFilterValues] = (0, import_react13.useState)({});
2065
+ const [filterApplyKey, setFilterApplyKey] = (0, import_react13.useState)(0);
2066
+ const [isFormOpen, setIsFormOpen] = (0, import_react13.useState)(false);
2067
+ const [editingItem, setEditingItem] = (0, import_react13.useState)(null);
2068
+ const [deleteDialogOpen, setDeleteDialogOpen] = (0, import_react13.useState)(false);
2069
+ const [itemToDelete, setItemToDelete] = (0, import_react13.useState)(null);
2070
+ const [deleteLoading, setDeleteLoading] = (0, import_react13.useState)(false);
2071
+ const [refreshKey, setRefreshKey] = (0, import_react13.useState)(0);
2072
+ const [bulkDialogOpen, setBulkDialogOpen] = (0, import_react13.useState)(false);
2073
+ const [showFilters, setShowFilters] = (0, import_react13.useState)(false);
2074
+ const [isRefetching, setIsRefetching] = (0, import_react13.useState)(false);
2075
+ const [roleOptions, setRoleOptions] = (0, import_react13.useState)([]);
2076
+ const hasLoadedRef = (0, import_react13.useRef)(false);
2048
2077
  const isMobile = useIsMobile();
2049
2078
  const showGroupColumn = !!manageUserGroups && roleOptions.length > 0;
2050
- (0, import_react12.useEffect)(() => {
2079
+ (0, import_react13.useEffect)(() => {
2080
+ const timeoutId = setTimeout(() => {
2081
+ if (searchInput !== searchQuery) {
2082
+ setPage(1);
2083
+ setSearchQuery(searchInput);
2084
+ }
2085
+ }, 300);
2086
+ return () => clearTimeout(timeoutId);
2087
+ }, [searchInput, searchQuery]);
2088
+ (0, import_react13.useEffect)(() => {
2051
2089
  if (!manageUserGroups) return;
2052
2090
  fetch("/api/admin/roles").then((r) => r.ok ? r.json() : null).then((data2) => {
2053
2091
  if (data2?.groups?.length) setRoleOptions(data2.groups.map((g) => ({ id: g.id, name: g.name })));
2054
2092
  }).catch(() => {
2055
2093
  });
2056
2094
  }, [manageUserGroups]);
2057
- (0, import_react12.useEffect)(() => {
2095
+ (0, import_react13.useEffect)(() => {
2058
2096
  async function loadData() {
2059
2097
  try {
2060
- setLoading(true);
2098
+ if (!hasLoadedRef.current) {
2099
+ setLoading(true);
2100
+ } else {
2101
+ setIsRefetching(true);
2102
+ }
2061
2103
  setError(null);
2062
2104
  const params = new URLSearchParams({
2063
2105
  page: page.toString(),
@@ -2097,6 +2139,8 @@ function AdminCRUD({
2097
2139
  setTotalPages(1);
2098
2140
  } finally {
2099
2141
  setLoading(false);
2142
+ setIsRefetching(false);
2143
+ hasLoadedRef.current = true;
2100
2144
  }
2101
2145
  }
2102
2146
  loadData();
@@ -2107,30 +2151,67 @@ function AdminCRUD({
2107
2151
  };
2108
2152
  const handleSearch = () => {
2109
2153
  setPage(1);
2154
+ setSearchQuery(searchInput);
2110
2155
  };
2111
2156
  const handleApplyFilters = () => {
2112
2157
  setPage(1);
2113
2158
  setFilterApplyKey((k) => k + 1);
2114
2159
  };
2160
+ const closeDeleteDialog = () => {
2161
+ console.debug("[CRUD][delete] closeDeleteDialog", {
2162
+ open: deleteDialogOpen,
2163
+ itemId: itemToDelete?.id,
2164
+ loading: deleteLoading
2165
+ });
2166
+ setDeleteDialogOpen(false);
2167
+ setItemToDelete(null);
2168
+ setDeleteLoading(false);
2169
+ };
2115
2170
  const handleDeleteClick = (item) => {
2171
+ console.debug("[CRUD][delete] handleDeleteClick", {
2172
+ itemId: item?.id,
2173
+ resource: resourceName
2174
+ });
2175
+ const active = typeof document !== "undefined" ? document.activeElement : null;
2176
+ if (active instanceof HTMLElement) {
2177
+ active.blur();
2178
+ }
2179
+ setDeleteLoading(false);
2116
2180
  setItemToDelete(item);
2117
- setDeleteDialogOpen(true);
2181
+ window.setTimeout(() => {
2182
+ setDeleteDialogOpen(true);
2183
+ }, 0);
2118
2184
  };
2119
2185
  const handleDelete = async () => {
2120
- if (!itemToDelete) return;
2186
+ if (!itemToDelete) {
2187
+ console.debug("[CRUD][delete] handleDelete blocked: no itemToDelete");
2188
+ return;
2189
+ }
2190
+ console.debug("[CRUD][delete] handleDelete start", {
2191
+ itemId: itemToDelete.id,
2192
+ resource: resourceName
2193
+ });
2121
2194
  setDeleteLoading(true);
2122
2195
  try {
2123
2196
  const res = await fetch(`${apiEndpoint}/${itemToDelete.id}`, { method: "DELETE" });
2197
+ console.debug("[CRUD][delete] handleDelete response", {
2198
+ itemId: itemToDelete.id,
2199
+ ok: res.ok,
2200
+ status: res.status
2201
+ });
2124
2202
  if (res.ok) {
2203
+ setData((prev) => prev.filter((row) => String(row.id) !== String(itemToDelete.id)));
2125
2204
  setRefreshKey((k) => k + 1);
2126
- setDeleteDialogOpen(false);
2127
- setItemToDelete(null);
2205
+ closeDeleteDialog();
2128
2206
  } else {
2129
2207
  console.error("Failed to delete item");
2130
2208
  }
2131
2209
  } catch (err) {
2132
2210
  console.error("Error deleting item:", err);
2133
2211
  } finally {
2212
+ console.debug("[CRUD][delete] handleDelete finally", {
2213
+ itemId: itemToDelete?.id
2214
+ });
2134
2215
  setDeleteLoading(false);
2135
2216
  }
2136
2217
  };
@@ -2165,18 +2246,33 @@ function AdminCRUD({
2165
2246
  }
2166
2247
  const result = await res.json();
2167
2248
  if (result.inviteLink) {
2168
- alert(`New invite link generated: ${result.inviteLink}
2169
-
2170
- Note: ${result.note}`);
2249
+ const note = result.note ? ` ${result.note}` : "";
2250
+ import_sonner4.toast.success(`New invite link generated.${note}`);
2171
2251
  }
2172
2252
  } catch (error2) {
2173
2253
  console.error("Error regenerating invite:", error2);
2174
- alert(error2 instanceof Error ? error2.message : "Failed to regenerate invite");
2254
+ import_sonner4.toast.error(error2 instanceof Error ? error2.message : "Failed to regenerate invite");
2175
2255
  }
2176
2256
  };
2177
2257
  const addEditPage = addEditPageUrl && addEditPageUrl.length > 0;
2178
2258
  const hasCustomView = customViewPageUrl && customViewPageUrl.length > 0;
2179
2259
  const resourceName = apiEndpoint.replace("/api/", "");
2260
+ const hasDetailViewPage = (/* @__PURE__ */ new Set(["contacts", "form-submissions", "orders", "payments"])).has(resourceName);
2261
+ const getRowDestination = (item) => {
2262
+ if (item.id == null) return "modal";
2263
+ if (addEditPage) return `${addEditPageUrl}/${item.id}`;
2264
+ if (hasCustomView) return `${customViewPageUrl}/${item.id}`;
2265
+ if (hasDetailViewPage) return `/admin/${resourceName}/${item.id}/view`;
2266
+ return "modal";
2267
+ };
2268
+ const handleRowClick = (item) => {
2269
+ const destination = getRowDestination(item);
2270
+ if (destination === "modal") {
2271
+ handleEdit(item);
2272
+ return;
2273
+ }
2274
+ router.push(destination);
2275
+ };
2180
2276
  const handleExport = async () => {
2181
2277
  try {
2182
2278
  const res = await fetch(`${apiEndpoint}/export?format=csv`);
@@ -2190,7 +2286,7 @@ Note: ${result.note}`);
2190
2286
  URL.revokeObjectURL(url);
2191
2287
  } catch (err) {
2192
2288
  console.error("Export error:", err);
2193
- alert("Failed to export data");
2289
+ import_sonner4.toast.error("Failed to export data");
2194
2290
  }
2195
2291
  };
2196
2292
  if (loading) {
@@ -2330,8 +2426,8 @@ Note: ${result.note}`);
2330
2426
  {
2331
2427
  type: "text",
2332
2428
  placeholder: "Search...",
2333
- value: searchQuery,
2334
- onChange: (e) => setSearchQuery(e.target.value),
2429
+ value: searchInput,
2430
+ onChange: (e) => setSearchInput(e.target.value),
2335
2431
  onKeyDown: (e) => e.key === "Enter" && handleSearch(),
2336
2432
  className: "border-0 focus-visible:ring-0 focus-visible:ring-offset-0 rounded-l-md rounded-r-none flex-1 min-w-0"
2337
2433
  }
@@ -2425,6 +2521,10 @@ Note: ${result.note}`);
2425
2521
  }),
2426
2522
  /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(Button, { variant: "outline", size: "sm", className: "h-8", onClick: handleApplyFilters, children: "Apply filters" })
2427
2523
  ] }),
2524
+ isRefetching && /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: "mb-3 flex items-center text-xs text-gray-500", children: [
2525
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { className: "animate-spin rounded-full h-3.5 w-3.5 border-2 border-gray-300 border-t-gray-600" }),
2526
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { className: "ml-2", children: "Refreshing list..." })
2527
+ ] }),
2428
2528
  isMobile ? /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { className: "flex flex-col gap-2 min-w-0", children: data && data.length > 0 ? data.map((item, index) => {
2429
2529
  const displayCols = columns?.slice(0, 4) ?? [];
2430
2530
  const primary = displayCols[0];
@@ -2432,27 +2532,17 @@ Note: ${result.note}`);
2432
2532
  return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(
2433
2533
  "div",
2434
2534
  {
2435
- className: "min-w-0 rounded-md border border-gray-200 bg-gray-50/50 p-2.5 flex flex-col gap-1",
2535
+ className: "min-w-0 rounded-md border border-gray-200 bg-gray-50/50 p-2.5 flex flex-col gap-1 cursor-pointer",
2536
+ onClick: () => handleRowClick(item),
2436
2537
  children: [
2437
2538
  /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: "flex items-center justify-between gap-2", children: [
2438
2539
  /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { className: "min-w-0 break-words flex-1 leading-tight", children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { className: "font-medium", children: primaryVal != null ? String(primaryVal) : "\u2014" }) }),
2439
- /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(DropdownMenu, { children: [
2540
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { onClick: (e) => e.stopPropagation(), children: /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(DropdownMenu, { children: [
2440
2541
  /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(Button, { variant: "ghost", size: "icon", className: "h-8 w-8 shrink-0", children: [
2441
2542
  /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_lucide_react12.MoreVertical, { className: "h-4 w-4" }),
2442
2543
  /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { className: "sr-only", children: "Actions" })
2443
2544
  ] }) }),
2444
2545
  /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(DropdownMenuContent, { align: "end", children: [
2445
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(DropdownMenuItem, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(
2446
- import_link4.default,
2447
- {
2448
- href: hasCustomView ? `${customViewPageUrl}/${item.id}` : `/admin/${resourceName}/${item.id}/view`,
2449
- className: "flex items-center gap-2",
2450
- children: [
2451
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_lucide_react12.Eye, { className: "h-4 w-4" }),
2452
- "View"
2453
- ]
2454
- }
2455
- ) }),
2456
2546
  !addEditPage && /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(DropdownMenuItem, { onClick: () => handleEdit(item), children: [
2457
2547
  /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_lucide_react12.Edit, { className: "h-4 w-4 mr-2" }),
2458
2548
  "Edit"
@@ -2477,7 +2567,7 @@ Note: ${result.note}`);
2477
2567
  }
2478
2568
  )
2479
2569
  ] })
2480
- ] })
2570
+ ] }, `mobile-actions-${String(item.id ?? index)}-${refreshKey}`) })
2481
2571
  ] }),
2482
2572
  displayCols.slice(1).map((col) => /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: "text-sm text-gray-600 flex gap-1 min-w-0 leading-tight", children: [
2483
2573
  /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("span", { className: "shrink-0", children: [
@@ -2486,7 +2576,7 @@ Note: ${result.note}`);
2486
2576
  ] }),
2487
2577
  /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { className: "min-w-0 break-words", children: formatCellValue(getNestedValue(item, col.field || col.key), col) })
2488
2578
  ] }, col.field || col.key)),
2489
- showGroupColumn && /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: "text-sm text-gray-600 flex gap-1 items-center min-w-0", children: [
2579
+ showGroupColumn && /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: "text-sm text-gray-600 flex gap-1 items-center min-w-0", onClick: (e) => e.stopPropagation(), children: [
2490
2580
  /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { className: "shrink-0", children: "Group:" }),
2491
2581
  /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(
2492
2582
  "select",
@@ -2526,70 +2616,94 @@ Note: ${result.note}`);
2526
2616
  showGroupColumn && /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(TableHead, { className: "min-w-[140px]", children: "Group" }),
2527
2617
  /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(TableHead, { className: "w-12 text-center", children: "Actions" })
2528
2618
  ] }) }),
2529
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(TableBody, { children: data && data.length > 0 ? data.map((item, index) => /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(TableRow, { children: [
2530
- columns && columns.map((col, colIndex) => {
2531
- const fieldKey = col.field || col.key;
2532
- const value = getNestedValue(item, fieldKey);
2533
- return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(TableCell, { children: formatCellValue(value, col) }, `${item.id}-${colIndex}-${fieldKey}`);
2534
- }),
2535
- showGroupColumn && /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(TableCell, { children: /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(
2536
- "select",
2537
- {
2538
- className: "max-w-[180px] rounded border border-gray-300 px-2 py-1 text-sm dark:border-gray-600 dark:bg-gray-800",
2539
- value: item.groupId != null && roleOptions.some((g) => g.id === item.groupId) ? String(item.groupId) : "",
2540
- onChange: (e) => {
2541
- const v = e.target.value;
2542
- if (v) handleUserGroupChange(Number(item.id), Number(v));
2543
- },
2544
- children: [
2545
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("option", { value: "", children: "\u2014" }),
2546
- roleOptions.map((g) => /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("option", { value: g.id, children: g.name }, g.id))
2547
- ]
2548
- }
2549
- ) }),
2550
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(TableCell, { className: "text-center", children: /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(DropdownMenu, { children: [
2551
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(Button, { variant: "ghost", size: "icon", className: "h-8 w-8", children: [
2552
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_lucide_react12.MoreVertical, { className: "h-4 w-4" }),
2553
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { className: "sr-only", children: "Actions" })
2554
- ] }) }),
2555
- /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(DropdownMenuContent, { align: "end", children: [
2556
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(DropdownMenuItem, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(
2557
- import_link4.default,
2619
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(TableBody, { children: data && data.length > 0 ? data.map((item, index) => /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(
2620
+ TableRow,
2621
+ {
2622
+ className: "cursor-pointer",
2623
+ onClick: () => handleRowClick(item),
2624
+ children: [
2625
+ columns && columns.map((col, colIndex) => {
2626
+ const fieldKey = col.field || col.key;
2627
+ const value = getNestedValue(item, fieldKey);
2628
+ return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(TableCell, { children: formatCellValue(value, col) }, `${item.id}-${colIndex}-${fieldKey}`);
2629
+ }),
2630
+ showGroupColumn && /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(TableCell, { onClick: (e) => e.stopPropagation(), children: /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(
2631
+ "select",
2558
2632
  {
2559
- href: hasCustomView ? `${customViewPageUrl}/${item.id}` : `/admin/${resourceName}/${item.id}/view`,
2560
- className: "flex items-center gap-2",
2633
+ className: "max-w-[180px] rounded border border-gray-300 px-2 py-1 text-sm dark:border-gray-600 dark:bg-gray-800",
2634
+ value: item.groupId != null && roleOptions.some((g) => g.id === item.groupId) ? String(item.groupId) : "",
2635
+ onChange: (e) => {
2636
+ const v = e.target.value;
2637
+ if (v) handleUserGroupChange(Number(item.id), Number(v));
2638
+ },
2561
2639
  children: [
2562
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_lucide_react12.Eye, { className: "h-4 w-4" }),
2563
- "View"
2640
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("option", { value: "", children: "\u2014" }),
2641
+ roleOptions.map((g) => /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("option", { value: g.id, children: g.name }, g.id))
2564
2642
  ]
2565
2643
  }
2566
2644
  ) }),
2567
- !addEditPage && /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(DropdownMenuItem, { onClick: () => handleEdit(item), children: [
2568
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_lucide_react12.Edit, { className: "h-4 w-4 mr-2" }),
2569
- "Edit"
2570
- ] }),
2571
- addEditPage && /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(DropdownMenuItem, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(import_link4.default, { href: addEditPageUrl + "/" + item.id, className: "flex items-center gap-2", children: [
2572
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_lucide_react12.Edit, { className: "h-4 w-4" }),
2573
- "Edit"
2574
- ] }) }),
2575
- resourceName === "users" && /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(DropdownMenuItem, { onClick: () => handleRegenerateInvite(Number(item.id)), children: [
2576
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_lucide_react12.RefreshCw, { className: "h-4 w-4 mr-2" }),
2577
- "Regenerate Invite"
2578
- ] }),
2579
- /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(
2580
- DropdownMenuItem,
2581
- {
2582
- onClick: () => handleDeleteClick(item),
2583
- className: "text-red-600 focus:text-red-600",
2584
- children: [
2585
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_lucide_react12.Trash2, { className: "h-4 w-4 mr-2" }),
2586
- "Delete"
2587
- ]
2588
- }
2589
- )
2590
- ] })
2591
- ] }) })
2592
- ] }, String(item.id ?? index))) : /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(TableRow, { children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
2645
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(TableCell, { className: "text-center", onClick: (e) => e.stopPropagation(), children: /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: "flex items-center justify-center gap-1", children: [
2646
+ !addEditPage && /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(
2647
+ Button,
2648
+ {
2649
+ variant: "outline",
2650
+ size: "icon",
2651
+ className: "h-7 w-7",
2652
+ onClick: () => handleEdit(item),
2653
+ title: "Edit",
2654
+ children: [
2655
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_lucide_react12.Edit, { className: "h-3.5 w-3.5" }),
2656
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { className: "sr-only", children: "Edit" })
2657
+ ]
2658
+ }
2659
+ ),
2660
+ addEditPage && /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(
2661
+ Button,
2662
+ {
2663
+ variant: "outline",
2664
+ size: "icon",
2665
+ className: "h-7 w-7",
2666
+ onClick: () => router.push(addEditPageUrl + "/" + item.id),
2667
+ title: "Edit",
2668
+ children: [
2669
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_lucide_react12.Edit, { className: "h-3.5 w-3.5" }),
2670
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { className: "sr-only", children: "Edit" })
2671
+ ]
2672
+ }
2673
+ ),
2674
+ resourceName === "users" && /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(
2675
+ Button,
2676
+ {
2677
+ variant: "outline",
2678
+ size: "icon",
2679
+ className: "h-7 w-7",
2680
+ onClick: () => handleRegenerateInvite(Number(item.id)),
2681
+ title: "Regenerate Invite",
2682
+ children: [
2683
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_lucide_react12.RefreshCw, { className: "h-3.5 w-3.5" }),
2684
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { className: "sr-only", children: "Regenerate Invite" })
2685
+ ]
2686
+ }
2687
+ ),
2688
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(
2689
+ Button,
2690
+ {
2691
+ variant: "outline",
2692
+ size: "icon",
2693
+ className: "h-7 w-7 border-red-300 text-red-600 hover:text-red-700",
2694
+ onClick: () => handleDeleteClick(item),
2695
+ title: "Delete",
2696
+ children: [
2697
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_lucide_react12.Trash2, { className: "h-3.5 w-3.5" }),
2698
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { className: "sr-only", children: "Delete" })
2699
+ ]
2700
+ }
2701
+ )
2702
+ ] }) })
2703
+ ]
2704
+ },
2705
+ String(item.id ?? index)
2706
+ )) : /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(TableRow, { children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
2593
2707
  TableCell,
2594
2708
  {
2595
2709
  colSpan: columns ? columns.length + 1 + (showGroupColumn ? 1 : 0) : 1,
@@ -2635,21 +2749,35 @@ Note: ${result.note}`);
2635
2749
  existingData: editingItem
2636
2750
  }
2637
2751
  ),
2638
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(Dialog, { open: deleteDialogOpen, onOpenChange: setDeleteDialogOpen, children: /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(DialogContent, { children: [
2639
- /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(DialogHeader, { children: [
2640
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(DialogTitle, { children: "Confirm Delete" }),
2641
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(DialogDescription, { children: "Are you sure you want to delete this item? This action cannot be undone." }),
2642
- itemToDelete && /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: "mt-2 p-2 bg-gray-50 rounded", children: [
2643
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("strong", { children: "Item:" }),
2644
- " ",
2645
- String(itemToDelete.name ?? itemToDelete.title ?? itemToDelete.id ?? "")
2752
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
2753
+ Dialog,
2754
+ {
2755
+ open: deleteDialogOpen,
2756
+ onOpenChange: (open) => {
2757
+ console.debug("[CRUD][delete] dialog onOpenChange", {
2758
+ nextOpen: open,
2759
+ itemId: itemToDelete?.id
2760
+ });
2761
+ if (!open) closeDeleteDialog();
2762
+ else setDeleteDialogOpen(true);
2763
+ },
2764
+ children: /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(DialogContent, { children: [
2765
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(DialogHeader, { children: [
2766
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(DialogTitle, { children: "Confirm Delete" }),
2767
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(DialogDescription, { children: "Are you sure you want to delete this item? This action cannot be undone." }),
2768
+ itemToDelete && /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: "mt-2 p-2 bg-gray-50 rounded", children: [
2769
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("strong", { children: "Item:" }),
2770
+ " ",
2771
+ String(itemToDelete.name ?? itemToDelete.title ?? itemToDelete.id ?? "")
2772
+ ] })
2773
+ ] }),
2774
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(DialogFooter, { children: [
2775
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(Button, { variant: "outline", onClick: closeDeleteDialog, disabled: deleteLoading, children: "Cancel" }),
2776
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(Button, { variant: "destructive", onClick: handleDelete, disabled: deleteLoading, children: deleteLoading ? "Deleting..." : "Delete" })
2777
+ ] })
2646
2778
  ] })
2647
- ] }),
2648
- /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(DialogFooter, { children: [
2649
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(Button, { variant: "outline", onClick: () => setDeleteDialogOpen(false), disabled: deleteLoading, children: "Cancel" }),
2650
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(Button, { variant: "destructive", onClick: handleDelete, disabled: deleteLoading, children: deleteLoading ? "Deleting..." : "Delete" })
2651
- ] })
2652
- ] }) }),
2779
+ }
2780
+ ),
2653
2781
  bulkDialogOpen && /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
2654
2782
  BulkUploadDialog,
2655
2783
  {
@@ -2665,7 +2793,7 @@ Note: ${result.note}`);
2665
2793
  }
2666
2794
 
2667
2795
  // src/components/Admin/FormBuilder.tsx
2668
- var import_react14 = require("react");
2796
+ var import_react15 = require("react");
2669
2797
 
2670
2798
  // src/components/ui/badge.tsx
2671
2799
  var import_class_variance_authority4 = require("class-variance-authority");
@@ -2692,10 +2820,10 @@ function Badge({ className, variant, ...props }) {
2692
2820
 
2693
2821
  // src/components/Admin/FormBuilder.tsx
2694
2822
  var import_lucide_react14 = require("lucide-react");
2695
- var import_navigation4 = require("next/navigation");
2823
+ var import_navigation5 = require("next/navigation");
2696
2824
 
2697
2825
  // src/components/Admin/FormBuilder/FieldConfiguration.tsx
2698
- var import_react13 = require("react");
2826
+ var import_react14 = require("react");
2699
2827
  var import_lucide_react13 = require("lucide-react");
2700
2828
  var import_jsx_runtime24 = require("react/jsx-runtime");
2701
2829
  var FIELD_TYPES = [
@@ -2716,7 +2844,7 @@ var COLUMN_WIDTHS = [
2716
2844
  { value: 12, label: "Full Width (12 cols)" }
2717
2845
  ];
2718
2846
  function FieldConfiguration({ field, onUpdate }) {
2719
- const [newOption, setNewOption] = (0, import_react13.useState)("");
2847
+ const [newOption, setNewOption] = (0, import_react14.useState)("");
2720
2848
  const addOption = () => {
2721
2849
  if (newOption.trim()) {
2722
2850
  const currentOptions = field.options || [];
@@ -2989,7 +3117,7 @@ function FieldConfiguration({ field, onUpdate }) {
2989
3117
  // src/components/Admin/FormBuilder.tsx
2990
3118
  var import_jsx_runtime25 = require("react/jsx-runtime");
2991
3119
  function FormBuilder({ formId }) {
2992
- const [formData, setFormData] = (0, import_react14.useState)({
3120
+ const [formData, setFormData] = (0, import_react15.useState)({
2993
3121
  name: "",
2994
3122
  description: "",
2995
3123
  campaign: "",
@@ -2997,12 +3125,12 @@ function FormBuilder({ formId }) {
2997
3125
  published: false,
2998
3126
  fields: []
2999
3127
  });
3000
- const [errors, setErrors] = (0, import_react14.useState)([]);
3001
- const [isLoading, setIsLoading] = (0, import_react14.useState)(false);
3002
- const [isSaving, setIsSaving] = (0, import_react14.useState)(false);
3003
- const [selectedField, setSelectedField] = (0, import_react14.useState)(null);
3004
- const router = (0, import_navigation4.useRouter)();
3005
- const loadFormData = (0, import_react14.useCallback)(async () => {
3128
+ const [errors, setErrors] = (0, import_react15.useState)([]);
3129
+ const [isLoading, setIsLoading] = (0, import_react15.useState)(false);
3130
+ const [isSaving, setIsSaving] = (0, import_react15.useState)(false);
3131
+ const [selectedField, setSelectedField] = (0, import_react15.useState)(null);
3132
+ const router = (0, import_navigation5.useRouter)();
3133
+ const loadFormData = (0, import_react15.useCallback)(async () => {
3006
3134
  try {
3007
3135
  setIsLoading(true);
3008
3136
  const response = await fetch(`/api/forms/${formId}`);
@@ -3030,12 +3158,12 @@ function FormBuilder({ formId }) {
3030
3158
  setIsLoading(false);
3031
3159
  }
3032
3160
  }, [formId]);
3033
- (0, import_react14.useEffect)(() => {
3161
+ (0, import_react15.useEffect)(() => {
3034
3162
  if (formId) {
3035
3163
  loadFormData();
3036
3164
  }
3037
3165
  }, [formId, loadFormData]);
3038
- (0, import_react14.useEffect)(() => {
3166
+ (0, import_react15.useEffect)(() => {
3039
3167
  if (formData.name && !formData.slug) {
3040
3168
  const generatedSlug = formData.name.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/(^-|-$)/g, "");
3041
3169
  setFormData((prev) => ({ ...prev, slug: generatedSlug }));
@@ -3166,19 +3294,34 @@ function FormBuilder({ formId }) {
3166
3294
  /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("h1", { className: "text-xl font-bold text-white", children: formId ? "Edit Form" : "Create New Form" }),
3167
3295
  /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("p", { className: "text-xs text-gray-300 mt-0.5", children: "Design your form with drag-and-drop fields" })
3168
3296
  ] }),
3169
- /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { className: "flex items-center space-x-3", children: /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(
3170
- Button,
3171
- {
3172
- variant: "outline",
3173
- size: "sm",
3174
- className: "bg-white text-gray-800 hover:bg-gray-100 border-0 text-xs",
3175
- onClick: () => router.push("/admin/forms"),
3176
- children: [
3177
- /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_lucide_react14.X, { className: "h-4 w-4 mr-2" }),
3178
- "Close"
3179
- ]
3180
- }
3181
- ) })
3297
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: "flex items-center space-x-3", children: [
3298
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(
3299
+ Button,
3300
+ {
3301
+ variant: "outline",
3302
+ size: "icon",
3303
+ className: "md:hidden h-8 w-8 bg-white text-gray-800 hover:bg-gray-100 border-0",
3304
+ onClick: () => router.push("/admin/forms"),
3305
+ children: [
3306
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_lucide_react14.X, { className: "h-4 w-4" }),
3307
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { className: "sr-only", children: "Close" })
3308
+ ]
3309
+ }
3310
+ ),
3311
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(
3312
+ Button,
3313
+ {
3314
+ variant: "outline",
3315
+ size: "sm",
3316
+ className: "hidden md:inline-flex bg-white text-gray-800 hover:bg-gray-100 border-0 text-xs",
3317
+ onClick: () => router.push("/admin/forms"),
3318
+ children: [
3319
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_lucide_react14.X, { className: "h-4 w-4 mr-2" }),
3320
+ "Close"
3321
+ ]
3322
+ }
3323
+ )
3324
+ ] })
3182
3325
  ] }) }),
3183
3326
  errors.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { className: "bg-red-50 border-l-4 border-red-400 p-4 mx-6 mt-4", children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { className: "flex", children: /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: "ml-3", children: [
3184
3327
  /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("h3", { className: "text-sm font-medium text-red-800", children: "Please fix the following errors:" }),
@@ -3356,11 +3499,24 @@ function FormBuilder({ formId }) {
3356
3499
  /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { className: "bg-gray-50 border-t border-gray-200 px-6 py-4", children: /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: "flex items-center justify-between", children: [
3357
3500
  /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { className: "text-sm text-gray-600", children: formId ? "Editing existing form" : "Creating new form" }),
3358
3501
  /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: "flex items-center space-x-3", children: [
3502
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(
3503
+ Button,
3504
+ {
3505
+ variant: "outline",
3506
+ size: "icon",
3507
+ className: "md:hidden h-8 w-8 bg-white text-gray-800 hover:bg-gray-100 border-0",
3508
+ onClick: () => router.push("/admin/forms"),
3509
+ children: [
3510
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_lucide_react14.X, { className: "h-4 w-4" }),
3511
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { className: "sr-only", children: "Close" })
3512
+ ]
3513
+ }
3514
+ ),
3359
3515
  /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
3360
3516
  Button,
3361
3517
  {
3362
3518
  variant: "outline",
3363
- className: "bg-white text-gray-800 hover:bg-gray-100 border-0 text-xs",
3519
+ className: "hidden md:inline-flex bg-white text-gray-800 hover:bg-gray-100 border-0 text-xs",
3364
3520
  onClick: () => router.push("/admin/forms"),
3365
3521
  children: "Close"
3366
3522
  }
@@ -3370,19 +3526,45 @@ function FormBuilder({ formId }) {
3370
3526
  {
3371
3527
  onClick: () => handleSave(false),
3372
3528
  disabled: isSaving,
3373
- className: "bg-white text-gray-800 hover:bg-gray-100 border-0 text-xs",
3529
+ size: "icon",
3530
+ className: "md:hidden h-8 w-8 bg-white text-gray-800 hover:bg-gray-100 border-0",
3531
+ children: [
3532
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_lucide_react14.Save, { className: "h-4 w-4" }),
3533
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { className: "sr-only", children: isSaving ? "Saving..." : "Save" })
3534
+ ]
3535
+ }
3536
+ ),
3537
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(
3538
+ Button,
3539
+ {
3540
+ onClick: () => handleSave(false),
3541
+ disabled: isSaving,
3542
+ className: "hidden md:inline-flex bg-white text-gray-800 hover:bg-gray-100 border-0 text-xs",
3374
3543
  children: [
3375
3544
  /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_lucide_react14.Save, { className: "h-4 w-4 mr-2" }),
3376
3545
  isSaving ? "Saving..." : "Save"
3377
3546
  ]
3378
3547
  }
3379
3548
  ),
3549
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(
3550
+ Button,
3551
+ {
3552
+ onClick: () => handleSave(true),
3553
+ disabled: isSaving,
3554
+ size: "icon",
3555
+ className: "md:hidden h-8 w-8 bg-gray-800 text-white hover:bg-gray-700",
3556
+ children: [
3557
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_lucide_react14.Check, { className: "h-4 w-4" }),
3558
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { className: "sr-only", children: isSaving ? "Publishing..." : "Publish" })
3559
+ ]
3560
+ }
3561
+ ),
3380
3562
  /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
3381
3563
  Button,
3382
3564
  {
3383
3565
  onClick: () => handleSave(true),
3384
3566
  disabled: isSaving,
3385
- className: "bg-gray-800 text-white hover:bg-gray-700 text-xs",
3567
+ className: "hidden md:inline-flex bg-gray-800 text-white hover:bg-gray-700 text-xs",
3386
3568
  children: isSaving ? "Publishing..." : "Publish"
3387
3569
  }
3388
3570
  )
@@ -3392,10 +3574,10 @@ function FormBuilder({ formId }) {
3392
3574
  }
3393
3575
 
3394
3576
  // src/components/Admin/BlogEditorPage.tsx
3395
- var import_react20 = require("react");
3577
+ var import_react21 = require("react");
3396
3578
 
3397
3579
  // src/components/ui/image-upload.tsx
3398
- var import_react15 = require("react");
3580
+ var import_react16 = require("react");
3399
3581
  var import_lucide_react15 = require("lucide-react");
3400
3582
  var import_image3 = __toESM(require("next/image"), 1);
3401
3583
  var import_jsx_runtime26 = require("react/jsx-runtime");
@@ -3410,12 +3592,12 @@ function ImageUpload({
3410
3592
  // 10MB default
3411
3593
  acceptedTypes = ["image/jpeg", "image/png", "image/gif", "image/webp"]
3412
3594
  }) {
3413
- const [isDragOver, setIsDragOver] = (0, import_react15.useState)(false);
3414
- const [isUploading, setIsUploading] = (0, import_react15.useState)(false);
3415
- const [uploadProgress, setUploadProgress] = (0, import_react15.useState)(0);
3416
- const [error, setError] = (0, import_react15.useState)(null);
3417
- const fileInputRef = (0, import_react15.useRef)(null);
3418
- const handleFileSelect = (0, import_react15.useCallback)(async (file) => {
3595
+ const [isDragOver, setIsDragOver] = (0, import_react16.useState)(false);
3596
+ const [isUploading, setIsUploading] = (0, import_react16.useState)(false);
3597
+ const [uploadProgress, setUploadProgress] = (0, import_react16.useState)(0);
3598
+ const [error, setError] = (0, import_react16.useState)(null);
3599
+ const fileInputRef = (0, import_react16.useRef)(null);
3600
+ const handleFileSelect = (0, import_react16.useCallback)(async (file) => {
3419
3601
  setError(null);
3420
3602
  setUploadProgress(0);
3421
3603
  if (!acceptedTypes.includes(file.type)) {
@@ -3447,7 +3629,7 @@ function ImageUpload({
3447
3629
  setIsUploading(false);
3448
3630
  }
3449
3631
  }, [onChange, acceptedTypes, maxSize]);
3450
- const handleDrop = (0, import_react15.useCallback)((e) => {
3632
+ const handleDrop = (0, import_react16.useCallback)((e) => {
3451
3633
  e.preventDefault();
3452
3634
  setIsDragOver(false);
3453
3635
  const files = Array.from(e.dataTransfer.files);
@@ -3455,21 +3637,21 @@ function ImageUpload({
3455
3637
  handleFileSelect(files[0]);
3456
3638
  }
3457
3639
  }, [handleFileSelect]);
3458
- const handleDragOver = (0, import_react15.useCallback)((e) => {
3640
+ const handleDragOver = (0, import_react16.useCallback)((e) => {
3459
3641
  e.preventDefault();
3460
3642
  setIsDragOver(true);
3461
3643
  }, []);
3462
- const handleDragLeave = (0, import_react15.useCallback)((e) => {
3644
+ const handleDragLeave = (0, import_react16.useCallback)((e) => {
3463
3645
  e.preventDefault();
3464
3646
  setIsDragOver(false);
3465
3647
  }, []);
3466
- const handleFileInputChange = (0, import_react15.useCallback)((e) => {
3648
+ const handleFileInputChange = (0, import_react16.useCallback)((e) => {
3467
3649
  const files = e.target.files;
3468
3650
  if (files && files.length > 0) {
3469
3651
  handleFileSelect(files[0]);
3470
3652
  }
3471
3653
  }, [handleFileSelect]);
3472
- const handleRemove = (0, import_react15.useCallback)(() => {
3654
+ const handleRemove = (0, import_react16.useCallback)(() => {
3473
3655
  if (onRemove) {
3474
3656
  onRemove();
3475
3657
  } else {
@@ -3478,7 +3660,7 @@ function ImageUpload({
3478
3660
  setError(null);
3479
3661
  setUploadProgress(0);
3480
3662
  }, [onChange, onRemove]);
3481
- const openFileDialog = (0, import_react15.useCallback)(() => {
3663
+ const openFileDialog = (0, import_react16.useCallback)(() => {
3482
3664
  fileInputRef.current?.click();
3483
3665
  }, []);
3484
3666
  return /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { className: cn("space-y-3", className), children: [
@@ -3596,10 +3778,10 @@ function ImageUpload({
3596
3778
 
3597
3779
  // src/components/Admin/BlogEditorPage.tsx
3598
3780
  var import_lucide_react19 = require("lucide-react");
3599
- var import_navigation5 = require("next/navigation");
3781
+ var import_navigation6 = require("next/navigation");
3600
3782
 
3601
3783
  // src/components/Admin/TagAutocomplete.tsx
3602
- var import_react16 = require("react");
3784
+ var import_react17 = require("react");
3603
3785
  var import_lucide_react16 = require("lucide-react");
3604
3786
  var import_jsx_runtime27 = require("react/jsx-runtime");
3605
3787
  function TagAutocomplete({
@@ -3608,14 +3790,14 @@ function TagAutocomplete({
3608
3790
  placeholder = "Search or create tags...",
3609
3791
  className = ""
3610
3792
  }) {
3611
- const [inputValue, setInputValue] = (0, import_react16.useState)("");
3612
- const [suggestions, setSuggestions] = (0, import_react16.useState)([]);
3613
- const [isLoading, setIsLoading] = (0, import_react16.useState)(false);
3614
- const [showSuggestions, setShowSuggestions] = (0, import_react16.useState)(false);
3615
- const [isCreating, setIsCreating] = (0, import_react16.useState)(false);
3616
- const inputRef = (0, import_react16.useRef)(null);
3617
- const suggestionsRef = (0, import_react16.useRef)(null);
3618
- const fetchSuggestions = (0, import_react16.useCallback)(async (query) => {
3793
+ const [inputValue, setInputValue] = (0, import_react17.useState)("");
3794
+ const [suggestions, setSuggestions] = (0, import_react17.useState)([]);
3795
+ const [isLoading, setIsLoading] = (0, import_react17.useState)(false);
3796
+ const [showSuggestions, setShowSuggestions] = (0, import_react17.useState)(false);
3797
+ const [isCreating, setIsCreating] = (0, import_react17.useState)(false);
3798
+ const inputRef = (0, import_react17.useRef)(null);
3799
+ const suggestionsRef = (0, import_react17.useRef)(null);
3800
+ const fetchSuggestions = (0, import_react17.useCallback)(async (query) => {
3619
3801
  if (!query.trim()) {
3620
3802
  setSuggestions([]);
3621
3803
  return;
@@ -3637,7 +3819,7 @@ function TagAutocomplete({
3637
3819
  setIsLoading(false);
3638
3820
  }
3639
3821
  }, [selectedTags]);
3640
- (0, import_react16.useEffect)(() => {
3822
+ (0, import_react17.useEffect)(() => {
3641
3823
  const timeoutId = setTimeout(() => {
3642
3824
  fetchSuggestions(inputValue);
3643
3825
  }, 300);
@@ -3701,7 +3883,7 @@ function TagAutocomplete({
3701
3883
  inputRef.current?.blur();
3702
3884
  }
3703
3885
  };
3704
- (0, import_react16.useEffect)(() => {
3886
+ (0, import_react17.useEffect)(() => {
3705
3887
  const handleClickOutside = (event) => {
3706
3888
  if (suggestionsRef.current && !suggestionsRef.current.contains(event.target) && inputRef.current && !inputRef.current.contains(event.target)) {
3707
3889
  setShowSuggestions(false);
@@ -3760,7 +3942,10 @@ function TagAutocomplete({
3760
3942
  "div",
3761
3943
  {
3762
3944
  className: "px-4 py-2 hover:bg-gray-100 cursor-pointer text-sm",
3763
- onClick: () => handleSuggestionSelect(tag),
3945
+ onMouseDown: (e) => {
3946
+ e.preventDefault();
3947
+ handleSuggestionSelect(tag);
3948
+ },
3764
3949
  children: tag.name
3765
3950
  },
3766
3951
  tag.id
@@ -3776,7 +3961,10 @@ function TagAutocomplete({
3776
3961
  "div",
3777
3962
  {
3778
3963
  className: "px-4 py-2 hover:bg-gray-100 cursor-pointer text-sm text-gray-700 flex items-center",
3779
- onClick: handleCreateTag,
3964
+ onMouseDown: (e) => {
3965
+ e.preventDefault();
3966
+ handleCreateTag();
3967
+ },
3780
3968
  children: [
3781
3969
  /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(import_lucide_react16.Plus, { className: "h-3 w-3 mr-2" }),
3782
3970
  'Create "',
@@ -3792,7 +3980,7 @@ function TagAutocomplete({
3792
3980
 
3793
3981
  // src/components/Admin/JoditRichText.tsx
3794
3982
  var import_dynamic = __toESM(require("next/dynamic"), 1);
3795
- var import_react17 = require("react");
3983
+ var import_react18 = require("react");
3796
3984
  var import_jodit_min = require("jodit/es2021/jodit.min.css");
3797
3985
  var import_jsx_runtime28 = require("react/jsx-runtime");
3798
3986
  var JoditEditor = (0, import_dynamic.default)(() => import("jodit-react").then((m) => m.default), {
@@ -3800,7 +3988,7 @@ var JoditEditor = (0, import_dynamic.default)(() => import("jodit-react").then((
3800
3988
  loading: () => /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("div", { className: "min-h-[300px] rounded-md border border-gray-200 bg-gray-50 animate-pulse" })
3801
3989
  });
3802
3990
  function JoditRichText({ value, onChange, placeholder, minHeight = 400 }) {
3803
- const config = (0, import_react17.useMemo)(
3991
+ const config = (0, import_react18.useMemo)(
3804
3992
  () => ({
3805
3993
  readonly: false,
3806
3994
  placeholder: placeholder ?? "",
@@ -3864,7 +4052,7 @@ function JoditRichText({ value, onChange, placeholder, minHeight = 400 }) {
3864
4052
  }
3865
4053
 
3866
4054
  // src/components/Admin/CategoryAutocomplete.tsx
3867
- var import_react18 = require("react");
4055
+ var import_react19 = require("react");
3868
4056
  var import_lucide_react17 = require("lucide-react");
3869
4057
  var import_jsx_runtime29 = require("react/jsx-runtime");
3870
4058
  function CategoryAutocomplete({
@@ -3873,13 +4061,13 @@ function CategoryAutocomplete({
3873
4061
  placeholder = "Search or create category...",
3874
4062
  className = ""
3875
4063
  }) {
3876
- const [inputValue, setInputValue] = (0, import_react18.useState)("");
3877
- const [suggestions, setSuggestions] = (0, import_react18.useState)([]);
3878
- const [isLoading, setIsLoading] = (0, import_react18.useState)(false);
3879
- const [showSuggestions, setShowSuggestions] = (0, import_react18.useState)(false);
3880
- const [isCreating, setIsCreating] = (0, import_react18.useState)(false);
3881
- const inputRef = (0, import_react18.useRef)(null);
3882
- const suggestionsRef = (0, import_react18.useRef)(null);
4064
+ const [inputValue, setInputValue] = (0, import_react19.useState)("");
4065
+ const [suggestions, setSuggestions] = (0, import_react19.useState)([]);
4066
+ const [isLoading, setIsLoading] = (0, import_react19.useState)(false);
4067
+ const [showSuggestions, setShowSuggestions] = (0, import_react19.useState)(false);
4068
+ const [isCreating, setIsCreating] = (0, import_react19.useState)(false);
4069
+ const inputRef = (0, import_react19.useRef)(null);
4070
+ const suggestionsRef = (0, import_react19.useRef)(null);
3883
4071
  const fetchSuggestions = async (query) => {
3884
4072
  if (!query.trim()) {
3885
4073
  setSuggestions([]);
@@ -3899,7 +4087,7 @@ function CategoryAutocomplete({
3899
4087
  setIsLoading(false);
3900
4088
  }
3901
4089
  };
3902
- (0, import_react18.useEffect)(() => {
4090
+ (0, import_react19.useEffect)(() => {
3903
4091
  const timeoutId = setTimeout(() => {
3904
4092
  fetchSuggestions(inputValue);
3905
4093
  }, 300);
@@ -3961,7 +4149,7 @@ function CategoryAutocomplete({
3961
4149
  inputRef.current?.blur();
3962
4150
  }
3963
4151
  };
3964
- (0, import_react18.useEffect)(() => {
4152
+ (0, import_react19.useEffect)(() => {
3965
4153
  const handleClickOutside = (event) => {
3966
4154
  if (suggestionsRef.current && !suggestionsRef.current.contains(event.target) && inputRef.current && !inputRef.current.contains(event.target)) {
3967
4155
  setShowSuggestions(false);
@@ -4020,7 +4208,10 @@ function CategoryAutocomplete({
4020
4208
  "div",
4021
4209
  {
4022
4210
  className: "px-4 py-2 hover:bg-gray-100 cursor-pointer text-sm flex items-center justify-between",
4023
- onClick: () => handleSuggestionSelect(category),
4211
+ onMouseDown: (e) => {
4212
+ e.preventDefault();
4213
+ handleSuggestionSelect(category);
4214
+ },
4024
4215
  children: [
4025
4216
  category.name,
4026
4217
  selectedCategory === category.name && /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(import_lucide_react17.Check, { className: "h-4 w-4 text-green-500" })
@@ -4039,7 +4230,10 @@ function CategoryAutocomplete({
4039
4230
  "div",
4040
4231
  {
4041
4232
  className: "px-4 py-2 hover:bg-gray-100 cursor-pointer text-sm text-gray-700 flex items-center",
4042
- onClick: handleCreateCategory,
4233
+ onMouseDown: (e) => {
4234
+ e.preventDefault();
4235
+ handleCreateCategory();
4236
+ },
4043
4237
  children: [
4044
4238
  /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(import_lucide_react17.Plus, { className: "h-3 w-3 mr-2" }),
4045
4239
  'Create "',
@@ -4054,7 +4248,7 @@ function CategoryAutocomplete({
4054
4248
  }
4055
4249
 
4056
4250
  // src/components/Admin/UserAutocomplete.tsx
4057
- var import_react19 = require("react");
4251
+ var import_react20 = require("react");
4058
4252
  var import_lucide_react18 = require("lucide-react");
4059
4253
  var import_jsx_runtime30 = require("react/jsx-runtime");
4060
4254
  function UserAutocomplete({
@@ -4063,12 +4257,12 @@ function UserAutocomplete({
4063
4257
  placeholder = "Select author...",
4064
4258
  className = ""
4065
4259
  }) {
4066
- const [inputValue, setInputValue] = (0, import_react19.useState)("");
4067
- const [suggestions, setSuggestions] = (0, import_react19.useState)([]);
4068
- const [isLoading, setIsLoading] = (0, import_react19.useState)(false);
4069
- const [showSuggestions, setShowSuggestions] = (0, import_react19.useState)(false);
4070
- const inputRef = (0, import_react19.useRef)(null);
4071
- const suggestionsRef = (0, import_react19.useRef)(null);
4260
+ const [inputValue, setInputValue] = (0, import_react20.useState)("");
4261
+ const [suggestions, setSuggestions] = (0, import_react20.useState)([]);
4262
+ const [isLoading, setIsLoading] = (0, import_react20.useState)(false);
4263
+ const [showSuggestions, setShowSuggestions] = (0, import_react20.useState)(false);
4264
+ const inputRef = (0, import_react20.useRef)(null);
4265
+ const suggestionsRef = (0, import_react20.useRef)(null);
4072
4266
  const fetchSuggestions = async (query) => {
4073
4267
  setIsLoading(true);
4074
4268
  try {
@@ -4088,7 +4282,7 @@ function UserAutocomplete({
4088
4282
  setIsLoading(false);
4089
4283
  }
4090
4284
  };
4091
- (0, import_react19.useEffect)(() => {
4285
+ (0, import_react20.useEffect)(() => {
4092
4286
  const timeoutId = setTimeout(() => {
4093
4287
  fetchSuggestions(inputValue);
4094
4288
  }, 300);
@@ -4119,7 +4313,7 @@ function UserAutocomplete({
4119
4313
  inputRef.current?.blur();
4120
4314
  }
4121
4315
  };
4122
- (0, import_react19.useEffect)(() => {
4316
+ (0, import_react20.useEffect)(() => {
4123
4317
  const handleClickOutside = (event) => {
4124
4318
  if (suggestionsRef.current && !suggestionsRef.current.contains(event.target) && inputRef.current && !inputRef.current.contains(event.target)) {
4125
4319
  setShowSuggestions(false);
@@ -4166,7 +4360,10 @@ function UserAutocomplete({
4166
4360
  "div",
4167
4361
  {
4168
4362
  className: "px-4 py-2 hover:bg-gray-100 cursor-pointer text-sm flex items-center justify-between",
4169
- onClick: () => handleSuggestionSelect(user),
4363
+ onMouseDown: (e) => {
4364
+ e.preventDefault();
4365
+ handleSuggestionSelect(user);
4366
+ },
4170
4367
  children: [
4171
4368
  /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { className: "flex flex-col", children: [
4172
4369
  /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("span", { className: "font-medium", children: user.name }),
@@ -4185,40 +4382,40 @@ function UserAutocomplete({
4185
4382
  // src/components/Admin/BlogEditorPage.tsx
4186
4383
  var import_jsx_runtime31 = require("react/jsx-runtime");
4187
4384
  function BlogEditor({ existingBlog }) {
4188
- const [title, setTitle] = (0, import_react20.useState)(existingBlog?.title || "");
4189
- const [slug, setSlug] = (0, import_react20.useState)(existingBlog?.slug || "");
4190
- const [coverImage, setCoverImage] = (0, import_react20.useState)(
4385
+ const [title, setTitle] = (0, import_react21.useState)(existingBlog?.title || "");
4386
+ const [slug, setSlug] = (0, import_react21.useState)(existingBlog?.slug || "");
4387
+ const [coverImage, setCoverImage] = (0, import_react21.useState)(
4191
4388
  existingBlog?.coverImage || null
4192
4389
  );
4193
- const [ogImage, setOgImage] = (0, import_react20.useState)(
4390
+ const [ogImage, setOgImage] = (0, import_react21.useState)(
4194
4391
  existingBlog?.seo?.ogImage || existingBlog?.ogImage || null
4195
4392
  );
4196
- const [metaTitle, setMetaTitle] = (0, import_react20.useState)(existingBlog?.seo?.title || "");
4197
- const [metaDescription, setMetaDescription] = (0, import_react20.useState)(
4393
+ const [metaTitle, setMetaTitle] = (0, import_react21.useState)(existingBlog?.seo?.title || "");
4394
+ const [metaDescription, setMetaDescription] = (0, import_react21.useState)(
4198
4395
  existingBlog?.seo?.description || ""
4199
4396
  );
4200
- const [metaKeywords, setMetaKeywords] = (0, import_react20.useState)(
4397
+ const [metaKeywords, setMetaKeywords] = (0, import_react21.useState)(
4201
4398
  existingBlog?.seo?.keywords || ""
4202
4399
  );
4203
- const [published, setPublished] = (0, import_react20.useState)(existingBlog?.published || false);
4204
- const [tags, setTags] = (0, import_react20.useState)(
4400
+ const [published, setPublished] = (0, import_react21.useState)(existingBlog?.published || false);
4401
+ const [tags, setTags] = (0, import_react21.useState)(
4205
4402
  existingBlog?.tags?.map((tag) => tag.name) || []
4206
4403
  );
4207
- const [category, setCategory] = (0, import_react20.useState)(
4404
+ const [category, setCategory] = (0, import_react21.useState)(
4208
4405
  existingBlog?.category?.name || null
4209
4406
  );
4210
- const [authorId, setAuthorId] = (0, import_react20.useState)(
4407
+ const [authorId, setAuthorId] = (0, import_react21.useState)(
4211
4408
  existingBlog?.authorId || null
4212
4409
  );
4213
- const [content, setContent] = (0, import_react20.useState)(existingBlog?.content || "");
4214
- const [createdAt, setCreatedAt] = (0, import_react20.useState)(
4410
+ const [content, setContent] = (0, import_react21.useState)(existingBlog?.content || "");
4411
+ const [createdAt, setCreatedAt] = (0, import_react21.useState)(
4215
4412
  existingBlog?.createdAt ? new Date(existingBlog.createdAt).toISOString().slice(0, 16) : (/* @__PURE__ */ new Date()).toISOString().slice(0, 16)
4216
4413
  );
4217
- const [errors, setErrors] = (0, import_react20.useState)([]);
4218
- const [isLoading, setIsLoading] = (0, import_react20.useState)(false);
4219
- const [isSaving, setIsSaving] = (0, import_react20.useState)(false);
4220
- const router = (0, import_navigation5.useRouter)();
4221
- (0, import_react20.useEffect)(() => {
4414
+ const [errors, setErrors] = (0, import_react21.useState)([]);
4415
+ const [isLoading, setIsLoading] = (0, import_react21.useState)(false);
4416
+ const [isSaving, setIsSaving] = (0, import_react21.useState)(false);
4417
+ const router = (0, import_navigation6.useRouter)();
4418
+ (0, import_react21.useEffect)(() => {
4222
4419
  if (title && !slug) {
4223
4420
  const generatedSlug = title.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/(^-|-$)/g, "");
4224
4421
  setSlug(generatedSlug);
@@ -4343,11 +4540,25 @@ function BlogEditor({ existingBlog }) {
4343
4540
  ),
4344
4541
  /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("span", { className: "text-xs text-gray-300", children: "Published" })
4345
4542
  ] }),
4543
+ /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)(
4544
+ Button,
4545
+ {
4546
+ size: "icon",
4547
+ className: "md:hidden h-8 w-8 bg-white text-gray-800 hover:bg-gray-100 border-0",
4548
+ onClick: () => handleSave(published),
4549
+ disabled: isSaving,
4550
+ title: isSaving ? "Saving..." : "Save",
4551
+ children: [
4552
+ /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(import_lucide_react19.Save, { className: "h-4 w-4" }),
4553
+ /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("span", { className: "sr-only", children: isSaving ? "Saving..." : "Save" })
4554
+ ]
4555
+ }
4556
+ ),
4346
4557
  /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)(
4347
4558
  Button,
4348
4559
  {
4349
4560
  size: "sm",
4350
- className: "flex items-center bg-white text-gray-800 hover:bg-gray-100 border-0 text-xs",
4561
+ className: "hidden md:inline-flex items-center bg-white text-gray-800 hover:bg-gray-100 border-0 text-xs",
4351
4562
  onClick: () => handleSave(published),
4352
4563
  disabled: isSaving,
4353
4564
  children: [
@@ -4356,12 +4567,26 @@ function BlogEditor({ existingBlog }) {
4356
4567
  ]
4357
4568
  }
4358
4569
  ),
4570
+ /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)(
4571
+ Button,
4572
+ {
4573
+ variant: "outline",
4574
+ size: "icon",
4575
+ className: "md:hidden h-8 w-8 bg-white text-gray-800 hover:bg-gray-100 border-0",
4576
+ onClick: () => router.back(),
4577
+ title: "Close",
4578
+ children: [
4579
+ /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(import_lucide_react19.X, { className: "h-4 w-4" }),
4580
+ /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("span", { className: "sr-only", children: "Close" })
4581
+ ]
4582
+ }
4583
+ ),
4359
4584
  /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)(
4360
4585
  Button,
4361
4586
  {
4362
4587
  variant: "outline",
4363
4588
  size: "sm",
4364
- className: "flex items-center bg-white text-gray-800 hover:bg-gray-100 border-0 text-xs",
4589
+ className: "hidden md:inline-flex items-center bg-white text-gray-800 hover:bg-gray-100 border-0 text-xs",
4365
4590
  onClick: () => router.back(),
4366
4591
  children: [
4367
4592
  /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(import_lucide_react19.X, { className: "h-4 w-4 mr-1" }),
@@ -4543,11 +4768,11 @@ function BlogEditor({ existingBlog }) {
4543
4768
  }
4544
4769
 
4545
4770
  // src/components/Admin/AnalyticsChart.tsx
4546
- var import_react21 = require("react");
4771
+ var import_react22 = require("react");
4547
4772
  var import_jsx_runtime32 = require("react/jsx-runtime");
4548
4773
  function AnalyticsChart({ data, title, type }) {
4549
- const canvasRef = (0, import_react21.useRef)(null);
4550
- (0, import_react21.useEffect)(() => {
4774
+ const canvasRef = (0, import_react22.useRef)(null);
4775
+ (0, import_react22.useEffect)(() => {
4551
4776
  if (!canvasRef.current || !data.length) return;
4552
4777
  const ctx = canvasRef.current.getContext("2d");
4553
4778
  if (!ctx) return;
@@ -4739,13 +4964,13 @@ function AnalyticsCard({ title, value, subtitle, icon, trend }) {
4739
4964
  }
4740
4965
 
4741
4966
  // src/components/Admin/AnalyticsExclusion.tsx
4742
- var import_navigation6 = require("next/navigation");
4967
+ var import_navigation7 = require("next/navigation");
4743
4968
 
4744
4969
  // src/hooks/use-analytics.ts
4745
- var import_react22 = require("react");
4970
+ var import_react23 = require("react");
4746
4971
  function useAnalytics(pathname) {
4747
4972
  const isAdminRoute = pathname != null && pathname.startsWith("/admin");
4748
- (0, import_react22.useEffect)(() => {
4973
+ (0, import_react23.useEffect)(() => {
4749
4974
  if (isAdminRoute && typeof window !== "undefined") {
4750
4975
  if (typeof window.gtag === "function") {
4751
4976
  window.gtag = () => {
@@ -4762,7 +4987,7 @@ function useAnalytics(pathname) {
4762
4987
  // src/components/Admin/AnalyticsExclusion.tsx
4763
4988
  var import_jsx_runtime36 = require("react/jsx-runtime");
4764
4989
  function AnalyticsExclusion() {
4765
- const pathname = (0, import_navigation6.usePathname)();
4990
+ const pathname = (0, import_navigation7.usePathname)();
4766
4991
  const { isAdminRoute, shouldTrack } = useAnalytics(pathname);
4767
4992
  if (!isAdminRoute) return null;
4768
4993
  return /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)("div", { className: "fixed bottom-4 right-4 bg-green-100 border border-green-400 text-green-700 px-4 py-2 rounded text-sm z-50", children: [
@@ -4772,15 +4997,15 @@ function AnalyticsExclusion() {
4772
4997
  }
4773
4998
 
4774
4999
  // src/components/Admin/ComponentSettings.tsx
4775
- var import_react23 = require("react");
5000
+ var import_react24 = require("react");
4776
5001
  var import_jsx_runtime37 = require("react/jsx-runtime");
4777
5002
  function EntitySelect({
4778
5003
  prop,
4779
5004
  value,
4780
5005
  onChange
4781
5006
  }) {
4782
- const [options, setOptions] = (0, import_react23.useState)([]);
4783
- (0, import_react23.useEffect)(() => {
5007
+ const [options, setOptions] = (0, import_react24.useState)([]);
5008
+ (0, import_react24.useEffect)(() => {
4784
5009
  if (!prop.entity) return;
4785
5010
  fetch(`/api/${prop.entity}`).then((r) => r.ok ? r.json() : { data: [] }).then((res) => setOptions(res.data || res || [])).catch(() => {
4786
5011
  });
@@ -4918,7 +5143,7 @@ function ComponentSettings({
4918
5143
  }
4919
5144
 
4920
5145
  // src/components/Admin/NavbarEditor.tsx
4921
- var import_react24 = require("react");
5146
+ var import_react25 = require("react");
4922
5147
  var import_lucide_react21 = require("lucide-react");
4923
5148
  var import_jsx_runtime38 = require("react/jsx-runtime");
4924
5149
  function generateId() {
@@ -4938,9 +5163,9 @@ function NavItemEditor({
4938
5163
  canMoveUp,
4939
5164
  canMoveDown
4940
5165
  }) {
4941
- const [expanded, setExpanded] = (0, import_react24.useState)(false);
4942
- const [pages, setPages] = (0, import_react24.useState)([]);
4943
- (0, import_react24.useEffect)(() => {
5166
+ const [expanded, setExpanded] = (0, import_react25.useState)(false);
5167
+ const [pages, setPages] = (0, import_react25.useState)([]);
5168
+ (0, import_react25.useEffect)(() => {
4944
5169
  if (!expanded) return;
4945
5170
  fetch("/api/pages").then((r) => r.ok ? r.json() : []).then((data) => {
4946
5171
  const res = data;
@@ -5208,9 +5433,9 @@ function NavbarEditor({ config, onChange }) {
5208
5433
 
5209
5434
  // src/admin/pages/SignInPage.tsx
5210
5435
  var import_link5 = __toESM(require("next/link"), 1);
5211
- var import_react25 = require("react");
5212
- var import_react26 = require("next-auth/react");
5213
- var import_navigation7 = require("next/navigation");
5436
+ var import_react26 = require("react");
5437
+ var import_react27 = require("next-auth/react");
5438
+ var import_navigation8 = require("next/navigation");
5214
5439
 
5215
5440
  // src/components/Admin/AuthPageLayout.tsx
5216
5441
  var import_image5 = __toESM(require("next/image"), 1);
@@ -5268,13 +5493,13 @@ function AuthPageLayout({ children }) {
5268
5493
  // src/admin/pages/SignInPage.tsx
5269
5494
  var import_jsx_runtime41 = require("react/jsx-runtime");
5270
5495
  var SigninPage = () => {
5271
- const [email, setEmail] = (0, import_react25.useState)("");
5272
- const [password, setPassword] = (0, import_react25.useState)("");
5273
- const [error, setError] = (0, import_react25.useState)("");
5274
- const [loading, setLoading] = (0, import_react25.useState)(false);
5275
- const router = (0, import_navigation7.useRouter)();
5276
- const { status } = (0, import_react26.useSession)();
5277
- (0, import_react25.useEffect)(() => {
5496
+ const [email, setEmail] = (0, import_react26.useState)("");
5497
+ const [password, setPassword] = (0, import_react26.useState)("");
5498
+ const [error, setError] = (0, import_react26.useState)("");
5499
+ const [loading, setLoading] = (0, import_react26.useState)(false);
5500
+ const router = (0, import_navigation8.useRouter)();
5501
+ const { status } = (0, import_react27.useSession)();
5502
+ (0, import_react26.useEffect)(() => {
5278
5503
  if (status === "authenticated") {
5279
5504
  router.replace("/admin/dashboard");
5280
5505
  }
@@ -5284,7 +5509,7 @@ var SigninPage = () => {
5284
5509
  setLoading(true);
5285
5510
  setError("");
5286
5511
  try {
5287
- const result = await (0, import_react26.signIn)("credentials", {
5512
+ const result = await (0, import_react27.signIn)("credentials", {
5288
5513
  email,
5289
5514
  password,
5290
5515
  redirect: false
@@ -5357,13 +5582,13 @@ var SigninPage = () => {
5357
5582
  var SignInPage_default = SigninPage;
5358
5583
 
5359
5584
  // src/admin/pages/ForgotPasswordPage.tsx
5360
- var import_react27 = require("react");
5585
+ var import_react28 = require("react");
5361
5586
  var import_link6 = __toESM(require("next/link"), 1);
5362
5587
  var import_jsx_runtime42 = require("react/jsx-runtime");
5363
5588
  function ForgotPasswordPage() {
5364
- const [email, setEmail] = (0, import_react27.useState)("");
5365
- const [loading, setLoading] = (0, import_react27.useState)(false);
5366
- const [message, setMessage] = (0, import_react27.useState)("");
5589
+ const [email, setEmail] = (0, import_react28.useState)("");
5590
+ const [loading, setLoading] = (0, import_react28.useState)(false);
5591
+ const [message, setMessage] = (0, import_react28.useState)("");
5367
5592
  const handleSubmit = async (e) => {
5368
5593
  e.preventDefault();
5369
5594
  if (!email.trim()) return;
@@ -5405,17 +5630,17 @@ function ForgotPasswordPage() {
5405
5630
  }
5406
5631
 
5407
5632
  // src/admin/pages/ResetPasswordPage.tsx
5408
- var import_react28 = require("react");
5409
- var import_navigation8 = require("next/navigation");
5633
+ var import_react29 = require("react");
5634
+ var import_navigation9 = require("next/navigation");
5410
5635
  var import_link7 = __toESM(require("next/link"), 1);
5411
5636
  var import_jsx_runtime43 = require("react/jsx-runtime");
5412
5637
  function ResetPasswordPageContent() {
5413
- const searchParams = (0, import_navigation8.useSearchParams)();
5638
+ const searchParams = (0, import_navigation9.useSearchParams)();
5414
5639
  const token = searchParams.get("token");
5415
- const [formData, setFormData] = (0, import_react28.useState)({ password: "", confirmPassword: "" });
5416
- const [loading, setLoading] = (0, import_react28.useState)(false);
5417
- const [message, setMessage] = (0, import_react28.useState)("");
5418
- (0, import_react28.useEffect)(() => {
5640
+ const [formData, setFormData] = (0, import_react29.useState)({ password: "", confirmPassword: "" });
5641
+ const [loading, setLoading] = (0, import_react29.useState)(false);
5642
+ const [message, setMessage] = (0, import_react29.useState)("");
5643
+ (0, import_react29.useEffect)(() => {
5419
5644
  if (!token) setMessage("Invalid reset link. Token is missing.");
5420
5645
  }, [token]);
5421
5646
  const handleSubmit = async (e) => {
@@ -5477,26 +5702,26 @@ function ResetPasswordPageContent() {
5477
5702
  ] }) });
5478
5703
  }
5479
5704
  function ResetPasswordPage() {
5480
- return /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(import_react28.Suspense, { fallback: /* @__PURE__ */ (0, import_jsx_runtime43.jsx)("div", { className: "min-h-screen flex items-center justify-center bg-gray-50 dark:bg-dark", children: /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)("div", { className: "max-w-[400px] w-full p-6 text-center", children: [
5705
+ return /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(import_react29.Suspense, { fallback: /* @__PURE__ */ (0, import_jsx_runtime43.jsx)("div", { className: "min-h-screen flex items-center justify-center bg-gray-50 dark:bg-dark", children: /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)("div", { className: "max-w-[400px] w-full p-6 text-center", children: [
5481
5706
  /* @__PURE__ */ (0, import_jsx_runtime43.jsx)("div", { className: "animate-spin rounded-full h-6 w-6 border-2 border-gray-300 border-t-gray-600 mx-auto" }),
5482
5707
  /* @__PURE__ */ (0, import_jsx_runtime43.jsx)("p", { className: "mt-3 text-sm text-body-color", children: "Loading..." })
5483
5708
  ] }) }), children: /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(ResetPasswordPageContent, {}) });
5484
5709
  }
5485
5710
 
5486
5711
  // src/admin/pages/InvitePage.tsx
5487
- var import_react29 = require("react");
5488
- var import_navigation9 = require("next/navigation");
5712
+ var import_react30 = require("react");
5713
+ var import_navigation10 = require("next/navigation");
5489
5714
  var import_jsx_runtime44 = require("react/jsx-runtime");
5490
5715
  function InvitePageContent() {
5491
- const searchParams = (0, import_navigation9.useSearchParams)();
5716
+ const searchParams = (0, import_navigation10.useSearchParams)();
5492
5717
  const token = searchParams.get("token");
5493
- const [formData, setFormData] = (0, import_react29.useState)({
5718
+ const [formData, setFormData] = (0, import_react30.useState)({
5494
5719
  password: "",
5495
5720
  confirmPassword: ""
5496
5721
  });
5497
- const [loading, setLoading] = (0, import_react29.useState)(false);
5498
- const [message, setMessage] = (0, import_react29.useState)("");
5499
- (0, import_react29.useEffect)(() => {
5722
+ const [loading, setLoading] = (0, import_react30.useState)(false);
5723
+ const [message, setMessage] = (0, import_react30.useState)("");
5724
+ (0, import_react30.useEffect)(() => {
5500
5725
  if (!token) {
5501
5726
  setMessage("Invalid invite link. Token is missing.");
5502
5727
  }
@@ -5561,29 +5786,70 @@ function InvitePageContent() {
5561
5786
  ] }) });
5562
5787
  }
5563
5788
  function InvitePage() {
5564
- return /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(import_react29.Suspense, { fallback: /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("div", { className: "min-h-screen flex items-center justify-center bg-gray-50", children: /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)("div", { className: "max-w-[400px] w-full p-6 text-center", children: [
5789
+ return /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(import_react30.Suspense, { fallback: /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("div", { className: "min-h-screen flex items-center justify-center bg-gray-50", children: /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)("div", { className: "max-w-[400px] w-full p-6 text-center", children: [
5565
5790
  /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("div", { className: "animate-spin rounded-full h-6 w-6 border-2 border-gray-300 border-t-gray-600 mx-auto" }),
5566
5791
  /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("p", { className: "mt-3 text-sm text-gray-600", children: "Loading..." })
5567
5792
  ] }) }), children: /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(InvitePageContent, {}) });
5568
5793
  }
5569
5794
 
5570
5795
  // src/admin/pages/DashboardPage.tsx
5571
- var import_react30 = require("next-auth/react");
5572
- var import_react31 = require("react");
5796
+ var import_react31 = require("next-auth/react");
5797
+ var import_react32 = require("react");
5798
+ var import_navigation11 = require("next/navigation");
5799
+ var import_chart2 = require("chart.js");
5800
+ var import_react_chartjs_22 = require("react-chartjs-2");
5573
5801
  var import_lucide_react22 = require("lucide-react");
5574
5802
  var import_jsx_runtime45 = require("react/jsx-runtime");
5803
+ import_chart2.Chart.register(import_chart2.ArcElement, import_chart2.Tooltip, import_chart2.Legend);
5575
5804
  function DashboardPage() {
5576
- const { data: session } = (0, import_react30.useSession)();
5577
- const [analyticsData, setAnalyticsData] = (0, import_react31.useState)(null);
5578
- const [dashboardStats, setDashboardStats] = (0, import_react31.useState)(null);
5579
- const [loading, setLoading] = (0, import_react31.useState)({ analytics: true, stats: true });
5580
- const [analyticsEnabled, setAnalyticsEnabled] = (0, import_react31.useState)(false);
5581
- (0, import_react31.useEffect)(() => {
5805
+ const { data: session } = (0, import_react31.useSession)();
5806
+ const router = (0, import_navigation11.useRouter)();
5807
+ const { storeEnabled } = (0, import_react32.useContext)(AdminConfigContext);
5808
+ const [analyticsData, setAnalyticsData] = (0, import_react32.useState)(null);
5809
+ const [ecommerceData, setEcommerceData] = (0, import_react32.useState)(null);
5810
+ const [dashboardStats, setDashboardStats] = (0, import_react32.useState)(null);
5811
+ const [loading, setLoading] = (0, import_react32.useState)({ analytics: true, stats: true, ecommerce: true });
5812
+ const [analyticsEnabled, setAnalyticsEnabled] = (0, import_react32.useState)(false);
5813
+ const [days, setDays] = (0, import_react32.useState)(30);
5814
+ const [activeTab, setActiveTab] = (0, import_react32.useState)("overview");
5815
+ const formatMoney4 = (0, import_react32.useMemo)(
5816
+ () => (value) => new Intl.NumberFormat(void 0, {
5817
+ style: "currency",
5818
+ currency: "INR",
5819
+ maximumFractionDigits: 0
5820
+ }).format(value || 0),
5821
+ []
5822
+ );
5823
+ const safePct = (v, max) => max > 0 ? Math.max(6, Math.round(v / max * 100)) : 0;
5824
+ const productPalette = ["#2563eb", "#0ea5e9", "#14b8a6", "#22c55e", "#eab308", "#f97316"];
5825
+ const salesBreakdownPalette = {
5826
+ sales: "#22c55e",
5827
+ returns: "#ef4444",
5828
+ replacements: "#f59e0b"
5829
+ };
5830
+ const contactTypeColor = (type) => {
5831
+ const t = type.trim().toLowerCase();
5832
+ if (t === "customer") return "#2563eb";
5833
+ if (t === "lead") return "#a855f7";
5834
+ if (t === "vendor") return "#14b8a6";
5835
+ return "#6b7280";
5836
+ };
5837
+ const metricBarColor = (label) => {
5838
+ const key = label.toLowerCase();
5839
+ if (key.includes("contact")) return "bg-blue-500";
5840
+ if (key.includes("submission")) return "bg-purple-500";
5841
+ if (key.includes("net sales")) return "bg-green-500";
5842
+ if (key.includes("gross sales")) return "bg-emerald-500";
5843
+ if (key.includes("return")) return "bg-red-500";
5844
+ return "bg-gray-600";
5845
+ };
5846
+ (0, import_react32.useEffect)(() => {
5582
5847
  const fetchData = async () => {
5583
- const analyticsPromise = fetch("/api/analytics?days=30");
5848
+ const analyticsPromise = fetch(`/api/analytics?days=${days}`);
5584
5849
  const statsPromise = fetch("/api/dashboard/stats");
5850
+ const ecommercePromise = storeEnabled ? fetch(`/api/dashboard/ecommerce?days=${days}`) : Promise.resolve(null);
5585
5851
  try {
5586
- const [analyticsResponse, statsResponse] = await Promise.all([analyticsPromise, statsPromise]);
5852
+ const [analyticsResponse, statsResponse, ecommerceResponse] = await Promise.all([analyticsPromise, statsPromise, ecommercePromise]);
5587
5853
  if (analyticsResponse.ok) {
5588
5854
  const data = await analyticsResponse.json();
5589
5855
  setAnalyticsData(data);
@@ -5601,15 +5867,22 @@ function DashboardPage() {
5601
5867
  const stats = await statsResponse.json();
5602
5868
  setDashboardStats(stats);
5603
5869
  }
5870
+ if (ecommerceResponse && ecommerceResponse.ok) {
5871
+ const ecommerce = await ecommerceResponse.json();
5872
+ setEcommerceData(ecommerce);
5873
+ } else {
5874
+ setEcommerceData(null);
5875
+ }
5604
5876
  } catch (error) {
5605
5877
  setAnalyticsEnabled(false);
5878
+ setEcommerceData(null);
5606
5879
  } finally {
5607
- setLoading({ analytics: false, stats: false });
5880
+ setLoading({ analytics: false, stats: false, ecommerce: false });
5608
5881
  }
5609
5882
  };
5610
5883
  fetchData();
5611
- }, []);
5612
- const isLoading = loading.analytics || loading.stats;
5884
+ }, [days, storeEnabled]);
5885
+ const isLoading = loading.analytics || loading.stats || storeEnabled && loading.ecommerce;
5613
5886
  return /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)("div", { className: "min-w-0 rounded-lg bg-white shadow-md", children: [
5614
5887
  /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("div", { className: "bg-gray-800 border-b border-gray-700 px-4 py-2.5 rounded-t-lg", children: /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)("div", { className: "flex items-center justify-between", children: [
5615
5888
  /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)("div", { children: [
@@ -5625,13 +5898,54 @@ function DashboardPage() {
5625
5898
  ] }) })
5626
5899
  ] }) }),
5627
5900
  /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)("div", { className: "min-w-0 p-4 bg-gray-50", children: [
5628
- /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)("div", { className: "mb-4", children: [
5629
- /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)("div", { className: "flex items-center mb-2", children: [
5901
+ /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)("div", { className: "flex flex-wrap items-center justify-between gap-2 mb-3", children: [
5902
+ /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)("div", { className: "flex items-center gap-2", children: [
5903
+ /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(
5904
+ "button",
5905
+ {
5906
+ onClick: () => setActiveTab("overview"),
5907
+ 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"}`,
5908
+ children: "Overview"
5909
+ }
5910
+ ),
5911
+ /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(
5912
+ "button",
5913
+ {
5914
+ onClick: () => setActiveTab("crm"),
5915
+ 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"}`,
5916
+ children: "CRM / Engagement"
5917
+ }
5918
+ ),
5919
+ storeEnabled && /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(
5920
+ "button",
5921
+ {
5922
+ onClick: () => setActiveTab("sales"),
5923
+ 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"}`,
5924
+ children: "Sales"
5925
+ }
5926
+ )
5927
+ ] }),
5928
+ /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)(
5929
+ "select",
5930
+ {
5931
+ value: days,
5932
+ onChange: (e) => setDays(Number(e.target.value)),
5933
+ className: "border border-gray-300 text-xs rounded px-2 py-1 bg-white",
5934
+ children: [
5935
+ /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("option", { value: 7, children: "Last 7 days" }),
5936
+ /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("option", { value: 30, children: "Last 30 days" }),
5937
+ /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("option", { value: 90, children: "Last 90 days" })
5938
+ ]
5939
+ }
5940
+ )
5941
+ ] }),
5942
+ activeTab === "overview" && /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)("div", { className: "mb-5", children: [
5943
+ /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)("div", { className: "flex items-center mb-3", children: [
5630
5944
  /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(import_lucide_react22.BarChart3, { className: "w-4 h-4 text-gray-600 mr-2" }),
5631
- /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("h2", { className: "text-sm font-semibold text-gray-800", children: "Overview" })
5945
+ /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("h2", { className: "text-sm font-semibold text-gray-800", children: "Contacts & Forms" })
5632
5946
  ] }),
5633
- /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)("div", { className: "grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-3", children: [
5634
- /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)("div", { className: "bg-white rounded border border-gray-200 p-2.5 shadow-sm", children: [
5947
+ /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)("div", { className: "grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-4", children: [
5948
+ /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)("div", { className: "bg-white rounded border border-gray-200 p-3 shadow-sm", children: [
5635
5949
  /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)("div", { className: "flex items-center justify-between mb-1.5", children: [
5636
5950
  /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("p", { className: "text-xs font-medium text-gray-600", children: "Total Contacts" }),
5637
5951
  /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("div", { className: "p-1 bg-gray-200 rounded", children: /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(import_lucide_react22.Users, { className: "w-3.5 h-3.5 text-gray-600" }) })
@@ -5647,7 +5961,7 @@ function DashboardPage() {
5647
5961
  ] })
5648
5962
  ] })
5649
5963
  ] }),
5650
- /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)("div", { className: "bg-white rounded border border-gray-200 p-2.5 shadow-sm", children: [
5964
+ /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)("div", { className: "bg-white rounded border border-gray-200 p-3 shadow-sm", children: [
5651
5965
  /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)("div", { className: "flex items-center justify-between mb-1.5", children: [
5652
5966
  /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("p", { className: "text-xs font-medium text-gray-600", children: "Form Submissions" }),
5653
5967
  /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("div", { className: "p-1 bg-gray-200 rounded", children: /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(import_lucide_react22.FileText, { className: "w-3.5 h-3.5 text-gray-600" }) })
@@ -5663,7 +5977,7 @@ function DashboardPage() {
5663
5977
  ] })
5664
5978
  ] })
5665
5979
  ] }),
5666
- /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)("div", { className: "bg-white rounded border border-gray-200 p-2.5 shadow-sm", children: [
5980
+ /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)("div", { className: "bg-white rounded border border-gray-200 p-3 shadow-sm", children: [
5667
5981
  /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)("div", { className: "flex items-center justify-between mb-1.5", children: [
5668
5982
  /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("p", { className: "text-xs font-medium text-gray-600", children: "Active Forms" }),
5669
5983
  /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("div", { className: "p-1 bg-gray-200 rounded", children: /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(import_lucide_react22.ClipboardList, { className: "w-3.5 h-3.5 text-gray-600" }) })
@@ -5673,7 +5987,7 @@ function DashboardPage() {
5673
5987
  /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("p", { className: "text-xs text-gray-500", children: "Total" })
5674
5988
  ] })
5675
5989
  ] }),
5676
- /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)("div", { className: "bg-white rounded border border-gray-200 p-2.5 shadow-sm", children: [
5990
+ /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)("div", { className: "bg-white rounded border border-gray-200 p-3 shadow-sm", children: [
5677
5991
  /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)("div", { className: "flex items-center justify-between mb-1.5", children: [
5678
5992
  /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("p", { className: "text-xs font-medium text-gray-600", children: "Registered Users" }),
5679
5993
  /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("div", { className: "p-1 bg-gray-200 rounded", children: /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(import_lucide_react22.UserCheck, { className: "w-3.5 h-3.5 text-gray-600" }) })
@@ -5685,8 +5999,151 @@ function DashboardPage() {
5685
5999
  ] })
5686
6000
  ] })
5687
6001
  ] }),
5688
- /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("div", { className: "border-t-2 border-dotted border-gray-200 my-6" }),
5689
- analyticsEnabled && !isLoading && analyticsData && /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)(import_jsx_runtime45.Fragment, { children: [
6002
+ activeTab === "overview" && !isLoading && /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)("div", { className: "mb-6 bg-white rounded-lg border border-gray-200 p-4 shadow-sm", children: [
6003
+ /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)("div", { className: "flex items-center mb-3", children: [
6004
+ /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(import_lucide_react22.Activity, { className: "w-4 h-4 text-gray-600 mr-2" }),
6005
+ /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("h3", { className: "text-sm font-semibold text-gray-800", children: "Overview Snapshot" })
6006
+ ] }),
6007
+ /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)("div", { className: "grid grid-cols-1 lg:grid-cols-2 gap-6", children: [
6008
+ /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)("div", { children: [
6009
+ /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("h4", { className: "text-xs font-semibold text-gray-700 mb-2", children: "Contacts & Forms" }),
6010
+ (() => {
6011
+ const rows = [
6012
+ { label: "Contacts (total)", value: dashboardStats?.contacts.total || 0 },
6013
+ { label: "New contacts", value: dashboardStats?.contacts.recent || 0 },
6014
+ { label: "Submissions", value: dashboardStats?.forms.submissions || 0 },
6015
+ { label: "New submissions", value: dashboardStats?.forms.recentSubmissions || 0 }
6016
+ ];
6017
+ const max = Math.max(...rows.map((r) => r.value), 0);
6018
+ return /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("div", { className: "space-y-2", children: rows.map((r) => /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)("div", { children: [
6019
+ /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)("div", { className: "flex items-center justify-between text-xs mb-1", children: [
6020
+ /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("span", { className: "text-gray-600", children: r.label }),
6021
+ /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("span", { className: "font-semibold text-gray-900", children: r.value })
6022
+ ] }),
6023
+ /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("div", { className: "h-2 rounded bg-gray-100 overflow-hidden", children: /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("div", { className: `h-2 rounded ${metricBarColor(r.label)}`, style: { width: `${safePct(r.value, max)}%` } }) })
6024
+ ] }, r.label)) });
6025
+ })()
6026
+ ] }),
6027
+ storeEnabled && ecommerceData && /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)("div", { children: [
6028
+ /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("h4", { className: "text-xs font-semibold text-gray-700 mb-2", children: "Sales, Returns & Products" }),
6029
+ (() => {
6030
+ const salesBase = Math.max(ecommerceData.kpis.grossSales, 1);
6031
+ const rows = [
6032
+ { label: "Net sales", value: ecommerceData.kpis.netSales, display: formatMoney4(ecommerceData.kpis.netSales) },
6033
+ { label: "Gross sales", value: ecommerceData.kpis.grossSales, display: formatMoney4(ecommerceData.kpis.grossSales) },
6034
+ { label: "Return value", value: ecommerceData.kpis.returnValue, display: formatMoney4(ecommerceData.kpis.returnValue) },
6035
+ { label: "Return rate", value: ecommerceData.kpis.returnRate, display: `${ecommerceData.kpis.returnRate.toFixed(1)}%` }
6036
+ ];
6037
+ const topProduct = ecommerceData.topProducts[0];
6038
+ return /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)("div", { className: "space-y-2", children: [
6039
+ rows.map((r) => /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)("div", { children: [
6040
+ /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)("div", { className: "flex items-center justify-between text-xs mb-1", children: [
6041
+ /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("span", { className: "text-gray-600", children: r.label }),
6042
+ /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("span", { className: "font-semibold text-gray-900", children: r.display })
6043
+ ] }),
6044
+ /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("div", { className: "h-2 rounded bg-gray-100 overflow-hidden", children: /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(
6045
+ "div",
6046
+ {
6047
+ className: `h-2 rounded ${metricBarColor(r.label)}`,
6048
+ style: { width: `${r.label === "Return rate" ? Math.max(6, Math.round(r.value)) : safePct(r.value, salesBase)}%` }
6049
+ }
6050
+ ) })
6051
+ ] }, r.label)),
6052
+ topProduct && /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)("div", { className: "pt-1 text-xs text-gray-600", children: [
6053
+ "Top product: ",
6054
+ /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("span", { className: "font-medium text-gray-900", children: topProduct.name }),
6055
+ " (",
6056
+ topProduct.units,
6057
+ " units)"
6058
+ ] })
6059
+ ] });
6060
+ })()
6061
+ ] })
6062
+ ] })
6063
+ ] }),
6064
+ activeTab === "overview" && !isLoading && /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)("div", { className: "grid grid-cols-1 lg:grid-cols-3 gap-6 mb-7", children: [
6065
+ storeEnabled && ecommerceData && /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)("div", { className: "bg-white rounded-lg border border-gray-200 p-4 shadow-sm", children: [
6066
+ /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("h3", { className: "text-sm font-semibold text-gray-800 mb-3", children: "Sales vs Returns vs Replacements" }),
6067
+ /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("div", { className: "h-56", children: /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(
6068
+ import_react_chartjs_22.Doughnut,
6069
+ {
6070
+ data: {
6071
+ labels: ["Sales", "Returns", "Replacements"],
6072
+ datasets: [
6073
+ {
6074
+ data: [
6075
+ ecommerceData.salesBreakdown?.sales.value ?? ecommerceData.kpis.grossSales,
6076
+ ecommerceData.salesBreakdown?.returns.value ?? ecommerceData.kpis.returnValue,
6077
+ ecommerceData.salesBreakdown?.replacements.value ?? 0
6078
+ ],
6079
+ backgroundColor: [
6080
+ salesBreakdownPalette.sales,
6081
+ salesBreakdownPalette.returns,
6082
+ salesBreakdownPalette.replacements
6083
+ ],
6084
+ borderWidth: 0
6085
+ }
6086
+ ]
6087
+ },
6088
+ options: {
6089
+ maintainAspectRatio: false,
6090
+ plugins: {
6091
+ legend: { position: "bottom" }
6092
+ }
6093
+ }
6094
+ }
6095
+ ) })
6096
+ ] }),
6097
+ storeEnabled && ecommerceData && /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)("div", { className: "bg-white rounded-lg border border-gray-200 p-4 shadow-sm", children: [
6098
+ /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("h3", { className: "text-sm font-semibold text-gray-800 mb-3", children: "Product-wise Sales (Top)" }),
6099
+ /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("div", { className: "h-56", children: /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(
6100
+ import_react_chartjs_22.Doughnut,
6101
+ {
6102
+ data: {
6103
+ labels: ecommerceData.topProducts.map((p) => p.name),
6104
+ datasets: [
6105
+ {
6106
+ data: ecommerceData.topProducts.map((p) => p.sales),
6107
+ backgroundColor: productPalette.slice(0, Math.max(3, ecommerceData.topProducts.length)),
6108
+ borderWidth: 0
6109
+ }
6110
+ ]
6111
+ },
6112
+ options: {
6113
+ maintainAspectRatio: false,
6114
+ plugins: {
6115
+ legend: { position: "bottom" }
6116
+ }
6117
+ }
6118
+ }
6119
+ ) })
6120
+ ] }),
6121
+ /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)("div", { className: "bg-white rounded-lg border border-gray-200 p-4 shadow-sm", children: [
6122
+ /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("h3", { className: "text-sm font-semibold text-gray-800 mb-3", children: "Contact Distribution" }),
6123
+ /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("div", { className: "h-56", children: /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(
6124
+ import_react_chartjs_22.Doughnut,
6125
+ {
6126
+ data: {
6127
+ labels: (dashboardStats?.contactTypes?.length ? dashboardStats.contactTypes : [{ type: "unknown", count: dashboardStats?.contacts.total || 0 }]).map((c) => c.type),
6128
+ datasets: [
6129
+ {
6130
+ data: (dashboardStats?.contactTypes?.length ? dashboardStats.contactTypes : [{ type: "unknown", count: dashboardStats?.contacts.total || 0 }]).map((c) => c.count),
6131
+ backgroundColor: (dashboardStats?.contactTypes?.length ? dashboardStats.contactTypes : [{ type: "unknown", count: dashboardStats?.contacts.total || 0 }]).map((c) => contactTypeColor(c.type)),
6132
+ borderWidth: 0
6133
+ }
6134
+ ]
6135
+ },
6136
+ options: {
6137
+ maintainAspectRatio: false,
6138
+ plugins: {
6139
+ legend: { position: "bottom" }
6140
+ }
6141
+ }
6142
+ }
6143
+ ) })
6144
+ ] })
6145
+ ] }),
6146
+ activeTab === "overview" && analyticsEnabled && !isLoading && analyticsData && /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)(import_jsx_runtime45.Fragment, { children: [
5690
6147
  /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)("div", { className: "mb-4", children: [
5691
6148
  /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)("div", { className: "flex items-center mb-2", children: [
5692
6149
  /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(import_lucide_react22.Globe, { className: "w-4 h-4 text-gray-600 mr-2" }),
@@ -5772,31 +6229,279 @@ function DashboardPage() {
5772
6229
  /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("div", { className: "border-t-2 border-dotted border-gray-200 my-6" }),
5773
6230
  /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("div", { className: "mb-6", children: /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(GeographicMap, { data: analyticsData.geographicData }) })
5774
6231
  ] }),
6232
+ activeTab === "crm" && !isLoading && /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)(import_jsx_runtime45.Fragment, { children: [
6233
+ /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)("div", { className: "mb-4", children: [
6234
+ /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)("div", { className: "flex items-center mb-2", children: [
6235
+ /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(import_lucide_react22.Users, { className: "w-4 h-4 text-gray-600 mr-2" }),
6236
+ /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("h2", { className: "text-sm font-semibold text-gray-800", children: "CRM Activity" })
6237
+ ] }),
6238
+ /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)("div", { className: "grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-3", children: [
6239
+ /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)("button", { onClick: () => router.push("/admin/contacts"), className: "text-left bg-white rounded border border-gray-200 p-2.5 shadow-sm", children: [
6240
+ /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("p", { className: "text-xs text-gray-600", children: "Contacts" }),
6241
+ /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("p", { className: "text-lg font-bold text-gray-900", children: dashboardStats?.contacts.total || 0 }),
6242
+ /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)("p", { className: "text-xs text-green-600", children: [
6243
+ "+",
6244
+ dashboardStats?.contacts.recent || 0,
6245
+ " recent"
6246
+ ] })
6247
+ ] }),
6248
+ /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)("button", { onClick: () => router.push("/admin/forms"), className: "text-left bg-white rounded border border-gray-200 p-2.5 shadow-sm", children: [
6249
+ /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("p", { className: "text-xs text-gray-600", children: "Active Forms" }),
6250
+ /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("p", { className: "text-lg font-bold text-gray-900", children: dashboardStats?.forms.total || 0 })
6251
+ ] }),
6252
+ /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)("button", { onClick: () => router.push("/admin/submissions"), className: "text-left bg-white rounded border border-gray-200 p-2.5 shadow-sm", children: [
6253
+ /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("p", { className: "text-xs text-gray-600", children: "Form Submissions" }),
6254
+ /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("p", { className: "text-lg font-bold text-gray-900", children: dashboardStats?.forms.submissions || 0 }),
6255
+ /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)("p", { className: "text-xs text-green-600", children: [
6256
+ "+",
6257
+ dashboardStats?.forms.recentSubmissions || 0,
6258
+ " recent"
6259
+ ] })
6260
+ ] }),
6261
+ /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)("button", { onClick: () => router.push("/admin/blogs"), className: "text-left bg-white rounded border border-gray-200 p-2.5 shadow-sm", children: [
6262
+ /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("p", { className: "text-xs text-gray-600", children: "Blogs" }),
6263
+ /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("p", { className: "text-lg font-bold text-gray-900", children: dashboardStats?.blogs || 0 })
6264
+ ] })
6265
+ ] })
6266
+ ] }),
6267
+ /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)("div", { className: "grid grid-cols-1 lg:grid-cols-2 gap-6 mb-6", children: [
6268
+ /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)("div", { className: "bg-white rounded-lg border border-gray-100 p-4 shadow-sm", children: [
6269
+ /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("h3", { className: "text-base font-semibold text-gray-800 mb-3", children: "Engagement Funnel" }),
6270
+ (() => {
6271
+ const contacts = dashboardStats?.contacts.total || 0;
6272
+ const submissions = dashboardStats?.forms.submissions || 0;
6273
+ const visitors = analyticsData?.visitors || 0;
6274
+ const base = Math.max(visitors, contacts, submissions, 1);
6275
+ const rows = [
6276
+ { label: "Visitors", value: visitors },
6277
+ { label: "Contacts", value: contacts },
6278
+ { label: "Submissions", value: submissions }
6279
+ ];
6280
+ return /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)("div", { className: "space-y-3", children: [
6281
+ rows.map((r) => /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)("div", { children: [
6282
+ /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)("div", { className: "flex items-center justify-between text-xs mb-1", children: [
6283
+ /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("span", { className: "text-gray-600", children: r.label }),
6284
+ /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("span", { className: "font-semibold text-gray-900", children: r.value.toLocaleString() })
6285
+ ] }),
6286
+ /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("div", { className: "h-2 rounded bg-gray-100 overflow-hidden", children: /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("div", { className: "h-2 bg-gray-700 rounded", style: { width: `${safePct(r.value, base)}%` } }) })
6287
+ ] }, r.label)),
6288
+ /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)("div", { className: "pt-1 text-xs text-gray-600", children: [
6289
+ "Contact rate:",
6290
+ " ",
6291
+ /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)("span", { className: "font-semibold text-gray-900", children: [
6292
+ visitors > 0 ? (contacts / visitors * 100).toFixed(1) : "0.0",
6293
+ "%"
6294
+ ] }),
6295
+ " ",
6296
+ " | Submission rate:",
6297
+ " ",
6298
+ /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)("span", { className: "font-semibold text-gray-900", children: [
6299
+ visitors > 0 ? (submissions / visitors * 100).toFixed(1) : "0.0",
6300
+ "%"
6301
+ ] })
6302
+ ] })
6303
+ ] });
6304
+ })()
6305
+ ] }),
6306
+ /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)("div", { className: "bg-white rounded-lg border border-gray-100 p-4 shadow-sm", children: [
6307
+ /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("h3", { className: "text-base font-semibold text-gray-800 mb-3", children: "CRM Distribution" }),
6308
+ (() => {
6309
+ const contacts = dashboardStats?.contacts.total || 0;
6310
+ const forms = dashboardStats?.forms.total || 0;
6311
+ const blogs = dashboardStats?.blogs || 0;
6312
+ const users = dashboardStats?.users || 0;
6313
+ const base = Math.max(contacts, forms, blogs, users, 1);
6314
+ const rows = [
6315
+ { label: "Contacts", value: contacts },
6316
+ { label: "Forms", value: forms },
6317
+ { label: "Blogs", value: blogs },
6318
+ { label: "Users", value: users }
6319
+ ];
6320
+ return /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("div", { className: "space-y-2", children: rows.map((r) => /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)("div", { children: [
6321
+ /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)("div", { className: "flex items-center justify-between text-xs mb-1", children: [
6322
+ /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("span", { className: "text-gray-600", children: r.label }),
6323
+ /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("span", { className: "font-semibold text-gray-900", children: r.value })
6324
+ ] }),
6325
+ /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("div", { className: "h-2 rounded bg-gray-100 overflow-hidden", children: /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("div", { className: "h-2 bg-gray-700 rounded", style: { width: `${safePct(r.value, base)}%` } }) })
6326
+ ] }, r.label)) });
6327
+ })()
6328
+ ] })
6329
+ ] }),
6330
+ analyticsEnabled && analyticsData && /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)("div", { className: "bg-white rounded-lg border border-gray-100 p-4 shadow-sm mb-2", children: [
6331
+ /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("h3", { className: "text-base font-semibold text-gray-800 mb-3", children: "Top Content & Sources" }),
6332
+ /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)("div", { className: "grid grid-cols-1 lg:grid-cols-2 gap-6", children: [
6333
+ /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)("div", { children: [
6334
+ /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("p", { className: "text-xs font-semibold text-gray-700 mb-2", children: "Top Pages" }),
6335
+ /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("div", { className: "space-y-1", children: analyticsData.topPages.slice(0, 5).map((page, index) => /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)("div", { className: "flex items-center justify-between text-xs", children: [
6336
+ /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("span", { className: "text-gray-600 truncate max-w-[75%]", children: page.page }),
6337
+ /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("span", { className: "font-semibold text-gray-900", children: page.views.toLocaleString() })
6338
+ ] }, index)) })
6339
+ ] }),
6340
+ /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)("div", { children: [
6341
+ /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("p", { className: "text-xs font-semibold text-gray-700 mb-2", children: "Traffic Sources" }),
6342
+ /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("div", { className: "space-y-1", children: analyticsData.trafficSources.slice(0, 5).map((source, index) => /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)("div", { className: "flex items-center justify-between text-xs", children: [
6343
+ /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("span", { className: "text-gray-600", children: source.source }),
6344
+ /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("span", { className: "font-semibold text-gray-900", children: source.sessions.toLocaleString() })
6345
+ ] }, index)) })
6346
+ ] })
6347
+ ] })
6348
+ ] })
6349
+ ] }),
6350
+ activeTab === "sales" && !isLoading && storeEnabled && ecommerceData && /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)(import_jsx_runtime45.Fragment, { children: [
6351
+ /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("div", { className: "border-t-2 border-dotted border-gray-200 my-6" }),
6352
+ /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)("div", { className: "mb-4", children: [
6353
+ /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)("div", { className: "flex items-center mb-2", children: [
6354
+ /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(import_lucide_react22.BarChart3, { className: "w-4 h-4 text-gray-600 mr-2" }),
6355
+ /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("h2", { className: "text-sm font-semibold text-gray-800", children: "Store Analytics" })
6356
+ ] }),
6357
+ /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)("div", { className: "grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-3", children: [
6358
+ /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)("button", { onClick: () => router.push("/admin/orders"), className: "text-left bg-white rounded border border-gray-200 p-2.5 shadow-sm", children: [
6359
+ /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("p", { className: "text-xs text-gray-600", children: "Net Sales" }),
6360
+ /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("p", { className: "text-lg font-bold text-gray-900", children: formatMoney4(ecommerceData.kpis.netSales) })
6361
+ ] }),
6362
+ /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)("button", { onClick: () => router.push("/admin/orders"), className: "text-left bg-white rounded border border-gray-200 p-2.5 shadow-sm", children: [
6363
+ /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("p", { className: "text-xs text-gray-600", children: "Orders" }),
6364
+ /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("p", { className: "text-lg font-bold text-gray-900", children: ecommerceData.kpis.ordersPlaced })
6365
+ ] }),
6366
+ /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)("button", { onClick: () => router.push("/admin/orders"), className: "text-left bg-white rounded border border-gray-200 p-2.5 shadow-sm", children: [
6367
+ /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("p", { className: "text-xs text-gray-600", children: "AOV" }),
6368
+ /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("p", { className: "text-lg font-bold text-gray-900", children: formatMoney4(ecommerceData.kpis.averageOrderValue) })
6369
+ ] }),
6370
+ /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)("button", { onClick: () => router.push("/admin/contacts"), className: "text-left bg-white rounded border border-gray-200 p-2.5 shadow-sm", children: [
6371
+ /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("p", { className: "text-xs text-gray-600", children: "Returning Customer Rate" }),
6372
+ /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)("p", { className: "text-lg font-bold text-gray-900", children: [
6373
+ ecommerceData.kpis.returningCustomerRate.toFixed(1),
6374
+ "%"
6375
+ ] })
6376
+ ] }),
6377
+ /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)("button", { onClick: () => router.push("/admin/orders"), className: "text-left bg-white rounded border border-gray-200 p-2.5 shadow-sm", children: [
6378
+ /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("p", { className: "text-xs text-gray-600", children: "Return Rate" }),
6379
+ /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)("p", { className: "text-lg font-bold text-gray-900", children: [
6380
+ ecommerceData.kpis.returnRate.toFixed(1),
6381
+ "%"
6382
+ ] })
6383
+ ] }),
6384
+ /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)("button", { onClick: () => router.push("/admin/payments"), className: "text-left bg-white rounded border border-gray-200 p-2.5 shadow-sm", children: [
6385
+ /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("p", { className: "text-xs text-gray-600", children: "Payment Success" }),
6386
+ /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)("p", { className: "text-lg font-bold text-gray-900", children: [
6387
+ ecommerceData.kpis.paymentSuccessRate.toFixed(1),
6388
+ "%"
6389
+ ] })
6390
+ ] })
6391
+ ] })
6392
+ ] }),
6393
+ /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)("div", { className: "grid grid-cols-1 lg:grid-cols-2 gap-6 mb-6", children: [
6394
+ /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)("div", { className: "bg-white rounded-lg border border-gray-100 p-4 shadow-sm", children: [
6395
+ /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("h3", { className: "text-base font-semibold text-gray-800 mb-3", children: "Sales Over Time" }),
6396
+ /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("div", { className: "space-y-2 max-h-64 overflow-auto", children: ecommerceData.salesOverTime.slice(-10).map((point) => /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)("div", { className: "flex items-center justify-between text-xs", children: [
6397
+ /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("span", { className: "text-gray-600", children: point.date }),
6398
+ /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)("span", { className: "font-semibold text-gray-900", children: [
6399
+ formatMoney4(point.value),
6400
+ " (",
6401
+ point.orders,
6402
+ ")"
6403
+ ] })
6404
+ ] }, point.date)) })
6405
+ ] }),
6406
+ /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)("div", { className: "bg-white rounded-lg border border-gray-100 p-4 shadow-sm", children: [
6407
+ /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("h3", { className: "text-base font-semibold text-gray-800 mb-3", children: "Top Products" }),
6408
+ /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("div", { className: "space-y-2", children: ecommerceData.topProducts.map((p, idx) => /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)(
6409
+ "button",
6410
+ {
6411
+ onClick: () => router.push("/admin/products"),
6412
+ className: "w-full text-left flex items-center justify-between p-2 bg-gray-50 rounded-lg",
6413
+ children: [
6414
+ /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("span", { className: "text-xs text-gray-700 truncate max-w-[70%]", children: p.name }),
6415
+ /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)("span", { className: "text-xs font-semibold text-gray-900", children: [
6416
+ p.units,
6417
+ " / ",
6418
+ formatMoney4(p.sales)
6419
+ ] })
6420
+ ]
6421
+ },
6422
+ `${p.name}-${idx}`
6423
+ )) })
6424
+ ] })
6425
+ ] }),
6426
+ /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)("div", { className: "grid grid-cols-1 lg:grid-cols-3 gap-6 mb-2", children: [
6427
+ /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)("div", { className: "bg-white rounded-lg border border-gray-100 p-4 shadow-sm", children: [
6428
+ /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("h3", { className: "text-base font-semibold text-gray-800 mb-2", children: "Customer Mix" }),
6429
+ /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)("p", { className: "text-xs text-gray-700", children: [
6430
+ "New: ",
6431
+ ecommerceData.customerMix.newCustomers
6432
+ ] }),
6433
+ /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)("p", { className: "text-xs text-gray-700", children: [
6434
+ "Returning: ",
6435
+ ecommerceData.customerMix.returningCustomers
6436
+ ] }),
6437
+ /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)("p", { className: "text-xs text-gray-700", children: [
6438
+ "Repeat rate: ",
6439
+ ecommerceData.customerMix.repeatPurchaseRate.toFixed(1),
6440
+ "%"
6441
+ ] })
6442
+ ] }),
6443
+ /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)("div", { className: "bg-white rounded-lg border border-gray-100 p-4 shadow-sm", children: [
6444
+ /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("h3", { className: "text-base font-semibold text-gray-800 mb-2", children: "Returns Trend" }),
6445
+ /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)("p", { className: "text-xs text-gray-700", children: [
6446
+ "Return value: ",
6447
+ formatMoney4(ecommerceData.kpis.returnValue)
6448
+ ] }),
6449
+ /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)("p", { className: "text-xs text-gray-700", children: [
6450
+ "Return orders: ",
6451
+ ecommerceData.returnsTrend.reduce((s, r) => s + r.count, 0)
6452
+ ] }),
6453
+ /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)("p", { className: "text-xs text-gray-700", children: [
6454
+ "Return rate: ",
6455
+ ecommerceData.kpis.returnRate.toFixed(1),
6456
+ "%"
6457
+ ] })
6458
+ ] }),
6459
+ /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)("div", { className: "bg-white rounded-lg border border-gray-100 p-4 shadow-sm", children: [
6460
+ /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("h3", { className: "text-base font-semibold text-gray-800 mb-2", children: "Inventory Risk" }),
6461
+ /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)("p", { className: "text-xs text-gray-700", children: [
6462
+ "Out of stock: ",
6463
+ ecommerceData.inventoryRisk.outOfStockCount
6464
+ ] }),
6465
+ /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)("p", { className: "text-xs text-gray-700", children: [
6466
+ "Low stock: ",
6467
+ ecommerceData.inventoryRisk.lowStockCount
6468
+ ] }),
6469
+ /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)("p", { className: "text-xs text-gray-700", children: [
6470
+ "Total units: ",
6471
+ ecommerceData.inventoryRisk.totalInventory
6472
+ ] })
6473
+ ] })
6474
+ ] })
6475
+ ] }),
5775
6476
  isLoading && /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)("div", { className: "flex items-center justify-center py-8", children: [
5776
6477
  /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("div", { className: "animate-spin rounded-full h-5 w-5 border-2 border-gray-300 border-t-gray-600" }),
5777
6478
  /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("span", { className: "ml-2 text-sm text-gray-600", children: "Loading dashboard data..." })
5778
6479
  ] }),
5779
- !isLoading && !analyticsEnabled && /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)("div", { className: "text-center py-8", children: [
6480
+ !isLoading && activeTab === "overview" && !analyticsEnabled && /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)("div", { className: "text-center py-8", children: [
5780
6481
  /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(import_lucide_react22.Globe, { className: "w-10 h-10 text-gray-400 mx-auto mb-3" }),
5781
6482
  /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("h3", { className: "text-base font-medium text-gray-600 mb-1", children: "Analytics Not Configured" }),
5782
6483
  /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("p", { className: "text-xs text-gray-500", children: "Google Analytics integration is required to view website analytics." })
6484
+ ] }),
6485
+ !isLoading && activeTab === "sales" && !storeEnabled && /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)("div", { className: "text-center py-8", children: [
6486
+ /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("h3", { className: "text-base font-medium text-gray-600 mb-1", children: "Store analytics unavailable" }),
6487
+ /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("p", { className: "text-xs text-gray-500", children: "Enable store/ecomm to view sales reports." })
5783
6488
  ] })
5784
6489
  ] })
5785
6490
  ] });
5786
6491
  }
5787
6492
 
5788
6493
  // src/admin/pages/AdminPageResolver.tsx
5789
- var import_react47 = require("react");
5790
- var import_navigation19 = require("next/navigation");
6494
+ var import_react48 = require("react");
6495
+ var import_navigation21 = require("next/navigation");
5791
6496
 
5792
6497
  // src/admin/pages/SubmissionDetailPage.tsx
5793
- var import_react32 = require("react");
6498
+ var import_react33 = require("react");
5794
6499
  var import_link9 = __toESM(require("next/link"), 1);
5795
6500
  var import_lucide_react24 = require("lucide-react");
5796
6501
 
5797
6502
  // src/components/Admin/DetailPageHeader.tsx
5798
6503
  var import_link8 = __toESM(require("next/link"), 1);
5799
- var import_navigation10 = require("next/navigation");
6504
+ var import_navigation12 = require("next/navigation");
5800
6505
  var import_lucide_react23 = require("lucide-react");
5801
6506
  var import_jsx_runtime46 = require("react/jsx-runtime");
5802
6507
  function DetailPageHeader({
@@ -5808,7 +6513,7 @@ function DetailPageHeader({
5808
6513
  onClose,
5809
6514
  menuItems = []
5810
6515
  }) {
5811
- const router = (0, import_navigation10.useRouter)();
6516
+ const router = (0, import_navigation12.useRouter)();
5812
6517
  const handleClose = () => {
5813
6518
  if (onClose) onClose();
5814
6519
  else if (closeHref) router.push(closeHref);
@@ -5833,20 +6538,32 @@ function DetailPageHeader({
5833
6538
  ] })
5834
6539
  ] }),
5835
6540
  /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)("div", { className: "flex items-center gap-2 shrink-0", children: [
5836
- menuItems.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)(DropdownMenu, { children: [
5837
- /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)(
5838
- Button,
5839
- {
5840
- variant: "ghost",
5841
- size: "icon",
5842
- className: "h-8 w-8 text-gray-300 hover:text-white hover:bg-gray-700",
5843
- children: [
5844
- /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(import_lucide_react23.MoreVertical, { className: "h-4 w-4" }),
5845
- /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("span", { className: "sr-only", children: "More" })
5846
- ]
5847
- }
5848
- ) }),
5849
- /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(DropdownMenuContent, { align: "end", className: "w-48", children: menuItems.map((item, i) => /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(DropdownMenuItem, { onClick: item.onClick, children: item.label }, i)) })
6541
+ menuItems.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)(import_jsx_runtime46.Fragment, { children: [
6542
+ /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("div", { className: "flex items-center gap-2 md:hidden", children: menuItems.map((item, i) => {
6543
+ const Icon2 = item.icon;
6544
+ return /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)(
6545
+ Button,
6546
+ {
6547
+ variant: item.variant ?? "outline",
6548
+ size: "icon",
6549
+ className: "h-8 w-8 border border-gray-600 bg-transparent text-white hover:bg-gray-700",
6550
+ onClick: item.onClick,
6551
+ title: item.label,
6552
+ children: [
6553
+ /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(Icon2, { className: "h-4 w-4" }),
6554
+ /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("span", { className: "sr-only", children: item.label })
6555
+ ]
6556
+ },
6557
+ i
6558
+ );
6559
+ }) }),
6560
+ /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("div", { className: "hidden md:flex items-center gap-2", children: menuItems.map((item, i) => {
6561
+ const Icon2 = item.icon;
6562
+ return /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)(Button, { variant: item.variant ?? "outline", size: "sm", onClick: item.onClick, children: [
6563
+ /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(Icon2, { className: "h-4 w-4 mr-1" }),
6564
+ item.label
6565
+ ] }, i);
6566
+ }) })
5850
6567
  ] }),
5851
6568
  /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)(
5852
6569
  Button,
@@ -5868,10 +6585,10 @@ function DetailPageHeader({
5868
6585
  // src/admin/pages/SubmissionDetailPage.tsx
5869
6586
  var import_jsx_runtime47 = require("react/jsx-runtime");
5870
6587
  function SubmissionDetailPage({ submissionId }) {
5871
- const [submission, setSubmission] = (0, import_react32.useState)(null);
5872
- const [loading, setLoading] = (0, import_react32.useState)(true);
5873
- const [error, setError] = (0, import_react32.useState)(null);
5874
- (0, import_react32.useEffect)(() => {
6588
+ const [submission, setSubmission] = (0, import_react33.useState)(null);
6589
+ const [loading, setLoading] = (0, import_react33.useState)(true);
6590
+ const [error, setError] = (0, import_react33.useState)(null);
6591
+ (0, import_react33.useEffect)(() => {
5875
6592
  async function load() {
5876
6593
  try {
5877
6594
  setLoading(true);
@@ -5979,9 +6696,9 @@ function SubmissionDetailPage({ submissionId }) {
5979
6696
  }
5980
6697
 
5981
6698
  // src/admin/pages/OrderDetailPage.tsx
5982
- var import_react33 = require("react");
6699
+ var import_react34 = require("react");
5983
6700
  var import_link10 = __toESM(require("next/link"), 1);
5984
- var import_navigation11 = require("next/navigation");
6701
+ var import_navigation13 = require("next/navigation");
5985
6702
  var import_lucide_react25 = require("lucide-react");
5986
6703
 
5987
6704
  // src/components/Admin/DetailPageLayout.tsx
@@ -6023,13 +6740,13 @@ function formatAddress(a) {
6023
6740
  return parts.join(", ") || "\u2014";
6024
6741
  }
6025
6742
  function OrderDetailPage({ orderId }) {
6026
- const router = (0, import_navigation11.useRouter)();
6027
- const [order, setOrder] = (0, import_react33.useState)(null);
6028
- const [loading, setLoading] = (0, import_react33.useState)(true);
6029
- const [error, setError] = (0, import_react33.useState)(null);
6030
- const [erpEnabled, setErpEnabled] = (0, import_react33.useState)(false);
6031
- const [reposting, setReposting] = (0, import_react33.useState)(false);
6032
- (0, import_react33.useEffect)(() => {
6743
+ const router = (0, import_navigation13.useRouter)();
6744
+ const [order, setOrder] = (0, import_react34.useState)(null);
6745
+ const [loading, setLoading] = (0, import_react34.useState)(true);
6746
+ const [error, setError] = (0, import_react34.useState)(null);
6747
+ const [erpEnabled, setErpEnabled] = (0, import_react34.useState)(false);
6748
+ const [reposting, setReposting] = (0, import_react34.useState)(false);
6749
+ (0, import_react34.useEffect)(() => {
6033
6750
  async function load() {
6034
6751
  try {
6035
6752
  setLoading(true);
@@ -6052,7 +6769,7 @@ function OrderDetailPage({ orderId }) {
6052
6769
  }
6053
6770
  load();
6054
6771
  }, [orderId]);
6055
- (0, import_react33.useEffect)(() => {
6772
+ (0, import_react34.useEffect)(() => {
6056
6773
  let cancelled = false;
6057
6774
  (async () => {
6058
6775
  try {
@@ -6108,7 +6825,7 @@ function OrderDetailPage({ orderId }) {
6108
6825
  title: `Order ${order.orderNumber}`,
6109
6826
  subtitle: /* @__PURE__ */ (0, import_jsx_runtime49.jsx)("span", { className: "text-sm text-gray-400", children: formatDateTime(order.createdAt) }),
6110
6827
  closeHref: "/admin/orders",
6111
- menuItems: erpEnabled ? [{ label: reposting ? "Reposting..." : "Repost to ERP", onClick: handleRepostToErp }] : void 0
6828
+ menuItems: erpEnabled ? [{ label: reposting ? "Reposting..." : "Repost to ERP", icon: import_lucide_react25.RefreshCw, onClick: handleRepostToErp }] : void 0
6112
6829
  }
6113
6830
  ),
6114
6831
  /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(
@@ -6348,9 +7065,9 @@ function OrderDetailPage({ orderId }) {
6348
7065
  }
6349
7066
 
6350
7067
  // src/admin/pages/PaymentDetailPage.tsx
6351
- var import_react34 = require("react");
7068
+ var import_react35 = require("react");
6352
7069
  var import_link11 = __toESM(require("next/link"), 1);
6353
- var import_navigation12 = require("next/navigation");
7070
+ var import_navigation14 = require("next/navigation");
6354
7071
  var import_lucide_react26 = require("lucide-react");
6355
7072
  var import_jsx_runtime50 = require("react/jsx-runtime");
6356
7073
  function formatMoney2(amount, currency = "INR") {
@@ -6361,11 +7078,11 @@ function formatMoney2(amount, currency = "INR") {
6361
7078
  }).format(Number(amount));
6362
7079
  }
6363
7080
  function PaymentDetailPage({ paymentId }) {
6364
- const router = (0, import_navigation12.useRouter)();
6365
- const [payment, setPayment] = (0, import_react34.useState)(null);
6366
- const [loading, setLoading] = (0, import_react34.useState)(true);
6367
- const [error, setError] = (0, import_react34.useState)(null);
6368
- (0, import_react34.useEffect)(() => {
7081
+ const router = (0, import_navigation14.useRouter)();
7082
+ const [payment, setPayment] = (0, import_react35.useState)(null);
7083
+ const [loading, setLoading] = (0, import_react35.useState)(true);
7084
+ const [error, setError] = (0, import_react35.useState)(null);
7085
+ (0, import_react35.useEffect)(() => {
6369
7086
  async function load() {
6370
7087
  try {
6371
7088
  setLoading(true);
@@ -6507,9 +7224,9 @@ function PaymentDetailPage({ paymentId }) {
6507
7224
  }
6508
7225
 
6509
7226
  // src/admin/pages/ContactDetailPage.tsx
6510
- var import_react35 = require("react");
7227
+ var import_react36 = require("react");
6511
7228
  var import_link12 = __toESM(require("next/link"), 1);
6512
- var import_navigation13 = require("next/navigation");
7229
+ var import_navigation15 = require("next/navigation");
6513
7230
  var import_lucide_react27 = require("lucide-react");
6514
7231
  var import_jsx_runtime51 = require("react/jsx-runtime");
6515
7232
  function formatMoney3(amount, currency = "INR") {
@@ -6525,13 +7242,13 @@ function formatAddress2(a) {
6525
7242
  }
6526
7243
  var ADDRESS_TAGS = [{ value: "", label: "\u2014" }, { value: "default", label: "Default" }, { value: "billing", label: "Billing" }, { value: "shipping", label: "Shipping" }];
6527
7244
  function ContactDetailPage({ contactId }) {
6528
- const router = (0, import_navigation13.useRouter)();
6529
- const [contact, setContact] = (0, import_react35.useState)(null);
6530
- const [loading, setLoading] = (0, import_react35.useState)(true);
6531
- const [error, setError] = (0, import_react35.useState)(null);
6532
- const [addAddressOpen, setAddAddressOpen] = (0, import_react35.useState)(false);
6533
- const [addAddressSaving, setAddAddressSaving] = (0, import_react35.useState)(false);
6534
- const [addAddressForm, setAddAddressForm] = (0, import_react35.useState)({
7245
+ const router = (0, import_navigation15.useRouter)();
7246
+ const [contact, setContact] = (0, import_react36.useState)(null);
7247
+ const [loading, setLoading] = (0, import_react36.useState)(true);
7248
+ const [error, setError] = (0, import_react36.useState)(null);
7249
+ const [addAddressOpen, setAddAddressOpen] = (0, import_react36.useState)(false);
7250
+ const [addAddressSaving, setAddAddressSaving] = (0, import_react36.useState)(false);
7251
+ const [addAddressForm, setAddAddressForm] = (0, import_react36.useState)({
6535
7252
  tag: "",
6536
7253
  line1: "",
6537
7254
  line2: "",
@@ -6543,7 +7260,7 @@ function ContactDetailPage({ contactId }) {
6543
7260
  const loadContact = () => {
6544
7261
  fetch(`/api/contacts/${contactId}`).then((res) => res.ok ? res.json() : null).then((data) => setContact(data)).catch(() => setContact(null));
6545
7262
  };
6546
- (0, import_react35.useEffect)(() => {
7263
+ (0, import_react36.useEffect)(() => {
6547
7264
  async function load() {
6548
7265
  try {
6549
7266
  setLoading(true);
@@ -6879,9 +7596,9 @@ function ContactDetailPage({ contactId }) {
6879
7596
  }
6880
7597
 
6881
7598
  // src/admin/pages/SettingsPage.tsx
6882
- var import_react36 = require("react");
6883
- var import_navigation14 = require("next/navigation");
6884
- var import_sonner4 = require("sonner");
7599
+ var import_react37 = require("react");
7600
+ var import_navigation16 = require("next/navigation");
7601
+ var import_sonner5 = require("sonner");
6885
7602
  var import_lucide_react28 = require("lucide-react");
6886
7603
  var import_jsx_runtime52 = require("react/jsx-runtime");
6887
7604
  var DEFAULTS = {
@@ -6905,25 +7622,25 @@ function hexToHsl(hex) {
6905
7622
  return `${Math.round(h * 360)} ${Math.round(s * 100)}% ${Math.round(l * 100)}%`;
6906
7623
  }
6907
7624
  function SettingsPage() {
6908
- const searchParams = (0, import_navigation14.useSearchParams)();
7625
+ const searchParams = (0, import_navigation16.useSearchParams)();
6909
7626
  const tabParam = searchParams.get("tab");
6910
- const { theme, themeRegistry } = (0, import_react36.useContext)(AdminConfigContext);
6911
- const [tab, setTab] = (0, import_react36.useState)(
7627
+ const { theme, themeRegistry } = (0, import_react37.useContext)(AdminConfigContext);
7628
+ const [tab, setTab] = (0, import_react37.useState)(
6912
7629
  tabParam === "navbar" ? "navbar" : tabParam === "store" ? "store" : "appearance"
6913
7630
  );
6914
- (0, import_react36.useEffect)(() => {
7631
+ (0, import_react37.useEffect)(() => {
6915
7632
  if (tabParam === "navbar") setTab("navbar");
6916
7633
  else if (tabParam === "store") setTab("store");
6917
7634
  }, [tabParam]);
6918
- const [settings, setSettings] = (0, import_react36.useState)(DEFAULTS);
6919
- const [loading, setLoading] = (0, import_react36.useState)(true);
6920
- const [saving, setSaving] = (0, import_react36.useState)(false);
6921
- const [activeThemeId, setActiveThemeId] = (0, import_react36.useState)("");
6922
- const [navbarConfig, setNavbarConfig] = (0, import_react36.useState)({ logo: "", items: [], ctaLabel: "", ctaUrl: "" });
6923
- const [themeSettingsLoading, setThemeSettingsLoading] = (0, import_react36.useState)(true);
6924
- const [storeEnabled, setStoreEnabled] = (0, import_react36.useState)(false);
6925
- const [storeSettingsLoading, setStoreSettingsLoading] = (0, import_react36.useState)(true);
6926
- (0, import_react36.useEffect)(() => {
7635
+ const [settings, setSettings] = (0, import_react37.useState)(DEFAULTS);
7636
+ const [loading, setLoading] = (0, import_react37.useState)(true);
7637
+ const [saving, setSaving] = (0, import_react37.useState)(false);
7638
+ const [activeThemeId, setActiveThemeId] = (0, import_react37.useState)("");
7639
+ const [navbarConfig, setNavbarConfig] = (0, import_react37.useState)({ logo: "", items: [], ctaLabel: "", ctaUrl: "" });
7640
+ const [themeSettingsLoading, setThemeSettingsLoading] = (0, import_react37.useState)(true);
7641
+ const [storeEnabled, setStoreEnabled] = (0, import_react37.useState)(false);
7642
+ const [storeSettingsLoading, setStoreSettingsLoading] = (0, import_react37.useState)(true);
7643
+ (0, import_react37.useEffect)(() => {
6927
7644
  fetch("/api/settings/admin_view").then((r) => r.ok ? r.json() : {}).then((data) => {
6928
7645
  setSettings({
6929
7646
  primaryColor: data.primaryColor || DEFAULTS.primaryColor,
@@ -6932,7 +7649,7 @@ function SettingsPage() {
6932
7649
  });
6933
7650
  }).finally(() => setLoading(false));
6934
7651
  }, []);
6935
- (0, import_react36.useEffect)(() => {
7652
+ (0, import_react37.useEffect)(() => {
6936
7653
  fetch("/api/settings/theme").then((r) => r.ok ? r.json() : null).then((data) => {
6937
7654
  if (!data) return;
6938
7655
  setActiveThemeId((data.activeThemeId || "").trim());
@@ -6944,7 +7661,7 @@ function SettingsPage() {
6944
7661
  }
6945
7662
  }).finally(() => setThemeSettingsLoading(false));
6946
7663
  }, []);
6947
- (0, import_react36.useEffect)(() => {
7664
+ (0, import_react37.useEffect)(() => {
6948
7665
  fetch("/api/settings/store").then((r) => r.ok ? r.json() : {}).then((data) => {
6949
7666
  setStoreEnabled(data.enabled === "true");
6950
7667
  }).finally(() => setStoreSettingsLoading(false));
@@ -6968,9 +7685,9 @@ function SettingsPage() {
6968
7685
  document.documentElement.style.setProperty("--secondary", hexToHsl(settings.secondaryColor));
6969
7686
  if (settings.compactView === "true") document.documentElement.classList.add("compact");
6970
7687
  else document.documentElement.classList.remove("compact");
6971
- import_sonner4.toast.success("Settings saved");
7688
+ import_sonner5.toast.success("Settings saved");
6972
7689
  } catch {
6973
- import_sonner4.toast.error("Failed to save settings");
7690
+ import_sonner5.toast.error("Failed to save settings");
6974
7691
  } finally {
6975
7692
  setSaving(false);
6976
7693
  }
@@ -6984,10 +7701,10 @@ function SettingsPage() {
6984
7701
  headers: { "Content-Type": "application/json" },
6985
7702
  body: JSON.stringify({ activeThemeId: { value: id, type: "public" } })
6986
7703
  });
6987
- import_sonner4.toast.success("Theme updated");
7704
+ import_sonner5.toast.success("Theme updated");
6988
7705
  window.location.reload();
6989
7706
  } catch {
6990
- import_sonner4.toast.error("Failed to save theme");
7707
+ import_sonner5.toast.error("Failed to save theme");
6991
7708
  } finally {
6992
7709
  setSaving(false);
6993
7710
  }
@@ -7000,9 +7717,9 @@ function SettingsPage() {
7000
7717
  headers: { "Content-Type": "application/json" },
7001
7718
  body: JSON.stringify({ navbar: { value: JSON.stringify(navbarConfig), type: "public" } })
7002
7719
  });
7003
- import_sonner4.toast.success("Navbar saved");
7720
+ import_sonner5.toast.success("Navbar saved");
7004
7721
  } catch {
7005
- import_sonner4.toast.error("Failed to save");
7722
+ import_sonner5.toast.error("Failed to save");
7006
7723
  } finally {
7007
7724
  setSaving(false);
7008
7725
  }
@@ -7015,10 +7732,10 @@ function SettingsPage() {
7015
7732
  headers: { "Content-Type": "application/json" },
7016
7733
  body: JSON.stringify({ enabled: { value: storeEnabled ? "true" : "false", type: "public" } })
7017
7734
  });
7018
- import_sonner4.toast.success("Store settings saved");
7735
+ import_sonner5.toast.success("Store settings saved");
7019
7736
  window.location.reload();
7020
7737
  } catch {
7021
- import_sonner4.toast.error("Failed to save store settings");
7738
+ import_sonner5.toast.error("Failed to save store settings");
7022
7739
  } finally {
7023
7740
  setSaving(false);
7024
7741
  }
@@ -7134,11 +7851,24 @@ function SettingsPage() {
7134
7851
  }
7135
7852
 
7136
7853
  // src/admin/pages/MediaLibraryPage.tsx
7137
- var import_react37 = require("react");
7854
+ var import_react38 = __toESM(require("react"), 1);
7855
+
7856
+ // src/lib/media-zip-extract.ts
7857
+ var import_typeorm = require("typeorm");
7858
+ var ZIP_MIME_TYPES = /* @__PURE__ */ new Set(["application/zip", "application/x-zip-compressed"]);
7859
+ var MAX_TOTAL_UNCOMPRESSED = 80 * 1024 * 1024;
7860
+ function isZipMedia(mime, filename) {
7861
+ if (mime && ZIP_MIME_TYPES.has(mime)) return true;
7862
+ return filename.toLowerCase().endsWith(".zip");
7863
+ }
7864
+
7865
+ // src/admin/pages/MediaLibraryPage.tsx
7138
7866
  var import_lucide_react29 = require("lucide-react");
7139
- var import_sonner5 = require("sonner");
7867
+ var import_sonner6 = require("sonner");
7140
7868
  var import_jsx_runtime53 = require("react/jsx-runtime");
7141
- function getTypeCategory(mime) {
7869
+ function getTypeCategory(mime, kind, filename) {
7870
+ if (kind === "folder" || mime === "inode/directory") return "folder";
7871
+ if (isZipMedia(mime, filename ?? "")) return "zip";
7142
7872
  if (!mime) return "other";
7143
7873
  if (mime.startsWith("image/")) return "image";
7144
7874
  if (mime.startsWith("video/")) return "video";
@@ -7146,56 +7876,66 @@ function getTypeCategory(mime) {
7146
7876
  if (mime === "application/pdf" || mime.startsWith("application/")) return "document";
7147
7877
  return "other";
7148
7878
  }
7149
- function getTypeLabel(mime) {
7150
- const c = getTypeCategory(mime);
7879
+ function getTypeLabel(mime, kind, filename) {
7880
+ if (kind === "folder" || mime === "inode/directory") return "Folder";
7881
+ if (isZipMedia(mime, filename ?? "")) return "Zip";
7882
+ const c = getTypeCategory(mime, kind, filename);
7151
7883
  const labels = {
7152
7884
  image: "Image",
7153
7885
  video: "Video",
7154
7886
  audio: "Audio",
7155
7887
  document: "Document",
7888
+ folder: "Folder",
7889
+ zip: "Zip",
7156
7890
  other: "Other"
7157
7891
  };
7158
7892
  return labels[c] || "Other";
7159
7893
  }
7160
- function TypeIcon({ mimeType }) {
7161
- const c = getTypeCategory(mimeType);
7894
+ function TypeIcon({ mimeType, kind, filename }) {
7895
+ if (kind === "folder" || mimeType === "inode/directory") {
7896
+ return /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(import_lucide_react29.Folder, { className: "h-10 w-10 text-amber-500" });
7897
+ }
7898
+ if (isZipMedia(mimeType, filename ?? "")) {
7899
+ return /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(import_lucide_react29.Archive, { className: "h-10 w-10 text-violet-600" });
7900
+ }
7901
+ const c = getTypeCategory(mimeType, kind, filename);
7162
7902
  if (c === "image") return /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(import_lucide_react29.Image, { className: "h-8 w-8 text-gray-400" });
7163
7903
  if (c === "video") return /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(import_lucide_react29.Film, { className: "h-8 w-8 text-gray-400" });
7164
7904
  if (c === "document") return /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(import_lucide_react29.FileText, { className: "h-8 w-8 text-gray-400" });
7165
7905
  return /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(import_lucide_react29.File, { className: "h-8 w-8 text-gray-400" });
7166
7906
  }
7167
- function groupByMonth(items) {
7168
- const groups = {};
7169
- items.forEach((item) => {
7170
- const d = new Date(item.createdAt);
7171
- const key = `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, "0")}`;
7172
- const label = d.toLocaleDateString("en-US", { year: "numeric", month: "long" });
7173
- if (!groups[label]) groups[label] = [];
7174
- groups[label].push(item);
7175
- });
7176
- return groups;
7177
- }
7178
7907
  function MediaLibraryPage() {
7179
- const [data, setData] = (0, import_react37.useState)([]);
7180
- const [loading, setLoading] = (0, import_react37.useState)(true);
7181
- const [page, setPage] = (0, import_react37.useState)(1);
7182
- const [totalPages, setTotalPages] = (0, import_react37.useState)(1);
7183
- const [search, setSearch] = (0, import_react37.useState)("");
7184
- const [searchInput, setSearchInput] = (0, import_react37.useState)("");
7185
- const [typeFilter, setTypeFilter] = (0, import_react37.useState)("");
7186
- const [uploading, setUploading] = (0, import_react37.useState)(false);
7187
- const [editModal, setEditModal] = (0, import_react37.useState)(null);
7188
- const [editAlt, setEditAlt] = (0, import_react37.useState)("");
7189
- const [editPublic, setEditPublic] = (0, import_react37.useState)(false);
7190
- const fileInputRef = (0, import_react37.useRef)(null);
7191
- const load = (0, import_react37.useCallback)(async () => {
7908
+ const [data, setData] = (0, import_react38.useState)([]);
7909
+ const [loading, setLoading] = (0, import_react38.useState)(true);
7910
+ const [page, setPage] = (0, import_react38.useState)(1);
7911
+ const [totalPages, setTotalPages] = (0, import_react38.useState)(1);
7912
+ const [search, setSearch] = (0, import_react38.useState)("");
7913
+ const [searchInput, setSearchInput] = (0, import_react38.useState)("");
7914
+ const [typeFilter, setTypeFilter] = (0, import_react38.useState)("");
7915
+ const [sortField, setSortField] = (0, import_react38.useState)("filename");
7916
+ const [sortOrder, setSortOrder] = (0, import_react38.useState)("asc");
7917
+ const [viewMode, setViewMode] = (0, import_react38.useState)("grid");
7918
+ const [uploading, setUploading] = (0, import_react38.useState)(false);
7919
+ const [currentParentId, setCurrentParentId] = (0, import_react38.useState)(null);
7920
+ const [crumb, setCrumb] = (0, import_react38.useState)([]);
7921
+ const [newFolderOpen, setNewFolderOpen] = (0, import_react38.useState)(false);
7922
+ const [newFolderName, setNewFolderName] = (0, import_react38.useState)("");
7923
+ const [editModal, setEditModal] = (0, import_react38.useState)(null);
7924
+ const [deleteTarget, setDeleteTarget] = (0, import_react38.useState)(null);
7925
+ const [editAlt, setEditAlt] = (0, import_react38.useState)("");
7926
+ const [editPublic, setEditPublic] = (0, import_react38.useState)(false);
7927
+ const [editFilename, setEditFilename] = (0, import_react38.useState)("");
7928
+ const [extractingId, setExtractingId] = (0, import_react38.useState)(null);
7929
+ const fileInputRef = (0, import_react38.useRef)(null);
7930
+ const load = (0, import_react38.useCallback)(async () => {
7192
7931
  setLoading(true);
7193
7932
  const params = new URLSearchParams({
7194
7933
  page: String(page),
7195
7934
  limit: "24",
7196
- sortField: "createdAt",
7197
- sortOrder: "desc"
7935
+ sortField,
7936
+ sortOrder
7198
7937
  });
7938
+ params.set("parentId", currentParentId === null ? "" : String(currentParentId));
7199
7939
  if (search) params.set("search", search);
7200
7940
  if (typeFilter) params.set("type", typeFilter);
7201
7941
  try {
@@ -7210,11 +7950,33 @@ function MediaLibraryPage() {
7210
7950
  } finally {
7211
7951
  setLoading(false);
7212
7952
  }
7213
- }, [page, search, typeFilter]);
7214
- (0, import_react37.useEffect)(() => {
7953
+ }, [page, search, typeFilter, currentParentId, sortField, sortOrder]);
7954
+ (0, import_react38.useEffect)(() => {
7215
7955
  load();
7216
7956
  }, [load]);
7217
7957
  const handleSearch = () => setSearch(searchInput.trim());
7958
+ const goRoot = (0, import_react38.useCallback)(() => {
7959
+ setPage(1);
7960
+ setCurrentParentId(null);
7961
+ setCrumb([]);
7962
+ }, []);
7963
+ const goCrumb = (0, import_react38.useCallback)((index) => {
7964
+ setPage(1);
7965
+ if (index < 0) {
7966
+ goRoot();
7967
+ return;
7968
+ }
7969
+ const slice = crumb.slice(0, index + 1);
7970
+ setCrumb(slice);
7971
+ const last = slice[slice.length - 1];
7972
+ setCurrentParentId(last.id);
7973
+ }, [crumb, goRoot]);
7974
+ const enterFolder = (item) => {
7975
+ if (item.kind !== "folder") return;
7976
+ setPage(1);
7977
+ setCurrentParentId(item.id);
7978
+ setCrumb((c) => [...c, { id: item.id, name: item.filename }]);
7979
+ };
7218
7980
  const handleUpload = async (e) => {
7219
7981
  const file = e.target.files?.[0];
7220
7982
  if (!file) return;
@@ -7222,6 +7984,7 @@ function MediaLibraryPage() {
7222
7984
  try {
7223
7985
  const formData = new FormData();
7224
7986
  formData.append("file", file);
7987
+ if (currentParentId != null) formData.append("parentId", String(currentParentId));
7225
7988
  const uploadRes = await fetch("/api/upload", { method: "POST", body: formData });
7226
7989
  const uploadJson = await uploadRes.json();
7227
7990
  if (!uploadRes.ok) throw new Error(uploadJson.error || "Upload failed");
@@ -7231,69 +7994,134 @@ function MediaLibraryPage() {
7231
7994
  method: "POST",
7232
7995
  headers: { "Content-Type": "application/json" },
7233
7996
  body: JSON.stringify({
7997
+ kind: "file",
7234
7998
  filename: file.name,
7235
7999
  url: filePath.startsWith("http") ? filePath : filePath,
7236
8000
  mimeType: file.type || "application/octet-stream",
7237
8001
  size: file.size,
7238
8002
  alt: null,
7239
- isPublic: false
8003
+ isPublic: false,
8004
+ parentId: currentParentId
7240
8005
  })
7241
8006
  });
7242
8007
  if (!createRes.ok) throw new Error("Failed to create media record");
7243
- import_sonner5.toast.success("File uploaded");
8008
+ import_sonner6.toast.success("File uploaded");
7244
8009
  load();
7245
8010
  } catch (err) {
7246
- import_sonner5.toast.error(err instanceof Error ? err.message : "Upload failed");
8011
+ import_sonner6.toast.error(err instanceof Error ? err.message : "Upload failed");
7247
8012
  } finally {
7248
8013
  setUploading(false);
7249
8014
  e.target.value = "";
7250
8015
  }
7251
8016
  };
7252
- const handleDelete = async (id) => {
7253
- if (!confirm("Delete this file?")) return;
8017
+ const createFolder = async () => {
8018
+ const name = newFolderName.trim();
8019
+ if (!name) {
8020
+ import_sonner6.toast.error("Enter a folder name");
8021
+ return;
8022
+ }
8023
+ try {
8024
+ const res = await fetch("/api/media", {
8025
+ method: "POST",
8026
+ headers: { "Content-Type": "application/json" },
8027
+ body: JSON.stringify({
8028
+ kind: "folder",
8029
+ filename: name,
8030
+ parentId: currentParentId
8031
+ })
8032
+ });
8033
+ const j = await res.json().catch(() => ({}));
8034
+ if (!res.ok) throw new Error(j.error || "Failed to create folder");
8035
+ import_sonner6.toast.success("Folder created");
8036
+ setNewFolderOpen(false);
8037
+ setNewFolderName("");
8038
+ load();
8039
+ } catch (err) {
8040
+ import_sonner6.toast.error(err instanceof Error ? err.message : "Failed");
8041
+ }
8042
+ };
8043
+ const handleExtractZip = async (id) => {
8044
+ setExtractingId(id);
8045
+ try {
8046
+ const res = await fetch(`/api/media/extract/${id}`, { method: "POST" });
8047
+ const j = await res.json().catch(() => ({}));
8048
+ if (!res.ok) throw new Error(j.error || "Extract failed");
8049
+ import_sonner6.toast.success(
8050
+ `Extracted ${j.files ?? 0} file(s)` + (j.folderEntries ? `, ${j.folderEntries} folder path(s)` : "")
8051
+ );
8052
+ load();
8053
+ } catch (e) {
8054
+ import_sonner6.toast.error(e instanceof Error ? e.message : "Extract failed");
8055
+ } finally {
8056
+ setExtractingId(null);
8057
+ }
8058
+ };
8059
+ const handleDelete = async (item) => {
7254
8060
  try {
7255
- const res = await fetch(`/api/media/${id}`, { method: "DELETE" });
8061
+ const res = await fetch(`/api/media/${item.id}`, { method: "DELETE" });
7256
8062
  if (!res.ok) throw new Error("Delete failed");
7257
- import_sonner5.toast.success("Deleted");
8063
+ import_sonner6.toast.success("Deleted");
8064
+ setDeleteTarget(null);
7258
8065
  load();
7259
8066
  } catch {
7260
- import_sonner5.toast.error("Delete failed");
8067
+ import_sonner6.toast.error("Delete failed");
7261
8068
  }
7262
8069
  };
7263
8070
  const handleSaveEdit = async () => {
7264
8071
  if (!editModal) return;
7265
8072
  try {
8073
+ const isFolder = editModal.kind === "folder";
8074
+ const body = isFolder ? { filename: editFilename.trim() || editModal.filename } : { alt: editAlt || null, isPublic: editPublic };
8075
+ if (isFolder && !body.filename) {
8076
+ import_sonner6.toast.error("Name required");
8077
+ return;
8078
+ }
7266
8079
  const res = await fetch(`/api/media/${editModal.id}`, {
7267
8080
  method: "PUT",
7268
8081
  headers: { "Content-Type": "application/json" },
7269
- body: JSON.stringify({ alt: editAlt || null, isPublic: editPublic })
8082
+ body: JSON.stringify(body)
7270
8083
  });
7271
8084
  if (!res.ok) throw new Error("Update failed");
7272
- import_sonner5.toast.success("Updated");
8085
+ import_sonner6.toast.success("Updated");
7273
8086
  setEditModal(null);
7274
8087
  load();
7275
8088
  } catch {
7276
- import_sonner5.toast.error("Update failed");
8089
+ import_sonner6.toast.error("Update failed");
7277
8090
  }
7278
8091
  };
7279
8092
  const copyUrl = (url) => {
7280
8093
  const full = url.startsWith("http") ? url : `${typeof window !== "undefined" ? window.location.origin : ""}${url}`;
7281
8094
  navigator.clipboard.writeText(full);
7282
- import_sonner5.toast.success("URL copied");
8095
+ import_sonner6.toast.success("URL copied");
7283
8096
  };
7284
8097
  const openEdit = (item) => {
7285
8098
  setEditModal(item);
7286
8099
  setEditAlt(item.alt || "");
7287
8100
  setEditPublic(item.isPublic);
8101
+ setEditFilename(item.filename);
7288
8102
  };
7289
- const grouped = groupByMonth(data);
7290
- const isImage = (mime) => getTypeCategory(mime) === "image";
8103
+ const isImage = (mime, kind, filename) => kind !== "folder" && getTypeCategory(mime, kind, filename) === "image";
8104
+ const listViewData = import_react38.default.useMemo(() => {
8105
+ const sorted = [...data];
8106
+ const byDateDesc = (a, b) => new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime();
8107
+ const folders = sorted.filter((x) => x.kind === "folder").sort(byDateDesc);
8108
+ const files = sorted.filter((x) => x.kind !== "folder").sort(byDateDesc);
8109
+ return [...folders, ...files];
8110
+ }, [data]);
7291
8111
  return /* @__PURE__ */ (0, import_jsx_runtime53.jsxs)("div", { className: "min-w-0 rounded-lg bg-white shadow-md", children: [
7292
8112
  /* @__PURE__ */ (0, import_jsx_runtime53.jsxs)("div", { className: "bg-gray-800 border-b border-gray-700 px-4 py-2.5 rounded-t-lg", children: [
7293
8113
  /* @__PURE__ */ (0, import_jsx_runtime53.jsx)("h1", { className: "text-base font-semibold text-white", children: "Media Library" }),
7294
- /* @__PURE__ */ (0, import_jsx_runtime53.jsx)("p", { className: "text-xs text-gray-300 mt-0.5", children: "Upload and manage files. Group by type or date." })
8114
+ /* @__PURE__ */ (0, import_jsx_runtime53.jsx)("p", { className: "text-xs text-gray-300 mt-0.5", children: "Folders and files (Google Drive\u2013style). Storage mirrors the folder tree under uploads/." })
7295
8115
  ] }),
7296
8116
  /* @__PURE__ */ (0, import_jsx_runtime53.jsxs)("div", { className: "min-w-0 p-4 space-y-3", children: [
8117
+ /* @__PURE__ */ (0, import_jsx_runtime53.jsxs)("div", { className: "flex flex-wrap items-center gap-2 text-sm text-gray-700", children: [
8118
+ /* @__PURE__ */ (0, import_jsx_runtime53.jsx)("span", { className: "font-medium text-gray-600", children: "Location:" }),
8119
+ /* @__PURE__ */ (0, import_jsx_runtime53.jsx)("button", { type: "button", className: "text-blue-600 hover:underline", onClick: () => goCrumb(-1), children: "Media" }),
8120
+ crumb.map((c, i) => /* @__PURE__ */ (0, import_jsx_runtime53.jsxs)("span", { className: "flex items-center gap-1", children: [
8121
+ /* @__PURE__ */ (0, import_jsx_runtime53.jsx)("span", { className: "text-gray-400", children: "/" }),
8122
+ /* @__PURE__ */ (0, import_jsx_runtime53.jsx)("button", { type: "button", className: "text-blue-600 hover:underline", onClick: () => goCrumb(i), children: c.name })
8123
+ ] }, `${c.id}-${i}`))
8124
+ ] }),
7297
8125
  /* @__PURE__ */ (0, import_jsx_runtime53.jsxs)("div", { className: "flex flex-wrap items-center gap-3", children: [
7298
8126
  /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(
7299
8127
  "input",
@@ -7303,7 +8131,7 @@ function MediaLibraryPage() {
7303
8131
  className: "hidden",
7304
8132
  onChange: handleUpload,
7305
8133
  disabled: uploading,
7306
- accept: "image/*,video/*,audio/*,.pdf,.doc,.docx"
8134
+ accept: "image/*,video/*,audio/*,.pdf,.doc,.docx,.zip"
7307
8135
  }
7308
8136
  ),
7309
8137
  /* @__PURE__ */ (0, import_jsx_runtime53.jsxs)(
@@ -7319,11 +8147,15 @@ function MediaLibraryPage() {
7319
8147
  ]
7320
8148
  }
7321
8149
  ),
8150
+ /* @__PURE__ */ (0, import_jsx_runtime53.jsxs)(Button, { type: "button", variant: "secondary", className: "flex items-center gap-2", onClick: () => setNewFolderOpen(true), children: [
8151
+ /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(import_lucide_react29.FolderPlus, { className: "h-4 w-4" }),
8152
+ "New folder"
8153
+ ] }),
7322
8154
  /* @__PURE__ */ (0, import_jsx_runtime53.jsxs)("div", { className: "flex items-center gap-2 flex-1 min-w-[200px]", children: [
7323
8155
  /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(
7324
8156
  Input,
7325
8157
  {
7326
- placeholder: "Search by filename...",
8158
+ placeholder: "Search by name...",
7327
8159
  value: searchInput,
7328
8160
  onChange: (e) => setSearchInput(e.target.value),
7329
8161
  onKeyDown: (e) => e.key === "Enter" && handleSearch()
@@ -7345,61 +8177,192 @@ function MediaLibraryPage() {
7345
8177
  /* @__PURE__ */ (0, import_jsx_runtime53.jsx)("option", { value: "application", children: "Documents" })
7346
8178
  ]
7347
8179
  }
7348
- )
8180
+ ),
8181
+ /* @__PURE__ */ (0, import_jsx_runtime53.jsxs)(
8182
+ "select",
8183
+ {
8184
+ className: "border rounded-md px-3 py-2 text-sm bg-white max-w-[200px]",
8185
+ value: `${sortField}:${sortOrder}`,
8186
+ onChange: (e) => {
8187
+ const [f, o] = e.target.value.split(":");
8188
+ setSortField(f);
8189
+ setSortOrder(o);
8190
+ setPage(1);
8191
+ },
8192
+ children: [
8193
+ /* @__PURE__ */ (0, import_jsx_runtime53.jsx)("option", { value: "filename:asc", children: "Name A\u2013Z" }),
8194
+ /* @__PURE__ */ (0, import_jsx_runtime53.jsx)("option", { value: "filename:desc", children: "Name Z\u2013A" }),
8195
+ /* @__PURE__ */ (0, import_jsx_runtime53.jsx)("option", { value: "createdAt:desc", children: "Newest first" }),
8196
+ /* @__PURE__ */ (0, import_jsx_runtime53.jsx)("option", { value: "createdAt:asc", children: "Oldest first" })
8197
+ ]
8198
+ }
8199
+ ),
8200
+ /* @__PURE__ */ (0, import_jsx_runtime53.jsxs)("div", { className: "inline-flex rounded-md border border-gray-300 overflow-hidden bg-white", children: [
8201
+ /* @__PURE__ */ (0, import_jsx_runtime53.jsxs)(
8202
+ "button",
8203
+ {
8204
+ type: "button",
8205
+ 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"}`,
8206
+ onClick: () => setViewMode("grid"),
8207
+ title: "Grid view",
8208
+ children: [
8209
+ /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(import_lucide_react29.LayoutGrid, { className: "h-4 w-4" }),
8210
+ "Grid"
8211
+ ]
8212
+ }
8213
+ ),
8214
+ /* @__PURE__ */ (0, import_jsx_runtime53.jsxs)(
8215
+ "button",
8216
+ {
8217
+ type: "button",
8218
+ 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"}`,
8219
+ onClick: () => setViewMode("list"),
8220
+ title: "List view",
8221
+ children: [
8222
+ /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(import_lucide_react29.List, { className: "h-4 w-4" }),
8223
+ "List"
8224
+ ]
8225
+ }
8226
+ )
8227
+ ] })
7349
8228
  ] }),
7350
- loading ? /* @__PURE__ */ (0, import_jsx_runtime53.jsx)("div", { className: "flex justify-center py-12", children: /* @__PURE__ */ (0, import_jsx_runtime53.jsx)("div", { className: "animate-spin rounded-full h-8 w-8 border-2 border-gray-300 border-t-gray-600" }) }) : data.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime53.jsx)("div", { className: "text-center py-12 text-gray-500", children: "No media yet. Upload a file to get started." }) : /* @__PURE__ */ (0, import_jsx_runtime53.jsx)("div", { className: "space-y-8", children: Object.entries(grouped).map(([monthLabel, items]) => /* @__PURE__ */ (0, import_jsx_runtime53.jsxs)("div", { children: [
7351
- /* @__PURE__ */ (0, import_jsx_runtime53.jsx)("h2", { className: "text-sm font-semibold text-gray-500 uppercase tracking-wider mb-3", children: monthLabel }),
7352
- /* @__PURE__ */ (0, import_jsx_runtime53.jsx)("div", { className: "grid grid-cols-2 sm:grid-cols-3 md:grid-cols-4 lg:grid-cols-6 gap-4", children: items.map((item) => /* @__PURE__ */ (0, import_jsx_runtime53.jsxs)(
8229
+ loading ? /* @__PURE__ */ (0, import_jsx_runtime53.jsx)("div", { className: "flex justify-center py-12", children: /* @__PURE__ */ (0, import_jsx_runtime53.jsx)("div", { className: "animate-spin rounded-full h-8 w-8 border-2 border-gray-300 border-t-gray-600" }) }) : data.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime53.jsx)("div", { className: "text-center py-12 text-gray-500", children: "This folder is empty. Create a folder or upload a file." }) : viewMode === "grid" ? /* @__PURE__ */ (0, import_jsx_runtime53.jsx)("div", { className: "grid grid-cols-2 sm:grid-cols-3 md:grid-cols-4 lg:grid-cols-6 gap-4", children: data.map((item) => {
8230
+ const isF = item.kind === "folder";
8231
+ return /* @__PURE__ */ (0, import_jsx_runtime53.jsxs)(
7353
8232
  "div",
7354
8233
  {
7355
8234
  className: "border rounded-lg overflow-hidden bg-gray-50 hover:bg-gray-100 transition-colors group",
7356
8235
  children: [
7357
- /* @__PURE__ */ (0, import_jsx_runtime53.jsxs)("div", { className: "aspect-square flex items-center justify-center bg-gray-200 relative", children: [
7358
- isImage(item.mimeType) ? /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(
7359
- "img",
7360
- {
7361
- src: item.url,
7362
- alt: item.alt || item.filename,
7363
- className: "w-full h-full object-cover"
7364
- }
7365
- ) : /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(TypeIcon, { mimeType: item.mimeType }),
7366
- /* @__PURE__ */ (0, import_jsx_runtime53.jsxs)("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", children: [
7367
- /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(
7368
- Button,
7369
- {
7370
- size: "icon",
7371
- variant: "secondary",
7372
- className: "h-8 w-8",
7373
- onClick: () => copyUrl(item.url),
7374
- children: /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(import_lucide_react29.Copy, { className: "h-3 w-3" })
7375
- }
7376
- ),
7377
- /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(Button, { size: "icon", variant: "secondary", className: "h-8 w-8", onClick: () => openEdit(item), children: /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(import_lucide_react29.Edit2, { className: "h-3 w-3" }) }),
7378
- /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(
7379
- Button,
7380
- {
7381
- size: "icon",
7382
- variant: "destructive",
7383
- className: "h-8 w-8",
7384
- onClick: () => handleDelete(item.id),
7385
- children: /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(import_lucide_react29.Trash2, { className: "h-3 w-3" })
7386
- }
7387
- )
7388
- ] })
7389
- ] }),
8236
+ /* @__PURE__ */ (0, import_jsx_runtime53.jsxs)(
8237
+ "button",
8238
+ {
8239
+ type: "button",
8240
+ className: "w-full aspect-square flex items-center justify-center bg-gray-200 relative cursor-pointer",
8241
+ onClick: () => isF && enterFolder(item),
8242
+ children: [
8243
+ isImage(item.mimeType, item.kind, item.filename) ? /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(
8244
+ "img",
8245
+ {
8246
+ src: item.url,
8247
+ alt: item.alt || item.filename,
8248
+ className: "w-full h-full object-cover"
8249
+ }
8250
+ ) : /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(TypeIcon, { mimeType: item.mimeType, kind: item.kind, filename: item.filename }),
8251
+ /* @__PURE__ */ (0, import_jsx_runtime53.jsxs)("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: [
8252
+ !isF && isZipMedia(item.mimeType, item.filename) ? /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(
8253
+ Button,
8254
+ {
8255
+ size: "icon",
8256
+ variant: "outline",
8257
+ className: "h-8 w-8",
8258
+ title: "Extract zip into this folder",
8259
+ disabled: extractingId === item.id,
8260
+ onClick: (e) => {
8261
+ e.stopPropagation();
8262
+ handleExtractZip(item.id);
8263
+ },
8264
+ children: /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(import_lucide_react29.Archive, { className: "h-3 w-3" })
8265
+ }
8266
+ ) : null,
8267
+ !isF && item.url ? /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(
8268
+ Button,
8269
+ {
8270
+ size: "icon",
8271
+ variant: "outline",
8272
+ className: "h-8 w-8",
8273
+ onClick: (e) => {
8274
+ e.stopPropagation();
8275
+ copyUrl(item.url);
8276
+ },
8277
+ children: /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(import_lucide_react29.Copy, { className: "h-3 w-3" })
8278
+ }
8279
+ ) : null,
8280
+ /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(
8281
+ Button,
8282
+ {
8283
+ size: "icon",
8284
+ variant: "outline",
8285
+ className: "h-8 w-8",
8286
+ onClick: (e) => {
8287
+ e.stopPropagation();
8288
+ openEdit(item);
8289
+ },
8290
+ children: /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(import_lucide_react29.Edit2, { className: "h-3 w-3" })
8291
+ }
8292
+ ),
8293
+ /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(
8294
+ Button,
8295
+ {
8296
+ size: "icon",
8297
+ variant: "outline",
8298
+ className: "h-8 w-8 border-red-300 text-red-600 hover:text-red-700",
8299
+ onClick: (e) => {
8300
+ e.stopPropagation();
8301
+ setDeleteTarget(item);
8302
+ },
8303
+ children: /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(import_lucide_react29.Trash2, { className: "h-3 w-3" })
8304
+ }
8305
+ )
8306
+ ] })
8307
+ ]
8308
+ }
8309
+ ),
7390
8310
  /* @__PURE__ */ (0, import_jsx_runtime53.jsxs)("div", { className: "p-2", children: [
7391
- /* @__PURE__ */ (0, import_jsx_runtime53.jsx)("p", { className: "text-xs font-medium text-gray-900 truncate", title: item.filename, children: item.filename }),
8311
+ /* @__PURE__ */ (0, import_jsx_runtime53.jsx)("p", { className: "text-xs font-medium text-gray-900 truncate text-left", title: item.filename, children: item.filename }),
7392
8312
  /* @__PURE__ */ (0, import_jsx_runtime53.jsxs)("div", { className: "flex items-center justify-between mt-1", children: [
7393
8313
  /* @__PURE__ */ (0, import_jsx_runtime53.jsx)("span", { className: "text-xs text-gray-500", children: formatDate(item.createdAt) }),
7394
- /* @__PURE__ */ (0, import_jsx_runtime53.jsx)("span", { className: "text-xs px-1.5 py-0.5 rounded bg-gray-200 text-gray-600", children: getTypeLabel(item.mimeType) })
8314
+ /* @__PURE__ */ (0, import_jsx_runtime53.jsx)("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) })
7395
8315
  ] }),
7396
- item.isPublic && /* @__PURE__ */ (0, import_jsx_runtime53.jsx)("span", { className: "text-xs text-green-600 mt-0.5 block", children: "Public" })
8316
+ item.isPublic && !isF && /* @__PURE__ */ (0, import_jsx_runtime53.jsx)("span", { className: "text-xs text-green-600 mt-0.5 block", children: "Public" }),
8317
+ isF && /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(
8318
+ "button",
8319
+ {
8320
+ type: "button",
8321
+ className: "text-xs text-blue-600 mt-1 hover:underline",
8322
+ onClick: () => enterFolder(item),
8323
+ children: "Open"
8324
+ }
8325
+ )
7397
8326
  ] })
7398
8327
  ]
7399
8328
  },
7400
8329
  item.id
7401
- )) })
7402
- ] }, monthLabel)) }),
8330
+ );
8331
+ }) }) : /* @__PURE__ */ (0, import_jsx_runtime53.jsx)("div", { className: "overflow-x-auto rounded-md border border-gray-200 bg-white", children: /* @__PURE__ */ (0, import_jsx_runtime53.jsxs)("table", { className: "w-full text-sm", children: [
8332
+ /* @__PURE__ */ (0, import_jsx_runtime53.jsx)("thead", { children: /* @__PURE__ */ (0, import_jsx_runtime53.jsxs)("tr", { className: "border-b bg-gray-50", children: [
8333
+ /* @__PURE__ */ (0, import_jsx_runtime53.jsx)("th", { className: "p-3 text-left font-medium", children: "Name" }),
8334
+ /* @__PURE__ */ (0, import_jsx_runtime53.jsx)("th", { className: "p-3 text-left font-medium", children: "Type" }),
8335
+ /* @__PURE__ */ (0, import_jsx_runtime53.jsx)("th", { className: "p-3 text-left font-medium", children: "Created" }),
8336
+ /* @__PURE__ */ (0, import_jsx_runtime53.jsx)("th", { className: "p-3 text-left font-medium", children: "Size" }),
8337
+ /* @__PURE__ */ (0, import_jsx_runtime53.jsx)("th", { className: "p-3 text-right font-medium", children: "Actions" })
8338
+ ] }) }),
8339
+ /* @__PURE__ */ (0, import_jsx_runtime53.jsx)("tbody", { children: listViewData.map((item) => {
8340
+ const isF = item.kind === "folder";
8341
+ return /* @__PURE__ */ (0, import_jsx_runtime53.jsxs)("tr", { className: "border-b border-gray-100 hover:bg-gray-50", children: [
8342
+ /* @__PURE__ */ (0, import_jsx_runtime53.jsx)("td", { className: "p-3", children: /* @__PURE__ */ (0, import_jsx_runtime53.jsxs)(
8343
+ "button",
8344
+ {
8345
+ type: "button",
8346
+ className: `inline-flex items-center gap-2 ${isF ? "text-blue-600 hover:underline" : "text-gray-900"}`,
8347
+ onClick: () => isF && enterFolder(item),
8348
+ children: [
8349
+ /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(TypeIcon, { mimeType: item.mimeType, kind: item.kind, filename: item.filename }),
8350
+ /* @__PURE__ */ (0, import_jsx_runtime53.jsx)("span", { className: "truncate max-w-[260px]", title: item.filename, children: item.filename })
8351
+ ]
8352
+ }
8353
+ ) }),
8354
+ /* @__PURE__ */ (0, import_jsx_runtime53.jsx)("td", { className: "p-3 text-gray-600", children: getTypeLabel(item.mimeType, item.kind, item.filename) }),
8355
+ /* @__PURE__ */ (0, import_jsx_runtime53.jsx)("td", { className: "p-3 text-gray-600", children: formatDate(item.createdAt) }),
8356
+ /* @__PURE__ */ (0, import_jsx_runtime53.jsx)("td", { className: "p-3 text-gray-600", children: isF ? "\u2014" : `${Math.round((item.size || 0) / 1024)} KB` }),
8357
+ /* @__PURE__ */ (0, import_jsx_runtime53.jsx)("td", { className: "p-3", children: /* @__PURE__ */ (0, import_jsx_runtime53.jsxs)("div", { className: "flex items-center justify-end gap-1", children: [
8358
+ !isF && isZipMedia(item.mimeType, item.filename) && /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(Button, { size: "icon", variant: "outline", className: "h-8 w-8", onClick: () => handleExtractZip(item.id), disabled: extractingId === item.id, children: /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(import_lucide_react29.Archive, { className: "h-3 w-3" }) }),
8359
+ !isF && item.url && /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(Button, { size: "icon", variant: "outline", className: "h-8 w-8", onClick: () => copyUrl(item.url), children: /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(import_lucide_react29.Copy, { className: "h-3 w-3" }) }),
8360
+ /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(Button, { size: "icon", variant: "outline", className: "h-8 w-8", onClick: () => openEdit(item), children: /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(import_lucide_react29.Edit2, { className: "h-3 w-3" }) }),
8361
+ /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(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__ */ (0, import_jsx_runtime53.jsx)(import_lucide_react29.Trash2, { className: "h-3 w-3" }) })
8362
+ ] }) })
8363
+ ] }, item.id);
8364
+ }) })
8365
+ ] }) }),
7403
8366
  totalPages > 1 && /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(Pagination, { className: "mt-6", children: /* @__PURE__ */ (0, import_jsx_runtime53.jsxs)(PaginationContent, { children: [
7404
8367
  /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(PaginationItem, { children: /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(
7405
8368
  PaginationPrevious,
@@ -7421,9 +8384,28 @@ function MediaLibraryPage() {
7421
8384
  ) })
7422
8385
  ] }) })
7423
8386
  ] }),
8387
+ /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(Dialog, { open: newFolderOpen, onOpenChange: setNewFolderOpen, children: /* @__PURE__ */ (0, import_jsx_runtime53.jsxs)(DialogContent, { children: [
8388
+ /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(DialogHeader, { children: /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(DialogTitle, { children: "New folder" }) }),
8389
+ /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(
8390
+ Input,
8391
+ {
8392
+ placeholder: "Folder name",
8393
+ value: newFolderName,
8394
+ onChange: (e) => setNewFolderName(e.target.value),
8395
+ onKeyDown: (e) => e.key === "Enter" && createFolder()
8396
+ }
8397
+ ),
8398
+ /* @__PURE__ */ (0, import_jsx_runtime53.jsxs)(DialogFooter, { children: [
8399
+ /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(Button, { variant: "outline", onClick: () => setNewFolderOpen(false), children: "Cancel" }),
8400
+ /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(Button, { onClick: createFolder, children: "Create" })
8401
+ ] })
8402
+ ] }) }),
7424
8403
  /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(Dialog, { open: !!editModal, onOpenChange: (open) => !open && setEditModal(null), children: /* @__PURE__ */ (0, import_jsx_runtime53.jsxs)(DialogContent, { children: [
7425
- /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(DialogHeader, { children: /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(DialogTitle, { children: "Edit media" }) }),
7426
- editModal && /* @__PURE__ */ (0, import_jsx_runtime53.jsxs)("div", { className: "space-y-4 py-2", children: [
8404
+ /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(DialogHeader, { children: /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(DialogTitle, { children: editModal?.kind === "folder" ? "Rename folder" : "Edit media" }) }),
8405
+ editModal && /* @__PURE__ */ (0, import_jsx_runtime53.jsx)("div", { className: "space-y-4 py-2", children: editModal.kind === "folder" ? /* @__PURE__ */ (0, import_jsx_runtime53.jsxs)("div", { children: [
8406
+ /* @__PURE__ */ (0, import_jsx_runtime53.jsx)("label", { className: "text-sm font-medium", children: "Name" }),
8407
+ /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(Input, { value: editFilename, onChange: (e) => setEditFilename(e.target.value), className: "mt-1" })
8408
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime53.jsxs)(import_jsx_runtime53.Fragment, { children: [
7427
8409
  /* @__PURE__ */ (0, import_jsx_runtime53.jsxs)("div", { children: [
7428
8410
  /* @__PURE__ */ (0, import_jsx_runtime53.jsx)("label", { className: "text-sm font-medium", children: "Alt text" }),
7429
8411
  /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(
@@ -7448,20 +8430,37 @@ function MediaLibraryPage() {
7448
8430
  ),
7449
8431
  /* @__PURE__ */ (0, import_jsx_runtime53.jsx)("label", { htmlFor: "edit-public", className: "text-sm", children: "Public (visible on site)" })
7450
8432
  ] })
7451
- ] }),
8433
+ ] }) }),
7452
8434
  /* @__PURE__ */ (0, import_jsx_runtime53.jsxs)(DialogFooter, { children: [
7453
8435
  /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(Button, { variant: "outline", onClick: () => setEditModal(null), children: "Cancel" }),
7454
8436
  /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(Button, { onClick: handleSaveEdit, children: "Save" })
7455
8437
  ] })
8438
+ ] }) }),
8439
+ /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(Dialog, { open: !!deleteTarget, onOpenChange: (open) => !open && setDeleteTarget(null), children: /* @__PURE__ */ (0, import_jsx_runtime53.jsxs)(DialogContent, { children: [
8440
+ /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(DialogHeader, { children: /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(DialogTitle, { children: "Confirm Delete" }) }),
8441
+ /* @__PURE__ */ (0, import_jsx_runtime53.jsx)("p", { className: "text-sm text-gray-600", children: deleteTarget?.kind === "folder" ? "Delete this folder and everything inside it?" : "Delete this file?" }),
8442
+ /* @__PURE__ */ (0, import_jsx_runtime53.jsxs)(DialogFooter, { children: [
8443
+ /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(Button, { variant: "outline", onClick: () => setDeleteTarget(null), children: "Cancel" }),
8444
+ /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(
8445
+ Button,
8446
+ {
8447
+ variant: "destructive",
8448
+ onClick: () => {
8449
+ if (deleteTarget) handleDelete(deleteTarget);
8450
+ },
8451
+ children: "Delete"
8452
+ }
8453
+ )
8454
+ ] })
7456
8455
  ] }) })
7457
8456
  ] });
7458
8457
  }
7459
8458
 
7460
8459
  // src/admin/pages/PageBuilderPage.tsx
7461
- var import_react38 = require("react");
8460
+ var import_react39 = require("react");
7462
8461
  var import_core = require("@craftjs/core");
7463
8462
  var import_lucide_react30 = require("lucide-react");
7464
- var import_navigation15 = require("next/navigation");
8463
+ var import_navigation17 = require("next/navigation");
7465
8464
 
7466
8465
  // src/theme/registry.ts
7467
8466
  function buildResolver(theme) {
@@ -7486,7 +8485,7 @@ function getCatalog(theme) {
7486
8485
 
7487
8486
  // src/admin/pages/PageBuilderPage.tsx
7488
8487
  var LucideIcons = __toESM(require("lucide-react"), 1);
7489
- var import_react39 = __toESM(require("react"), 1);
8488
+ var import_react40 = __toESM(require("react"), 1);
7490
8489
  var import_jsx_runtime54 = require("react/jsx-runtime");
7491
8490
  function createSelectable(Comp) {
7492
8491
  function SelectableWrapper(props) {
@@ -7531,16 +8530,16 @@ function DraggableCatalogItem({
7531
8530
  Icon: Icon2,
7532
8531
  description
7533
8532
  }) {
7534
- const elRef = (0, import_react38.useRef)(null);
7535
- (0, import_react38.useEffect)(() => {
8533
+ const elRef = (0, import_react39.useRef)(null);
8534
+ (0, import_react39.useEffect)(() => {
7536
8535
  if (!elRef.current) return;
7537
8536
  if (meta.canContainChildren) {
7538
8537
  connectors.create(
7539
8538
  elRef.current,
7540
- import_react39.default.createElement(import_core.Element, { is: Comp, canvas: true, ...meta.defaultProps })
8539
+ import_react40.default.createElement(import_core.Element, { is: Comp, canvas: true, ...meta.defaultProps })
7541
8540
  );
7542
8541
  } else {
7543
- connectors.create(elRef.current, import_react39.default.createElement(Comp, meta.defaultProps));
8542
+ connectors.create(elRef.current, import_react40.default.createElement(Comp, meta.defaultProps));
7544
8543
  }
7545
8544
  }, [connectors, Comp, meta.defaultProps, meta.name, meta.canContainChildren]);
7546
8545
  return /* @__PURE__ */ (0, import_jsx_runtime54.jsxs)(
@@ -7559,7 +8558,7 @@ function DraggableCatalogItem({
7559
8558
  function ComponentPickerContent({ theme, resolver }) {
7560
8559
  const { connectors } = (0, import_core.useEditor)();
7561
8560
  const catalog = getCatalog(theme);
7562
- const [collapsed, setCollapsed] = (0, import_react38.useState)({});
8561
+ const [collapsed, setCollapsed] = (0, import_react39.useState)({});
7563
8562
  const toggleCategory = (cat) => {
7564
8563
  setCollapsed((prev) => ({ ...prev, [cat]: !prev[cat] }));
7565
8564
  };
@@ -7764,7 +8763,7 @@ function LayersPanelContent() {
7764
8763
  nodes: state.nodes,
7765
8764
  selectedSet: state.events.selected
7766
8765
  }));
7767
- const [expanded, setExpanded] = (0, import_react38.useState)({});
8766
+ const [expanded, setExpanded] = (0, import_react39.useState)({});
7768
8767
  const nodeMap = nodes || {};
7769
8768
  const rootId = (() => {
7770
8769
  const ids = Object.keys(nodeMap);
@@ -7886,10 +8885,10 @@ function CollapsibleSection({
7886
8885
  ] });
7887
8886
  }
7888
8887
  function RightSidebar({ theme, resolver, activeTab, setActiveTab, seoProps }) {
7889
- const [componentsOpen, setComponentsOpen] = (0, import_react38.useState)(true);
7890
- const [propertiesOpen, setPropertiesOpen] = (0, import_react38.useState)(true);
7891
- const [layoutOpen, setLayoutOpen] = (0, import_react38.useState)(true);
7892
- const [layersOpen, setLayersOpen] = (0, import_react38.useState)(true);
8888
+ const [componentsOpen, setComponentsOpen] = (0, import_react39.useState)(true);
8889
+ const [propertiesOpen, setPropertiesOpen] = (0, import_react39.useState)(true);
8890
+ const [layoutOpen, setLayoutOpen] = (0, import_react39.useState)(true);
8891
+ const [layersOpen, setLayersOpen] = (0, import_react39.useState)(true);
7893
8892
  return /* @__PURE__ */ (0, import_jsx_runtime54.jsxs)("div", { className: "flex flex-col flex-1 overflow-hidden", children: [
7894
8893
  /* @__PURE__ */ (0, import_jsx_runtime54.jsx)("div", { className: "flex border-b flex-shrink-0", children: ["designer", "seo"].map((tab) => /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(
7895
8894
  "button",
@@ -7957,7 +8956,7 @@ function SaveButton({
7957
8956
  className
7958
8957
  }) {
7959
8958
  const { query } = (0, import_core.useEditor)();
7960
- const [saving, setSaving] = (0, import_react38.useState)(false);
8959
+ const [saving, setSaving] = (0, import_react39.useState)(false);
7961
8960
  const handleSave = async () => {
7962
8961
  setSaving(true);
7963
8962
  try {
@@ -8029,22 +9028,22 @@ function SaveButton({
8029
9028
  );
8030
9029
  }
8031
9030
  function PageBuilderPage({ pageId }) {
8032
- const { theme } = (0, import_react38.useContext)(AdminConfigContext);
8033
- const router = (0, import_navigation15.useRouter)();
8034
- const [title, setTitle] = (0, import_react38.useState)("");
8035
- const [slug, setSlug] = (0, import_react38.useState)("");
8036
- const [published, setPublished] = (0, import_react38.useState)(false);
8037
- const [initialContent, setInitialContent] = (0, import_react38.useState)(null);
8038
- const [loading, setLoading] = (0, import_react38.useState)(!!pageId);
8039
- const [rightTab, setRightTab] = (0, import_react38.useState)("designer");
8040
- const [seoTitle, setSeoTitle] = (0, import_react38.useState)("");
8041
- const [seoDescription, setSeoDescription] = (0, import_react38.useState)("");
8042
- const [seoKeywords, setSeoKeywords] = (0, import_react38.useState)("");
8043
- const [seoOgTitle, setSeoOgTitle] = (0, import_react38.useState)("");
8044
- const [seoOgDescription, setSeoOgDescription] = (0, import_react38.useState)("");
8045
- const [seoOgImage, setSeoOgImage] = (0, import_react38.useState)("");
8046
- const [pageSeoId, setPageSeoId] = (0, import_react38.useState)(null);
8047
- (0, import_react38.useEffect)(() => {
9031
+ const { theme } = (0, import_react39.useContext)(AdminConfigContext);
9032
+ const router = (0, import_navigation17.useRouter)();
9033
+ const [title, setTitle] = (0, import_react39.useState)("");
9034
+ const [slug, setSlug] = (0, import_react39.useState)("");
9035
+ const [published, setPublished] = (0, import_react39.useState)(false);
9036
+ const [initialContent, setInitialContent] = (0, import_react39.useState)(null);
9037
+ const [loading, setLoading] = (0, import_react39.useState)(!!pageId);
9038
+ const [rightTab, setRightTab] = (0, import_react39.useState)("designer");
9039
+ const [seoTitle, setSeoTitle] = (0, import_react39.useState)("");
9040
+ const [seoDescription, setSeoDescription] = (0, import_react39.useState)("");
9041
+ const [seoKeywords, setSeoKeywords] = (0, import_react39.useState)("");
9042
+ const [seoOgTitle, setSeoOgTitle] = (0, import_react39.useState)("");
9043
+ const [seoOgDescription, setSeoOgDescription] = (0, import_react39.useState)("");
9044
+ const [seoOgImage, setSeoOgImage] = (0, import_react39.useState)("");
9045
+ const [pageSeoId, setPageSeoId] = (0, import_react39.useState)(null);
9046
+ (0, import_react39.useEffect)(() => {
8048
9047
  if (!pageId) {
8049
9048
  setInitialContent(null);
8050
9049
  setPageSeoId(null);
@@ -8073,7 +9072,7 @@ function PageBuilderPage({ pageId }) {
8073
9072
  }
8074
9073
  }).finally(() => setLoading(false));
8075
9074
  }, [pageId]);
8076
- (0, import_react38.useEffect)(() => {
9075
+ (0, import_react39.useEffect)(() => {
8077
9076
  if (title && !slug) {
8078
9077
  setSlug(
8079
9078
  title.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/(^-|-$)/g, "")
@@ -8118,19 +9117,49 @@ function PageBuilderPage({ pageId }) {
8118
9117
  onSaved: (id) => {
8119
9118
  if (!pageId) router.replace(`/admin/pages/${id}`);
8120
9119
  },
8121
- className: "flex items-center bg-white text-gray-800 hover:bg-gray-100 border-0 text-xs",
9120
+ className: "md:hidden h-8 w-8 p-0 bg-white text-gray-800 hover:bg-gray-100 border-0",
9121
+ children: [
9122
+ /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(import_lucide_react30.Save, { className: "h-4 w-4" }),
9123
+ /* @__PURE__ */ (0, import_jsx_runtime54.jsx)("span", { className: "sr-only", children: "Save" })
9124
+ ]
9125
+ }
9126
+ ),
9127
+ /* @__PURE__ */ (0, import_jsx_runtime54.jsxs)(
9128
+ SaveButton,
9129
+ {
9130
+ pageId,
9131
+ existingSeoId: pageSeoId,
9132
+ onSeoIdChange: setPageSeoId,
9133
+ pageData: { title, slug, published, seoTitle, seoDescription, seoKeywords, seoOgTitle, seoOgDescription, seoOgImage },
9134
+ onSaved: (id) => {
9135
+ if (!pageId) router.replace(`/admin/pages/${id}`);
9136
+ },
9137
+ className: "hidden md:inline-flex items-center bg-white text-gray-800 hover:bg-gray-100 border-0 text-xs",
8122
9138
  children: [
8123
9139
  /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(import_lucide_react30.Save, { className: "h-4 w-4 mr-1" }),
8124
9140
  " Save"
8125
9141
  ]
8126
9142
  }
8127
9143
  ),
9144
+ /* @__PURE__ */ (0, import_jsx_runtime54.jsxs)(
9145
+ Button,
9146
+ {
9147
+ variant: "outline",
9148
+ size: "icon",
9149
+ className: "md:hidden h-8 w-8 bg-white text-gray-800 hover:bg-gray-100 border-0",
9150
+ onClick: () => router.push("/admin/pages"),
9151
+ children: [
9152
+ /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(import_lucide_react30.X, { className: "h-4 w-4" }),
9153
+ /* @__PURE__ */ (0, import_jsx_runtime54.jsx)("span", { className: "sr-only", children: "Close" })
9154
+ ]
9155
+ }
9156
+ ),
8128
9157
  /* @__PURE__ */ (0, import_jsx_runtime54.jsxs)(
8129
9158
  Button,
8130
9159
  {
8131
9160
  variant: "outline",
8132
9161
  size: "sm",
8133
- className: "flex items-center bg-white text-gray-800 hover:bg-gray-100 border-0 text-xs",
9162
+ className: "hidden md:inline-flex items-center bg-white text-gray-800 hover:bg-gray-100 border-0 text-xs",
8134
9163
  onClick: () => router.push("/admin/pages"),
8135
9164
  children: [
8136
9165
  /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(import_lucide_react30.X, { className: "h-4 w-4 mr-1" }),
@@ -8191,7 +9220,7 @@ function PageBuilderPage({ pageId }) {
8191
9220
  }
8192
9221
 
8193
9222
  // src/admin/pages/PluginsPage.tsx
8194
- var import_react40 = require("react");
9223
+ var import_react41 = require("react");
8195
9224
  var import_lucide_react32 = require("lucide-react");
8196
9225
 
8197
9226
  // src/lib/email-recipients.ts
@@ -8239,7 +9268,7 @@ var Checkbox = React19.forwardRef(({ className, ...props }, ref) => /* @__PURE__
8239
9268
  Checkbox.displayName = CheckboxPrimitive.Root.displayName;
8240
9269
 
8241
9270
  // src/admin/pages/PluginsPage.tsx
8242
- var import_sonner6 = require("sonner");
9271
+ var import_sonner7 = require("sonner");
8243
9272
  var import_jsx_runtime56 = require("react/jsx-runtime");
8244
9273
  function normalizeChatMode(raw) {
8245
9274
  if (raw === "external" || raw === "llm") return raw;
@@ -8305,7 +9334,7 @@ function EmailRecipientTags({
8305
9334
  onChange,
8306
9335
  placeholder
8307
9336
  }) {
8308
- const [draft, setDraft] = (0, import_react40.useState)("");
9337
+ const [draft, setDraft] = (0, import_react41.useState)("");
8309
9338
  const commitDraft = () => {
8310
9339
  const parts = splitInputToEmails(draft);
8311
9340
  if (!parts.length) return;
@@ -8381,36 +9410,36 @@ function PluginSettingsPanel({
8381
9410
  const isEmail = settingsGroup === "email";
8382
9411
  const isErp = settingsGroup === "erp";
8383
9412
  const isSms = settingsGroup === "sms";
8384
- const [enabled, setEnabled] = (0, import_react40.useState)(true);
8385
- const [botName, setBotName] = (0, import_react40.useState)("");
8386
- const [icon, setIcon] = (0, import_react40.useState)("");
8387
- const [iconImageUrl, setIconImageUrl] = (0, import_react40.useState)("");
8388
- const [iconBackgroundColor, setIconBackgroundColor] = (0, import_react40.useState)("#6366f1");
8389
- const [headerColor, setHeaderColor] = (0, import_react40.useState)("#6366f1");
8390
- const [salesTeamEmails, setSalesTeamEmails] = (0, import_react40.useState)([]);
8391
- const [fulfilmentTeamEmails, setFulfilmentTeamEmails] = (0, import_react40.useState)([]);
8392
- const [crmEmails, setCrmEmails] = (0, import_react40.useState)([]);
8393
- const [logoUrl, setLogoUrl] = (0, import_react40.useState)("");
8394
- const [companyName, setCompanyName] = (0, import_react40.useState)("");
8395
- const [supportEmail, setSupportEmail] = (0, import_react40.useState)("");
8396
- const [supportPhone, setSupportPhone] = (0, import_react40.useState)("");
8397
- const [followUsTitle, setFollowUsTitle] = (0, import_react40.useState)("Follow Us");
8398
- const [socialLinkRows, setSocialLinkRows] = (0, import_react40.useState)([{ ...EMPTY_SOCIAL_ROW }]);
8399
- const [footerDisclaimer, setFooterDisclaimer] = (0, import_react40.useState)("");
8400
- const [chatMode, setChatMode] = (0, import_react40.useState)("whatsapp");
8401
- const [whatsappPhone, setWhatsappPhone] = (0, import_react40.useState)("");
8402
- const [externalChatSnippet, setExternalChatSnippet] = (0, import_react40.useState)("");
8403
- const [erpPipelineName, setErpPipelineName] = (0, import_react40.useState)("");
8404
- const [erpPipelineStageName, setErpPipelineStageName] = (0, import_react40.useState)("");
8405
- const [erpFormsCatalog, setErpFormsCatalog] = (0, import_react40.useState)([]);
8406
- const [erpOpportunityFormIds, setErpOpportunityFormIds] = (0, import_react40.useState)([]);
8407
- const [erpOpportunityIdsKeyPresent, setErpOpportunityIdsKeyPresent] = (0, import_react40.useState)(false);
8408
- const [smsProviderChoice, setSmsProviderChoice] = (0, import_react40.useState)("auto");
8409
- const [msg91ApiMode, setMsg91ApiMode] = (0, import_react40.useState)("auto");
8410
- const [smsTplItems, setSmsTplItems] = (0, import_react40.useState)([]);
8411
- const [loading, setLoading] = (0, import_react40.useState)(true);
8412
- const [saving, setSaving] = (0, import_react40.useState)(false);
8413
- (0, import_react40.useEffect)(() => {
9413
+ const [enabled, setEnabled] = (0, import_react41.useState)(true);
9414
+ const [botName, setBotName] = (0, import_react41.useState)("");
9415
+ const [icon, setIcon] = (0, import_react41.useState)("");
9416
+ const [iconImageUrl, setIconImageUrl] = (0, import_react41.useState)("");
9417
+ const [iconBackgroundColor, setIconBackgroundColor] = (0, import_react41.useState)("#6366f1");
9418
+ const [headerColor, setHeaderColor] = (0, import_react41.useState)("#6366f1");
9419
+ const [salesTeamEmails, setSalesTeamEmails] = (0, import_react41.useState)([]);
9420
+ const [fulfilmentTeamEmails, setFulfilmentTeamEmails] = (0, import_react41.useState)([]);
9421
+ const [crmEmails, setCrmEmails] = (0, import_react41.useState)([]);
9422
+ const [logoUrl, setLogoUrl] = (0, import_react41.useState)("");
9423
+ const [companyName, setCompanyName] = (0, import_react41.useState)("");
9424
+ const [supportEmail, setSupportEmail] = (0, import_react41.useState)("");
9425
+ const [supportPhone, setSupportPhone] = (0, import_react41.useState)("");
9426
+ const [followUsTitle, setFollowUsTitle] = (0, import_react41.useState)("Follow Us");
9427
+ const [socialLinkRows, setSocialLinkRows] = (0, import_react41.useState)([{ ...EMPTY_SOCIAL_ROW }]);
9428
+ const [footerDisclaimer, setFooterDisclaimer] = (0, import_react41.useState)("");
9429
+ const [chatMode, setChatMode] = (0, import_react41.useState)("whatsapp");
9430
+ const [whatsappPhone, setWhatsappPhone] = (0, import_react41.useState)("");
9431
+ const [externalChatSnippet, setExternalChatSnippet] = (0, import_react41.useState)("");
9432
+ const [erpPipelineName, setErpPipelineName] = (0, import_react41.useState)("");
9433
+ const [erpPipelineStageName, setErpPipelineStageName] = (0, import_react41.useState)("");
9434
+ const [erpFormsCatalog, setErpFormsCatalog] = (0, import_react41.useState)([]);
9435
+ const [erpOpportunityFormIds, setErpOpportunityFormIds] = (0, import_react41.useState)([]);
9436
+ const [erpOpportunityIdsKeyPresent, setErpOpportunityIdsKeyPresent] = (0, import_react41.useState)(false);
9437
+ const [smsProviderChoice, setSmsProviderChoice] = (0, import_react41.useState)("auto");
9438
+ const [msg91ApiMode, setMsg91ApiMode] = (0, import_react41.useState)("auto");
9439
+ const [smsTplItems, setSmsTplItems] = (0, import_react41.useState)([]);
9440
+ const [loading, setLoading] = (0, import_react41.useState)(true);
9441
+ const [saving, setSaving] = (0, import_react41.useState)(false);
9442
+ (0, import_react41.useEffect)(() => {
8414
9443
  setLoading(true);
8415
9444
  fetch(`/api/settings/${settingsGroup}`).then((r) => r.ok ? r.json() : {}).then(async (data) => {
8416
9445
  setEnabled(data.enabled !== "false");
@@ -8467,7 +9496,7 @@ function PluginSettingsPanel({
8467
9496
  }
8468
9497
  }).finally(() => setLoading(false));
8469
9498
  }, [settingsGroup, isLlm, isEmail, isErp, isSms]);
8470
- (0, import_react40.useEffect)(() => {
9499
+ (0, import_react41.useEffect)(() => {
8471
9500
  if (!isErp || loading) return;
8472
9501
  fetch("/api/forms?limit=500&sortField=name&sortOrder=asc").then((r) => r.ok ? r.json() : { data: [] }).then((res) => {
8473
9502
  const rows = (res.data ?? []).map((f) => ({
@@ -8551,10 +9580,10 @@ function PluginSettingsPanel({
8551
9580
  });
8552
9581
  if (!res2.ok) throw new Error();
8553
9582
  }
8554
- import_sonner6.toast.success("Settings saved");
9583
+ import_sonner7.toast.success("Settings saved");
8555
9584
  onSaved?.();
8556
9585
  } catch {
8557
- import_sonner6.toast.error("Failed to save");
9586
+ import_sonner7.toast.error("Failed to save");
8558
9587
  } finally {
8559
9588
  setSaving(false);
8560
9589
  }
@@ -9170,10 +10199,10 @@ function PluginListItem({
9170
10199
  );
9171
10200
  }
9172
10201
  function PluginsPage() {
9173
- const { pluginDescriptors = [] } = (0, import_react40.useContext)(AdminConfigContext);
9174
- const [selectedName, setSelectedName] = (0, import_react40.useState)(null);
9175
- const [enabledMap, setEnabledMap] = (0, import_react40.useState)({});
9176
- (0, import_react40.useEffect)(() => {
10202
+ const { pluginDescriptors = [] } = (0, import_react41.useContext)(AdminConfigContext);
10203
+ const [selectedName, setSelectedName] = (0, import_react41.useState)(null);
10204
+ const [enabledMap, setEnabledMap] = (0, import_react41.useState)({});
10205
+ (0, import_react41.useEffect)(() => {
9177
10206
  pluginDescriptors.forEach((p) => {
9178
10207
  if (!p.settingsGroup) return;
9179
10208
  fetch(`/api/settings/${p.settingsGroup}`).then((r) => r.ok ? r.json() : {}).then(
@@ -9234,8 +10263,8 @@ function PluginsPage() {
9234
10263
  }
9235
10264
 
9236
10265
  // src/admin/pages/BrandEditPage.tsx
9237
- var import_react41 = require("react");
9238
- var import_navigation16 = require("next/navigation");
10266
+ var import_react42 = require("react");
10267
+ var import_navigation18 = require("next/navigation");
9239
10268
  var import_lucide_react33 = require("lucide-react");
9240
10269
 
9241
10270
  // src/components/Admin/SeoSection.tsx
@@ -9330,20 +10359,20 @@ async function fetchSeo(seoId) {
9330
10359
  var import_jsx_runtime58 = require("react/jsx-runtime");
9331
10360
  var isCreate = (id) => id === "create";
9332
10361
  function BrandEditPage({ brandId }) {
9333
- const router = (0, import_navigation16.useRouter)();
10362
+ const router = (0, import_navigation18.useRouter)();
9334
10363
  const create = isCreate(brandId);
9335
- const [loading, setLoading] = (0, import_react41.useState)(!create);
9336
- const [saving, setSaving] = (0, import_react41.useState)(false);
9337
- const [errors, setErrors] = (0, import_react41.useState)([]);
9338
- const [name, setName] = (0, import_react41.useState)("");
9339
- const [slug, setSlug] = (0, import_react41.useState)("");
9340
- const [description, setDescription] = (0, import_react41.useState)("");
9341
- const [logo, setLogo] = (0, import_react41.useState)("");
9342
- const [active, setActive] = (0, import_react41.useState)(true);
9343
- const [sortOrder, setSortOrder] = (0, import_react41.useState)(0);
9344
- const [seoId, setSeoId] = (0, import_react41.useState)(null);
9345
- const [seo, setSeo] = (0, import_react41.useState)({ seoTitle: "", seoDescription: "", seoKeywords: "", seoOgTitle: "", seoOgDescription: "", seoOgImage: "" });
9346
- (0, import_react41.useEffect)(() => {
10364
+ const [loading, setLoading] = (0, import_react42.useState)(!create);
10365
+ const [saving, setSaving] = (0, import_react42.useState)(false);
10366
+ const [errors, setErrors] = (0, import_react42.useState)([]);
10367
+ const [name, setName] = (0, import_react42.useState)("");
10368
+ const [slug, setSlug] = (0, import_react42.useState)("");
10369
+ const [description, setDescription] = (0, import_react42.useState)("");
10370
+ const [logo, setLogo] = (0, import_react42.useState)("");
10371
+ const [active, setActive] = (0, import_react42.useState)(true);
10372
+ const [sortOrder, setSortOrder] = (0, import_react42.useState)(0);
10373
+ const [seoId, setSeoId] = (0, import_react42.useState)(null);
10374
+ const [seo, setSeo] = (0, import_react42.useState)({ seoTitle: "", seoDescription: "", seoKeywords: "", seoOgTitle: "", seoOgDescription: "", seoOgImage: "" });
10375
+ (0, import_react42.useEffect)(() => {
9347
10376
  if (create) return;
9348
10377
  let cancelled = false;
9349
10378
  (async () => {
@@ -9423,8 +10452,8 @@ function BrandEditPage({ brandId }) {
9423
10452
  subtitle: create ? "Create a new brand" : "Update brand details",
9424
10453
  closeHref: "/admin/brands",
9425
10454
  menuItems: [
9426
- { label: saving ? "Saving..." : "Save", onClick: handleSave },
9427
- { label: active ? "Deactivate" : "Activate", onClick: () => setActive(!active) }
10455
+ { label: saving ? "Saving..." : "Save", icon: import_lucide_react33.Save, onClick: handleSave },
10456
+ { label: active ? "Deactivate" : "Activate", icon: import_lucide_react33.Power, onClick: () => setActive(!active) }
9428
10457
  ]
9429
10458
  }
9430
10459
  ),
@@ -9532,12 +10561,12 @@ function BrandEditPage({ brandId }) {
9532
10561
  }
9533
10562
 
9534
10563
  // src/admin/pages/ProductEditPage.tsx
9535
- var import_react43 = require("react");
9536
- var import_navigation17 = require("next/navigation");
10564
+ var import_react44 = require("react");
10565
+ var import_navigation19 = require("next/navigation");
9537
10566
  var import_lucide_react34 = require("lucide-react");
9538
10567
 
9539
10568
  // src/components/Admin/AttributeFacetNameInput.tsx
9540
- var import_react42 = require("react");
10569
+ var import_react43 = require("react");
9541
10570
  var import_jsx_runtime59 = require("react/jsx-runtime");
9542
10571
  function slugFromName(name) {
9543
10572
  const s = name.toLowerCase().trim().replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "");
@@ -9548,13 +10577,16 @@ function AttributeFacetNameInput({
9548
10577
  onChange,
9549
10578
  inputClassName
9550
10579
  }) {
9551
- const [draft, setDraft] = (0, import_react42.useState)(value);
9552
- const [open, setOpen] = (0, import_react42.useState)(false);
9553
- const [list, setList] = (0, import_react42.useState)([]);
9554
- (0, import_react42.useEffect)(() => {
9555
- setDraft(value);
9556
- }, [value]);
9557
- (0, import_react42.useEffect)(() => {
10580
+ const [draft, setDraft] = (0, import_react43.useState)(value);
10581
+ const [open, setOpen] = (0, import_react43.useState)(false);
10582
+ const [list, setList] = (0, import_react43.useState)([]);
10583
+ const isFocusedRef = (0, import_react43.useRef)(false);
10584
+ (0, import_react43.useEffect)(() => {
10585
+ if (!isFocusedRef.current && value !== draft) {
10586
+ setDraft(value);
10587
+ }
10588
+ }, [value, draft]);
10589
+ (0, import_react43.useEffect)(() => {
9558
10590
  const q = draft.trim();
9559
10591
  if (!q) {
9560
10592
  setList([]);
@@ -9616,8 +10648,12 @@ function AttributeFacetNameInput({
9616
10648
  setDraft(e.target.value);
9617
10649
  setOpen(true);
9618
10650
  },
9619
- onFocus: () => setOpen(true),
10651
+ onFocus: () => {
10652
+ setOpen(true);
10653
+ isFocusedRef.current = true;
10654
+ },
9620
10655
  onBlur: () => setTimeout(() => {
10656
+ isFocusedRef.current = false;
9621
10657
  setOpen(false);
9622
10658
  onChange(draft.trim());
9623
10659
  }, 200),
@@ -9705,37 +10741,37 @@ function pickOtherMetadata(m) {
9705
10741
  return rest;
9706
10742
  }
9707
10743
  function ProductEditPage({ productId }) {
9708
- const router = (0, import_navigation17.useRouter)();
10744
+ const router = (0, import_navigation19.useRouter)();
9709
10745
  const create = isCreate2(productId);
9710
- const [loading, setLoading] = (0, import_react43.useState)(!create);
9711
- const [saving, setSaving] = (0, import_react43.useState)(false);
9712
- const [errors, setErrors] = (0, import_react43.useState)([]);
9713
- const [collections, setCollections] = (0, import_react43.useState)([]);
9714
- const [brands, setBrands] = (0, import_react43.useState)([]);
9715
- const [categories, setCategories] = (0, import_react43.useState)([]);
9716
- const [name, setName] = (0, import_react43.useState)("");
9717
- const [productSlug, setProductSlug] = (0, import_react43.useState)("");
9718
- const [sku, setSku] = (0, import_react43.useState)("");
9719
- const [hsn, setHsn] = (0, import_react43.useState)("");
9720
- const [uom, setUom] = (0, import_react43.useState)("");
9721
- const [productType, setProductType] = (0, import_react43.useState)("product");
9722
- const [collectionId, setCollectionId] = (0, import_react43.useState)(null);
9723
- const [brandId, setBrandId] = (0, import_react43.useState)(null);
9724
- const [categoryId, setCategoryId] = (0, import_react43.useState)(null);
9725
- const [price, setPrice] = (0, import_react43.useState)("");
9726
- const [compareAtPrice, setCompareAtPrice] = (0, import_react43.useState)("");
9727
- const [quantity, setQuantity] = (0, import_react43.useState)(1);
9728
- const [status, setStatus] = (0, import_react43.useState)("draft");
9729
- const [featured, setFeatured] = (0, import_react43.useState)(false);
9730
- const [description, setDescription] = (0, import_react43.useState)("");
9731
- const [images, setImages] = (0, import_react43.useState)([{ url: "", alt: "", isDefault: true }]);
9732
- const [specifications, setSpecifications] = (0, import_react43.useState)([{ key: "", value: "" }]);
9733
- const [otherMetadata, setOtherMetadata] = (0, import_react43.useState)({});
9734
- const [facetRows, setFacetRows] = (0, import_react43.useState)([{ name: "", value: "" }]);
9735
- const [taxMasterList, setTaxMasterList] = (0, import_react43.useState)([]);
9736
- const [taxRows, setTaxRows] = (0, import_react43.useState)([{ taxId: "", rate: "" }]);
9737
- const [seoId, setSeoId] = (0, import_react43.useState)(null);
9738
- const [seo, setSeo] = (0, import_react43.useState)({
10746
+ const [loading, setLoading] = (0, import_react44.useState)(!create);
10747
+ const [saving, setSaving] = (0, import_react44.useState)(false);
10748
+ const [errors, setErrors] = (0, import_react44.useState)([]);
10749
+ const [collections, setCollections] = (0, import_react44.useState)([]);
10750
+ const [brands, setBrands] = (0, import_react44.useState)([]);
10751
+ const [categories, setCategories] = (0, import_react44.useState)([]);
10752
+ const [name, setName] = (0, import_react44.useState)("");
10753
+ const [productSlug, setProductSlug] = (0, import_react44.useState)("");
10754
+ const [sku, setSku] = (0, import_react44.useState)("");
10755
+ const [hsn, setHsn] = (0, import_react44.useState)("");
10756
+ const [uom, setUom] = (0, import_react44.useState)("");
10757
+ const [productType, setProductType] = (0, import_react44.useState)("product");
10758
+ const [collectionId, setCollectionId] = (0, import_react44.useState)(null);
10759
+ const [brandId, setBrandId] = (0, import_react44.useState)(null);
10760
+ const [categoryId, setCategoryId] = (0, import_react44.useState)(null);
10761
+ const [price, setPrice] = (0, import_react44.useState)("");
10762
+ const [compareAtPrice, setCompareAtPrice] = (0, import_react44.useState)("");
10763
+ const [quantity, setQuantity] = (0, import_react44.useState)(1);
10764
+ const [status, setStatus] = (0, import_react44.useState)("draft");
10765
+ const [featured, setFeatured] = (0, import_react44.useState)(false);
10766
+ const [description, setDescription] = (0, import_react44.useState)("");
10767
+ const [images, setImages] = (0, import_react44.useState)([{ url: "", alt: "", isDefault: true }]);
10768
+ const [specifications, setSpecifications] = (0, import_react44.useState)([{ key: "", value: "" }]);
10769
+ const [otherMetadata, setOtherMetadata] = (0, import_react44.useState)({});
10770
+ const [facetRows, setFacetRows] = (0, import_react44.useState)([{ name: "", value: "" }]);
10771
+ const [taxMasterList, setTaxMasterList] = (0, import_react44.useState)([]);
10772
+ const [taxRows, setTaxRows] = (0, import_react44.useState)([{ taxId: "", rate: "" }]);
10773
+ const [seoId, setSeoId] = (0, import_react44.useState)(null);
10774
+ const [seo, setSeo] = (0, import_react44.useState)({
9739
10775
  seoTitle: "",
9740
10776
  seoDescription: "",
9741
10777
  seoKeywords: "",
@@ -9743,7 +10779,7 @@ function ProductEditPage({ productId }) {
9743
10779
  seoOgDescription: "",
9744
10780
  seoOgImage: ""
9745
10781
  });
9746
- (0, import_react43.useEffect)(() => {
10782
+ (0, import_react44.useEffect)(() => {
9747
10783
  let cancelled = false;
9748
10784
  (async () => {
9749
10785
  try {
@@ -9861,7 +10897,7 @@ function ProductEditPage({ productId }) {
9861
10897
  cancelled = true;
9862
10898
  };
9863
10899
  }, [productId, create]);
9864
- (0, import_react43.useEffect)(() => {
10900
+ (0, import_react44.useEffect)(() => {
9865
10901
  if (!create || !name.trim() || productSlug.trim()) return;
9866
10902
  setProductSlug(
9867
10903
  name.trim().toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/(^-|-$)/g, "")
@@ -10073,8 +11109,8 @@ function ProductEditPage({ productId }) {
10073
11109
  subtitle: create ? "Create a new product" : "Update product details",
10074
11110
  closeHref: "/admin/products",
10075
11111
  menuItems: [
10076
- { label: saving ? "Saving..." : "Save", onClick: handleSave },
10077
- { label: featured ? "Unfeature" : "Feature", onClick: () => setFeatured(!featured) }
11112
+ { label: saving ? "Saving..." : "Save", icon: import_lucide_react34.Save, onClick: handleSave },
11113
+ { label: featured ? "Unfeature" : "Feature", icon: import_lucide_react34.Star, onClick: () => setFeatured(!featured) }
10078
11114
  ]
10079
11115
  }
10080
11116
  ),
@@ -10392,8 +11428,8 @@ function ProductEditPage({ productId }) {
10392
11428
  }
10393
11429
 
10394
11430
  // src/admin/pages/CollectionEditPage.tsx
10395
- var import_react44 = require("react");
10396
- var import_navigation18 = require("next/navigation");
11431
+ var import_react45 = require("react");
11432
+ var import_navigation20 = require("next/navigation");
10397
11433
  var import_lucide_react35 = require("lucide-react");
10398
11434
  var import_jsx_runtime61 = require("react/jsx-runtime");
10399
11435
  var isCreate3 = (id) => id === "create";
@@ -10403,29 +11439,29 @@ var sectionCls2 = "min-w-0 overflow-hidden border border-gray-200 rounded-lg p-4
10403
11439
  var labelCls2 = "block text-xs font-medium text-gray-600 mb-1";
10404
11440
  var inputCls2 = "w-full rounded-md border border-gray-300 px-2 py-1.5 text-sm";
10405
11441
  function CollectionEditPage({ collectionId }) {
10406
- const router = (0, import_navigation18.useRouter)();
11442
+ const router = (0, import_navigation20.useRouter)();
10407
11443
  const create = isCreate3(collectionId);
10408
- const [loading, setLoading] = (0, import_react44.useState)(!create);
10409
- const [saving, setSaving] = (0, import_react44.useState)(false);
10410
- const [errors, setErrors] = (0, import_react44.useState)([]);
10411
- const [categories, setCategories] = (0, import_react44.useState)([]);
10412
- const [brands, setBrands] = (0, import_react44.useState)([]);
10413
- const [name, setName] = (0, import_react44.useState)("");
10414
- const [slug, setSlug] = (0, import_react44.useState)("");
10415
- const [hsn, setHsn] = (0, import_react44.useState)("");
10416
- const [categoryId, setCategoryId] = (0, import_react44.useState)(null);
10417
- const [brandId, setBrandId] = (0, import_react44.useState)(null);
10418
- const [description, setDescription] = (0, import_react44.useState)("");
10419
- const [image, setImage] = (0, import_react44.useState)("");
10420
- const [active, setActive] = (0, import_react44.useState)(true);
10421
- const [sortOrder, setSortOrder] = (0, import_react44.useState)(0);
10422
- const [advancedOpen, setAdvancedOpen] = (0, import_react44.useState)(false);
10423
- const [heroSlides, setHeroSlides] = (0, import_react44.useState)([emptySlide()]);
10424
- const [variants, setVariants] = (0, import_react44.useState)([emptyVariant()]);
10425
- const [experienceDescription, setExperienceDescription] = (0, import_react44.useState)("");
10426
- const [brochureUrl, setBrochureUrl] = (0, import_react44.useState)("");
10427
- const [seoId, setSeoId] = (0, import_react44.useState)(null);
10428
- const [seo, setSeo] = (0, import_react44.useState)({
11444
+ const [loading, setLoading] = (0, import_react45.useState)(!create);
11445
+ const [saving, setSaving] = (0, import_react45.useState)(false);
11446
+ const [errors, setErrors] = (0, import_react45.useState)([]);
11447
+ const [categories, setCategories] = (0, import_react45.useState)([]);
11448
+ const [brands, setBrands] = (0, import_react45.useState)([]);
11449
+ const [name, setName] = (0, import_react45.useState)("");
11450
+ const [slug, setSlug] = (0, import_react45.useState)("");
11451
+ const [hsn, setHsn] = (0, import_react45.useState)("");
11452
+ const [categoryId, setCategoryId] = (0, import_react45.useState)(null);
11453
+ const [brandId, setBrandId] = (0, import_react45.useState)(null);
11454
+ const [description, setDescription] = (0, import_react45.useState)("");
11455
+ const [image, setImage] = (0, import_react45.useState)("");
11456
+ const [active, setActive] = (0, import_react45.useState)(true);
11457
+ const [sortOrder, setSortOrder] = (0, import_react45.useState)(0);
11458
+ const [advancedOpen, setAdvancedOpen] = (0, import_react45.useState)(false);
11459
+ const [heroSlides, setHeroSlides] = (0, import_react45.useState)([emptySlide()]);
11460
+ const [variants, setVariants] = (0, import_react45.useState)([emptyVariant()]);
11461
+ const [experienceDescription, setExperienceDescription] = (0, import_react45.useState)("");
11462
+ const [brochureUrl, setBrochureUrl] = (0, import_react45.useState)("");
11463
+ const [seoId, setSeoId] = (0, import_react45.useState)(null);
11464
+ const [seo, setSeo] = (0, import_react45.useState)({
10429
11465
  seoTitle: "",
10430
11466
  seoDescription: "",
10431
11467
  seoKeywords: "",
@@ -10433,7 +11469,7 @@ function CollectionEditPage({ collectionId }) {
10433
11469
  seoOgDescription: "",
10434
11470
  seoOgImage: ""
10435
11471
  });
10436
- (0, import_react44.useEffect)(() => {
11472
+ (0, import_react45.useEffect)(() => {
10437
11473
  let cancelled = false;
10438
11474
  (async () => {
10439
11475
  try {
@@ -10606,8 +11642,8 @@ function CollectionEditPage({ collectionId }) {
10606
11642
  subtitle: create ? "Create a new collection" : "Update collection and page content",
10607
11643
  closeHref: "/admin/collections",
10608
11644
  menuItems: [
10609
- { label: saving ? "Saving..." : "Save", onClick: handleSave },
10610
- { label: active ? "Deactivate" : "Activate", onClick: () => setActive(!active) }
11645
+ { label: saving ? "Saving..." : "Save", icon: import_lucide_react35.Save, onClick: handleSave },
11646
+ { label: active ? "Deactivate" : "Activate", icon: import_lucide_react35.Power, onClick: () => setActive(!active) }
10611
11647
  ]
10612
11648
  }
10613
11649
  ),
@@ -10750,8 +11786,8 @@ function CollectionEditPage({ collectionId }) {
10750
11786
  }
10751
11787
 
10752
11788
  // src/admin/pages/RolesPage.tsx
10753
- var import_react45 = require("react");
10754
- var import_react46 = require("next-auth/react");
11789
+ var import_react46 = require("react");
11790
+ var import_react47 = require("next-auth/react");
10755
11791
  var import_lucide_react36 = require("lucide-react");
10756
11792
 
10757
11793
  // src/auth/permission-entities.ts
@@ -10782,18 +11818,19 @@ function RoleListItem({
10782
11818
  );
10783
11819
  }
10784
11820
  function RolesPage() {
10785
- const { data: session, status } = (0, import_react46.useSession)();
11821
+ const { data: session, status } = (0, import_react47.useSession)();
10786
11822
  const u = session?.user;
10787
11823
  const canManage = !!u?.isRBACAdmin;
10788
- const [entities, setEntities] = (0, import_react45.useState)([]);
10789
- const [groups, setGroups] = (0, import_react45.useState)([]);
10790
- const [selectedId, setSelectedId] = (0, import_react45.useState)(null);
10791
- const [matrix, setMatrix] = (0, import_react45.useState)({});
10792
- const [loading, setLoading] = (0, import_react45.useState)(true);
10793
- const [saving, setSaving] = (0, import_react45.useState)(false);
10794
- const [newName, setNewName] = (0, import_react45.useState)("");
10795
- const [error, setError] = (0, import_react45.useState)(null);
10796
- const load = (0, import_react45.useCallback)(async () => {
11824
+ const [entities, setEntities] = (0, import_react46.useState)([]);
11825
+ const [groups, setGroups] = (0, import_react46.useState)([]);
11826
+ const [selectedId, setSelectedId] = (0, import_react46.useState)(null);
11827
+ const [matrix, setMatrix] = (0, import_react46.useState)({});
11828
+ const [loading, setLoading] = (0, import_react46.useState)(true);
11829
+ const [saving, setSaving] = (0, import_react46.useState)(false);
11830
+ const [newName, setNewName] = (0, import_react46.useState)("");
11831
+ const [deleteRoleOpen, setDeleteRoleOpen] = (0, import_react46.useState)(false);
11832
+ const [error, setError] = (0, import_react46.useState)(null);
11833
+ const load = (0, import_react46.useCallback)(async () => {
10797
11834
  setLoading(true);
10798
11835
  setError(null);
10799
11836
  try {
@@ -10818,11 +11855,11 @@ function RolesPage() {
10818
11855
  setLoading(false);
10819
11856
  }
10820
11857
  }, []);
10821
- (0, import_react45.useEffect)(() => {
11858
+ (0, import_react46.useEffect)(() => {
10822
11859
  if (status === "authenticated" && canManage) load();
10823
11860
  }, [status, canManage, load]);
10824
11861
  const selected = groups.find((g) => g.id === selectedId);
10825
- (0, import_react45.useEffect)(() => {
11862
+ (0, import_react46.useEffect)(() => {
10826
11863
  if (!selected || !entities.length) {
10827
11864
  setMatrix({});
10828
11865
  return;
@@ -10847,6 +11884,45 @@ function RolesPage() {
10847
11884
  [entity]: { ...prev[entity], [key]: !prev[entity][key] }
10848
11885
  }));
10849
11886
  };
11887
+ const PERM_KEYS = [
11888
+ "canCreate",
11889
+ "canRead",
11890
+ "canUpdate",
11891
+ "canDelete"
11892
+ ];
11893
+ const isColumnAllChecked = (key) => entities.length > 0 && entities.every((entity) => matrix[entity]?.[key]);
11894
+ const toggleColumn = (key) => {
11895
+ const nextValue = !isColumnAllChecked(key);
11896
+ setMatrix((prev) => {
11897
+ const next = { ...prev };
11898
+ for (const entity of entities) {
11899
+ if (!next[entity]) continue;
11900
+ next[entity] = { ...next[entity], [key]: nextValue };
11901
+ }
11902
+ return next;
11903
+ });
11904
+ };
11905
+ const isAllChecked = entities.length > 0 && entities.every((entity) => {
11906
+ const row = matrix[entity];
11907
+ return row ? PERM_KEYS.every((k) => row[k]) : false;
11908
+ });
11909
+ const toggleAll = () => {
11910
+ const nextValue = !isAllChecked;
11911
+ setMatrix((prev) => {
11912
+ const next = { ...prev };
11913
+ for (const entity of entities) {
11914
+ if (!next[entity]) continue;
11915
+ next[entity] = {
11916
+ ...next[entity],
11917
+ canCreate: nextValue,
11918
+ canRead: nextValue,
11919
+ canUpdate: nextValue,
11920
+ canDelete: nextValue
11921
+ };
11922
+ }
11923
+ return next;
11924
+ });
11925
+ };
10850
11926
  const saveMatrix = async () => {
10851
11927
  if (!selectedId) return;
10852
11928
  setSaving(true);
@@ -10895,7 +11971,6 @@ function RolesPage() {
10895
11971
  };
10896
11972
  const deleteGroup = async () => {
10897
11973
  if (!selectedId || !selected || isSuperAdminGroupName(selected.name)) return;
10898
- if (!confirm(`Delete group "${selected.name}"?`)) return;
10899
11974
  try {
10900
11975
  const res = await fetch(`/api/admin/roles/${selectedId}`, { method: "DELETE" });
10901
11976
  if (!res.ok) {
@@ -10904,6 +11979,7 @@ function RolesPage() {
10904
11979
  return;
10905
11980
  }
10906
11981
  setSelectedId(null);
11982
+ setDeleteRoleOpen(false);
10907
11983
  await load();
10908
11984
  } catch {
10909
11985
  setError("Delete failed");
@@ -10957,18 +12033,33 @@ function RolesPage() {
10957
12033
  /* @__PURE__ */ (0, import_jsx_runtime62.jsx)(import_lucide_react36.Save, { className: "h-3.5 w-3.5" }),
10958
12034
  saving ? "Saving\u2026" : "Save"
10959
12035
  ] }),
10960
- selected && !isSuperAdminGroupName(selected.name) && /* @__PURE__ */ (0, import_jsx_runtime62.jsxs)(Button, { size: "sm", variant: "outline", className: "gap-1 text-red-600", onClick: deleteGroup, children: [
12036
+ selected && !isSuperAdminGroupName(selected.name) && /* @__PURE__ */ (0, import_jsx_runtime62.jsxs)(Button, { size: "sm", variant: "outline", className: "gap-1 text-red-600", onClick: () => setDeleteRoleOpen(true), children: [
10961
12037
  /* @__PURE__ */ (0, import_jsx_runtime62.jsx)(import_lucide_react36.Trash2, { className: "h-3.5 w-3.5" }),
10962
12038
  "Delete role"
10963
12039
  ] })
10964
12040
  ] }),
10965
12041
  entities.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime62.jsx)("div", { className: "overflow-x-auto rounded-md border border-gray-200 dark:border-gray-600", children: /* @__PURE__ */ (0, import_jsx_runtime62.jsxs)("table", { className: "w-full text-sm", children: [
10966
12042
  /* @__PURE__ */ (0, import_jsx_runtime62.jsx)("thead", { children: /* @__PURE__ */ (0, import_jsx_runtime62.jsxs)("tr", { className: "border-b bg-gray-50 dark:bg-gray-900/50", children: [
10967
- /* @__PURE__ */ (0, import_jsx_runtime62.jsx)("th", { className: "p-3 text-left font-medium", children: "Resource" }),
10968
- /* @__PURE__ */ (0, import_jsx_runtime62.jsx)("th", { className: "p-2", children: "C" }),
10969
- /* @__PURE__ */ (0, import_jsx_runtime62.jsx)("th", { className: "p-2", children: "R" }),
10970
- /* @__PURE__ */ (0, import_jsx_runtime62.jsx)("th", { className: "p-2", children: "U" }),
10971
- /* @__PURE__ */ (0, import_jsx_runtime62.jsx)("th", { className: "p-2", children: "D" })
12043
+ /* @__PURE__ */ (0, import_jsx_runtime62.jsx)("th", { className: "p-3 text-left font-medium", children: /* @__PURE__ */ (0, import_jsx_runtime62.jsxs)("div", { className: "flex items-center gap-2", children: [
12044
+ /* @__PURE__ */ (0, import_jsx_runtime62.jsx)("input", { type: "checkbox", checked: isAllChecked, onChange: toggleAll }),
12045
+ /* @__PURE__ */ (0, import_jsx_runtime62.jsx)("span", { children: "Resource" })
12046
+ ] }) }),
12047
+ /* @__PURE__ */ (0, import_jsx_runtime62.jsx)("th", { className: "p-2", children: /* @__PURE__ */ (0, import_jsx_runtime62.jsxs)("div", { className: "flex items-center justify-center gap-1", children: [
12048
+ /* @__PURE__ */ (0, import_jsx_runtime62.jsx)("span", { children: "C" }),
12049
+ /* @__PURE__ */ (0, import_jsx_runtime62.jsx)("input", { type: "checkbox", checked: isColumnAllChecked("canCreate"), onChange: () => toggleColumn("canCreate") })
12050
+ ] }) }),
12051
+ /* @__PURE__ */ (0, import_jsx_runtime62.jsx)("th", { className: "p-2", children: /* @__PURE__ */ (0, import_jsx_runtime62.jsxs)("div", { className: "flex items-center justify-center gap-1", children: [
12052
+ /* @__PURE__ */ (0, import_jsx_runtime62.jsx)("span", { children: "R" }),
12053
+ /* @__PURE__ */ (0, import_jsx_runtime62.jsx)("input", { type: "checkbox", checked: isColumnAllChecked("canRead"), onChange: () => toggleColumn("canRead") })
12054
+ ] }) }),
12055
+ /* @__PURE__ */ (0, import_jsx_runtime62.jsx)("th", { className: "p-2", children: /* @__PURE__ */ (0, import_jsx_runtime62.jsxs)("div", { className: "flex items-center justify-center gap-1", children: [
12056
+ /* @__PURE__ */ (0, import_jsx_runtime62.jsx)("span", { children: "U" }),
12057
+ /* @__PURE__ */ (0, import_jsx_runtime62.jsx)("input", { type: "checkbox", checked: isColumnAllChecked("canUpdate"), onChange: () => toggleColumn("canUpdate") })
12058
+ ] }) }),
12059
+ /* @__PURE__ */ (0, import_jsx_runtime62.jsx)("th", { className: "p-2", children: /* @__PURE__ */ (0, import_jsx_runtime62.jsxs)("div", { className: "flex items-center justify-center gap-1", children: [
12060
+ /* @__PURE__ */ (0, import_jsx_runtime62.jsx)("span", { children: "D" }),
12061
+ /* @__PURE__ */ (0, import_jsx_runtime62.jsx)("input", { type: "checkbox", checked: isColumnAllChecked("canDelete"), onChange: () => toggleColumn("canDelete") })
12062
+ ] }) })
10972
12063
  ] }) }),
10973
12064
  /* @__PURE__ */ (0, import_jsx_runtime62.jsx)("tbody", { children: entities.map((entity) => {
10974
12065
  const row = matrix[entity];
@@ -10992,7 +12083,15 @@ function RolesPage() {
10992
12083
  /* @__PURE__ */ (0, import_jsx_runtime62.jsx)(Input, { placeholder: "New role name", value: newName, onChange: (e) => setNewName(e.target.value), onKeyDown: (e) => e.key === "Enter" && createGroup() }),
10993
12084
  /* @__PURE__ */ (0, import_jsx_runtime62.jsx)(Button, { type: "button", onClick: createGroup, children: "Add role" })
10994
12085
  ] })
10995
- ] })
12086
+ ] }),
12087
+ /* @__PURE__ */ (0, import_jsx_runtime62.jsx)(Dialog, { open: deleteRoleOpen, onOpenChange: setDeleteRoleOpen, children: /* @__PURE__ */ (0, import_jsx_runtime62.jsxs)(DialogContent, { children: [
12088
+ /* @__PURE__ */ (0, import_jsx_runtime62.jsx)(DialogHeader, { children: /* @__PURE__ */ (0, import_jsx_runtime62.jsx)(DialogTitle, { children: "Delete Role" }) }),
12089
+ /* @__PURE__ */ (0, import_jsx_runtime62.jsx)("p", { className: "text-sm text-gray-600", children: selected ? `Delete group "${selected.name}"?` : "Delete selected role?" }),
12090
+ /* @__PURE__ */ (0, import_jsx_runtime62.jsxs)(DialogFooter, { children: [
12091
+ /* @__PURE__ */ (0, import_jsx_runtime62.jsx)(Button, { variant: "outline", onClick: () => setDeleteRoleOpen(false), children: "Cancel" }),
12092
+ /* @__PURE__ */ (0, import_jsx_runtime62.jsx)(Button, { variant: "destructive", onClick: deleteGroup, children: "Delete" })
12093
+ ] })
12094
+ ] }) })
10996
12095
  ] });
10997
12096
  }
10998
12097
 
@@ -11270,9 +12369,9 @@ var CRUD_CONFIGS = {
11270
12369
  }
11271
12370
  };
11272
12371
  function BlogEditorWrapper({ blogId }) {
11273
- const [blog, setBlog] = (0, import_react47.useState)(null);
11274
- const [loading, setLoading] = (0, import_react47.useState)(!!blogId);
11275
- (0, import_react47.useEffect)(() => {
12372
+ const [blog, setBlog] = (0, import_react48.useState)(null);
12373
+ const [loading, setLoading] = (0, import_react48.useState)(!!blogId);
12374
+ (0, import_react48.useEffect)(() => {
11276
12375
  if (!blogId) return;
11277
12376
  fetch(`/api/blogs/${blogId}`).then((res) => res.ok ? res.json() : null).then((data) => setBlog(data)).finally(() => setLoading(false));
11278
12377
  }, [blogId]);
@@ -11285,10 +12384,10 @@ function BlogEditorWrapper({ blogId }) {
11285
12384
  return /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(BlogEditor, { existingBlog: blog });
11286
12385
  }
11287
12386
  function AdminPageResolver({ slug }) {
11288
- const router = (0, import_navigation19.useRouter)();
11289
- const { customCrudConfigs, storeEnabled } = (0, import_react47.useContext)(AdminConfigContext);
12387
+ const router = (0, import_navigation21.useRouter)();
12388
+ const { customCrudConfigs, storeEnabled } = (0, import_react48.useContext)(AdminConfigContext);
11290
12389
  const key = slug?.[0] || "dashboard";
11291
- (0, import_react47.useEffect)(() => {
12390
+ (0, import_react48.useEffect)(() => {
11292
12391
  if (key === "layout-settings") {
11293
12392
  router.replace("/admin/settings?tab=navbar");
11294
12393
  }
@@ -11348,7 +12447,7 @@ function AdminPageResolver({ slug }) {
11348
12447
  { field: "orderCount", displayName: "Orders" },
11349
12448
  { field: "totalPaid", displayName: "Total paid" }
11350
12449
  ] : crud.columns;
11351
- const extraListParams = (0, import_react47.useMemo)(
12450
+ const extraListParams = (0, import_react48.useMemo)(
11352
12451
  () => isContactsWithStore ? { includeSummary: "1" } : void 0,
11353
12452
  [isContactsWithStore]
11354
12453
  );
@@ -11371,22 +12470,22 @@ function AdminPageResolver({ slug }) {
11371
12470
  }
11372
12471
 
11373
12472
  // src/admin/pages/LayoutSettingsPage.tsx
11374
- var import_react48 = require("react");
12473
+ var import_react49 = require("react");
11375
12474
  var import_lucide_react37 = require("lucide-react");
11376
12475
  var import_jsx_runtime64 = require("react/jsx-runtime");
11377
12476
  function LayoutSettingsPage() {
11378
- const { theme } = (0, import_react48.useContext)(AdminConfigContext);
11379
- const [activeTab, setActiveTab] = (0, import_react48.useState)("navbar");
11380
- const [navbarConfig, setNavbarConfig] = (0, import_react48.useState)({
12477
+ const { theme } = (0, import_react49.useContext)(AdminConfigContext);
12478
+ const [activeTab, setActiveTab] = (0, import_react49.useState)("navbar");
12479
+ const [navbarConfig, setNavbarConfig] = (0, import_react49.useState)({
11381
12480
  logo: "",
11382
12481
  items: [],
11383
12482
  ctaLabel: "",
11384
12483
  ctaUrl: ""
11385
12484
  });
11386
- const [footerValues, setFooterValues] = (0, import_react48.useState)({});
11387
- const [saving, setSaving] = (0, import_react48.useState)(false);
11388
- const [loading, setLoading] = (0, import_react48.useState)(true);
11389
- (0, import_react48.useEffect)(() => {
12485
+ const [footerValues, setFooterValues] = (0, import_react49.useState)({});
12486
+ const [saving, setSaving] = (0, import_react49.useState)(false);
12487
+ const [loading, setLoading] = (0, import_react49.useState)(true);
12488
+ (0, import_react49.useEffect)(() => {
11390
12489
  fetch("/api/settings/theme").then((r) => r.ok ? r.json() : null).then((data) => {
11391
12490
  if (!data) return;
11392
12491
  if (data.navbar) {
@@ -11496,14 +12595,14 @@ var DEFAULT_ADMIN_NAV = [
11496
12595
  ];
11497
12596
 
11498
12597
  // src/admin/CmsProviders.tsx
11499
- var import_react49 = require("next-auth/react");
12598
+ var import_react50 = require("next-auth/react");
11500
12599
  var import_next_themes = require("next-themes");
11501
- var import_sonner7 = require("sonner");
12600
+ var import_sonner8 = require("sonner");
11502
12601
  var import_jsx_runtime65 = require("react/jsx-runtime");
11503
12602
  function CmsProviders({ children }) {
11504
- return /* @__PURE__ */ (0, import_jsx_runtime65.jsx)(import_react49.SessionProvider, { children: /* @__PURE__ */ (0, import_jsx_runtime65.jsxs)(import_next_themes.ThemeProvider, { attribute: "class", defaultTheme: "system", enableSystem: true, children: [
12603
+ return /* @__PURE__ */ (0, import_jsx_runtime65.jsx)(import_react50.SessionProvider, { children: /* @__PURE__ */ (0, import_jsx_runtime65.jsxs)(import_next_themes.ThemeProvider, { attribute: "class", defaultTheme: "system", enableSystem: true, children: [
11505
12604
  children,
11506
- /* @__PURE__ */ (0, import_jsx_runtime65.jsx)(import_sonner7.Toaster, { position: "top-right" })
12605
+ /* @__PURE__ */ (0, import_jsx_runtime65.jsx)(import_sonner8.Toaster, { position: "top-right" })
11507
12606
  ] }) });
11508
12607
  }
11509
12608
  // Annotate the CommonJS export names for ESM import in node: