@infuro/cms-core 1.0.14 → 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.14" : "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: [
@@ -4360,8 +4571,22 @@ function BlogEditor({ existingBlog }) {
4360
4571
  Button,
4361
4572
  {
4362
4573
  variant: "outline",
4363
- size: "sm",
4364
- className: "flex items-center bg-white text-gray-800 hover:bg-gray-100 border-0 text-xs",
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
+ ),
4584
+ /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)(
4585
+ Button,
4586
+ {
4587
+ variant: "outline",
4588
+ size: "sm",
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,11 +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
- (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)(() => {
6031
6750
  async function load() {
6032
6751
  try {
6033
6752
  setLoading(true);
@@ -6050,6 +6769,39 @@ function OrderDetailPage({ orderId }) {
6050
6769
  }
6051
6770
  load();
6052
6771
  }, [orderId]);
6772
+ (0, import_react34.useEffect)(() => {
6773
+ let cancelled = false;
6774
+ (async () => {
6775
+ try {
6776
+ const res = await fetch(`/api/orders/${orderId}/repost-erp`);
6777
+ if (!res.ok) return;
6778
+ const data = await res.json();
6779
+ if (!cancelled) setErpEnabled(data.enabled === true);
6780
+ } catch {
6781
+ }
6782
+ })();
6783
+ return () => {
6784
+ cancelled = true;
6785
+ };
6786
+ }, [orderId]);
6787
+ async function handleRepostToErp() {
6788
+ if (reposting) return;
6789
+ setReposting(true);
6790
+ setError(null);
6791
+ try {
6792
+ const res = await fetch(`/api/orders/${orderId}/repost-erp`, { method: "POST" });
6793
+ if (!res.ok) {
6794
+ const body = await res.json().catch(() => ({}));
6795
+ setError(body.error ?? "Failed to repost to ERP");
6796
+ return;
6797
+ }
6798
+ router.refresh();
6799
+ } catch {
6800
+ setError("Failed to repost to ERP");
6801
+ } finally {
6802
+ setReposting(false);
6803
+ }
6804
+ }
6053
6805
  if (loading) {
6054
6806
  return /* @__PURE__ */ (0, import_jsx_runtime49.jsx)("div", { className: "rounded-lg bg-white p-6 shadow-md", children: /* @__PURE__ */ (0, import_jsx_runtime49.jsx)("div", { className: "flex justify-center py-12", children: /* @__PURE__ */ (0, import_jsx_runtime49.jsx)("span", { className: "text-gray-500", children: "Loading..." }) }) });
6055
6807
  }
@@ -6072,7 +6824,8 @@ function OrderDetailPage({ orderId }) {
6072
6824
  {
6073
6825
  title: `Order ${order.orderNumber}`,
6074
6826
  subtitle: /* @__PURE__ */ (0, import_jsx_runtime49.jsx)("span", { className: "text-sm text-gray-400", children: formatDateTime(order.createdAt) }),
6075
- closeHref: "/admin/orders"
6827
+ closeHref: "/admin/orders",
6828
+ menuItems: erpEnabled ? [{ label: reposting ? "Reposting..." : "Repost to ERP", icon: import_lucide_react25.RefreshCw, onClick: handleRepostToErp }] : void 0
6076
6829
  }
6077
6830
  ),
6078
6831
  /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(
@@ -6312,9 +7065,9 @@ function OrderDetailPage({ orderId }) {
6312
7065
  }
6313
7066
 
6314
7067
  // src/admin/pages/PaymentDetailPage.tsx
6315
- var import_react34 = require("react");
7068
+ var import_react35 = require("react");
6316
7069
  var import_link11 = __toESM(require("next/link"), 1);
6317
- var import_navigation12 = require("next/navigation");
7070
+ var import_navigation14 = require("next/navigation");
6318
7071
  var import_lucide_react26 = require("lucide-react");
6319
7072
  var import_jsx_runtime50 = require("react/jsx-runtime");
6320
7073
  function formatMoney2(amount, currency = "INR") {
@@ -6325,11 +7078,11 @@ function formatMoney2(amount, currency = "INR") {
6325
7078
  }).format(Number(amount));
6326
7079
  }
6327
7080
  function PaymentDetailPage({ paymentId }) {
6328
- const router = (0, import_navigation12.useRouter)();
6329
- const [payment, setPayment] = (0, import_react34.useState)(null);
6330
- const [loading, setLoading] = (0, import_react34.useState)(true);
6331
- const [error, setError] = (0, import_react34.useState)(null);
6332
- (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)(() => {
6333
7086
  async function load() {
6334
7087
  try {
6335
7088
  setLoading(true);
@@ -6471,9 +7224,9 @@ function PaymentDetailPage({ paymentId }) {
6471
7224
  }
6472
7225
 
6473
7226
  // src/admin/pages/ContactDetailPage.tsx
6474
- var import_react35 = require("react");
7227
+ var import_react36 = require("react");
6475
7228
  var import_link12 = __toESM(require("next/link"), 1);
6476
- var import_navigation13 = require("next/navigation");
7229
+ var import_navigation15 = require("next/navigation");
6477
7230
  var import_lucide_react27 = require("lucide-react");
6478
7231
  var import_jsx_runtime51 = require("react/jsx-runtime");
6479
7232
  function formatMoney3(amount, currency = "INR") {
@@ -6489,13 +7242,13 @@ function formatAddress2(a) {
6489
7242
  }
6490
7243
  var ADDRESS_TAGS = [{ value: "", label: "\u2014" }, { value: "default", label: "Default" }, { value: "billing", label: "Billing" }, { value: "shipping", label: "Shipping" }];
6491
7244
  function ContactDetailPage({ contactId }) {
6492
- const router = (0, import_navigation13.useRouter)();
6493
- const [contact, setContact] = (0, import_react35.useState)(null);
6494
- const [loading, setLoading] = (0, import_react35.useState)(true);
6495
- const [error, setError] = (0, import_react35.useState)(null);
6496
- const [addAddressOpen, setAddAddressOpen] = (0, import_react35.useState)(false);
6497
- const [addAddressSaving, setAddAddressSaving] = (0, import_react35.useState)(false);
6498
- 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)({
6499
7252
  tag: "",
6500
7253
  line1: "",
6501
7254
  line2: "",
@@ -6507,7 +7260,7 @@ function ContactDetailPage({ contactId }) {
6507
7260
  const loadContact = () => {
6508
7261
  fetch(`/api/contacts/${contactId}`).then((res) => res.ok ? res.json() : null).then((data) => setContact(data)).catch(() => setContact(null));
6509
7262
  };
6510
- (0, import_react35.useEffect)(() => {
7263
+ (0, import_react36.useEffect)(() => {
6511
7264
  async function load() {
6512
7265
  try {
6513
7266
  setLoading(true);
@@ -6843,9 +7596,9 @@ function ContactDetailPage({ contactId }) {
6843
7596
  }
6844
7597
 
6845
7598
  // src/admin/pages/SettingsPage.tsx
6846
- var import_react36 = require("react");
6847
- var import_navigation14 = require("next/navigation");
6848
- var import_sonner4 = require("sonner");
7599
+ var import_react37 = require("react");
7600
+ var import_navigation16 = require("next/navigation");
7601
+ var import_sonner5 = require("sonner");
6849
7602
  var import_lucide_react28 = require("lucide-react");
6850
7603
  var import_jsx_runtime52 = require("react/jsx-runtime");
6851
7604
  var DEFAULTS = {
@@ -6869,25 +7622,25 @@ function hexToHsl(hex) {
6869
7622
  return `${Math.round(h * 360)} ${Math.round(s * 100)}% ${Math.round(l * 100)}%`;
6870
7623
  }
6871
7624
  function SettingsPage() {
6872
- const searchParams = (0, import_navigation14.useSearchParams)();
7625
+ const searchParams = (0, import_navigation16.useSearchParams)();
6873
7626
  const tabParam = searchParams.get("tab");
6874
- const { theme, themeRegistry } = (0, import_react36.useContext)(AdminConfigContext);
6875
- const [tab, setTab] = (0, import_react36.useState)(
7627
+ const { theme, themeRegistry } = (0, import_react37.useContext)(AdminConfigContext);
7628
+ const [tab, setTab] = (0, import_react37.useState)(
6876
7629
  tabParam === "navbar" ? "navbar" : tabParam === "store" ? "store" : "appearance"
6877
7630
  );
6878
- (0, import_react36.useEffect)(() => {
7631
+ (0, import_react37.useEffect)(() => {
6879
7632
  if (tabParam === "navbar") setTab("navbar");
6880
7633
  else if (tabParam === "store") setTab("store");
6881
7634
  }, [tabParam]);
6882
- const [settings, setSettings] = (0, import_react36.useState)(DEFAULTS);
6883
- const [loading, setLoading] = (0, import_react36.useState)(true);
6884
- const [saving, setSaving] = (0, import_react36.useState)(false);
6885
- const [activeThemeId, setActiveThemeId] = (0, import_react36.useState)("");
6886
- const [navbarConfig, setNavbarConfig] = (0, import_react36.useState)({ logo: "", items: [], ctaLabel: "", ctaUrl: "" });
6887
- const [themeSettingsLoading, setThemeSettingsLoading] = (0, import_react36.useState)(true);
6888
- const [storeEnabled, setStoreEnabled] = (0, import_react36.useState)(false);
6889
- const [storeSettingsLoading, setStoreSettingsLoading] = (0, import_react36.useState)(true);
6890
- (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)(() => {
6891
7644
  fetch("/api/settings/admin_view").then((r) => r.ok ? r.json() : {}).then((data) => {
6892
7645
  setSettings({
6893
7646
  primaryColor: data.primaryColor || DEFAULTS.primaryColor,
@@ -6896,7 +7649,7 @@ function SettingsPage() {
6896
7649
  });
6897
7650
  }).finally(() => setLoading(false));
6898
7651
  }, []);
6899
- (0, import_react36.useEffect)(() => {
7652
+ (0, import_react37.useEffect)(() => {
6900
7653
  fetch("/api/settings/theme").then((r) => r.ok ? r.json() : null).then((data) => {
6901
7654
  if (!data) return;
6902
7655
  setActiveThemeId((data.activeThemeId || "").trim());
@@ -6908,7 +7661,7 @@ function SettingsPage() {
6908
7661
  }
6909
7662
  }).finally(() => setThemeSettingsLoading(false));
6910
7663
  }, []);
6911
- (0, import_react36.useEffect)(() => {
7664
+ (0, import_react37.useEffect)(() => {
6912
7665
  fetch("/api/settings/store").then((r) => r.ok ? r.json() : {}).then((data) => {
6913
7666
  setStoreEnabled(data.enabled === "true");
6914
7667
  }).finally(() => setStoreSettingsLoading(false));
@@ -6932,9 +7685,9 @@ function SettingsPage() {
6932
7685
  document.documentElement.style.setProperty("--secondary", hexToHsl(settings.secondaryColor));
6933
7686
  if (settings.compactView === "true") document.documentElement.classList.add("compact");
6934
7687
  else document.documentElement.classList.remove("compact");
6935
- import_sonner4.toast.success("Settings saved");
7688
+ import_sonner5.toast.success("Settings saved");
6936
7689
  } catch {
6937
- import_sonner4.toast.error("Failed to save settings");
7690
+ import_sonner5.toast.error("Failed to save settings");
6938
7691
  } finally {
6939
7692
  setSaving(false);
6940
7693
  }
@@ -6948,10 +7701,10 @@ function SettingsPage() {
6948
7701
  headers: { "Content-Type": "application/json" },
6949
7702
  body: JSON.stringify({ activeThemeId: { value: id, type: "public" } })
6950
7703
  });
6951
- import_sonner4.toast.success("Theme updated");
7704
+ import_sonner5.toast.success("Theme updated");
6952
7705
  window.location.reload();
6953
7706
  } catch {
6954
- import_sonner4.toast.error("Failed to save theme");
7707
+ import_sonner5.toast.error("Failed to save theme");
6955
7708
  } finally {
6956
7709
  setSaving(false);
6957
7710
  }
@@ -6964,9 +7717,9 @@ function SettingsPage() {
6964
7717
  headers: { "Content-Type": "application/json" },
6965
7718
  body: JSON.stringify({ navbar: { value: JSON.stringify(navbarConfig), type: "public" } })
6966
7719
  });
6967
- import_sonner4.toast.success("Navbar saved");
7720
+ import_sonner5.toast.success("Navbar saved");
6968
7721
  } catch {
6969
- import_sonner4.toast.error("Failed to save");
7722
+ import_sonner5.toast.error("Failed to save");
6970
7723
  } finally {
6971
7724
  setSaving(false);
6972
7725
  }
@@ -6979,10 +7732,10 @@ function SettingsPage() {
6979
7732
  headers: { "Content-Type": "application/json" },
6980
7733
  body: JSON.stringify({ enabled: { value: storeEnabled ? "true" : "false", type: "public" } })
6981
7734
  });
6982
- import_sonner4.toast.success("Store settings saved");
7735
+ import_sonner5.toast.success("Store settings saved");
6983
7736
  window.location.reload();
6984
7737
  } catch {
6985
- import_sonner4.toast.error("Failed to save store settings");
7738
+ import_sonner5.toast.error("Failed to save store settings");
6986
7739
  } finally {
6987
7740
  setSaving(false);
6988
7741
  }
@@ -7098,11 +7851,24 @@ function SettingsPage() {
7098
7851
  }
7099
7852
 
7100
7853
  // src/admin/pages/MediaLibraryPage.tsx
7101
- 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
7102
7866
  var import_lucide_react29 = require("lucide-react");
7103
- var import_sonner5 = require("sonner");
7867
+ var import_sonner6 = require("sonner");
7104
7868
  var import_jsx_runtime53 = require("react/jsx-runtime");
7105
- 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";
7106
7872
  if (!mime) return "other";
7107
7873
  if (mime.startsWith("image/")) return "image";
7108
7874
  if (mime.startsWith("video/")) return "video";
@@ -7110,56 +7876,66 @@ function getTypeCategory(mime) {
7110
7876
  if (mime === "application/pdf" || mime.startsWith("application/")) return "document";
7111
7877
  return "other";
7112
7878
  }
7113
- function getTypeLabel(mime) {
7114
- 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);
7115
7883
  const labels = {
7116
7884
  image: "Image",
7117
7885
  video: "Video",
7118
7886
  audio: "Audio",
7119
7887
  document: "Document",
7888
+ folder: "Folder",
7889
+ zip: "Zip",
7120
7890
  other: "Other"
7121
7891
  };
7122
7892
  return labels[c] || "Other";
7123
7893
  }
7124
- function TypeIcon({ mimeType }) {
7125
- 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);
7126
7902
  if (c === "image") return /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(import_lucide_react29.Image, { className: "h-8 w-8 text-gray-400" });
7127
7903
  if (c === "video") return /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(import_lucide_react29.Film, { className: "h-8 w-8 text-gray-400" });
7128
7904
  if (c === "document") return /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(import_lucide_react29.FileText, { className: "h-8 w-8 text-gray-400" });
7129
7905
  return /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(import_lucide_react29.File, { className: "h-8 w-8 text-gray-400" });
7130
7906
  }
7131
- function groupByMonth(items) {
7132
- const groups = {};
7133
- items.forEach((item) => {
7134
- const d = new Date(item.createdAt);
7135
- const key = `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, "0")}`;
7136
- const label = d.toLocaleDateString("en-US", { year: "numeric", month: "long" });
7137
- if (!groups[label]) groups[label] = [];
7138
- groups[label].push(item);
7139
- });
7140
- return groups;
7141
- }
7142
7907
  function MediaLibraryPage() {
7143
- const [data, setData] = (0, import_react37.useState)([]);
7144
- const [loading, setLoading] = (0, import_react37.useState)(true);
7145
- const [page, setPage] = (0, import_react37.useState)(1);
7146
- const [totalPages, setTotalPages] = (0, import_react37.useState)(1);
7147
- const [search, setSearch] = (0, import_react37.useState)("");
7148
- const [searchInput, setSearchInput] = (0, import_react37.useState)("");
7149
- const [typeFilter, setTypeFilter] = (0, import_react37.useState)("");
7150
- const [uploading, setUploading] = (0, import_react37.useState)(false);
7151
- const [editModal, setEditModal] = (0, import_react37.useState)(null);
7152
- const [editAlt, setEditAlt] = (0, import_react37.useState)("");
7153
- const [editPublic, setEditPublic] = (0, import_react37.useState)(false);
7154
- const fileInputRef = (0, import_react37.useRef)(null);
7155
- 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 () => {
7156
7931
  setLoading(true);
7157
7932
  const params = new URLSearchParams({
7158
7933
  page: String(page),
7159
7934
  limit: "24",
7160
- sortField: "createdAt",
7161
- sortOrder: "desc"
7935
+ sortField,
7936
+ sortOrder
7162
7937
  });
7938
+ params.set("parentId", currentParentId === null ? "" : String(currentParentId));
7163
7939
  if (search) params.set("search", search);
7164
7940
  if (typeFilter) params.set("type", typeFilter);
7165
7941
  try {
@@ -7174,11 +7950,33 @@ function MediaLibraryPage() {
7174
7950
  } finally {
7175
7951
  setLoading(false);
7176
7952
  }
7177
- }, [page, search, typeFilter]);
7178
- (0, import_react37.useEffect)(() => {
7953
+ }, [page, search, typeFilter, currentParentId, sortField, sortOrder]);
7954
+ (0, import_react38.useEffect)(() => {
7179
7955
  load();
7180
7956
  }, [load]);
7181
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
+ };
7182
7980
  const handleUpload = async (e) => {
7183
7981
  const file = e.target.files?.[0];
7184
7982
  if (!file) return;
@@ -7186,6 +7984,7 @@ function MediaLibraryPage() {
7186
7984
  try {
7187
7985
  const formData = new FormData();
7188
7986
  formData.append("file", file);
7987
+ if (currentParentId != null) formData.append("parentId", String(currentParentId));
7189
7988
  const uploadRes = await fetch("/api/upload", { method: "POST", body: formData });
7190
7989
  const uploadJson = await uploadRes.json();
7191
7990
  if (!uploadRes.ok) throw new Error(uploadJson.error || "Upload failed");
@@ -7195,69 +7994,134 @@ function MediaLibraryPage() {
7195
7994
  method: "POST",
7196
7995
  headers: { "Content-Type": "application/json" },
7197
7996
  body: JSON.stringify({
7997
+ kind: "file",
7198
7998
  filename: file.name,
7199
7999
  url: filePath.startsWith("http") ? filePath : filePath,
7200
8000
  mimeType: file.type || "application/octet-stream",
7201
8001
  size: file.size,
7202
8002
  alt: null,
7203
- isPublic: false
8003
+ isPublic: false,
8004
+ parentId: currentParentId
7204
8005
  })
7205
8006
  });
7206
8007
  if (!createRes.ok) throw new Error("Failed to create media record");
7207
- import_sonner5.toast.success("File uploaded");
8008
+ import_sonner6.toast.success("File uploaded");
7208
8009
  load();
7209
8010
  } catch (err) {
7210
- import_sonner5.toast.error(err instanceof Error ? err.message : "Upload failed");
8011
+ import_sonner6.toast.error(err instanceof Error ? err.message : "Upload failed");
7211
8012
  } finally {
7212
8013
  setUploading(false);
7213
8014
  e.target.value = "";
7214
8015
  }
7215
8016
  };
7216
- const handleDelete = async (id) => {
7217
- 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
+ }
7218
8023
  try {
7219
- const res = await fetch(`/api/media/${id}`, { method: "DELETE" });
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) => {
8060
+ try {
8061
+ const res = await fetch(`/api/media/${item.id}`, { method: "DELETE" });
7220
8062
  if (!res.ok) throw new Error("Delete failed");
7221
- import_sonner5.toast.success("Deleted");
8063
+ import_sonner6.toast.success("Deleted");
8064
+ setDeleteTarget(null);
7222
8065
  load();
7223
8066
  } catch {
7224
- import_sonner5.toast.error("Delete failed");
8067
+ import_sonner6.toast.error("Delete failed");
7225
8068
  }
7226
8069
  };
7227
8070
  const handleSaveEdit = async () => {
7228
8071
  if (!editModal) return;
7229
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
+ }
7230
8079
  const res = await fetch(`/api/media/${editModal.id}`, {
7231
8080
  method: "PUT",
7232
8081
  headers: { "Content-Type": "application/json" },
7233
- body: JSON.stringify({ alt: editAlt || null, isPublic: editPublic })
8082
+ body: JSON.stringify(body)
7234
8083
  });
7235
8084
  if (!res.ok) throw new Error("Update failed");
7236
- import_sonner5.toast.success("Updated");
8085
+ import_sonner6.toast.success("Updated");
7237
8086
  setEditModal(null);
7238
8087
  load();
7239
8088
  } catch {
7240
- import_sonner5.toast.error("Update failed");
8089
+ import_sonner6.toast.error("Update failed");
7241
8090
  }
7242
8091
  };
7243
8092
  const copyUrl = (url) => {
7244
8093
  const full = url.startsWith("http") ? url : `${typeof window !== "undefined" ? window.location.origin : ""}${url}`;
7245
8094
  navigator.clipboard.writeText(full);
7246
- import_sonner5.toast.success("URL copied");
8095
+ import_sonner6.toast.success("URL copied");
7247
8096
  };
7248
8097
  const openEdit = (item) => {
7249
8098
  setEditModal(item);
7250
8099
  setEditAlt(item.alt || "");
7251
8100
  setEditPublic(item.isPublic);
8101
+ setEditFilename(item.filename);
7252
8102
  };
7253
- const grouped = groupByMonth(data);
7254
- 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]);
7255
8111
  return /* @__PURE__ */ (0, import_jsx_runtime53.jsxs)("div", { className: "min-w-0 rounded-lg bg-white shadow-md", children: [
7256
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: [
7257
8113
  /* @__PURE__ */ (0, import_jsx_runtime53.jsx)("h1", { className: "text-base font-semibold text-white", children: "Media Library" }),
7258
- /* @__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/." })
7259
8115
  ] }),
7260
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
+ ] }),
7261
8125
  /* @__PURE__ */ (0, import_jsx_runtime53.jsxs)("div", { className: "flex flex-wrap items-center gap-3", children: [
7262
8126
  /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(
7263
8127
  "input",
@@ -7267,7 +8131,7 @@ function MediaLibraryPage() {
7267
8131
  className: "hidden",
7268
8132
  onChange: handleUpload,
7269
8133
  disabled: uploading,
7270
- accept: "image/*,video/*,audio/*,.pdf,.doc,.docx"
8134
+ accept: "image/*,video/*,audio/*,.pdf,.doc,.docx,.zip"
7271
8135
  }
7272
8136
  ),
7273
8137
  /* @__PURE__ */ (0, import_jsx_runtime53.jsxs)(
@@ -7283,11 +8147,15 @@ function MediaLibraryPage() {
7283
8147
  ]
7284
8148
  }
7285
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
+ ] }),
7286
8154
  /* @__PURE__ */ (0, import_jsx_runtime53.jsxs)("div", { className: "flex items-center gap-2 flex-1 min-w-[200px]", children: [
7287
8155
  /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(
7288
8156
  Input,
7289
8157
  {
7290
- placeholder: "Search by filename...",
8158
+ placeholder: "Search by name...",
7291
8159
  value: searchInput,
7292
8160
  onChange: (e) => setSearchInput(e.target.value),
7293
8161
  onKeyDown: (e) => e.key === "Enter" && handleSearch()
@@ -7309,61 +8177,192 @@ function MediaLibraryPage() {
7309
8177
  /* @__PURE__ */ (0, import_jsx_runtime53.jsx)("option", { value: "application", children: "Documents" })
7310
8178
  ]
7311
8179
  }
7312
- )
7313
- ] }),
7314
- 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: [
7315
- /* @__PURE__ */ (0, import_jsx_runtime53.jsx)("h2", { className: "text-sm font-semibold text-gray-500 uppercase tracking-wider mb-3", children: monthLabel }),
7316
- /* @__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)(
7317
- "div",
8180
+ ),
8181
+ /* @__PURE__ */ (0, import_jsx_runtime53.jsxs)(
8182
+ "select",
7318
8183
  {
7319
- className: "border rounded-lg overflow-hidden bg-gray-50 hover:bg-gray-100 transition-colors group",
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
+ },
7320
8192
  children: [
7321
- /* @__PURE__ */ (0, import_jsx_runtime53.jsxs)("div", { className: "aspect-square flex items-center justify-center bg-gray-200 relative", children: [
7322
- isImage(item.mimeType) ? /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(
7323
- "img",
7324
- {
7325
- src: item.url,
7326
- alt: item.alt || item.filename,
7327
- className: "w-full h-full object-cover"
7328
- }
7329
- ) : /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(TypeIcon, { mimeType: item.mimeType }),
7330
- /* @__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: [
7331
- /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(
7332
- Button,
7333
- {
7334
- size: "icon",
7335
- variant: "secondary",
7336
- className: "h-8 w-8",
7337
- onClick: () => copyUrl(item.url),
7338
- children: /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(import_lucide_react29.Copy, { className: "h-3 w-3" })
7339
- }
7340
- ),
7341
- /* @__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" }) }),
7342
- /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(
7343
- Button,
7344
- {
7345
- size: "icon",
7346
- variant: "destructive",
7347
- className: "h-8 w-8",
7348
- onClick: () => handleDelete(item.id),
7349
- children: /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(import_lucide_react29.Trash2, { className: "h-3 w-3" })
7350
- }
7351
- )
7352
- ] })
7353
- ] }),
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
+ ] })
8228
+ ] }),
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)(
8232
+ "div",
8233
+ {
8234
+ className: "border rounded-lg overflow-hidden bg-gray-50 hover:bg-gray-100 transition-colors group",
8235
+ children: [
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
+ ),
7354
8310
  /* @__PURE__ */ (0, import_jsx_runtime53.jsxs)("div", { className: "p-2", children: [
7355
- /* @__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 }),
7356
8312
  /* @__PURE__ */ (0, import_jsx_runtime53.jsxs)("div", { className: "flex items-center justify-between mt-1", children: [
7357
8313
  /* @__PURE__ */ (0, import_jsx_runtime53.jsx)("span", { className: "text-xs text-gray-500", children: formatDate(item.createdAt) }),
7358
- /* @__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) })
7359
8315
  ] }),
7360
- 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
+ )
7361
8326
  ] })
7362
8327
  ]
7363
8328
  },
7364
8329
  item.id
7365
- )) })
7366
- ] }, 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
+ ] }) }),
7367
8366
  totalPages > 1 && /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(Pagination, { className: "mt-6", children: /* @__PURE__ */ (0, import_jsx_runtime53.jsxs)(PaginationContent, { children: [
7368
8367
  /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(PaginationItem, { children: /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(
7369
8368
  PaginationPrevious,
@@ -7385,9 +8384,28 @@ function MediaLibraryPage() {
7385
8384
  ) })
7386
8385
  ] }) })
7387
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
+ ] }) }),
7388
8403
  /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(Dialog, { open: !!editModal, onOpenChange: (open) => !open && setEditModal(null), children: /* @__PURE__ */ (0, import_jsx_runtime53.jsxs)(DialogContent, { children: [
7389
- /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(DialogHeader, { children: /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(DialogTitle, { children: "Edit media" }) }),
7390
- 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: [
7391
8409
  /* @__PURE__ */ (0, import_jsx_runtime53.jsxs)("div", { children: [
7392
8410
  /* @__PURE__ */ (0, import_jsx_runtime53.jsx)("label", { className: "text-sm font-medium", children: "Alt text" }),
7393
8411
  /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(
@@ -7412,20 +8430,37 @@ function MediaLibraryPage() {
7412
8430
  ),
7413
8431
  /* @__PURE__ */ (0, import_jsx_runtime53.jsx)("label", { htmlFor: "edit-public", className: "text-sm", children: "Public (visible on site)" })
7414
8432
  ] })
7415
- ] }),
8433
+ ] }) }),
7416
8434
  /* @__PURE__ */ (0, import_jsx_runtime53.jsxs)(DialogFooter, { children: [
7417
8435
  /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(Button, { variant: "outline", onClick: () => setEditModal(null), children: "Cancel" }),
7418
8436
  /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(Button, { onClick: handleSaveEdit, children: "Save" })
7419
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
+ ] })
7420
8455
  ] }) })
7421
8456
  ] });
7422
8457
  }
7423
8458
 
7424
8459
  // src/admin/pages/PageBuilderPage.tsx
7425
- var import_react38 = require("react");
8460
+ var import_react39 = require("react");
7426
8461
  var import_core = require("@craftjs/core");
7427
8462
  var import_lucide_react30 = require("lucide-react");
7428
- var import_navigation15 = require("next/navigation");
8463
+ var import_navigation17 = require("next/navigation");
7429
8464
 
7430
8465
  // src/theme/registry.ts
7431
8466
  function buildResolver(theme) {
@@ -7450,7 +8485,7 @@ function getCatalog(theme) {
7450
8485
 
7451
8486
  // src/admin/pages/PageBuilderPage.tsx
7452
8487
  var LucideIcons = __toESM(require("lucide-react"), 1);
7453
- var import_react39 = __toESM(require("react"), 1);
8488
+ var import_react40 = __toESM(require("react"), 1);
7454
8489
  var import_jsx_runtime54 = require("react/jsx-runtime");
7455
8490
  function createSelectable(Comp) {
7456
8491
  function SelectableWrapper(props) {
@@ -7495,16 +8530,16 @@ function DraggableCatalogItem({
7495
8530
  Icon: Icon2,
7496
8531
  description
7497
8532
  }) {
7498
- const elRef = (0, import_react38.useRef)(null);
7499
- (0, import_react38.useEffect)(() => {
8533
+ const elRef = (0, import_react39.useRef)(null);
8534
+ (0, import_react39.useEffect)(() => {
7500
8535
  if (!elRef.current) return;
7501
8536
  if (meta.canContainChildren) {
7502
8537
  connectors.create(
7503
8538
  elRef.current,
7504
- 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 })
7505
8540
  );
7506
8541
  } else {
7507
- connectors.create(elRef.current, import_react39.default.createElement(Comp, meta.defaultProps));
8542
+ connectors.create(elRef.current, import_react40.default.createElement(Comp, meta.defaultProps));
7508
8543
  }
7509
8544
  }, [connectors, Comp, meta.defaultProps, meta.name, meta.canContainChildren]);
7510
8545
  return /* @__PURE__ */ (0, import_jsx_runtime54.jsxs)(
@@ -7523,7 +8558,7 @@ function DraggableCatalogItem({
7523
8558
  function ComponentPickerContent({ theme, resolver }) {
7524
8559
  const { connectors } = (0, import_core.useEditor)();
7525
8560
  const catalog = getCatalog(theme);
7526
- const [collapsed, setCollapsed] = (0, import_react38.useState)({});
8561
+ const [collapsed, setCollapsed] = (0, import_react39.useState)({});
7527
8562
  const toggleCategory = (cat) => {
7528
8563
  setCollapsed((prev) => ({ ...prev, [cat]: !prev[cat] }));
7529
8564
  };
@@ -7728,7 +8763,7 @@ function LayersPanelContent() {
7728
8763
  nodes: state.nodes,
7729
8764
  selectedSet: state.events.selected
7730
8765
  }));
7731
- const [expanded, setExpanded] = (0, import_react38.useState)({});
8766
+ const [expanded, setExpanded] = (0, import_react39.useState)({});
7732
8767
  const nodeMap = nodes || {};
7733
8768
  const rootId = (() => {
7734
8769
  const ids = Object.keys(nodeMap);
@@ -7850,10 +8885,10 @@ function CollapsibleSection({
7850
8885
  ] });
7851
8886
  }
7852
8887
  function RightSidebar({ theme, resolver, activeTab, setActiveTab, seoProps }) {
7853
- const [componentsOpen, setComponentsOpen] = (0, import_react38.useState)(true);
7854
- const [propertiesOpen, setPropertiesOpen] = (0, import_react38.useState)(true);
7855
- const [layoutOpen, setLayoutOpen] = (0, import_react38.useState)(true);
7856
- 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);
7857
8892
  return /* @__PURE__ */ (0, import_jsx_runtime54.jsxs)("div", { className: "flex flex-col flex-1 overflow-hidden", children: [
7858
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)(
7859
8894
  "button",
@@ -7921,7 +8956,7 @@ function SaveButton({
7921
8956
  className
7922
8957
  }) {
7923
8958
  const { query } = (0, import_core.useEditor)();
7924
- const [saving, setSaving] = (0, import_react38.useState)(false);
8959
+ const [saving, setSaving] = (0, import_react39.useState)(false);
7925
8960
  const handleSave = async () => {
7926
8961
  setSaving(true);
7927
8962
  try {
@@ -7993,22 +9028,22 @@ function SaveButton({
7993
9028
  );
7994
9029
  }
7995
9030
  function PageBuilderPage({ pageId }) {
7996
- const { theme } = (0, import_react38.useContext)(AdminConfigContext);
7997
- const router = (0, import_navigation15.useRouter)();
7998
- const [title, setTitle] = (0, import_react38.useState)("");
7999
- const [slug, setSlug] = (0, import_react38.useState)("");
8000
- const [published, setPublished] = (0, import_react38.useState)(false);
8001
- const [initialContent, setInitialContent] = (0, import_react38.useState)(null);
8002
- const [loading, setLoading] = (0, import_react38.useState)(!!pageId);
8003
- const [rightTab, setRightTab] = (0, import_react38.useState)("designer");
8004
- const [seoTitle, setSeoTitle] = (0, import_react38.useState)("");
8005
- const [seoDescription, setSeoDescription] = (0, import_react38.useState)("");
8006
- const [seoKeywords, setSeoKeywords] = (0, import_react38.useState)("");
8007
- const [seoOgTitle, setSeoOgTitle] = (0, import_react38.useState)("");
8008
- const [seoOgDescription, setSeoOgDescription] = (0, import_react38.useState)("");
8009
- const [seoOgImage, setSeoOgImage] = (0, import_react38.useState)("");
8010
- const [pageSeoId, setPageSeoId] = (0, import_react38.useState)(null);
8011
- (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)(() => {
8012
9047
  if (!pageId) {
8013
9048
  setInitialContent(null);
8014
9049
  setPageSeoId(null);
@@ -8037,7 +9072,7 @@ function PageBuilderPage({ pageId }) {
8037
9072
  }
8038
9073
  }).finally(() => setLoading(false));
8039
9074
  }, [pageId]);
8040
- (0, import_react38.useEffect)(() => {
9075
+ (0, import_react39.useEffect)(() => {
8041
9076
  if (title && !slug) {
8042
9077
  setSlug(
8043
9078
  title.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/(^-|-$)/g, "")
@@ -8082,19 +9117,49 @@ function PageBuilderPage({ pageId }) {
8082
9117
  onSaved: (id) => {
8083
9118
  if (!pageId) router.replace(`/admin/pages/${id}`);
8084
9119
  },
8085
- 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",
8086
9138
  children: [
8087
9139
  /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(import_lucide_react30.Save, { className: "h-4 w-4 mr-1" }),
8088
9140
  " Save"
8089
9141
  ]
8090
9142
  }
8091
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
+ ),
8092
9157
  /* @__PURE__ */ (0, import_jsx_runtime54.jsxs)(
8093
9158
  Button,
8094
9159
  {
8095
9160
  variant: "outline",
8096
9161
  size: "sm",
8097
- 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",
8098
9163
  onClick: () => router.push("/admin/pages"),
8099
9164
  children: [
8100
9165
  /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(import_lucide_react30.X, { className: "h-4 w-4 mr-1" }),
@@ -8155,7 +9220,7 @@ function PageBuilderPage({ pageId }) {
8155
9220
  }
8156
9221
 
8157
9222
  // src/admin/pages/PluginsPage.tsx
8158
- var import_react40 = require("react");
9223
+ var import_react41 = require("react");
8159
9224
  var import_lucide_react32 = require("lucide-react");
8160
9225
 
8161
9226
  // src/lib/email-recipients.ts
@@ -8203,7 +9268,7 @@ var Checkbox = React19.forwardRef(({ className, ...props }, ref) => /* @__PURE__
8203
9268
  Checkbox.displayName = CheckboxPrimitive.Root.displayName;
8204
9269
 
8205
9270
  // src/admin/pages/PluginsPage.tsx
8206
- var import_sonner6 = require("sonner");
9271
+ var import_sonner7 = require("sonner");
8207
9272
  var import_jsx_runtime56 = require("react/jsx-runtime");
8208
9273
  function normalizeChatMode(raw) {
8209
9274
  if (raw === "external" || raw === "llm") return raw;
@@ -8269,7 +9334,7 @@ function EmailRecipientTags({
8269
9334
  onChange,
8270
9335
  placeholder
8271
9336
  }) {
8272
- const [draft, setDraft] = (0, import_react40.useState)("");
9337
+ const [draft, setDraft] = (0, import_react41.useState)("");
8273
9338
  const commitDraft = () => {
8274
9339
  const parts = splitInputToEmails(draft);
8275
9340
  if (!parts.length) return;
@@ -8345,36 +9410,36 @@ function PluginSettingsPanel({
8345
9410
  const isEmail = settingsGroup === "email";
8346
9411
  const isErp = settingsGroup === "erp";
8347
9412
  const isSms = settingsGroup === "sms";
8348
- const [enabled, setEnabled] = (0, import_react40.useState)(true);
8349
- const [botName, setBotName] = (0, import_react40.useState)("");
8350
- const [icon, setIcon] = (0, import_react40.useState)("");
8351
- const [iconImageUrl, setIconImageUrl] = (0, import_react40.useState)("");
8352
- const [iconBackgroundColor, setIconBackgroundColor] = (0, import_react40.useState)("#6366f1");
8353
- const [headerColor, setHeaderColor] = (0, import_react40.useState)("#6366f1");
8354
- const [salesTeamEmails, setSalesTeamEmails] = (0, import_react40.useState)([]);
8355
- const [fulfilmentTeamEmails, setFulfilmentTeamEmails] = (0, import_react40.useState)([]);
8356
- const [crmEmails, setCrmEmails] = (0, import_react40.useState)([]);
8357
- const [logoUrl, setLogoUrl] = (0, import_react40.useState)("");
8358
- const [companyName, setCompanyName] = (0, import_react40.useState)("");
8359
- const [supportEmail, setSupportEmail] = (0, import_react40.useState)("");
8360
- const [supportPhone, setSupportPhone] = (0, import_react40.useState)("");
8361
- const [followUsTitle, setFollowUsTitle] = (0, import_react40.useState)("Follow Us");
8362
- const [socialLinkRows, setSocialLinkRows] = (0, import_react40.useState)([{ ...EMPTY_SOCIAL_ROW }]);
8363
- const [footerDisclaimer, setFooterDisclaimer] = (0, import_react40.useState)("");
8364
- const [chatMode, setChatMode] = (0, import_react40.useState)("whatsapp");
8365
- const [whatsappPhone, setWhatsappPhone] = (0, import_react40.useState)("");
8366
- const [externalChatSnippet, setExternalChatSnippet] = (0, import_react40.useState)("");
8367
- const [erpPipelineName, setErpPipelineName] = (0, import_react40.useState)("");
8368
- const [erpPipelineStageName, setErpPipelineStageName] = (0, import_react40.useState)("");
8369
- const [erpFormsCatalog, setErpFormsCatalog] = (0, import_react40.useState)([]);
8370
- const [erpOpportunityFormIds, setErpOpportunityFormIds] = (0, import_react40.useState)([]);
8371
- const [erpOpportunityIdsKeyPresent, setErpOpportunityIdsKeyPresent] = (0, import_react40.useState)(false);
8372
- const [smsProviderChoice, setSmsProviderChoice] = (0, import_react40.useState)("auto");
8373
- const [msg91ApiMode, setMsg91ApiMode] = (0, import_react40.useState)("auto");
8374
- const [smsTplItems, setSmsTplItems] = (0, import_react40.useState)([]);
8375
- const [loading, setLoading] = (0, import_react40.useState)(true);
8376
- const [saving, setSaving] = (0, import_react40.useState)(false);
8377
- (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)(() => {
8378
9443
  setLoading(true);
8379
9444
  fetch(`/api/settings/${settingsGroup}`).then((r) => r.ok ? r.json() : {}).then(async (data) => {
8380
9445
  setEnabled(data.enabled !== "false");
@@ -8431,7 +9496,7 @@ function PluginSettingsPanel({
8431
9496
  }
8432
9497
  }).finally(() => setLoading(false));
8433
9498
  }, [settingsGroup, isLlm, isEmail, isErp, isSms]);
8434
- (0, import_react40.useEffect)(() => {
9499
+ (0, import_react41.useEffect)(() => {
8435
9500
  if (!isErp || loading) return;
8436
9501
  fetch("/api/forms?limit=500&sortField=name&sortOrder=asc").then((r) => r.ok ? r.json() : { data: [] }).then((res) => {
8437
9502
  const rows = (res.data ?? []).map((f) => ({
@@ -8515,10 +9580,10 @@ function PluginSettingsPanel({
8515
9580
  });
8516
9581
  if (!res2.ok) throw new Error();
8517
9582
  }
8518
- import_sonner6.toast.success("Settings saved");
9583
+ import_sonner7.toast.success("Settings saved");
8519
9584
  onSaved?.();
8520
9585
  } catch {
8521
- import_sonner6.toast.error("Failed to save");
9586
+ import_sonner7.toast.error("Failed to save");
8522
9587
  } finally {
8523
9588
  setSaving(false);
8524
9589
  }
@@ -9134,10 +10199,10 @@ function PluginListItem({
9134
10199
  );
9135
10200
  }
9136
10201
  function PluginsPage() {
9137
- const { pluginDescriptors = [] } = (0, import_react40.useContext)(AdminConfigContext);
9138
- const [selectedName, setSelectedName] = (0, import_react40.useState)(null);
9139
- const [enabledMap, setEnabledMap] = (0, import_react40.useState)({});
9140
- (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)(() => {
9141
10206
  pluginDescriptors.forEach((p) => {
9142
10207
  if (!p.settingsGroup) return;
9143
10208
  fetch(`/api/settings/${p.settingsGroup}`).then((r) => r.ok ? r.json() : {}).then(
@@ -9198,8 +10263,8 @@ function PluginsPage() {
9198
10263
  }
9199
10264
 
9200
10265
  // src/admin/pages/BrandEditPage.tsx
9201
- var import_react41 = require("react");
9202
- var import_navigation16 = require("next/navigation");
10266
+ var import_react42 = require("react");
10267
+ var import_navigation18 = require("next/navigation");
9203
10268
  var import_lucide_react33 = require("lucide-react");
9204
10269
 
9205
10270
  // src/components/Admin/SeoSection.tsx
@@ -9294,20 +10359,20 @@ async function fetchSeo(seoId) {
9294
10359
  var import_jsx_runtime58 = require("react/jsx-runtime");
9295
10360
  var isCreate = (id) => id === "create";
9296
10361
  function BrandEditPage({ brandId }) {
9297
- const router = (0, import_navigation16.useRouter)();
10362
+ const router = (0, import_navigation18.useRouter)();
9298
10363
  const create = isCreate(brandId);
9299
- const [loading, setLoading] = (0, import_react41.useState)(!create);
9300
- const [saving, setSaving] = (0, import_react41.useState)(false);
9301
- const [errors, setErrors] = (0, import_react41.useState)([]);
9302
- const [name, setName] = (0, import_react41.useState)("");
9303
- const [slug, setSlug] = (0, import_react41.useState)("");
9304
- const [description, setDescription] = (0, import_react41.useState)("");
9305
- const [logo, setLogo] = (0, import_react41.useState)("");
9306
- const [active, setActive] = (0, import_react41.useState)(true);
9307
- const [sortOrder, setSortOrder] = (0, import_react41.useState)(0);
9308
- const [seoId, setSeoId] = (0, import_react41.useState)(null);
9309
- const [seo, setSeo] = (0, import_react41.useState)({ seoTitle: "", seoDescription: "", seoKeywords: "", seoOgTitle: "", seoOgDescription: "", seoOgImage: "" });
9310
- (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)(() => {
9311
10376
  if (create) return;
9312
10377
  let cancelled = false;
9313
10378
  (async () => {
@@ -9387,8 +10452,8 @@ function BrandEditPage({ brandId }) {
9387
10452
  subtitle: create ? "Create a new brand" : "Update brand details",
9388
10453
  closeHref: "/admin/brands",
9389
10454
  menuItems: [
9390
- { label: saving ? "Saving..." : "Save", onClick: handleSave },
9391
- { 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) }
9392
10457
  ]
9393
10458
  }
9394
10459
  ),
@@ -9496,12 +10561,12 @@ function BrandEditPage({ brandId }) {
9496
10561
  }
9497
10562
 
9498
10563
  // src/admin/pages/ProductEditPage.tsx
9499
- var import_react43 = require("react");
9500
- var import_navigation17 = require("next/navigation");
10564
+ var import_react44 = require("react");
10565
+ var import_navigation19 = require("next/navigation");
9501
10566
  var import_lucide_react34 = require("lucide-react");
9502
10567
 
9503
10568
  // src/components/Admin/AttributeFacetNameInput.tsx
9504
- var import_react42 = require("react");
10569
+ var import_react43 = require("react");
9505
10570
  var import_jsx_runtime59 = require("react/jsx-runtime");
9506
10571
  function slugFromName(name) {
9507
10572
  const s = name.toLowerCase().trim().replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "");
@@ -9512,13 +10577,16 @@ function AttributeFacetNameInput({
9512
10577
  onChange,
9513
10578
  inputClassName
9514
10579
  }) {
9515
- const [draft, setDraft] = (0, import_react42.useState)(value);
9516
- const [open, setOpen] = (0, import_react42.useState)(false);
9517
- const [list, setList] = (0, import_react42.useState)([]);
9518
- (0, import_react42.useEffect)(() => {
9519
- setDraft(value);
9520
- }, [value]);
9521
- (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)(() => {
9522
10590
  const q = draft.trim();
9523
10591
  if (!q) {
9524
10592
  setList([]);
@@ -9580,8 +10648,12 @@ function AttributeFacetNameInput({
9580
10648
  setDraft(e.target.value);
9581
10649
  setOpen(true);
9582
10650
  },
9583
- onFocus: () => setOpen(true),
10651
+ onFocus: () => {
10652
+ setOpen(true);
10653
+ isFocusedRef.current = true;
10654
+ },
9584
10655
  onBlur: () => setTimeout(() => {
10656
+ isFocusedRef.current = false;
9585
10657
  setOpen(false);
9586
10658
  onChange(draft.trim());
9587
10659
  }, 200),
@@ -9669,33 +10741,37 @@ function pickOtherMetadata(m) {
9669
10741
  return rest;
9670
10742
  }
9671
10743
  function ProductEditPage({ productId }) {
9672
- const router = (0, import_navigation17.useRouter)();
10744
+ const router = (0, import_navigation19.useRouter)();
9673
10745
  const create = isCreate2(productId);
9674
- const [loading, setLoading] = (0, import_react43.useState)(!create);
9675
- const [saving, setSaving] = (0, import_react43.useState)(false);
9676
- const [errors, setErrors] = (0, import_react43.useState)([]);
9677
- const [collections, setCollections] = (0, import_react43.useState)([]);
9678
- const [brands, setBrands] = (0, import_react43.useState)([]);
9679
- const [categories, setCategories] = (0, import_react43.useState)([]);
9680
- const [name, setName] = (0, import_react43.useState)("");
9681
- const [productSlug, setProductSlug] = (0, import_react43.useState)("");
9682
- const [sku, setSku] = (0, import_react43.useState)("");
9683
- const [hsn, setHsn] = (0, import_react43.useState)("");
9684
- const [collectionId, setCollectionId] = (0, import_react43.useState)(null);
9685
- const [brandId, setBrandId] = (0, import_react43.useState)(null);
9686
- const [categoryId, setCategoryId] = (0, import_react43.useState)(null);
9687
- const [price, setPrice] = (0, import_react43.useState)("");
9688
- const [compareAtPrice, setCompareAtPrice] = (0, import_react43.useState)("");
9689
- const [quantity, setQuantity] = (0, import_react43.useState)(1);
9690
- const [status, setStatus] = (0, import_react43.useState)("draft");
9691
- const [featured, setFeatured] = (0, import_react43.useState)(false);
9692
- const [description, setDescription] = (0, import_react43.useState)("");
9693
- const [images, setImages] = (0, import_react43.useState)([{ url: "", alt: "", isDefault: true }]);
9694
- const [specifications, setSpecifications] = (0, import_react43.useState)([{ key: "", value: "" }]);
9695
- const [otherMetadata, setOtherMetadata] = (0, import_react43.useState)({});
9696
- const [facetRows, setFacetRows] = (0, import_react43.useState)([{ name: "", value: "" }]);
9697
- const [seoId, setSeoId] = (0, import_react43.useState)(null);
9698
- 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)({
9699
10775
  seoTitle: "",
9700
10776
  seoDescription: "",
9701
10777
  seoKeywords: "",
@@ -9703,15 +10779,16 @@ function ProductEditPage({ productId }) {
9703
10779
  seoOgDescription: "",
9704
10780
  seoOgImage: ""
9705
10781
  });
9706
- (0, import_react43.useEffect)(() => {
10782
+ (0, import_react44.useEffect)(() => {
9707
10783
  let cancelled = false;
9708
10784
  (async () => {
9709
10785
  try {
9710
- const [colRes, brandRes, catRes, attrRes] = await Promise.all([
10786
+ const [colRes, brandRes, catRes, attrRes, taxesRes] = await Promise.all([
9711
10787
  fetch("/api/collections?limit=500"),
9712
10788
  fetch("/api/brands?limit=500"),
9713
10789
  fetch("/api/product_categories?limit=500"),
9714
- fetch("/api/attributes?limit=500")
10790
+ fetch("/api/attributes?limit=500"),
10791
+ fetch("/api/taxes?limit=200&sortField=name&sortOrder=asc")
9715
10792
  ]);
9716
10793
  let attrList = [];
9717
10794
  if (!cancelled && colRes.ok) {
@@ -9730,6 +10807,13 @@ function ProductEditPage({ productId }) {
9730
10807
  const d = await attrRes.json();
9731
10808
  if (Array.isArray(d.data)) attrList = d.data;
9732
10809
  }
10810
+ if (!cancelled && taxesRes.ok) {
10811
+ const d = await taxesRes.json();
10812
+ const raw = Array.isArray(d.data) ? d.data : [];
10813
+ setTaxMasterList(
10814
+ raw.filter((t) => t.active !== false && t.deleted !== true)
10815
+ );
10816
+ }
9733
10817
  if (create) {
9734
10818
  if (!cancelled) {
9735
10819
  setProductSlug("");
@@ -9745,6 +10829,8 @@ function ProductEditPage({ productId }) {
9745
10829
  setProductSlug(typeof product.slug === "string" ? product.slug : "");
9746
10830
  setSku(product.sku ?? "");
9747
10831
  setHsn(product.hsn ?? "");
10832
+ setUom(product.uom != null ? String(product.uom) : "");
10833
+ setProductType(product.type === "service" ? "service" : "product");
9748
10834
  setCollectionId(product.collectionId ?? null);
9749
10835
  setBrandId(product.brandId ?? null);
9750
10836
  setCategoryId(product.categoryId ?? null);
@@ -9775,6 +10861,19 @@ function ProductEditPage({ productId }) {
9775
10861
  const seoData = await fetchSeo(product.seoId);
9776
10862
  if (!cancelled) setSeo(seoData);
9777
10863
  }
10864
+ const ptRes = await fetch(`/api/product_taxes?productId=${productId}&limit=100`);
10865
+ if (ptRes.ok && !cancelled) {
10866
+ const ptData = await ptRes.json();
10867
+ const pts = Array.isArray(ptData.data) ? ptData.data : [];
10868
+ if (pts.length > 0) {
10869
+ setTaxRows(
10870
+ pts.map((p) => ({
10871
+ taxId: p.taxId,
10872
+ rate: p.rate != null && p.rate !== "" ? String(p.rate) : ""
10873
+ }))
10874
+ );
10875
+ } else if (!cancelled) setTaxRows([{ taxId: "", rate: "" }]);
10876
+ }
9778
10877
  const paRes = await fetch(`/api/product_attributes?productId=${productId}&limit=100`);
9779
10878
  if (paRes.ok && !cancelled) {
9780
10879
  const paData = await paRes.json();
@@ -9798,7 +10897,7 @@ function ProductEditPage({ productId }) {
9798
10897
  cancelled = true;
9799
10898
  };
9800
10899
  }, [productId, create]);
9801
- (0, import_react43.useEffect)(() => {
10900
+ (0, import_react44.useEffect)(() => {
9802
10901
  if (!create || !name.trim() || productSlug.trim()) return;
9803
10902
  setProductSlug(
9804
10903
  name.trim().toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/(^-|-$)/g, "")
@@ -9823,6 +10922,8 @@ function ProductEditPage({ productId }) {
9823
10922
  name: name.trim(),
9824
10923
  sku: sku.trim() || null,
9825
10924
  hsn: hsn.trim() || null,
10925
+ uom: uom.trim() || null,
10926
+ type: productType,
9826
10927
  collectionId: collectionId || null,
9827
10928
  brandId: brandId || null,
9828
10929
  categoryId: categoryId || null,
@@ -9919,6 +11020,55 @@ function ProductEditPage({ productId }) {
9919
11020
  });
9920
11021
  }
9921
11022
  }
11023
+ const parseTaxRate = (s) => {
11024
+ const t = s.trim();
11025
+ if (!t) return null;
11026
+ const n = Number(t);
11027
+ return Number.isFinite(n) ? n : null;
11028
+ };
11029
+ const ratesDiffer = (a, b) => {
11030
+ if (a == null && b == null) return false;
11031
+ if (a == null || b == null) return true;
11032
+ return Math.abs(a - b) > 1e-6;
11033
+ };
11034
+ const wantedTax = /* @__PURE__ */ new Map();
11035
+ for (const row of taxRows) {
11036
+ if (row.taxId === "") continue;
11037
+ wantedTax.set(row.taxId, parseTaxRate(row.rate));
11038
+ }
11039
+ const ptListRes = await fetch(`/api/product_taxes?productId=${savedId}&limit=200`);
11040
+ const ptListData = ptListRes.ok ? await ptListRes.json() : { data: [] };
11041
+ const existingPt = Array.isArray(ptListData.data) ? ptListData.data : [];
11042
+ for (const ep of existingPt) {
11043
+ if (!wantedTax.has(ep.taxId)) {
11044
+ await fetch(`/api/product_taxes/${ep.id}`, { method: "DELETE" });
11045
+ }
11046
+ }
11047
+ const survivors = existingPt.filter((ep) => wantedTax.has(ep.taxId));
11048
+ for (const [taxId, rate] of wantedTax) {
11049
+ const ep = survivors.find((e) => e.taxId === taxId);
11050
+ if (!ep) {
11051
+ await fetch("/api/product_taxes", {
11052
+ method: "POST",
11053
+ headers: { "Content-Type": "application/json" },
11054
+ body: JSON.stringify({
11055
+ productId: Number(savedId),
11056
+ taxId,
11057
+ rate
11058
+ })
11059
+ });
11060
+ } else {
11061
+ const existingRate = ep.rate == null || String(ep.rate).trim() === "" ? null : Number(ep.rate);
11062
+ const er = Number.isFinite(existingRate) ? existingRate : null;
11063
+ if (ratesDiffer(er, rate)) {
11064
+ await fetch(`/api/product_taxes/${ep.id}`, {
11065
+ method: "PUT",
11066
+ headers: { "Content-Type": "application/json" },
11067
+ body: JSON.stringify({ rate })
11068
+ });
11069
+ }
11070
+ }
11071
+ }
9922
11072
  router.push("/admin/products");
9923
11073
  } catch {
9924
11074
  setErrors(["Failed to save"]);
@@ -9936,6 +11086,18 @@ function ProductEditPage({ productId }) {
9936
11086
  const addFacet = () => setFacetRows((prev) => [...prev, { name: "", value: "" }]);
9937
11087
  const removeFacet = (i) => setFacetRows((prev) => prev.length <= 1 ? prev : prev.filter((_, j) => j !== i));
9938
11088
  const setFacet = (i, field, value) => setFacetRows((prev) => prev.map((row, j) => j === i ? { ...row, [field]: value } : row));
11089
+ const addTaxRow = () => setTaxRows((prev) => [...prev, { taxId: "", rate: "" }]);
11090
+ const removeTaxRow = (i) => setTaxRows((prev) => prev.length <= 1 ? prev : prev.filter((_, j) => j !== i));
11091
+ const setTaxRow = (i, patch) => setTaxRows((prev) => prev.map((row, j) => j === i ? { ...row, ...patch } : row));
11092
+ const taxesForSelect = (rowIndex) => {
11093
+ const row = taxRows[rowIndex];
11094
+ const selectedElsewhere = new Set(
11095
+ taxRows.map((r, j) => j !== rowIndex && r.taxId !== "" ? r.taxId : null).filter((x) => x != null)
11096
+ );
11097
+ return taxMasterList.filter(
11098
+ (t) => !selectedElsewhere.has(t.id) || row && row.taxId !== "" && t.id === row.taxId
11099
+ );
11100
+ };
9939
11101
  if (loading) {
9940
11102
  return /* @__PURE__ */ (0, import_jsx_runtime60.jsx)("div", { className: "flex items-center justify-center py-12", children: /* @__PURE__ */ (0, import_jsx_runtime60.jsx)("span", { className: "text-gray-500", children: "Loading..." }) });
9941
11103
  }
@@ -9947,8 +11109,8 @@ function ProductEditPage({ productId }) {
9947
11109
  subtitle: create ? "Create a new product" : "Update product details",
9948
11110
  closeHref: "/admin/products",
9949
11111
  menuItems: [
9950
- { label: saving ? "Saving..." : "Save", onClick: handleSave },
9951
- { 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) }
9952
11114
  ]
9953
11115
  }
9954
11116
  ),
@@ -9980,6 +11142,36 @@ function ProductEditPage({ productId }) {
9980
11142
  /* @__PURE__ */ (0, import_jsx_runtime60.jsx)("input", { type: "text", value: hsn, onChange: (e) => setHsn(e.target.value), className: inputCls })
9981
11143
  ] })
9982
11144
  ] }),
11145
+ /* @__PURE__ */ (0, import_jsx_runtime60.jsxs)("div", { className: "grid grid-cols-2 gap-4", children: [
11146
+ /* @__PURE__ */ (0, import_jsx_runtime60.jsxs)("div", { children: [
11147
+ /* @__PURE__ */ (0, import_jsx_runtime60.jsx)("label", { className: labelCls, children: "UOM" }),
11148
+ /* @__PURE__ */ (0, import_jsx_runtime60.jsx)(
11149
+ "input",
11150
+ {
11151
+ type: "text",
11152
+ value: uom,
11153
+ onChange: (e) => setUom(e.target.value),
11154
+ className: inputCls,
11155
+ placeholder: "e.g. pcs, kg, hrs"
11156
+ }
11157
+ )
11158
+ ] }),
11159
+ /* @__PURE__ */ (0, import_jsx_runtime60.jsxs)("div", { children: [
11160
+ /* @__PURE__ */ (0, import_jsx_runtime60.jsx)("label", { className: labelCls, children: "Product type" }),
11161
+ /* @__PURE__ */ (0, import_jsx_runtime60.jsxs)(
11162
+ "select",
11163
+ {
11164
+ value: productType,
11165
+ onChange: (e) => setProductType(e.target.value === "service" ? "service" : "product"),
11166
+ className: inputCls,
11167
+ children: [
11168
+ /* @__PURE__ */ (0, import_jsx_runtime60.jsx)("option", { value: "product", children: "Product" }),
11169
+ /* @__PURE__ */ (0, import_jsx_runtime60.jsx)("option", { value: "service", children: "Service" })
11170
+ ]
11171
+ }
11172
+ )
11173
+ ] })
11174
+ ] }),
9983
11175
  /* @__PURE__ */ (0, import_jsx_runtime60.jsxs)("div", { className: "grid grid-cols-2 gap-4", children: [
9984
11176
  /* @__PURE__ */ (0, import_jsx_runtime60.jsxs)("div", { children: [
9985
11177
  /* @__PURE__ */ (0, import_jsx_runtime60.jsx)("label", { className: labelCls, children: "Brand" }),
@@ -10030,6 +11222,78 @@ function ProductEditPage({ productId }) {
10030
11222
  ] })
10031
11223
  ] })
10032
11224
  ] }),
11225
+ /* @__PURE__ */ (0, import_jsx_runtime60.jsxs)("section", { children: [
11226
+ /* @__PURE__ */ (0, import_jsx_runtime60.jsx)("h2", { className: "text-xs font-semibold text-gray-400 uppercase tracking-wider mb-2", children: "Taxes" }),
11227
+ /* @__PURE__ */ (0, import_jsx_runtime60.jsx)("p", { className: "text-xs text-gray-500 mb-2", children: "Link taxes for this product. Leave rate empty to use the tax's default rate; set a value to override." }),
11228
+ /* @__PURE__ */ (0, import_jsx_runtime60.jsxs)("div", { className: `${sectionCls} space-y-2`, children: [
11229
+ taxRows.map((row, i) => {
11230
+ const options = taxesForSelect(i);
11231
+ const master = row.taxId !== "" ? taxMasterList.find((t) => t.id === row.taxId) : void 0;
11232
+ const defaultRateHint = master != null ? `Default: ${String(master.rate)}%` : void 0;
11233
+ return /* @__PURE__ */ (0, import_jsx_runtime60.jsxs)("div", { className: "flex flex-wrap gap-2 items-end", children: [
11234
+ /* @__PURE__ */ (0, import_jsx_runtime60.jsxs)("div", { className: "min-w-[160px] flex-1", children: [
11235
+ /* @__PURE__ */ (0, import_jsx_runtime60.jsx)("label", { className: labelCls, children: "Tax" }),
11236
+ /* @__PURE__ */ (0, import_jsx_runtime60.jsxs)(
11237
+ "select",
11238
+ {
11239
+ value: row.taxId === "" ? "" : String(row.taxId),
11240
+ onChange: (e) => {
11241
+ const v = e.target.value;
11242
+ setTaxRow(i, { taxId: v === "" ? "" : Number(v) });
11243
+ },
11244
+ className: inputCls,
11245
+ children: [
11246
+ /* @__PURE__ */ (0, import_jsx_runtime60.jsx)("option", { value: "", children: "\u2014" }),
11247
+ options.map((t) => /* @__PURE__ */ (0, import_jsx_runtime60.jsxs)("option", { value: t.id, children: [
11248
+ t.name,
11249
+ " (",
11250
+ String(t.rate),
11251
+ "%)"
11252
+ ] }, t.id))
11253
+ ]
11254
+ }
11255
+ )
11256
+ ] }),
11257
+ /* @__PURE__ */ (0, import_jsx_runtime60.jsxs)("div", { className: "w-28", children: [
11258
+ /* @__PURE__ */ (0, import_jsx_runtime60.jsx)("label", { className: labelCls, children: "Rate %" }),
11259
+ /* @__PURE__ */ (0, import_jsx_runtime60.jsx)(
11260
+ "input",
11261
+ {
11262
+ type: "text",
11263
+ inputMode: "decimal",
11264
+ value: row.rate,
11265
+ onChange: (e) => setTaxRow(i, { rate: e.target.value }),
11266
+ className: inputCls,
11267
+ placeholder: defaultRateHint ?? "optional",
11268
+ title: defaultRateHint
11269
+ }
11270
+ )
11271
+ ] }),
11272
+ /* @__PURE__ */ (0, import_jsx_runtime60.jsx)(
11273
+ "button",
11274
+ {
11275
+ type: "button",
11276
+ onClick: () => removeTaxRow(i),
11277
+ className: "p-2 text-gray-400 hover:text-red-600 rounded shrink-0 mb-0.5",
11278
+ children: /* @__PURE__ */ (0, import_jsx_runtime60.jsx)(import_lucide_react34.Trash2, { className: "h-4 w-4" })
11279
+ }
11280
+ )
11281
+ ] }, i);
11282
+ }),
11283
+ /* @__PURE__ */ (0, import_jsx_runtime60.jsxs)(
11284
+ "button",
11285
+ {
11286
+ type: "button",
11287
+ onClick: addTaxRow,
11288
+ className: "inline-flex items-center gap-1 rounded border border-gray-300 bg-white px-2 py-1.5 text-xs font-medium text-gray-700 hover:bg-gray-50",
11289
+ children: [
11290
+ /* @__PURE__ */ (0, import_jsx_runtime60.jsx)(import_lucide_react34.Plus, { className: "h-3.5 w-3.5" }),
11291
+ " Add tax"
11292
+ ]
11293
+ }
11294
+ )
11295
+ ] })
11296
+ ] }),
10033
11297
  /* @__PURE__ */ (0, import_jsx_runtime60.jsxs)("section", { children: [
10034
11298
  /* @__PURE__ */ (0, import_jsx_runtime60.jsx)("h2", { className: "text-xs font-semibold text-gray-400 uppercase tracking-wider mb-2", children: "Attributes (facets)" }),
10035
11299
  /* @__PURE__ */ (0, import_jsx_runtime60.jsx)("p", { className: "text-xs text-gray-500 mb-2", children: "Search existing attributes or create new ones (like blog categories). Value on the right." }),
@@ -10164,8 +11428,8 @@ function ProductEditPage({ productId }) {
10164
11428
  }
10165
11429
 
10166
11430
  // src/admin/pages/CollectionEditPage.tsx
10167
- var import_react44 = require("react");
10168
- var import_navigation18 = require("next/navigation");
11431
+ var import_react45 = require("react");
11432
+ var import_navigation20 = require("next/navigation");
10169
11433
  var import_lucide_react35 = require("lucide-react");
10170
11434
  var import_jsx_runtime61 = require("react/jsx-runtime");
10171
11435
  var isCreate3 = (id) => id === "create";
@@ -10175,29 +11439,29 @@ var sectionCls2 = "min-w-0 overflow-hidden border border-gray-200 rounded-lg p-4
10175
11439
  var labelCls2 = "block text-xs font-medium text-gray-600 mb-1";
10176
11440
  var inputCls2 = "w-full rounded-md border border-gray-300 px-2 py-1.5 text-sm";
10177
11441
  function CollectionEditPage({ collectionId }) {
10178
- const router = (0, import_navigation18.useRouter)();
11442
+ const router = (0, import_navigation20.useRouter)();
10179
11443
  const create = isCreate3(collectionId);
10180
- const [loading, setLoading] = (0, import_react44.useState)(!create);
10181
- const [saving, setSaving] = (0, import_react44.useState)(false);
10182
- const [errors, setErrors] = (0, import_react44.useState)([]);
10183
- const [categories, setCategories] = (0, import_react44.useState)([]);
10184
- const [brands, setBrands] = (0, import_react44.useState)([]);
10185
- const [name, setName] = (0, import_react44.useState)("");
10186
- const [slug, setSlug] = (0, import_react44.useState)("");
10187
- const [hsn, setHsn] = (0, import_react44.useState)("");
10188
- const [categoryId, setCategoryId] = (0, import_react44.useState)(null);
10189
- const [brandId, setBrandId] = (0, import_react44.useState)(null);
10190
- const [description, setDescription] = (0, import_react44.useState)("");
10191
- const [image, setImage] = (0, import_react44.useState)("");
10192
- const [active, setActive] = (0, import_react44.useState)(true);
10193
- const [sortOrder, setSortOrder] = (0, import_react44.useState)(0);
10194
- const [advancedOpen, setAdvancedOpen] = (0, import_react44.useState)(false);
10195
- const [heroSlides, setHeroSlides] = (0, import_react44.useState)([emptySlide()]);
10196
- const [variants, setVariants] = (0, import_react44.useState)([emptyVariant()]);
10197
- const [experienceDescription, setExperienceDescription] = (0, import_react44.useState)("");
10198
- const [brochureUrl, setBrochureUrl] = (0, import_react44.useState)("");
10199
- const [seoId, setSeoId] = (0, import_react44.useState)(null);
10200
- 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)({
10201
11465
  seoTitle: "",
10202
11466
  seoDescription: "",
10203
11467
  seoKeywords: "",
@@ -10205,7 +11469,7 @@ function CollectionEditPage({ collectionId }) {
10205
11469
  seoOgDescription: "",
10206
11470
  seoOgImage: ""
10207
11471
  });
10208
- (0, import_react44.useEffect)(() => {
11472
+ (0, import_react45.useEffect)(() => {
10209
11473
  let cancelled = false;
10210
11474
  (async () => {
10211
11475
  try {
@@ -10378,8 +11642,8 @@ function CollectionEditPage({ collectionId }) {
10378
11642
  subtitle: create ? "Create a new collection" : "Update collection and page content",
10379
11643
  closeHref: "/admin/collections",
10380
11644
  menuItems: [
10381
- { label: saving ? "Saving..." : "Save", onClick: handleSave },
10382
- { 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) }
10383
11647
  ]
10384
11648
  }
10385
11649
  ),
@@ -10522,8 +11786,8 @@ function CollectionEditPage({ collectionId }) {
10522
11786
  }
10523
11787
 
10524
11788
  // src/admin/pages/RolesPage.tsx
10525
- var import_react45 = require("react");
10526
- var import_react46 = require("next-auth/react");
11789
+ var import_react46 = require("react");
11790
+ var import_react47 = require("next-auth/react");
10527
11791
  var import_lucide_react36 = require("lucide-react");
10528
11792
 
10529
11793
  // src/auth/permission-entities.ts
@@ -10554,18 +11818,19 @@ function RoleListItem({
10554
11818
  );
10555
11819
  }
10556
11820
  function RolesPage() {
10557
- const { data: session, status } = (0, import_react46.useSession)();
11821
+ const { data: session, status } = (0, import_react47.useSession)();
10558
11822
  const u = session?.user;
10559
11823
  const canManage = !!u?.isRBACAdmin;
10560
- const [entities, setEntities] = (0, import_react45.useState)([]);
10561
- const [groups, setGroups] = (0, import_react45.useState)([]);
10562
- const [selectedId, setSelectedId] = (0, import_react45.useState)(null);
10563
- const [matrix, setMatrix] = (0, import_react45.useState)({});
10564
- const [loading, setLoading] = (0, import_react45.useState)(true);
10565
- const [saving, setSaving] = (0, import_react45.useState)(false);
10566
- const [newName, setNewName] = (0, import_react45.useState)("");
10567
- const [error, setError] = (0, import_react45.useState)(null);
10568
- 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 () => {
10569
11834
  setLoading(true);
10570
11835
  setError(null);
10571
11836
  try {
@@ -10590,11 +11855,11 @@ function RolesPage() {
10590
11855
  setLoading(false);
10591
11856
  }
10592
11857
  }, []);
10593
- (0, import_react45.useEffect)(() => {
11858
+ (0, import_react46.useEffect)(() => {
10594
11859
  if (status === "authenticated" && canManage) load();
10595
11860
  }, [status, canManage, load]);
10596
11861
  const selected = groups.find((g) => g.id === selectedId);
10597
- (0, import_react45.useEffect)(() => {
11862
+ (0, import_react46.useEffect)(() => {
10598
11863
  if (!selected || !entities.length) {
10599
11864
  setMatrix({});
10600
11865
  return;
@@ -10619,6 +11884,45 @@ function RolesPage() {
10619
11884
  [entity]: { ...prev[entity], [key]: !prev[entity][key] }
10620
11885
  }));
10621
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
+ };
10622
11926
  const saveMatrix = async () => {
10623
11927
  if (!selectedId) return;
10624
11928
  setSaving(true);
@@ -10667,7 +11971,6 @@ function RolesPage() {
10667
11971
  };
10668
11972
  const deleteGroup = async () => {
10669
11973
  if (!selectedId || !selected || isSuperAdminGroupName(selected.name)) return;
10670
- if (!confirm(`Delete group "${selected.name}"?`)) return;
10671
11974
  try {
10672
11975
  const res = await fetch(`/api/admin/roles/${selectedId}`, { method: "DELETE" });
10673
11976
  if (!res.ok) {
@@ -10676,6 +11979,7 @@ function RolesPage() {
10676
11979
  return;
10677
11980
  }
10678
11981
  setSelectedId(null);
11982
+ setDeleteRoleOpen(false);
10679
11983
  await load();
10680
11984
  } catch {
10681
11985
  setError("Delete failed");
@@ -10729,18 +12033,33 @@ function RolesPage() {
10729
12033
  /* @__PURE__ */ (0, import_jsx_runtime62.jsx)(import_lucide_react36.Save, { className: "h-3.5 w-3.5" }),
10730
12034
  saving ? "Saving\u2026" : "Save"
10731
12035
  ] }),
10732
- 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: [
10733
12037
  /* @__PURE__ */ (0, import_jsx_runtime62.jsx)(import_lucide_react36.Trash2, { className: "h-3.5 w-3.5" }),
10734
12038
  "Delete role"
10735
12039
  ] })
10736
12040
  ] }),
10737
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: [
10738
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: [
10739
- /* @__PURE__ */ (0, import_jsx_runtime62.jsx)("th", { className: "p-3 text-left font-medium", children: "Resource" }),
10740
- /* @__PURE__ */ (0, import_jsx_runtime62.jsx)("th", { className: "p-2", children: "C" }),
10741
- /* @__PURE__ */ (0, import_jsx_runtime62.jsx)("th", { className: "p-2", children: "R" }),
10742
- /* @__PURE__ */ (0, import_jsx_runtime62.jsx)("th", { className: "p-2", children: "U" }),
10743
- /* @__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
+ ] }) })
10744
12063
  ] }) }),
10745
12064
  /* @__PURE__ */ (0, import_jsx_runtime62.jsx)("tbody", { children: entities.map((entity) => {
10746
12065
  const row = matrix[entity];
@@ -10764,7 +12083,15 @@ function RolesPage() {
10764
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() }),
10765
12084
  /* @__PURE__ */ (0, import_jsx_runtime62.jsx)(Button, { type: "button", onClick: createGroup, children: "Add role" })
10766
12085
  ] })
10767
- ] })
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
+ ] }) })
10768
12095
  ] });
10769
12096
  }
10770
12097
 
@@ -11042,9 +12369,9 @@ var CRUD_CONFIGS = {
11042
12369
  }
11043
12370
  };
11044
12371
  function BlogEditorWrapper({ blogId }) {
11045
- const [blog, setBlog] = (0, import_react47.useState)(null);
11046
- const [loading, setLoading] = (0, import_react47.useState)(!!blogId);
11047
- (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)(() => {
11048
12375
  if (!blogId) return;
11049
12376
  fetch(`/api/blogs/${blogId}`).then((res) => res.ok ? res.json() : null).then((data) => setBlog(data)).finally(() => setLoading(false));
11050
12377
  }, [blogId]);
@@ -11057,10 +12384,10 @@ function BlogEditorWrapper({ blogId }) {
11057
12384
  return /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(BlogEditor, { existingBlog: blog });
11058
12385
  }
11059
12386
  function AdminPageResolver({ slug }) {
11060
- const router = (0, import_navigation19.useRouter)();
11061
- const { customCrudConfigs, storeEnabled } = (0, import_react47.useContext)(AdminConfigContext);
12387
+ const router = (0, import_navigation21.useRouter)();
12388
+ const { customCrudConfigs, storeEnabled } = (0, import_react48.useContext)(AdminConfigContext);
11062
12389
  const key = slug?.[0] || "dashboard";
11063
- (0, import_react47.useEffect)(() => {
12390
+ (0, import_react48.useEffect)(() => {
11064
12391
  if (key === "layout-settings") {
11065
12392
  router.replace("/admin/settings?tab=navbar");
11066
12393
  }
@@ -11120,7 +12447,7 @@ function AdminPageResolver({ slug }) {
11120
12447
  { field: "orderCount", displayName: "Orders" },
11121
12448
  { field: "totalPaid", displayName: "Total paid" }
11122
12449
  ] : crud.columns;
11123
- const extraListParams = (0, import_react47.useMemo)(
12450
+ const extraListParams = (0, import_react48.useMemo)(
11124
12451
  () => isContactsWithStore ? { includeSummary: "1" } : void 0,
11125
12452
  [isContactsWithStore]
11126
12453
  );
@@ -11143,22 +12470,22 @@ function AdminPageResolver({ slug }) {
11143
12470
  }
11144
12471
 
11145
12472
  // src/admin/pages/LayoutSettingsPage.tsx
11146
- var import_react48 = require("react");
12473
+ var import_react49 = require("react");
11147
12474
  var import_lucide_react37 = require("lucide-react");
11148
12475
  var import_jsx_runtime64 = require("react/jsx-runtime");
11149
12476
  function LayoutSettingsPage() {
11150
- const { theme } = (0, import_react48.useContext)(AdminConfigContext);
11151
- const [activeTab, setActiveTab] = (0, import_react48.useState)("navbar");
11152
- 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)({
11153
12480
  logo: "",
11154
12481
  items: [],
11155
12482
  ctaLabel: "",
11156
12483
  ctaUrl: ""
11157
12484
  });
11158
- const [footerValues, setFooterValues] = (0, import_react48.useState)({});
11159
- const [saving, setSaving] = (0, import_react48.useState)(false);
11160
- const [loading, setLoading] = (0, import_react48.useState)(true);
11161
- (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)(() => {
11162
12489
  fetch("/api/settings/theme").then((r) => r.ok ? r.json() : null).then((data) => {
11163
12490
  if (!data) return;
11164
12491
  if (data.navbar) {
@@ -11268,14 +12595,14 @@ var DEFAULT_ADMIN_NAV = [
11268
12595
  ];
11269
12596
 
11270
12597
  // src/admin/CmsProviders.tsx
11271
- var import_react49 = require("next-auth/react");
12598
+ var import_react50 = require("next-auth/react");
11272
12599
  var import_next_themes = require("next-themes");
11273
- var import_sonner7 = require("sonner");
12600
+ var import_sonner8 = require("sonner");
11274
12601
  var import_jsx_runtime65 = require("react/jsx-runtime");
11275
12602
  function CmsProviders({ children }) {
11276
- 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: [
11277
12604
  children,
11278
- /* @__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" })
11279
12606
  ] }) });
11280
12607
  }
11281
12608
  // Annotate the CommonJS export names for ESM import in node: