@infuro/cms-core 1.0.12 → 1.0.15
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 +1326 -544
- package/dist/admin.cjs.map +1 -1
- package/dist/admin.js +1170 -388
- package/dist/admin.js.map +1 -1
- package/dist/api.cjs +1486 -98
- package/dist/api.cjs.map +1 -1
- package/dist/api.d.cts +1 -1
- package/dist/api.d.ts +1 -1
- package/dist/api.js +1485 -97
- package/dist/api.js.map +1 -1
- package/dist/auth.cjs +62 -19
- package/dist/auth.cjs.map +1 -1
- package/dist/auth.d.cts +12 -1
- package/dist/auth.d.ts +12 -1
- package/dist/auth.js +62 -19
- package/dist/auth.js.map +1 -1
- package/dist/{index-JrST6EIC.d.cts → index-BQnqJ7EO.d.cts} +30 -4
- package/dist/{index-C4Yl7js9.d.ts → index-BiagwMjV.d.ts} +30 -4
- package/dist/index.cjs +3305 -936
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +359 -54
- package/dist/index.d.ts +359 -54
- package/dist/index.js +3114 -768
- package/dist/index.js.map +1 -1
- package/dist/migrations/1774600000000-OrderKindParentOrderNumber.ts +36 -0
- package/dist/migrations/1774800000000-OtpChallengesUserPhone.ts +41 -0
- package/dist/migrations/1774900000000-MessageTemplates.ts +39 -0
- package/dist/migrations/1775000000000-ProductUomTypeOrderItemSnapshots.ts +29 -0
- package/package.json +1 -1
package/dist/admin.cjs
CHANGED
|
@@ -384,7 +384,7 @@ var AdminConfigContext = (0, import_react3.createContext)(defaultValue);
|
|
|
384
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==";
|
|
385
385
|
|
|
386
386
|
// src/lib/cms-version.ts
|
|
387
|
-
var CMS_VERSION = true ? "1.0.
|
|
387
|
+
var CMS_VERSION = true ? "1.0.15" : "0.0.0";
|
|
388
388
|
|
|
389
389
|
// src/components/Admin/Sidebar.tsx
|
|
390
390
|
var import_jsx_runtime4 = require("react/jsx-runtime");
|
|
@@ -781,9 +781,7 @@ function useAdminViewSettings() {
|
|
|
781
781
|
}, []);
|
|
782
782
|
}
|
|
783
783
|
function AdminLayoutInner({ children }) {
|
|
784
|
-
const
|
|
785
|
-
const session = sessionState?.data;
|
|
786
|
-
const status = sessionState?.status ?? "loading";
|
|
784
|
+
const { data: session, status } = (0, import_react7.useSession)();
|
|
787
785
|
const router = (0, import_navigation3.useRouter)();
|
|
788
786
|
const pathname = (0, import_navigation3.usePathname)();
|
|
789
787
|
const [loadingTimeout, setLoadingTimeout] = (0, import_react6.useState)(false);
|
|
@@ -6029,6 +6027,8 @@ function OrderDetailPage({ orderId }) {
|
|
|
6029
6027
|
const [order, setOrder] = (0, import_react33.useState)(null);
|
|
6030
6028
|
const [loading, setLoading] = (0, import_react33.useState)(true);
|
|
6031
6029
|
const [error, setError] = (0, import_react33.useState)(null);
|
|
6030
|
+
const [erpEnabled, setErpEnabled] = (0, import_react33.useState)(false);
|
|
6031
|
+
const [reposting, setReposting] = (0, import_react33.useState)(false);
|
|
6032
6032
|
(0, import_react33.useEffect)(() => {
|
|
6033
6033
|
async function load() {
|
|
6034
6034
|
try {
|
|
@@ -6052,6 +6052,39 @@ function OrderDetailPage({ orderId }) {
|
|
|
6052
6052
|
}
|
|
6053
6053
|
load();
|
|
6054
6054
|
}, [orderId]);
|
|
6055
|
+
(0, import_react33.useEffect)(() => {
|
|
6056
|
+
let cancelled = false;
|
|
6057
|
+
(async () => {
|
|
6058
|
+
try {
|
|
6059
|
+
const res = await fetch(`/api/orders/${orderId}/repost-erp`);
|
|
6060
|
+
if (!res.ok) return;
|
|
6061
|
+
const data = await res.json();
|
|
6062
|
+
if (!cancelled) setErpEnabled(data.enabled === true);
|
|
6063
|
+
} catch {
|
|
6064
|
+
}
|
|
6065
|
+
})();
|
|
6066
|
+
return () => {
|
|
6067
|
+
cancelled = true;
|
|
6068
|
+
};
|
|
6069
|
+
}, [orderId]);
|
|
6070
|
+
async function handleRepostToErp() {
|
|
6071
|
+
if (reposting) return;
|
|
6072
|
+
setReposting(true);
|
|
6073
|
+
setError(null);
|
|
6074
|
+
try {
|
|
6075
|
+
const res = await fetch(`/api/orders/${orderId}/repost-erp`, { method: "POST" });
|
|
6076
|
+
if (!res.ok) {
|
|
6077
|
+
const body = await res.json().catch(() => ({}));
|
|
6078
|
+
setError(body.error ?? "Failed to repost to ERP");
|
|
6079
|
+
return;
|
|
6080
|
+
}
|
|
6081
|
+
router.refresh();
|
|
6082
|
+
} catch {
|
|
6083
|
+
setError("Failed to repost to ERP");
|
|
6084
|
+
} finally {
|
|
6085
|
+
setReposting(false);
|
|
6086
|
+
}
|
|
6087
|
+
}
|
|
6055
6088
|
if (loading) {
|
|
6056
6089
|
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..." }) }) });
|
|
6057
6090
|
}
|
|
@@ -6074,7 +6107,8 @@ function OrderDetailPage({ orderId }) {
|
|
|
6074
6107
|
{
|
|
6075
6108
|
title: `Order ${order.orderNumber}`,
|
|
6076
6109
|
subtitle: /* @__PURE__ */ (0, import_jsx_runtime49.jsx)("span", { className: "text-sm text-gray-400", children: formatDateTime(order.createdAt) }),
|
|
6077
|
-
closeHref: "/admin/orders"
|
|
6110
|
+
closeHref: "/admin/orders",
|
|
6111
|
+
menuItems: erpEnabled ? [{ label: reposting ? "Reposting..." : "Repost to ERP", onClick: handleRepostToErp }] : void 0
|
|
6078
6112
|
}
|
|
6079
6113
|
),
|
|
6080
6114
|
/* @__PURE__ */ (0, import_jsx_runtime49.jsx)(
|
|
@@ -6111,9 +6145,86 @@ function OrderDetailPage({ orderId }) {
|
|
|
6111
6145
|
/* @__PURE__ */ (0, import_jsx_runtime49.jsxs)("div", { className: "min-w-0", children: [
|
|
6112
6146
|
/* @__PURE__ */ (0, import_jsx_runtime49.jsx)("dt", { className: "text-gray-500", children: "Total" }),
|
|
6113
6147
|
/* @__PURE__ */ (0, import_jsx_runtime49.jsx)("dd", { className: "font-medium text-gray-900", children: formatMoney(Number(order.total), currency) })
|
|
6148
|
+
] }),
|
|
6149
|
+
(order.orderKind || order.parentOrderId != null) && /* @__PURE__ */ (0, import_jsx_runtime49.jsxs)(import_jsx_runtime49.Fragment, { children: [
|
|
6150
|
+
/* @__PURE__ */ (0, import_jsx_runtime49.jsxs)("div", { className: "min-w-0", children: [
|
|
6151
|
+
/* @__PURE__ */ (0, import_jsx_runtime49.jsx)("dt", { className: "text-gray-500", children: "Kind" }),
|
|
6152
|
+
/* @__PURE__ */ (0, import_jsx_runtime49.jsx)("dd", { className: "font-medium text-gray-900 capitalize", children: order.orderKind ?? "sale" })
|
|
6153
|
+
] }),
|
|
6154
|
+
order.parentOrderId != null && /* @__PURE__ */ (0, import_jsx_runtime49.jsxs)("div", { className: "min-w-0", children: [
|
|
6155
|
+
/* @__PURE__ */ (0, import_jsx_runtime49.jsx)("dt", { className: "text-gray-500", children: "Parent order" }),
|
|
6156
|
+
/* @__PURE__ */ (0, import_jsx_runtime49.jsx)("dd", { className: "font-medium text-gray-900", children: /* @__PURE__ */ (0, import_jsx_runtime49.jsxs)(
|
|
6157
|
+
import_link10.default,
|
|
6158
|
+
{
|
|
6159
|
+
href: `/admin/orders/${order.parentOrderId}/view`,
|
|
6160
|
+
className: "text-blue-600 hover:underline",
|
|
6161
|
+
children: [
|
|
6162
|
+
"#",
|
|
6163
|
+
order.parentOrderId
|
|
6164
|
+
]
|
|
6165
|
+
}
|
|
6166
|
+
) })
|
|
6167
|
+
] })
|
|
6114
6168
|
] })
|
|
6115
6169
|
] }) })
|
|
6116
6170
|
] }),
|
|
6171
|
+
(() => {
|
|
6172
|
+
const fulfillment = order.metadata?.fulfillment;
|
|
6173
|
+
if (!fulfillment?.status && !fulfillment?.trackingId && !(fulfillment?.events && fulfillment.events.length))
|
|
6174
|
+
return null;
|
|
6175
|
+
return /* @__PURE__ */ (0, import_jsx_runtime49.jsxs)("section", { children: [
|
|
6176
|
+
/* @__PURE__ */ (0, import_jsx_runtime49.jsx)("h2", { className: "text-xs font-semibold text-gray-400 uppercase tracking-wider mb-2", children: "Fulfillment" }),
|
|
6177
|
+
/* @__PURE__ */ (0, import_jsx_runtime49.jsxs)("div", { className: "min-w-0 border border-gray-200 rounded-lg p-4 bg-gray-50/50 text-sm space-y-2", children: [
|
|
6178
|
+
fulfillment.status && /* @__PURE__ */ (0, import_jsx_runtime49.jsxs)("p", { children: [
|
|
6179
|
+
/* @__PURE__ */ (0, import_jsx_runtime49.jsx)("span", { className: "text-gray-500", children: "Status: " }),
|
|
6180
|
+
/* @__PURE__ */ (0, import_jsx_runtime49.jsx)("span", { className: "font-medium text-gray-900", children: fulfillment.status })
|
|
6181
|
+
] }),
|
|
6182
|
+
fulfillment.trackingId && /* @__PURE__ */ (0, import_jsx_runtime49.jsxs)("p", { children: [
|
|
6183
|
+
/* @__PURE__ */ (0, import_jsx_runtime49.jsx)("span", { className: "text-gray-500", children: "Tracking: " }),
|
|
6184
|
+
/* @__PURE__ */ (0, import_jsx_runtime49.jsx)("span", { className: "font-mono text-gray-900", children: fulfillment.trackingId })
|
|
6185
|
+
] }),
|
|
6186
|
+
fulfillment.events && fulfillment.events.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime49.jsx)("ul", { className: "mt-3 space-y-2 border-t border-gray-200 pt-3", children: fulfillment.events.map((ev, i) => /* @__PURE__ */ (0, import_jsx_runtime49.jsxs)("li", { className: "text-gray-800", children: [
|
|
6187
|
+
ev.at && /* @__PURE__ */ (0, import_jsx_runtime49.jsx)("span", { className: "text-gray-500 text-xs block", children: ev.at }),
|
|
6188
|
+
ev.label && /* @__PURE__ */ (0, import_jsx_runtime49.jsx)("span", { className: "font-medium", children: ev.label }),
|
|
6189
|
+
ev.detail && /* @__PURE__ */ (0, import_jsx_runtime49.jsx)("span", { className: "text-gray-600 ml-1", children: ev.detail })
|
|
6190
|
+
] }, i)) })
|
|
6191
|
+
] })
|
|
6192
|
+
] });
|
|
6193
|
+
})(),
|
|
6194
|
+
(order.orderKind ?? "sale") === "sale" && /* @__PURE__ */ (0, import_jsx_runtime49.jsxs)("section", { children: [
|
|
6195
|
+
/* @__PURE__ */ (0, import_jsx_runtime49.jsx)("h2", { className: "text-xs font-semibold text-gray-400 uppercase tracking-wider mb-2", children: "Invoice" }),
|
|
6196
|
+
/* @__PURE__ */ (0, import_jsx_runtime49.jsxs)("div", { className: "min-w-0 border border-gray-200 rounded-lg p-4 bg-gray-50/50 text-sm", children: [
|
|
6197
|
+
order.metadata?.invoice?.invoiceNumber && /* @__PURE__ */ (0, import_jsx_runtime49.jsxs)("p", { className: "text-gray-700 mb-2", children: [
|
|
6198
|
+
"#",
|
|
6199
|
+
String((order.metadata?.invoice).invoiceNumber)
|
|
6200
|
+
] }),
|
|
6201
|
+
/* @__PURE__ */ (0, import_jsx_runtime49.jsx)(
|
|
6202
|
+
"a",
|
|
6203
|
+
{
|
|
6204
|
+
href: `/api/orders/${order.id}/invoice`,
|
|
6205
|
+
target: "_blank",
|
|
6206
|
+
rel: "noopener noreferrer",
|
|
6207
|
+
className: "text-blue-600 font-medium hover:underline",
|
|
6208
|
+
children: "Download invoice PDF"
|
|
6209
|
+
}
|
|
6210
|
+
)
|
|
6211
|
+
] })
|
|
6212
|
+
] }),
|
|
6213
|
+
(order.relatedOrders ?? []).length > 0 && /* @__PURE__ */ (0, import_jsx_runtime49.jsxs)("section", { children: [
|
|
6214
|
+
/* @__PURE__ */ (0, import_jsx_runtime49.jsx)("h2", { className: "text-xs font-semibold text-gray-400 uppercase tracking-wider mb-2", children: "Returns & replacements" }),
|
|
6215
|
+
/* @__PURE__ */ (0, import_jsx_runtime49.jsx)("div", { className: "min-w-0 border border-gray-200 rounded-lg overflow-hidden", children: /* @__PURE__ */ (0, import_jsx_runtime49.jsxs)(Table, { children: [
|
|
6216
|
+
/* @__PURE__ */ (0, import_jsx_runtime49.jsx)(TableHeader, { children: /* @__PURE__ */ (0, import_jsx_runtime49.jsxs)(TableRow, { className: "bg-gray-50", children: [
|
|
6217
|
+
/* @__PURE__ */ (0, import_jsx_runtime49.jsx)(TableHead, { className: "font-medium", children: "Number" }),
|
|
6218
|
+
/* @__PURE__ */ (0, import_jsx_runtime49.jsx)(TableHead, { className: "font-medium", children: "Kind" }),
|
|
6219
|
+
/* @__PURE__ */ (0, import_jsx_runtime49.jsx)(TableHead, { className: "font-medium", children: "Status" })
|
|
6220
|
+
] }) }),
|
|
6221
|
+
/* @__PURE__ */ (0, import_jsx_runtime49.jsx)(TableBody, { children: (order.relatedOrders ?? []).map((r) => /* @__PURE__ */ (0, import_jsx_runtime49.jsxs)(TableRow, { children: [
|
|
6222
|
+
/* @__PURE__ */ (0, import_jsx_runtime49.jsx)(TableCell, { children: /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(import_link10.default, { href: `/admin/orders/${r.id}/view`, className: "text-blue-600 hover:underline font-medium", children: r.orderNumber }) }),
|
|
6223
|
+
/* @__PURE__ */ (0, import_jsx_runtime49.jsx)(TableCell, { className: "capitalize", children: r.orderKind ?? "\u2014" }),
|
|
6224
|
+
/* @__PURE__ */ (0, import_jsx_runtime49.jsx)(TableCell, { className: "capitalize", children: r.status ?? "\u2014" })
|
|
6225
|
+
] }, r.id)) })
|
|
6226
|
+
] }) })
|
|
6227
|
+
] }),
|
|
6117
6228
|
/* @__PURE__ */ (0, import_jsx_runtime49.jsxs)("section", { children: [
|
|
6118
6229
|
/* @__PURE__ */ (0, import_jsx_runtime49.jsx)("h2", { className: "text-xs font-semibold text-gray-400 uppercase tracking-wider mb-2", children: "Line items" }),
|
|
6119
6230
|
/* @__PURE__ */ (0, import_jsx_runtime49.jsx)("div", { className: "min-w-0 overflow-x-auto border border-gray-200 rounded-lg", children: /* @__PURE__ */ (0, import_jsx_runtime49.jsxs)(Table, { children: [
|
|
@@ -7836,33 +7947,50 @@ function RightSidebar({ theme, resolver, activeTab, setActiveTab, seoProps }) {
|
|
|
7836
7947
|
] })
|
|
7837
7948
|
] });
|
|
7838
7949
|
}
|
|
7839
|
-
function SaveButton({
|
|
7950
|
+
function SaveButton({
|
|
7951
|
+
pageId,
|
|
7952
|
+
pageData,
|
|
7953
|
+
existingSeoId,
|
|
7954
|
+
onSeoIdChange,
|
|
7955
|
+
onSaved,
|
|
7956
|
+
children,
|
|
7957
|
+
className
|
|
7958
|
+
}) {
|
|
7840
7959
|
const { query } = (0, import_core.useEditor)();
|
|
7841
7960
|
const [saving, setSaving] = (0, import_react38.useState)(false);
|
|
7842
7961
|
const handleSave = async () => {
|
|
7843
7962
|
setSaving(true);
|
|
7844
7963
|
try {
|
|
7845
7964
|
const content = JSON.parse(query.serialize());
|
|
7846
|
-
let
|
|
7847
|
-
const hasSeo = pageData.seoTitle || pageData.seoDescription || pageData.seoKeywords;
|
|
7965
|
+
let resolvedSeoId = existingSeoId;
|
|
7966
|
+
const hasSeo = pageData.seoTitle || pageData.seoDescription || pageData.seoKeywords || pageData.seoOgTitle || pageData.seoOgDescription || pageData.seoOgImage;
|
|
7848
7967
|
if (hasSeo) {
|
|
7849
7968
|
const seoPayload = {
|
|
7850
|
-
title: pageData.seoTitle,
|
|
7851
|
-
description: pageData.seoDescription,
|
|
7852
|
-
keywords: pageData.seoKeywords,
|
|
7853
|
-
ogTitle: pageData.seoOgTitle,
|
|
7854
|
-
ogDescription: pageData.seoOgDescription,
|
|
7855
|
-
ogImage: pageData.seoOgImage,
|
|
7969
|
+
title: pageData.seoTitle || null,
|
|
7970
|
+
description: pageData.seoDescription || null,
|
|
7971
|
+
keywords: pageData.seoKeywords || null,
|
|
7972
|
+
ogTitle: pageData.seoOgTitle || null,
|
|
7973
|
+
ogDescription: pageData.seoOgDescription || null,
|
|
7974
|
+
ogImage: pageData.seoOgImage || null,
|
|
7856
7975
|
slug: pageData.slug
|
|
7857
7976
|
};
|
|
7858
|
-
|
|
7859
|
-
|
|
7860
|
-
|
|
7861
|
-
|
|
7862
|
-
|
|
7863
|
-
|
|
7864
|
-
|
|
7865
|
-
|
|
7977
|
+
if (existingSeoId) {
|
|
7978
|
+
const seoRes = await fetch(`/api/seos/${existingSeoId}`, {
|
|
7979
|
+
method: "PUT",
|
|
7980
|
+
headers: { "Content-Type": "application/json" },
|
|
7981
|
+
body: JSON.stringify(seoPayload)
|
|
7982
|
+
});
|
|
7983
|
+
if (seoRes.ok) resolvedSeoId = existingSeoId;
|
|
7984
|
+
} else {
|
|
7985
|
+
const seoRes = await fetch("/api/seos", {
|
|
7986
|
+
method: "POST",
|
|
7987
|
+
headers: { "Content-Type": "application/json" },
|
|
7988
|
+
body: JSON.stringify(seoPayload)
|
|
7989
|
+
});
|
|
7990
|
+
if (seoRes.ok) {
|
|
7991
|
+
const seoData = await seoRes.json();
|
|
7992
|
+
resolvedSeoId = seoData.id ?? null;
|
|
7993
|
+
}
|
|
7866
7994
|
}
|
|
7867
7995
|
}
|
|
7868
7996
|
const payload = {
|
|
@@ -7871,7 +7999,7 @@ function SaveButton({ pageId, pageData, onSaved, children, className }) {
|
|
|
7871
7999
|
content,
|
|
7872
8000
|
published: pageData.published
|
|
7873
8001
|
};
|
|
7874
|
-
if (
|
|
8002
|
+
if (resolvedSeoId != null) payload.seoId = resolvedSeoId;
|
|
7875
8003
|
const url = pageId ? `/api/pages/${pageId}` : "/api/pages";
|
|
7876
8004
|
const method = pageId ? "PUT" : "POST";
|
|
7877
8005
|
const res = await fetch(url, {
|
|
@@ -7881,6 +8009,8 @@ function SaveButton({ pageId, pageData, onSaved, children, className }) {
|
|
|
7881
8009
|
});
|
|
7882
8010
|
if (res.ok) {
|
|
7883
8011
|
const saved = await res.json();
|
|
8012
|
+
const nextSeo = saved.seoId != null && saved.seoId !== "" ? Number(saved.seoId) : resolvedSeoId;
|
|
8013
|
+
if (Number.isFinite(nextSeo)) onSeoIdChange(nextSeo);
|
|
7884
8014
|
onSaved(saved.id?.toString() || pageId || "");
|
|
7885
8015
|
}
|
|
7886
8016
|
} finally {
|
|
@@ -7913,9 +8043,11 @@ function PageBuilderPage({ pageId }) {
|
|
|
7913
8043
|
const [seoOgTitle, setSeoOgTitle] = (0, import_react38.useState)("");
|
|
7914
8044
|
const [seoOgDescription, setSeoOgDescription] = (0, import_react38.useState)("");
|
|
7915
8045
|
const [seoOgImage, setSeoOgImage] = (0, import_react38.useState)("");
|
|
8046
|
+
const [pageSeoId, setPageSeoId] = (0, import_react38.useState)(null);
|
|
7916
8047
|
(0, import_react38.useEffect)(() => {
|
|
7917
8048
|
if (!pageId) {
|
|
7918
8049
|
setInitialContent(null);
|
|
8050
|
+
setPageSeoId(null);
|
|
7919
8051
|
setLoading(false);
|
|
7920
8052
|
return;
|
|
7921
8053
|
}
|
|
@@ -7924,6 +8056,9 @@ function PageBuilderPage({ pageId }) {
|
|
|
7924
8056
|
setTitle(data.title || "");
|
|
7925
8057
|
setSlug(data.slug || "");
|
|
7926
8058
|
setPublished(data.published || false);
|
|
8059
|
+
setPageSeoId(
|
|
8060
|
+
data.seoId != null && data.seoId !== "" ? Number(data.seoId) : data.seo?.id != null ? Number(data.seo.id) : null
|
|
8061
|
+
);
|
|
7927
8062
|
if (data.content) {
|
|
7928
8063
|
setInitialContent(JSON.stringify(data.content));
|
|
7929
8064
|
}
|
|
@@ -7977,6 +8112,8 @@ function PageBuilderPage({ pageId }) {
|
|
|
7977
8112
|
SaveButton,
|
|
7978
8113
|
{
|
|
7979
8114
|
pageId,
|
|
8115
|
+
existingSeoId: pageSeoId,
|
|
8116
|
+
onSeoIdChange: setPageSeoId,
|
|
7980
8117
|
pageData: { title, slug, published, seoTitle, seoDescription, seoKeywords, seoOgTitle, seoOgDescription, seoOgImage },
|
|
7981
8118
|
onSaved: (id) => {
|
|
7982
8119
|
if (!pageId) router.replace(`/admin/pages/${id}`);
|
|
@@ -8055,7 +8192,7 @@ function PageBuilderPage({ pageId }) {
|
|
|
8055
8192
|
|
|
8056
8193
|
// src/admin/pages/PluginsPage.tsx
|
|
8057
8194
|
var import_react40 = require("react");
|
|
8058
|
-
var
|
|
8195
|
+
var import_lucide_react32 = require("lucide-react");
|
|
8059
8196
|
|
|
8060
8197
|
// src/lib/email-recipients.ts
|
|
8061
8198
|
function parseEmailRecipientsFromConfig(raw) {
|
|
@@ -8076,15 +8213,57 @@ function serializeEmailRecipients(emails) {
|
|
|
8076
8213
|
return JSON.stringify(emails);
|
|
8077
8214
|
}
|
|
8078
8215
|
|
|
8216
|
+
// src/components/ui/checkbox.tsx
|
|
8217
|
+
var React19 = __toESM(require("react"), 1);
|
|
8218
|
+
var CheckboxPrimitive = __toESM(require("@radix-ui/react-checkbox"), 1);
|
|
8219
|
+
var import_lucide_react31 = require("lucide-react");
|
|
8220
|
+
var import_jsx_runtime55 = require("react/jsx-runtime");
|
|
8221
|
+
var Checkbox = React19.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
|
|
8222
|
+
CheckboxPrimitive.Root,
|
|
8223
|
+
{
|
|
8224
|
+
ref,
|
|
8225
|
+
className: cn(
|
|
8226
|
+
"peer h-4 w-4 shrink-0 rounded-sm border border-primary ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 data-[state=checked]:bg-primary data-[state=checked]:text-primary-foreground",
|
|
8227
|
+
className
|
|
8228
|
+
),
|
|
8229
|
+
...props,
|
|
8230
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
|
|
8231
|
+
CheckboxPrimitive.Indicator,
|
|
8232
|
+
{
|
|
8233
|
+
className: cn("flex items-center justify-center text-current"),
|
|
8234
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(import_lucide_react31.Check, { className: "h-4 w-4" })
|
|
8235
|
+
}
|
|
8236
|
+
)
|
|
8237
|
+
}
|
|
8238
|
+
));
|
|
8239
|
+
Checkbox.displayName = CheckboxPrimitive.Root.displayName;
|
|
8240
|
+
|
|
8079
8241
|
// src/admin/pages/PluginsPage.tsx
|
|
8080
8242
|
var import_sonner6 = require("sonner");
|
|
8081
|
-
var
|
|
8243
|
+
var import_jsx_runtime56 = require("react/jsx-runtime");
|
|
8244
|
+
function normalizeChatMode(raw) {
|
|
8245
|
+
if (raw === "external" || raw === "llm") return raw;
|
|
8246
|
+
return "whatsapp";
|
|
8247
|
+
}
|
|
8082
8248
|
var ICON_MAP = {
|
|
8083
|
-
storage:
|
|
8084
|
-
email:
|
|
8085
|
-
payment:
|
|
8086
|
-
llm:
|
|
8249
|
+
storage: import_lucide_react32.HardDrive,
|
|
8250
|
+
email: import_lucide_react32.Mail,
|
|
8251
|
+
payment: import_lucide_react32.CreditCard,
|
|
8252
|
+
llm: import_lucide_react32.MessageCircle,
|
|
8253
|
+
analytics: import_lucide_react32.BarChart3,
|
|
8254
|
+
erp: import_lucide_react32.Building2,
|
|
8255
|
+
sms: import_lucide_react32.Smartphone
|
|
8087
8256
|
};
|
|
8257
|
+
function normalizeSmsProviderChoice(raw) {
|
|
8258
|
+
const x = (raw || "auto").toLowerCase().trim();
|
|
8259
|
+
if (x === "msg91" || x === "twilio" || x === "webhook" || x === "auto") return x;
|
|
8260
|
+
return "auto";
|
|
8261
|
+
}
|
|
8262
|
+
function normalizeMsg91ApiMode(raw) {
|
|
8263
|
+
const x = (raw || "auto").toLowerCase().trim();
|
|
8264
|
+
if (x === "flow" || x === "sendhttp" || x === "auto") return x;
|
|
8265
|
+
return "auto";
|
|
8266
|
+
}
|
|
8088
8267
|
function splitInputToEmails(input) {
|
|
8089
8268
|
return input.split(/[,;]+/).map((s) => s.trim()).filter(Boolean);
|
|
8090
8269
|
}
|
|
@@ -8137,27 +8316,27 @@ function EmailRecipientTags({
|
|
|
8137
8316
|
onChange(next);
|
|
8138
8317
|
setDraft("");
|
|
8139
8318
|
};
|
|
8140
|
-
return /* @__PURE__ */ (0,
|
|
8141
|
-
/* @__PURE__ */ (0,
|
|
8142
|
-
/* @__PURE__ */ (0,
|
|
8319
|
+
return /* @__PURE__ */ (0, import_jsx_runtime56.jsxs)("div", { className: "space-y-1", children: [
|
|
8320
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsx)(Label3, { htmlFor: id, className: "text-sm", children: label }),
|
|
8321
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsxs)(
|
|
8143
8322
|
"div",
|
|
8144
8323
|
{
|
|
8145
8324
|
className: "flex min-h-9 flex-wrap items-center gap-1.5 rounded-md border border-input bg-background px-2 py-1.5 text-sm ring-offset-background focus-within:ring-2 focus-within:ring-ring focus-within:ring-offset-2 dark:border-gray-600",
|
|
8146
8325
|
children: [
|
|
8147
|
-
emails.map((email) => /* @__PURE__ */ (0,
|
|
8148
|
-
/* @__PURE__ */ (0,
|
|
8149
|
-
/* @__PURE__ */ (0,
|
|
8326
|
+
emails.map((email) => /* @__PURE__ */ (0, import_jsx_runtime56.jsxs)(Badge, { variant: "secondary", className: "gap-1 pr-0.5 font-normal", children: [
|
|
8327
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsx)("span", { className: "max-w-[220px] truncate", children: email }),
|
|
8328
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsx)(
|
|
8150
8329
|
"button",
|
|
8151
8330
|
{
|
|
8152
8331
|
type: "button",
|
|
8153
8332
|
className: "rounded p-0.5 hover:bg-muted",
|
|
8154
8333
|
"aria-label": `Remove ${email}`,
|
|
8155
8334
|
onClick: () => onChange(emails.filter((e) => e !== email)),
|
|
8156
|
-
children: /* @__PURE__ */ (0,
|
|
8335
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime56.jsx)(import_lucide_react32.X, { className: "h-3 w-3" })
|
|
8157
8336
|
}
|
|
8158
8337
|
)
|
|
8159
8338
|
] }, email)),
|
|
8160
|
-
/* @__PURE__ */ (0,
|
|
8339
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsx)(
|
|
8161
8340
|
"input",
|
|
8162
8341
|
{
|
|
8163
8342
|
id,
|
|
@@ -8184,14 +8363,14 @@ function EmailRecipientTags({
|
|
|
8184
8363
|
]
|
|
8185
8364
|
}
|
|
8186
8365
|
),
|
|
8187
|
-
/* @__PURE__ */ (0,
|
|
8366
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsx)("p", { className: "text-xs text-gray-500 dark:text-gray-400", children: hint })
|
|
8188
8367
|
] });
|
|
8189
8368
|
}
|
|
8190
8369
|
function PluginIcon({ descriptor, size = "md" }) {
|
|
8191
|
-
const Icon2 = descriptor.icon ? ICON_MAP[descriptor.icon] ??
|
|
8370
|
+
const Icon2 = descriptor.icon ? ICON_MAP[descriptor.icon] ?? import_lucide_react32.Puzzle : import_lucide_react32.Puzzle;
|
|
8192
8371
|
const sizeClass = size === "sm" ? "h-8 w-8" : "h-11 w-11";
|
|
8193
8372
|
const iconClass = size === "sm" ? "h-4 w-4" : "h-5 w-5";
|
|
8194
|
-
return /* @__PURE__ */ (0,
|
|
8373
|
+
return /* @__PURE__ */ (0, import_jsx_runtime56.jsx)("div", { className: `flex shrink-0 items-center justify-center rounded-lg bg-gray-100 text-gray-600 dark:bg-gray-700 dark:text-gray-300 ${sizeClass}`, children: /* @__PURE__ */ (0, import_jsx_runtime56.jsx)(Icon2, { className: iconClass }) });
|
|
8195
8374
|
}
|
|
8196
8375
|
function PluginSettingsPanel({
|
|
8197
8376
|
descriptor,
|
|
@@ -8200,6 +8379,8 @@ function PluginSettingsPanel({
|
|
|
8200
8379
|
const settingsGroup = descriptor.settingsGroup;
|
|
8201
8380
|
const isLlm = settingsGroup === "llm";
|
|
8202
8381
|
const isEmail = settingsGroup === "email";
|
|
8382
|
+
const isErp = settingsGroup === "erp";
|
|
8383
|
+
const isSms = settingsGroup === "sms";
|
|
8203
8384
|
const [enabled, setEnabled] = (0, import_react40.useState)(true);
|
|
8204
8385
|
const [botName, setBotName] = (0, import_react40.useState)("");
|
|
8205
8386
|
const [icon, setIcon] = (0, import_react40.useState)("");
|
|
@@ -8216,18 +8397,59 @@ function PluginSettingsPanel({
|
|
|
8216
8397
|
const [followUsTitle, setFollowUsTitle] = (0, import_react40.useState)("Follow Us");
|
|
8217
8398
|
const [socialLinkRows, setSocialLinkRows] = (0, import_react40.useState)([{ ...EMPTY_SOCIAL_ROW }]);
|
|
8218
8399
|
const [footerDisclaimer, setFooterDisclaimer] = (0, import_react40.useState)("");
|
|
8400
|
+
const [chatMode, setChatMode] = (0, import_react40.useState)("whatsapp");
|
|
8401
|
+
const [whatsappPhone, setWhatsappPhone] = (0, import_react40.useState)("");
|
|
8402
|
+
const [externalChatSnippet, setExternalChatSnippet] = (0, import_react40.useState)("");
|
|
8403
|
+
const [erpPipelineName, setErpPipelineName] = (0, import_react40.useState)("");
|
|
8404
|
+
const [erpPipelineStageName, setErpPipelineStageName] = (0, import_react40.useState)("");
|
|
8405
|
+
const [erpFormsCatalog, setErpFormsCatalog] = (0, import_react40.useState)([]);
|
|
8406
|
+
const [erpOpportunityFormIds, setErpOpportunityFormIds] = (0, import_react40.useState)([]);
|
|
8407
|
+
const [erpOpportunityIdsKeyPresent, setErpOpportunityIdsKeyPresent] = (0, import_react40.useState)(false);
|
|
8408
|
+
const [smsProviderChoice, setSmsProviderChoice] = (0, import_react40.useState)("auto");
|
|
8409
|
+
const [msg91ApiMode, setMsg91ApiMode] = (0, import_react40.useState)("auto");
|
|
8410
|
+
const [smsTplItems, setSmsTplItems] = (0, import_react40.useState)([]);
|
|
8219
8411
|
const [loading, setLoading] = (0, import_react40.useState)(true);
|
|
8220
8412
|
const [saving, setSaving] = (0, import_react40.useState)(false);
|
|
8221
8413
|
(0, import_react40.useEffect)(() => {
|
|
8222
|
-
|
|
8414
|
+
setLoading(true);
|
|
8415
|
+
fetch(`/api/settings/${settingsGroup}`).then((r) => r.ok ? r.json() : {}).then(async (data) => {
|
|
8223
8416
|
setEnabled(data.enabled !== "false");
|
|
8224
8417
|
setBotName(data.botName ?? "");
|
|
8225
8418
|
setIcon(data.icon ?? "");
|
|
8226
8419
|
if (isLlm) {
|
|
8420
|
+
setChatMode(normalizeChatMode(data.chatMode));
|
|
8421
|
+
setWhatsappPhone(data.whatsappPhone ?? "");
|
|
8422
|
+
setExternalChatSnippet(data.externalChatSnippet ?? "");
|
|
8227
8423
|
setIconImageUrl(data.iconImageUrl ?? "");
|
|
8228
8424
|
setIconBackgroundColor(data.iconBackgroundColor ?? "#6366f1");
|
|
8229
8425
|
setHeaderColor(data.headerColor ?? "#6366f1");
|
|
8230
8426
|
}
|
|
8427
|
+
if (isErp) {
|
|
8428
|
+
setErpPipelineName(data.pipelineName ?? data.pipelineId ?? "");
|
|
8429
|
+
setErpPipelineStageName(data.pipelineStageName ?? data.pipelineStageId ?? "");
|
|
8430
|
+
const rawOpp = data.opportunityFormIds;
|
|
8431
|
+
const keyPresent = rawOpp !== void 0 && rawOpp !== null && String(rawOpp).trim() !== "";
|
|
8432
|
+
setErpOpportunityIdsKeyPresent(keyPresent);
|
|
8433
|
+
if (keyPresent) {
|
|
8434
|
+
try {
|
|
8435
|
+
const p = JSON.parse(String(rawOpp));
|
|
8436
|
+
const ids = Array.isArray(p) ? p.map((x) => typeof x === "number" ? x : Number(x)).filter((n) => Number.isInteger(n) && n > 0) : [];
|
|
8437
|
+
setErpOpportunityFormIds([...new Set(ids)]);
|
|
8438
|
+
} catch {
|
|
8439
|
+
setErpOpportunityFormIds([]);
|
|
8440
|
+
}
|
|
8441
|
+
} else {
|
|
8442
|
+
setErpOpportunityFormIds([]);
|
|
8443
|
+
}
|
|
8444
|
+
}
|
|
8445
|
+
if (isSms) {
|
|
8446
|
+
setSmsProviderChoice(normalizeSmsProviderChoice(data.smsProvider ?? data.SMS_PROVIDER));
|
|
8447
|
+
setMsg91ApiMode(normalizeMsg91ApiMode(data.msg91ApiMode));
|
|
8448
|
+
const tr = await fetch("/api/message-templates/sms").then(
|
|
8449
|
+
(r) => r.ok ? r.json() : { items: [] }
|
|
8450
|
+
);
|
|
8451
|
+
setSmsTplItems(tr.items ?? []);
|
|
8452
|
+
}
|
|
8231
8453
|
if (isEmail) {
|
|
8232
8454
|
const sales = parseEmailRecipientsFromConfig(data.salesTeamEmails ?? data.salesTeamEmail);
|
|
8233
8455
|
const fulfil = parseEmailRecipientsFromConfig(data.fulfilmentTeamEmails ?? data.fulfilmentTeamEmail);
|
|
@@ -8244,14 +8466,48 @@ function PluginSettingsPanel({
|
|
|
8244
8466
|
setFooterDisclaimer(data.footerDisclaimer ?? "");
|
|
8245
8467
|
}
|
|
8246
8468
|
}).finally(() => setLoading(false));
|
|
8247
|
-
}, [settingsGroup, isLlm, isEmail]);
|
|
8469
|
+
}, [settingsGroup, isLlm, isEmail, isErp, isSms]);
|
|
8470
|
+
(0, import_react40.useEffect)(() => {
|
|
8471
|
+
if (!isErp || loading) return;
|
|
8472
|
+
fetch("/api/forms?limit=500&sortField=name&sortOrder=asc").then((r) => r.ok ? r.json() : { data: [] }).then((res) => {
|
|
8473
|
+
const rows = (res.data ?? []).map((f) => ({
|
|
8474
|
+
id: typeof f.id === "number" ? f.id : Number(f.id),
|
|
8475
|
+
name: String(f.name ?? "")
|
|
8476
|
+
})).filter((f) => Number.isInteger(f.id) && f.id > 0);
|
|
8477
|
+
setErpFormsCatalog(rows);
|
|
8478
|
+
}).catch(() => setErpFormsCatalog([]));
|
|
8479
|
+
}, [isErp, loading]);
|
|
8248
8480
|
const buildPayload = () => {
|
|
8481
|
+
if (isErp) {
|
|
8482
|
+
const sortedIds = [...new Set(erpOpportunityFormIds.filter((n) => Number.isInteger(n) && n > 0))].sort(
|
|
8483
|
+
(a, b) => a - b
|
|
8484
|
+
);
|
|
8485
|
+
const payload2 = {
|
|
8486
|
+
enabled: { value: enabled ? "true" : "false", type: "public" },
|
|
8487
|
+
pipelineName: { value: erpPipelineName, type: "public" },
|
|
8488
|
+
pipelineStageName: { value: erpPipelineStageName, type: "public" }
|
|
8489
|
+
};
|
|
8490
|
+
if (erpFormsCatalog.length > 0 || erpOpportunityIdsKeyPresent) {
|
|
8491
|
+
payload2.opportunityFormIds = { value: JSON.stringify(sortedIds), type: "public" };
|
|
8492
|
+
}
|
|
8493
|
+
return payload2;
|
|
8494
|
+
}
|
|
8495
|
+
if (isSms) {
|
|
8496
|
+
return {
|
|
8497
|
+
enabled: { value: enabled ? "true" : "false", type: "public" },
|
|
8498
|
+
smsProvider: { value: smsProviderChoice, type: "public" },
|
|
8499
|
+
msg91ApiMode: { value: msg91ApiMode, type: "public" }
|
|
8500
|
+
};
|
|
8501
|
+
}
|
|
8249
8502
|
const payload = {
|
|
8250
8503
|
enabled: { value: enabled ? "true" : "false", type: "public" },
|
|
8251
8504
|
botName: { value: botName, type: "public" },
|
|
8252
8505
|
icon: { value: icon, type: "public" }
|
|
8253
8506
|
};
|
|
8254
8507
|
if (isLlm) {
|
|
8508
|
+
payload.chatMode = { value: chatMode, type: "public" };
|
|
8509
|
+
payload.whatsappPhone = { value: whatsappPhone, type: "public" };
|
|
8510
|
+
payload.externalChatSnippet = { value: externalChatSnippet, type: "public" };
|
|
8255
8511
|
payload.iconImageUrl = { value: iconImageUrl, type: "public" };
|
|
8256
8512
|
payload.iconBackgroundColor = { value: iconBackgroundColor, type: "public" };
|
|
8257
8513
|
payload.headerColor = { value: headerColor, type: "public" };
|
|
@@ -8279,6 +8535,22 @@ function PluginSettingsPanel({
|
|
|
8279
8535
|
body: JSON.stringify(buildPayload())
|
|
8280
8536
|
});
|
|
8281
8537
|
if (!res.ok) throw new Error();
|
|
8538
|
+
if (isSms && smsTplItems.length > 0) {
|
|
8539
|
+
const res2 = await fetch("/api/message-templates/sms", {
|
|
8540
|
+
method: "PUT",
|
|
8541
|
+
headers: { "Content-Type": "application/json" },
|
|
8542
|
+
body: JSON.stringify({
|
|
8543
|
+
items: smsTplItems.map((t) => ({
|
|
8544
|
+
templateKey: t.templateKey,
|
|
8545
|
+
body: t.body,
|
|
8546
|
+
externalTemplateRef: t.externalTemplateRef,
|
|
8547
|
+
otpVarKey: t.otpVarKey,
|
|
8548
|
+
enabled: t.enabled
|
|
8549
|
+
}))
|
|
8550
|
+
})
|
|
8551
|
+
});
|
|
8552
|
+
if (!res2.ok) throw new Error();
|
|
8553
|
+
}
|
|
8282
8554
|
import_sonner6.toast.success("Settings saved");
|
|
8283
8555
|
onSaved?.();
|
|
8284
8556
|
} catch {
|
|
@@ -8287,10 +8559,101 @@ function PluginSettingsPanel({
|
|
|
8287
8559
|
setSaving(false);
|
|
8288
8560
|
}
|
|
8289
8561
|
};
|
|
8290
|
-
if (loading) return /* @__PURE__ */ (0,
|
|
8562
|
+
if (loading) return /* @__PURE__ */ (0, import_jsx_runtime56.jsx)("div", { className: "text-sm text-gray-500 dark:text-gray-400", children: "Loading..." });
|
|
8563
|
+
if (isErp) {
|
|
8564
|
+
return /* @__PURE__ */ (0, import_jsx_runtime56.jsxs)("div", { className: "space-y-4", children: [
|
|
8565
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsxs)("div", { className: "flex items-center justify-between gap-2", children: [
|
|
8566
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsx)(Label3, { htmlFor: `${settingsGroup}-enabled`, className: "text-sm", children: "Enabled" }),
|
|
8567
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsx)(Switch, { id: `${settingsGroup}-enabled`, checked: enabled, onCheckedChange: setEnabled })
|
|
8568
|
+
] }),
|
|
8569
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsx)("p", { className: "text-xs text-gray-500 dark:text-gray-400", children: "Webhook URL and JWT are set in server environment (see ERP integration guide). Pipeline fields apply to form submissions that are sent as opportunities." }),
|
|
8570
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsxs)("div", { className: "space-y-1", children: [
|
|
8571
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsx)(Label3, { htmlFor: `${settingsGroup}-pipelineName`, className: "text-sm", children: "Pipeline name" }),
|
|
8572
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsx)(
|
|
8573
|
+
Input,
|
|
8574
|
+
{
|
|
8575
|
+
id: `${settingsGroup}-pipelineName`,
|
|
8576
|
+
value: erpPipelineName,
|
|
8577
|
+
onChange: (e) => setErpPipelineName(e.target.value),
|
|
8578
|
+
placeholder: "e.g. Sales",
|
|
8579
|
+
className: "h-8 text-sm"
|
|
8580
|
+
}
|
|
8581
|
+
)
|
|
8582
|
+
] }),
|
|
8583
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsxs)("div", { className: "space-y-1", children: [
|
|
8584
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsx)(Label3, { htmlFor: `${settingsGroup}-pipelineStageName`, className: "text-sm", children: "Pipeline stage name" }),
|
|
8585
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsx)(
|
|
8586
|
+
Input,
|
|
8587
|
+
{
|
|
8588
|
+
id: `${settingsGroup}-pipelineStageName`,
|
|
8589
|
+
value: erpPipelineStageName,
|
|
8590
|
+
onChange: (e) => setErpPipelineStageName(e.target.value),
|
|
8591
|
+
placeholder: "e.g. New",
|
|
8592
|
+
className: "h-8 text-sm"
|
|
8593
|
+
}
|
|
8594
|
+
)
|
|
8595
|
+
] }),
|
|
8596
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsxs)("div", { className: "space-y-2", children: [
|
|
8597
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsxs)("div", { className: "flex flex-wrap items-center justify-between gap-2", children: [
|
|
8598
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsx)(Label3, { className: "text-sm", children: "Forms as CRM opportunity" }),
|
|
8599
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsxs)("div", { className: "flex gap-2 text-xs", children: [
|
|
8600
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsx)(
|
|
8601
|
+
"button",
|
|
8602
|
+
{
|
|
8603
|
+
type: "button",
|
|
8604
|
+
className: "text-primary underline-offset-2 hover:underline",
|
|
8605
|
+
onClick: () => setErpOpportunityFormIds(erpFormsCatalog.map((f) => f.id)),
|
|
8606
|
+
children: "Select all"
|
|
8607
|
+
}
|
|
8608
|
+
),
|
|
8609
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsx)(
|
|
8610
|
+
"button",
|
|
8611
|
+
{
|
|
8612
|
+
type: "button",
|
|
8613
|
+
className: "text-primary underline-offset-2 hover:underline",
|
|
8614
|
+
onClick: () => setErpOpportunityFormIds([]),
|
|
8615
|
+
children: "Clear"
|
|
8616
|
+
}
|
|
8617
|
+
)
|
|
8618
|
+
] })
|
|
8619
|
+
] }),
|
|
8620
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsxs)("p", { className: "text-xs text-gray-500 dark:text-gray-400", children: [
|
|
8621
|
+
"Every form submission with an email is sent to ERP: unchecked forms use ",
|
|
8622
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsx)("span", { className: "font-medium", children: "lead" }),
|
|
8623
|
+
" (",
|
|
8624
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsx)("code", { className: "text-[11px]", children: "lead.created" }),
|
|
8625
|
+
"); checked forms use ",
|
|
8626
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsx)("span", { className: "font-medium", children: "opportunity" }),
|
|
8627
|
+
" (",
|
|
8628
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsx)("code", { className: "text-[11px]", children: "form.submitted" }),
|
|
8629
|
+
") with the pipeline and stage above."
|
|
8630
|
+
] }),
|
|
8631
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsx)("div", { className: "max-h-48 space-y-2 overflow-y-auto rounded-md border border-input p-2 dark:border-gray-600", children: erpFormsCatalog.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime56.jsx)("p", { className: "text-xs text-gray-500 dark:text-gray-400", children: "No forms found." }) : erpFormsCatalog.map((f) => /* @__PURE__ */ (0, import_jsx_runtime56.jsxs)("label", { className: "flex cursor-pointer items-center gap-2 text-sm", children: [
|
|
8632
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsx)(
|
|
8633
|
+
Checkbox,
|
|
8634
|
+
{
|
|
8635
|
+
checked: erpOpportunityFormIds.includes(f.id),
|
|
8636
|
+
onCheckedChange: (c) => {
|
|
8637
|
+
const on = c === true;
|
|
8638
|
+
setErpOpportunityFormIds((prev) => {
|
|
8639
|
+
if (on) return prev.includes(f.id) ? prev : [...prev, f.id].sort((a, b) => a - b);
|
|
8640
|
+
return prev.filter((x) => x !== f.id);
|
|
8641
|
+
});
|
|
8642
|
+
}
|
|
8643
|
+
}
|
|
8644
|
+
),
|
|
8645
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsx)("span", { className: "min-w-0 truncate", children: f.name || `Form #${f.id}` })
|
|
8646
|
+
] }, f.id)) })
|
|
8647
|
+
] }),
|
|
8648
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsxs)(Button, { size: "sm", onClick: handleSave, disabled: saving, className: "gap-1", children: [
|
|
8649
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsx)(import_lucide_react32.Save, { className: "h-3.5 w-3.5" }),
|
|
8650
|
+
"Save"
|
|
8651
|
+
] })
|
|
8652
|
+
] });
|
|
8653
|
+
}
|
|
8291
8654
|
if (isEmail) {
|
|
8292
|
-
return /* @__PURE__ */ (0,
|
|
8293
|
-
/* @__PURE__ */ (0,
|
|
8655
|
+
return /* @__PURE__ */ (0, import_jsx_runtime56.jsxs)("div", { className: "space-y-4", children: [
|
|
8656
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsx)(
|
|
8294
8657
|
EmailRecipientTags,
|
|
8295
8658
|
{
|
|
8296
8659
|
id: `${settingsGroup}-salesTeamEmails`,
|
|
@@ -8301,7 +8664,7 @@ function PluginSettingsPanel({
|
|
|
8301
8664
|
placeholder: "e.g. sales@example.com"
|
|
8302
8665
|
}
|
|
8303
8666
|
),
|
|
8304
|
-
/* @__PURE__ */ (0,
|
|
8667
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsx)(
|
|
8305
8668
|
EmailRecipientTags,
|
|
8306
8669
|
{
|
|
8307
8670
|
id: `${settingsGroup}-fulfilmentTeamEmails`,
|
|
@@ -8312,7 +8675,7 @@ function PluginSettingsPanel({
|
|
|
8312
8675
|
placeholder: "e.g. fulfilment@example.com"
|
|
8313
8676
|
}
|
|
8314
8677
|
),
|
|
8315
|
-
/* @__PURE__ */ (0,
|
|
8678
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsx)(
|
|
8316
8679
|
EmailRecipientTags,
|
|
8317
8680
|
{
|
|
8318
8681
|
id: `${settingsGroup}-crmEmails`,
|
|
@@ -8323,34 +8686,34 @@ function PluginSettingsPanel({
|
|
|
8323
8686
|
placeholder: "e.g. crm@example.com"
|
|
8324
8687
|
}
|
|
8325
8688
|
),
|
|
8326
|
-
/* @__PURE__ */ (0,
|
|
8327
|
-
/* @__PURE__ */ (0,
|
|
8328
|
-
/* @__PURE__ */ (0,
|
|
8329
|
-
/* @__PURE__ */ (0,
|
|
8689
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsx)("p", { className: "text-xs text-gray-500 dark:text-gray-400", children: "Layout below merges with Branding settings; values here override branding when set. Use absolute URLs for logos in email." }),
|
|
8690
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsxs)("div", { className: "space-y-1", children: [
|
|
8691
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsx)(Label3, { htmlFor: `${settingsGroup}-logoUrl`, className: "text-sm", children: "Logo URL (optional override)" }),
|
|
8692
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsx)(Input, { id: `${settingsGroup}-logoUrl`, value: logoUrl, onChange: (e) => setLogoUrl(e.target.value), placeholder: "https://\u2026", className: "h-8 text-sm" })
|
|
8330
8693
|
] }),
|
|
8331
|
-
/* @__PURE__ */ (0,
|
|
8332
|
-
/* @__PURE__ */ (0,
|
|
8333
|
-
/* @__PURE__ */ (0,
|
|
8694
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsxs)("div", { className: "space-y-1", children: [
|
|
8695
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsx)(Label3, { htmlFor: `${settingsGroup}-companyName`, className: "text-sm", children: "Company name (optional override)" }),
|
|
8696
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsx)(Input, { id: `${settingsGroup}-companyName`, value: companyName, onChange: (e) => setCompanyName(e.target.value), className: "h-8 text-sm" })
|
|
8334
8697
|
] }),
|
|
8335
|
-
/* @__PURE__ */ (0,
|
|
8336
|
-
/* @__PURE__ */ (0,
|
|
8337
|
-
/* @__PURE__ */ (0,
|
|
8698
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsxs)("div", { className: "space-y-1", children: [
|
|
8699
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsx)(Label3, { htmlFor: `${settingsGroup}-supportEmail`, className: "text-sm", children: "Support email (footer)" }),
|
|
8700
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsx)(Input, { id: `${settingsGroup}-supportEmail`, value: supportEmail, onChange: (e) => setSupportEmail(e.target.value), type: "email", className: "h-8 text-sm" })
|
|
8338
8701
|
] }),
|
|
8339
|
-
/* @__PURE__ */ (0,
|
|
8340
|
-
/* @__PURE__ */ (0,
|
|
8341
|
-
/* @__PURE__ */ (0,
|
|
8702
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsxs)("div", { className: "space-y-1", children: [
|
|
8703
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsx)(Label3, { htmlFor: `${settingsGroup}-supportPhone`, className: "text-sm", children: "Support phone (footer)" }),
|
|
8704
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsx)(Input, { id: `${settingsGroup}-supportPhone`, value: supportPhone, onChange: (e) => setSupportPhone(e.target.value), className: "h-8 text-sm" })
|
|
8342
8705
|
] }),
|
|
8343
|
-
/* @__PURE__ */ (0,
|
|
8344
|
-
/* @__PURE__ */ (0,
|
|
8345
|
-
/* @__PURE__ */ (0,
|
|
8706
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsxs)("div", { className: "space-y-1", children: [
|
|
8707
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsx)(Label3, { htmlFor: `${settingsGroup}-followUsTitle`, className: "text-sm", children: "\u201CFollow us\u201D heading" }),
|
|
8708
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsx)(Input, { id: `${settingsGroup}-followUsTitle`, value: followUsTitle, onChange: (e) => setFollowUsTitle(e.target.value), className: "h-8 text-sm" })
|
|
8346
8709
|
] }),
|
|
8347
|
-
/* @__PURE__ */ (0,
|
|
8348
|
-
/* @__PURE__ */ (0,
|
|
8349
|
-
/* @__PURE__ */ (0,
|
|
8350
|
-
socialLinkRows.map((row, i) => /* @__PURE__ */ (0,
|
|
8351
|
-
/* @__PURE__ */ (0,
|
|
8352
|
-
/* @__PURE__ */ (0,
|
|
8353
|
-
/* @__PURE__ */ (0,
|
|
8710
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsxs)("div", { className: "space-y-2", children: [
|
|
8711
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsx)(Label3, { className: "text-sm", children: "Social links" }),
|
|
8712
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsx)("p", { className: "text-xs text-gray-500 dark:text-gray-400", children: "Add rows: icon image URL (optional), link URL, and emoji/text only if you are not using an image." }),
|
|
8713
|
+
socialLinkRows.map((row, i) => /* @__PURE__ */ (0, import_jsx_runtime56.jsxs)("div", { className: "flex flex-wrap items-end gap-2 border-b border-border/60 pb-3 dark:border-gray-600", children: [
|
|
8714
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsxs)("div", { className: "min-w-[160px] flex-1 space-y-1", children: [
|
|
8715
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsx)(Label3, { className: "text-xs text-muted-foreground", children: "Icon image URL" }),
|
|
8716
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsx)(
|
|
8354
8717
|
Input,
|
|
8355
8718
|
{
|
|
8356
8719
|
value: row.iconUrl,
|
|
@@ -8364,9 +8727,9 @@ function PluginSettingsPanel({
|
|
|
8364
8727
|
}
|
|
8365
8728
|
)
|
|
8366
8729
|
] }),
|
|
8367
|
-
/* @__PURE__ */ (0,
|
|
8368
|
-
/* @__PURE__ */ (0,
|
|
8369
|
-
/* @__PURE__ */ (0,
|
|
8730
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsxs)("div", { className: "min-w-[160px] flex-1 space-y-1", children: [
|
|
8731
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsx)(Label3, { className: "text-xs text-muted-foreground", children: "Link URL" }),
|
|
8732
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsx)(
|
|
8370
8733
|
Input,
|
|
8371
8734
|
{
|
|
8372
8735
|
value: row.url,
|
|
@@ -8380,9 +8743,9 @@ function PluginSettingsPanel({
|
|
|
8380
8743
|
}
|
|
8381
8744
|
)
|
|
8382
8745
|
] }),
|
|
8383
|
-
/* @__PURE__ */ (0,
|
|
8384
|
-
/* @__PURE__ */ (0,
|
|
8385
|
-
/* @__PURE__ */ (0,
|
|
8746
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsxs)("div", { className: "w-[120px] space-y-1", children: [
|
|
8747
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsx)(Label3, { className: "text-xs text-muted-foreground", children: "Emoji / text" }),
|
|
8748
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsx)(
|
|
8386
8749
|
Input,
|
|
8387
8750
|
{
|
|
8388
8751
|
value: row.iconFallback,
|
|
@@ -8396,7 +8759,7 @@ function PluginSettingsPanel({
|
|
|
8396
8759
|
}
|
|
8397
8760
|
)
|
|
8398
8761
|
] }),
|
|
8399
|
-
/* @__PURE__ */ (0,
|
|
8762
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsx)(
|
|
8400
8763
|
Button,
|
|
8401
8764
|
{
|
|
8402
8765
|
type: "button",
|
|
@@ -8409,11 +8772,11 @@ function PluginSettingsPanel({
|
|
|
8409
8772
|
if (socialLinkRows.length <= 1) setSocialLinkRows([{ ...EMPTY_SOCIAL_ROW }]);
|
|
8410
8773
|
else setSocialLinkRows(socialLinkRows.filter((_, j) => j !== i));
|
|
8411
8774
|
},
|
|
8412
|
-
children: /* @__PURE__ */ (0,
|
|
8775
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime56.jsx)(import_lucide_react32.X, { className: "h-4 w-4" })
|
|
8413
8776
|
}
|
|
8414
8777
|
)
|
|
8415
8778
|
] }, i)),
|
|
8416
|
-
/* @__PURE__ */ (0,
|
|
8779
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsxs)(
|
|
8417
8780
|
Button,
|
|
8418
8781
|
{
|
|
8419
8782
|
type: "button",
|
|
@@ -8422,15 +8785,15 @@ function PluginSettingsPanel({
|
|
|
8422
8785
|
className: "mt-1",
|
|
8423
8786
|
onClick: () => setSocialLinkRows([...socialLinkRows, { ...EMPTY_SOCIAL_ROW }]),
|
|
8424
8787
|
children: [
|
|
8425
|
-
/* @__PURE__ */ (0,
|
|
8788
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsx)(import_lucide_react32.Plus, { className: "mr-1 h-4 w-4" }),
|
|
8426
8789
|
"Add link"
|
|
8427
8790
|
]
|
|
8428
8791
|
}
|
|
8429
8792
|
)
|
|
8430
8793
|
] }),
|
|
8431
|
-
/* @__PURE__ */ (0,
|
|
8432
|
-
/* @__PURE__ */ (0,
|
|
8433
|
-
/* @__PURE__ */ (0,
|
|
8794
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsxs)("div", { className: "space-y-1", children: [
|
|
8795
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsx)(Label3, { htmlFor: `${settingsGroup}-footerDisclaimer`, className: "text-sm", children: "Footer disclaimer" }),
|
|
8796
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsx)(
|
|
8434
8797
|
Textarea,
|
|
8435
8798
|
{
|
|
8436
8799
|
id: `${settingsGroup}-footerDisclaimer`,
|
|
@@ -8441,106 +8804,318 @@ function PluginSettingsPanel({
|
|
|
8441
8804
|
}
|
|
8442
8805
|
)
|
|
8443
8806
|
] }),
|
|
8444
|
-
/* @__PURE__ */ (0,
|
|
8807
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsx)(Button, { size: "sm", onClick: handleSave, disabled: saving, children: saving ? "Saving\u2026" : "Save" })
|
|
8445
8808
|
] });
|
|
8446
8809
|
}
|
|
8447
|
-
|
|
8448
|
-
/* @__PURE__ */ (0,
|
|
8449
|
-
/* @__PURE__ */ (0,
|
|
8450
|
-
|
|
8451
|
-
|
|
8452
|
-
/* @__PURE__ */ (0, import_jsx_runtime55.jsxs)("div", { className: "space-y-1", children: [
|
|
8453
|
-
/* @__PURE__ */ (0, import_jsx_runtime55.jsx)(Label3, { htmlFor: `${settingsGroup}-botName`, className: "text-sm", children: "Name" }),
|
|
8454
|
-
/* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
|
|
8455
|
-
Input,
|
|
8456
|
-
{
|
|
8457
|
-
id: `${settingsGroup}-botName`,
|
|
8458
|
-
value: botName,
|
|
8459
|
-
onChange: (e) => setBotName(e.target.value),
|
|
8460
|
-
placeholder: "e.g. Support Bot",
|
|
8461
|
-
className: "h-8 text-sm"
|
|
8462
|
-
}
|
|
8463
|
-
)
|
|
8464
|
-
] }),
|
|
8465
|
-
isLlm ? /* @__PURE__ */ (0, import_jsx_runtime55.jsxs)(import_jsx_runtime55.Fragment, { children: [
|
|
8466
|
-
/* @__PURE__ */ (0, import_jsx_runtime55.jsxs)("div", { className: "space-y-1", children: [
|
|
8467
|
-
/* @__PURE__ */ (0, import_jsx_runtime55.jsx)(Label3, { htmlFor: `${settingsGroup}-iconImageUrl`, className: "text-sm", children: "Icon image URL" }),
|
|
8468
|
-
/* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
|
|
8469
|
-
Input,
|
|
8470
|
-
{
|
|
8471
|
-
id: `${settingsGroup}-iconImageUrl`,
|
|
8472
|
-
value: iconImageUrl,
|
|
8473
|
-
onChange: (e) => setIconImageUrl(e.target.value),
|
|
8474
|
-
placeholder: "https://\u2026 or /images/chat-icon.png",
|
|
8475
|
-
className: "h-8 text-sm"
|
|
8476
|
-
}
|
|
8477
|
-
),
|
|
8478
|
-
/* @__PURE__ */ (0, import_jsx_runtime55.jsx)("p", { className: "text-xs text-gray-500 dark:text-gray-400", children: "PNG or image URL. Leave empty to use emoji below." })
|
|
8810
|
+
if (isSms) {
|
|
8811
|
+
return /* @__PURE__ */ (0, import_jsx_runtime56.jsxs)("div", { className: "space-y-4", children: [
|
|
8812
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsxs)("div", { className: "flex items-center justify-between gap-2", children: [
|
|
8813
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsx)(Label3, { htmlFor: `${settingsGroup}-enabled`, className: "text-sm", children: "Enabled" }),
|
|
8814
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsx)(Switch, { id: `${settingsGroup}-enabled`, checked: enabled, onCheckedChange: setEnabled })
|
|
8479
8815
|
] }),
|
|
8480
|
-
/* @__PURE__ */ (0,
|
|
8481
|
-
/* @__PURE__ */ (0,
|
|
8482
|
-
/* @__PURE__ */ (0,
|
|
8483
|
-
|
|
8816
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsxs)("div", { className: "space-y-1", children: [
|
|
8817
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsx)(Label3, { htmlFor: `${settingsGroup}-smsProvider`, className: "text-sm", children: "Active provider" }),
|
|
8818
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsxs)(
|
|
8819
|
+
Select,
|
|
8484
8820
|
{
|
|
8485
|
-
|
|
8486
|
-
|
|
8487
|
-
|
|
8488
|
-
|
|
8489
|
-
|
|
8821
|
+
value: smsProviderChoice,
|
|
8822
|
+
onValueChange: (v) => setSmsProviderChoice(v),
|
|
8823
|
+
children: [
|
|
8824
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsx)(SelectTrigger, { id: `${settingsGroup}-smsProvider`, className: "h-9 text-sm", children: /* @__PURE__ */ (0, import_jsx_runtime56.jsx)(SelectValue, { placeholder: "Select provider" }) }),
|
|
8825
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsxs)(SelectContent, { children: [
|
|
8826
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsx)(SelectItem, { value: "auto", children: "Auto (MSG91 \u2192 Twilio \u2192 webhook, first with credentials)" }),
|
|
8827
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsx)(SelectItem, { value: "msg91", children: "MSG91 (India)" }),
|
|
8828
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsx)(SelectItem, { value: "twilio", children: "Twilio" }),
|
|
8829
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsx)(SelectItem, { value: "webhook", children: "HTTP webhook" })
|
|
8830
|
+
] })
|
|
8831
|
+
]
|
|
8490
8832
|
}
|
|
8491
8833
|
)
|
|
8492
8834
|
] }),
|
|
8493
|
-
/* @__PURE__ */ (0,
|
|
8494
|
-
/* @__PURE__ */ (0,
|
|
8495
|
-
|
|
8496
|
-
/* @__PURE__ */ (0,
|
|
8497
|
-
|
|
8498
|
-
|
|
8499
|
-
|
|
8500
|
-
|
|
8501
|
-
id: `${settingsGroup}-iconBg`,
|
|
8502
|
-
value: iconBackgroundColor,
|
|
8503
|
-
onChange: (e) => setIconBackgroundColor(e.target.value),
|
|
8504
|
-
className: "h-8 w-10 cursor-pointer rounded border border-gray-300 dark:border-gray-600"
|
|
8505
|
-
}
|
|
8506
|
-
),
|
|
8507
|
-
/* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
|
|
8508
|
-
Input,
|
|
8509
|
-
{
|
|
8510
|
-
value: iconBackgroundColor,
|
|
8511
|
-
onChange: (e) => setIconBackgroundColor(e.target.value),
|
|
8512
|
-
className: "h-8 w-24 text-sm font-mono"
|
|
8513
|
-
}
|
|
8514
|
-
)
|
|
8835
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsxs)("div", { className: "space-y-1", children: [
|
|
8836
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsx)(Label3, { htmlFor: `${settingsGroup}-msg91ApiMode`, className: "text-sm", children: "MSG91 API mode" }),
|
|
8837
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsxs)(Select, { value: msg91ApiMode, onValueChange: (v) => setMsg91ApiMode(v), children: [
|
|
8838
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsx)(SelectTrigger, { id: `${settingsGroup}-msg91ApiMode`, className: "h-9 text-sm", children: /* @__PURE__ */ (0, import_jsx_runtime56.jsx)(SelectValue, {}) }),
|
|
8839
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsxs)(SelectContent, { children: [
|
|
8840
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsx)(SelectItem, { value: "auto", children: "Auto (Flow if template ID + auth key; else sendhttp)" }),
|
|
8841
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsx)(SelectItem, { value: "flow", children: "Flow API (DLT template_id; recommended for India)" }),
|
|
8842
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsx)(SelectItem, { value: "sendhttp", children: "Legacy sendhttp (needs sender ID; not for arbitrary India text)" })
|
|
8515
8843
|
] })
|
|
8844
|
+
] })
|
|
8845
|
+
] }),
|
|
8846
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsxs)("div", { className: "space-y-3 rounded-md border border-gray-200 dark:border-gray-600 p-3", children: [
|
|
8847
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsx)("p", { className: "text-sm font-medium text-gray-900 dark:text-white", children: "SMS templates" }),
|
|
8848
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsxs)("p", { className: "text-xs text-gray-500 dark:text-gray-400", children: [
|
|
8849
|
+
"Defaults come from code; overrides and DLT / Flow IDs are stored here. Use ",
|
|
8850
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsx)("code", { className: "text-[11px]", children: "{{code}}" }),
|
|
8851
|
+
" in the message body for the OTP."
|
|
8516
8852
|
] }),
|
|
8517
|
-
/* @__PURE__ */ (0,
|
|
8518
|
-
/* @__PURE__ */ (0,
|
|
8519
|
-
|
|
8520
|
-
|
|
8521
|
-
"
|
|
8522
|
-
|
|
8523
|
-
|
|
8524
|
-
|
|
8525
|
-
|
|
8526
|
-
|
|
8527
|
-
|
|
8528
|
-
|
|
8529
|
-
|
|
8530
|
-
|
|
8531
|
-
|
|
8853
|
+
smsTplItems.map((t) => /* @__PURE__ */ (0, import_jsx_runtime56.jsxs)("div", { className: "space-y-2 border-t border-gray-100 pt-3 first:border-t-0 first:pt-0 dark:border-gray-700", children: [
|
|
8854
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsxs)("div", { className: "flex flex-wrap items-center justify-between gap-2", children: [
|
|
8855
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsxs)("div", { children: [
|
|
8856
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsx)("div", { className: "text-sm font-medium", children: t.name }),
|
|
8857
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsx)("div", { className: "text-[11px] font-mono text-gray-500", children: t.templateKey })
|
|
8858
|
+
] }),
|
|
8859
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsxs)("div", { className: "flex items-center gap-2", children: [
|
|
8860
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsx)(Label3, { htmlFor: `${settingsGroup}-tpl-${t.templateKey}-enabled`, className: "text-xs text-gray-600 dark:text-gray-400", children: "Apply custom body / Flow id" }),
|
|
8861
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsx)(
|
|
8862
|
+
Switch,
|
|
8863
|
+
{
|
|
8864
|
+
id: `${settingsGroup}-tpl-${t.templateKey}-enabled`,
|
|
8865
|
+
checked: t.enabled,
|
|
8866
|
+
onCheckedChange: (v) => setSmsTplItems(
|
|
8867
|
+
(items) => items.map((x) => x.templateKey === t.templateKey ? { ...x, enabled: v } : x)
|
|
8868
|
+
)
|
|
8869
|
+
}
|
|
8870
|
+
)
|
|
8871
|
+
] })
|
|
8872
|
+
] }),
|
|
8873
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsxs)("p", { className: "text-[11px] text-gray-500", children: [
|
|
8874
|
+
"Default: ",
|
|
8875
|
+
t.defaultBody
|
|
8876
|
+
] }),
|
|
8877
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsxs)("div", { className: "space-y-1", children: [
|
|
8878
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsx)(Label3, { className: "text-xs", children: "Message body" }),
|
|
8879
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsx)(
|
|
8880
|
+
Textarea,
|
|
8532
8881
|
{
|
|
8533
|
-
value:
|
|
8534
|
-
onChange: (e) =>
|
|
8535
|
-
|
|
8882
|
+
value: t.body,
|
|
8883
|
+
onChange: (e) => setSmsTplItems(
|
|
8884
|
+
(items) => items.map((x) => x.templateKey === t.templateKey ? { ...x, body: e.target.value } : x)
|
|
8885
|
+
),
|
|
8886
|
+
rows: 2,
|
|
8887
|
+
className: "text-sm"
|
|
8536
8888
|
}
|
|
8537
8889
|
)
|
|
8890
|
+
] }),
|
|
8891
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsxs)("div", { className: "grid gap-2 sm:grid-cols-2", children: [
|
|
8892
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsxs)("div", { className: "space-y-1", children: [
|
|
8893
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsx)(Label3, { className: "text-xs", children: "External template ref (e.g. MSG91 Flow / DLT id)" }),
|
|
8894
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsx)(
|
|
8895
|
+
Input,
|
|
8896
|
+
{
|
|
8897
|
+
value: t.externalTemplateRef,
|
|
8898
|
+
onChange: (e) => setSmsTplItems(
|
|
8899
|
+
(items) => items.map(
|
|
8900
|
+
(x) => x.templateKey === t.templateKey ? { ...x, externalTemplateRef: e.target.value } : x
|
|
8901
|
+
)
|
|
8902
|
+
),
|
|
8903
|
+
placeholder: "From MSG91 after DLT mapping",
|
|
8904
|
+
className: "h-8 text-sm"
|
|
8905
|
+
}
|
|
8906
|
+
)
|
|
8907
|
+
] }),
|
|
8908
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsxs)("div", { className: "space-y-1", children: [
|
|
8909
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsx)(Label3, { className: "text-xs", children: "OTP variable key (Flow recipient field)" }),
|
|
8910
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsx)(
|
|
8911
|
+
Input,
|
|
8912
|
+
{
|
|
8913
|
+
value: t.otpVarKey,
|
|
8914
|
+
onChange: (e) => setSmsTplItems(
|
|
8915
|
+
(items) => items.map(
|
|
8916
|
+
(x) => x.templateKey === t.templateKey ? { ...x, otpVarKey: e.target.value } : x
|
|
8917
|
+
)
|
|
8918
|
+
),
|
|
8919
|
+
className: "h-8 text-sm font-mono",
|
|
8920
|
+
placeholder: "var1"
|
|
8921
|
+
}
|
|
8922
|
+
)
|
|
8923
|
+
] })
|
|
8924
|
+
] })
|
|
8925
|
+
] }, t.templateKey))
|
|
8926
|
+
] }),
|
|
8927
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsxs)("p", { className: "text-xs text-gray-500 dark:text-gray-400", children: [
|
|
8928
|
+
"Server env: ",
|
|
8929
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsx)("code", { className: "text-[11px]", children: "MSG91_AUTH_KEY" }),
|
|
8930
|
+
"; optional global fallback ",
|
|
8931
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsx)("code", { className: "text-[11px]", children: "MSG91_TEMPLATE_ID" }),
|
|
8932
|
+
",",
|
|
8933
|
+
" ",
|
|
8934
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsx)("code", { className: "text-[11px]", children: "MSG91_OTP_VAR_KEY" }),
|
|
8935
|
+
"; sendhttp: ",
|
|
8936
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsx)("code", { className: "text-[11px]", children: "MSG91_SENDER_ID" }),
|
|
8937
|
+
",",
|
|
8938
|
+
" ",
|
|
8939
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsx)("code", { className: "text-[11px]", children: "MSG91_ROUTE" }),
|
|
8940
|
+
". Or ",
|
|
8941
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsx)("code", { className: "text-[11px]", children: "TWILIO_*" }),
|
|
8942
|
+
", ",
|
|
8943
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsx)("code", { className: "text-[11px]", children: "SMS_WEBHOOK_URL" }),
|
|
8944
|
+
".",
|
|
8945
|
+
" ",
|
|
8946
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsx)("code", { className: "text-[11px]", children: "SMS_PROVIDER" }),
|
|
8947
|
+
" matches the provider dropdown."
|
|
8948
|
+
] }),
|
|
8949
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsx)("p", { className: "text-xs text-gray-500 dark:text-gray-400", children: "India (TRAI DLT): register content on operators; map the approved template in MSG91 and set the Flow id per template above." }),
|
|
8950
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsxs)(Button, { size: "sm", onClick: handleSave, disabled: saving, className: "gap-1", children: [
|
|
8951
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsx)(import_lucide_react32.Save, { className: "h-3.5 w-3.5" }),
|
|
8952
|
+
"Save"
|
|
8953
|
+
] })
|
|
8954
|
+
] });
|
|
8955
|
+
}
|
|
8956
|
+
if (isLlm) {
|
|
8957
|
+
return /* @__PURE__ */ (0, import_jsx_runtime56.jsxs)("div", { className: "space-y-4", children: [
|
|
8958
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsxs)("div", { className: "flex items-center justify-between gap-2", children: [
|
|
8959
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsx)(Label3, { htmlFor: `${settingsGroup}-enabled`, className: "text-sm", children: "Enabled" }),
|
|
8960
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsx)(Switch, { id: `${settingsGroup}-enabled`, checked: enabled, onCheckedChange: setEnabled })
|
|
8961
|
+
] }),
|
|
8962
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsxs)("div", { className: "space-y-1", children: [
|
|
8963
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsx)(Label3, { htmlFor: `${settingsGroup}-chatMode`, className: "text-sm", children: "Support channel" }),
|
|
8964
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsxs)(Select, { value: chatMode, onValueChange: (v) => setChatMode(v), children: [
|
|
8965
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsx)(SelectTrigger, { id: `${settingsGroup}-chatMode`, className: "h-9 text-sm", children: /* @__PURE__ */ (0, import_jsx_runtime56.jsx)(SelectValue, { placeholder: "Select channel" }) }),
|
|
8966
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsxs)(SelectContent, { children: [
|
|
8967
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsx)(SelectItem, { value: "whatsapp", children: "WhatsApp" }),
|
|
8968
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsx)(SelectItem, { value: "external", children: "External (script)" }),
|
|
8969
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsx)(SelectItem, { value: "llm", children: "Infuro Chat Assistant" })
|
|
8970
|
+
] })
|
|
8971
|
+
] })
|
|
8972
|
+
] }),
|
|
8973
|
+
chatMode === "whatsapp" && /* @__PURE__ */ (0, import_jsx_runtime56.jsxs)("div", { className: "space-y-1", children: [
|
|
8974
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsx)(Label3, { htmlFor: `${settingsGroup}-whatsappPhone`, className: "text-sm", children: "Phone number" }),
|
|
8975
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsx)(
|
|
8976
|
+
Input,
|
|
8977
|
+
{
|
|
8978
|
+
id: `${settingsGroup}-whatsappPhone`,
|
|
8979
|
+
value: whatsappPhone,
|
|
8980
|
+
onChange: (e) => setWhatsappPhone(e.target.value),
|
|
8981
|
+
placeholder: "e.g. +1 555 123 4567",
|
|
8982
|
+
className: "h-8 text-sm"
|
|
8983
|
+
}
|
|
8984
|
+
),
|
|
8985
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsx)("p", { className: "text-xs text-gray-500 dark:text-gray-400", children: "Include country code. Opens WhatsApp (wa.me) when visitors tap the site button." })
|
|
8986
|
+
] }),
|
|
8987
|
+
chatMode === "external" && /* @__PURE__ */ (0, import_jsx_runtime56.jsxs)("div", { className: "space-y-1", children: [
|
|
8988
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsx)(Label3, { htmlFor: `${settingsGroup}-externalSnippet`, className: "text-sm", children: "Embed script" }),
|
|
8989
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsx)(
|
|
8990
|
+
Textarea,
|
|
8991
|
+
{
|
|
8992
|
+
id: `${settingsGroup}-externalSnippet`,
|
|
8993
|
+
value: externalChatSnippet,
|
|
8994
|
+
onChange: (e) => setExternalChatSnippet(e.target.value),
|
|
8995
|
+
rows: 8,
|
|
8996
|
+
placeholder: "Paste third-party widget HTML / script tags\u2026",
|
|
8997
|
+
className: "text-sm font-mono"
|
|
8998
|
+
}
|
|
8999
|
+
),
|
|
9000
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsx)("p", { className: "text-xs text-gray-500 dark:text-gray-400", children: "Only paste code from sources you trust." })
|
|
9001
|
+
] }),
|
|
9002
|
+
chatMode === "llm" && /* @__PURE__ */ (0, import_jsx_runtime56.jsxs)(import_jsx_runtime56.Fragment, { children: [
|
|
9003
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsxs)("div", { className: "space-y-1", children: [
|
|
9004
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsx)(Label3, { htmlFor: `${settingsGroup}-botName`, className: "text-sm", children: "Name" }),
|
|
9005
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsx)(
|
|
9006
|
+
Input,
|
|
9007
|
+
{
|
|
9008
|
+
id: `${settingsGroup}-botName`,
|
|
9009
|
+
value: botName,
|
|
9010
|
+
onChange: (e) => setBotName(e.target.value),
|
|
9011
|
+
placeholder: "e.g. Support Bot",
|
|
9012
|
+
className: "h-8 text-sm"
|
|
9013
|
+
}
|
|
9014
|
+
)
|
|
9015
|
+
] }),
|
|
9016
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsxs)("div", { className: "space-y-1", children: [
|
|
9017
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsx)(Label3, { htmlFor: `${settingsGroup}-iconImageUrl`, className: "text-sm", children: "Icon image URL" }),
|
|
9018
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsx)(
|
|
9019
|
+
Input,
|
|
9020
|
+
{
|
|
9021
|
+
id: `${settingsGroup}-iconImageUrl`,
|
|
9022
|
+
value: iconImageUrl,
|
|
9023
|
+
onChange: (e) => setIconImageUrl(e.target.value),
|
|
9024
|
+
placeholder: "https://\u2026 or /images/chat-icon.png",
|
|
9025
|
+
className: "h-8 text-sm"
|
|
9026
|
+
}
|
|
9027
|
+
),
|
|
9028
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsx)("p", { className: "text-xs text-gray-500 dark:text-gray-400", children: "PNG or image URL. Leave empty to use emoji below." })
|
|
9029
|
+
] }),
|
|
9030
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsxs)("div", { className: "space-y-1", children: [
|
|
9031
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsx)(Label3, { htmlFor: `${settingsGroup}-icon`, className: "text-sm", children: "Icon fallback (emoji)" }),
|
|
9032
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsx)(
|
|
9033
|
+
Input,
|
|
9034
|
+
{
|
|
9035
|
+
id: `${settingsGroup}-icon`,
|
|
9036
|
+
value: icon,
|
|
9037
|
+
onChange: (e) => setIcon(e.target.value),
|
|
9038
|
+
placeholder: "e.g. \u{1F4AC}",
|
|
9039
|
+
className: "h-8 text-sm w-20"
|
|
9040
|
+
}
|
|
9041
|
+
)
|
|
9042
|
+
] }),
|
|
9043
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsxs)("div", { className: "flex gap-4", children: [
|
|
9044
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsxs)("div", { className: "space-y-1", children: [
|
|
9045
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsx)(Label3, { htmlFor: `${settingsGroup}-iconBg`, className: "text-sm", children: "Icon background" }),
|
|
9046
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsxs)("div", { className: "flex items-center gap-2", children: [
|
|
9047
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsx)(
|
|
9048
|
+
"input",
|
|
9049
|
+
{
|
|
9050
|
+
type: "color",
|
|
9051
|
+
id: `${settingsGroup}-iconBg`,
|
|
9052
|
+
value: iconBackgroundColor,
|
|
9053
|
+
onChange: (e) => setIconBackgroundColor(e.target.value),
|
|
9054
|
+
className: "h-8 w-10 cursor-pointer rounded border border-gray-300 dark:border-gray-600"
|
|
9055
|
+
}
|
|
9056
|
+
),
|
|
9057
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsx)(
|
|
9058
|
+
Input,
|
|
9059
|
+
{
|
|
9060
|
+
value: iconBackgroundColor,
|
|
9061
|
+
onChange: (e) => setIconBackgroundColor(e.target.value),
|
|
9062
|
+
className: "h-8 w-24 text-sm font-mono"
|
|
9063
|
+
}
|
|
9064
|
+
)
|
|
9065
|
+
] })
|
|
9066
|
+
] }),
|
|
9067
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsxs)("div", { className: "space-y-1", children: [
|
|
9068
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsx)(Label3, { htmlFor: `${settingsGroup}-headerColor`, className: "text-sm", children: "Header color" }),
|
|
9069
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsxs)("div", { className: "flex items-center gap-2", children: [
|
|
9070
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsx)(
|
|
9071
|
+
"input",
|
|
9072
|
+
{
|
|
9073
|
+
type: "color",
|
|
9074
|
+
id: `${settingsGroup}-headerColor`,
|
|
9075
|
+
value: headerColor,
|
|
9076
|
+
onChange: (e) => setHeaderColor(e.target.value),
|
|
9077
|
+
className: "h-8 w-10 cursor-pointer rounded border border-gray-300 dark:border-gray-600"
|
|
9078
|
+
}
|
|
9079
|
+
),
|
|
9080
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsx)(
|
|
9081
|
+
Input,
|
|
9082
|
+
{
|
|
9083
|
+
value: headerColor,
|
|
9084
|
+
onChange: (e) => setHeaderColor(e.target.value),
|
|
9085
|
+
className: "h-8 w-24 text-sm font-mono"
|
|
9086
|
+
}
|
|
9087
|
+
)
|
|
9088
|
+
] })
|
|
8538
9089
|
] })
|
|
8539
9090
|
] })
|
|
9091
|
+
] }),
|
|
9092
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsxs)(Button, { size: "sm", onClick: handleSave, disabled: saving, className: "gap-1", children: [
|
|
9093
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsx)(import_lucide_react32.Save, { className: "h-3.5 w-3.5" }),
|
|
9094
|
+
"Save"
|
|
8540
9095
|
] })
|
|
8541
|
-
] })
|
|
8542
|
-
|
|
8543
|
-
|
|
9096
|
+
] });
|
|
9097
|
+
}
|
|
9098
|
+
return /* @__PURE__ */ (0, import_jsx_runtime56.jsxs)("div", { className: "space-y-4", children: [
|
|
9099
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsxs)("div", { className: "flex items-center justify-between gap-2", children: [
|
|
9100
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsx)(Label3, { htmlFor: `${settingsGroup}-enabled`, className: "text-sm", children: "Enabled" }),
|
|
9101
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsx)(Switch, { id: `${settingsGroup}-enabled`, checked: enabled, onCheckedChange: setEnabled })
|
|
9102
|
+
] }),
|
|
9103
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsxs)("div", { className: "space-y-1", children: [
|
|
9104
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsx)(Label3, { htmlFor: `${settingsGroup}-botName`, className: "text-sm", children: "Name" }),
|
|
9105
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsx)(
|
|
9106
|
+
Input,
|
|
9107
|
+
{
|
|
9108
|
+
id: `${settingsGroup}-botName`,
|
|
9109
|
+
value: botName,
|
|
9110
|
+
onChange: (e) => setBotName(e.target.value),
|
|
9111
|
+
placeholder: "e.g. Support Bot",
|
|
9112
|
+
className: "h-8 text-sm"
|
|
9113
|
+
}
|
|
9114
|
+
)
|
|
9115
|
+
] }),
|
|
9116
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsxs)("div", { className: "space-y-1", children: [
|
|
9117
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsx)(Label3, { htmlFor: `${settingsGroup}-icon`, className: "text-sm", children: "Icon (emoji or name)" }),
|
|
9118
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsx)(
|
|
8544
9119
|
Input,
|
|
8545
9120
|
{
|
|
8546
9121
|
id: `${settingsGroup}-icon`,
|
|
@@ -8551,8 +9126,8 @@ function PluginSettingsPanel({
|
|
|
8551
9126
|
}
|
|
8552
9127
|
)
|
|
8553
9128
|
] }),
|
|
8554
|
-
/* @__PURE__ */ (0,
|
|
8555
|
-
/* @__PURE__ */ (0,
|
|
9129
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsxs)(Button, { size: "sm", onClick: handleSave, disabled: saving, className: "gap-1", children: [
|
|
9130
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsx)(import_lucide_react32.Save, { className: "h-3.5 w-3.5" }),
|
|
8556
9131
|
"Save"
|
|
8557
9132
|
] })
|
|
8558
9133
|
] });
|
|
@@ -8563,28 +9138,28 @@ function PluginListItem({
|
|
|
8563
9138
|
selected,
|
|
8564
9139
|
onSelect
|
|
8565
9140
|
}) {
|
|
8566
|
-
return /* @__PURE__ */ (0,
|
|
9141
|
+
return /* @__PURE__ */ (0, import_jsx_runtime56.jsxs)(
|
|
8567
9142
|
"button",
|
|
8568
9143
|
{
|
|
8569
9144
|
type: "button",
|
|
8570
9145
|
onClick: onSelect,
|
|
8571
9146
|
className: `flex w-full items-center gap-3 rounded-lg border px-3 py-2.5 text-left transition-colors ${selected ? "border-gray-300 bg-gray-50 dark:border-gray-600 dark:bg-gray-700/50" : "border-transparent hover:bg-gray-50 dark:hover:bg-gray-800/50"}`,
|
|
8572
9147
|
children: [
|
|
8573
|
-
/* @__PURE__ */ (0,
|
|
8574
|
-
/* @__PURE__ */ (0,
|
|
8575
|
-
/* @__PURE__ */ (0,
|
|
8576
|
-
/* @__PURE__ */ (0,
|
|
8577
|
-
/* @__PURE__ */ (0,
|
|
9148
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsx)(PluginIcon, { descriptor, size: "sm" }),
|
|
9149
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsxs)("div", { className: "min-w-0 flex-1", children: [
|
|
9150
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsx)("div", { className: "font-medium text-gray-900 dark:text-white truncate", children: descriptor.label || descriptor.name }),
|
|
9151
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsxs)("div", { className: "flex items-center gap-2 mt-0.5", children: [
|
|
9152
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsxs)(
|
|
8578
9153
|
"span",
|
|
8579
9154
|
{
|
|
8580
9155
|
className: `inline-flex items-center gap-1 rounded-full px-1.5 py-0.5 text-xs font-medium ${enabled ? "bg-emerald-50 text-emerald-700 dark:bg-emerald-900/30 dark:text-emerald-400" : "bg-gray-100 text-gray-600 dark:bg-gray-700 dark:text-gray-400"}`,
|
|
8581
9156
|
children: [
|
|
8582
|
-
enabled ? /* @__PURE__ */ (0,
|
|
9157
|
+
enabled ? /* @__PURE__ */ (0, import_jsx_runtime56.jsx)(import_lucide_react32.CheckCircle2, { className: "h-3 w-3" }) : /* @__PURE__ */ (0, import_jsx_runtime56.jsx)(import_lucide_react32.XCircle, { className: "h-3 w-3" }),
|
|
8583
9158
|
enabled ? "On" : "Off"
|
|
8584
9159
|
]
|
|
8585
9160
|
}
|
|
8586
9161
|
),
|
|
8587
|
-
/* @__PURE__ */ (0,
|
|
9162
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsxs)("span", { className: "text-xs text-gray-400 dark:text-gray-500", children: [
|
|
8588
9163
|
"v",
|
|
8589
9164
|
descriptor.version
|
|
8590
9165
|
] })
|
|
@@ -8616,16 +9191,16 @@ function PluginsPage() {
|
|
|
8616
9191
|
).catch(() => {
|
|
8617
9192
|
});
|
|
8618
9193
|
};
|
|
8619
|
-
return /* @__PURE__ */ (0,
|
|
8620
|
-
/* @__PURE__ */ (0,
|
|
8621
|
-
/* @__PURE__ */ (0,
|
|
8622
|
-
/* @__PURE__ */ (0,
|
|
9194
|
+
return /* @__PURE__ */ (0, import_jsx_runtime56.jsxs)("div", { className: "min-w-0 rounded-lg bg-white shadow-md dark:bg-gray-800", children: [
|
|
9195
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsxs)("div", { className: "bg-gray-800 border-b border-gray-700 px-4 py-2.5 rounded-t-lg dark:bg-gray-900 dark:border-gray-700", children: [
|
|
9196
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsx)("h1", { className: "text-base font-semibold text-white", children: "Plugins" }),
|
|
9197
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsx)("p", { className: "text-xs text-gray-300 mt-0.5", children: "Registered plugins and their status" })
|
|
8623
9198
|
] }),
|
|
8624
|
-
/* @__PURE__ */ (0,
|
|
8625
|
-
/* @__PURE__ */ (0,
|
|
8626
|
-
/* @__PURE__ */ (0,
|
|
8627
|
-
] }) : /* @__PURE__ */ (0,
|
|
8628
|
-
/* @__PURE__ */ (0,
|
|
9199
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsx)("div", { className: "min-w-0 p-6", children: pluginDescriptors.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime56.jsxs)("div", { className: "py-12 text-center", children: [
|
|
9200
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsx)(import_lucide_react32.Puzzle, { className: "mx-auto h-10 w-10 text-gray-400" }),
|
|
9201
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsx)("p", { className: "mt-3 text-sm text-gray-500 dark:text-gray-400", children: "No plugins registered. Add plugin descriptors to your app admin layout." })
|
|
9202
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime56.jsxs)("div", { className: "flex gap-6", children: [
|
|
9203
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsx)("div", { className: "w-56 shrink-0 space-y-1", children: pluginDescriptors.map((p) => /* @__PURE__ */ (0, import_jsx_runtime56.jsx)(
|
|
8629
9204
|
PluginListItem,
|
|
8630
9205
|
{
|
|
8631
9206
|
descriptor: p,
|
|
@@ -8635,24 +9210,24 @@ function PluginsPage() {
|
|
|
8635
9210
|
},
|
|
8636
9211
|
p.name
|
|
8637
9212
|
)) }),
|
|
8638
|
-
/* @__PURE__ */ (0,
|
|
8639
|
-
/* @__PURE__ */ (0,
|
|
8640
|
-
/* @__PURE__ */ (0,
|
|
8641
|
-
] }) : /* @__PURE__ */ (0,
|
|
8642
|
-
/* @__PURE__ */ (0,
|
|
9213
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsx)("div", { className: "min-w-0 flex-1", children: !selectedName ? /* @__PURE__ */ (0, import_jsx_runtime56.jsxs)("div", { className: "flex flex-col items-center justify-center py-12 text-center", children: [
|
|
9214
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsx)(import_lucide_react32.Puzzle, { className: "h-10 w-10 text-gray-300 dark:text-gray-600" }),
|
|
9215
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsx)("p", { className: "mt-3 text-sm text-gray-500 dark:text-gray-400", children: "Select a plugin to view or edit its configuration." })
|
|
9216
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime56.jsx)("div", { className: "rounded-lg border border-gray-200 bg-gray-50/50 p-5 dark:border-gray-700 dark:bg-gray-800/50", children: selectedDescriptor?.settingsGroup ? /* @__PURE__ */ (0, import_jsx_runtime56.jsxs)(import_jsx_runtime56.Fragment, { children: [
|
|
9217
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsxs)("h2", { className: "text-sm font-medium text-gray-700 dark:text-gray-300 mb-4", children: [
|
|
8643
9218
|
selectedDescriptor.label || selectedDescriptor.name,
|
|
8644
9219
|
" \u2014 Configuration"
|
|
8645
9220
|
] }),
|
|
8646
|
-
/* @__PURE__ */ (0,
|
|
9221
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsx)(
|
|
8647
9222
|
PluginSettingsPanel,
|
|
8648
9223
|
{
|
|
8649
9224
|
descriptor: selectedDescriptor,
|
|
8650
9225
|
onSaved: () => refreshEnabled(selectedDescriptor.name)
|
|
8651
9226
|
}
|
|
8652
9227
|
)
|
|
8653
|
-
] }) : /* @__PURE__ */ (0,
|
|
8654
|
-
/* @__PURE__ */ (0,
|
|
8655
|
-
/* @__PURE__ */ (0,
|
|
9228
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime56.jsxs)("div", { className: "flex flex-col items-center justify-center py-12 text-center", children: [
|
|
9229
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsx)(import_lucide_react32.Puzzle, { className: "h-10 w-10 text-gray-300 dark:text-gray-600" }),
|
|
9230
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsx)("p", { className: "mt-3 text-sm text-gray-500 dark:text-gray-400", children: "No configuration available for this plugin." })
|
|
8656
9231
|
] }) }) })
|
|
8657
9232
|
] }) })
|
|
8658
9233
|
] });
|
|
@@ -8661,48 +9236,48 @@ function PluginsPage() {
|
|
|
8661
9236
|
// src/admin/pages/BrandEditPage.tsx
|
|
8662
9237
|
var import_react41 = require("react");
|
|
8663
9238
|
var import_navigation16 = require("next/navigation");
|
|
8664
|
-
var
|
|
9239
|
+
var import_lucide_react33 = require("lucide-react");
|
|
8665
9240
|
|
|
8666
9241
|
// src/components/Admin/SeoSection.tsx
|
|
8667
|
-
var
|
|
9242
|
+
var import_jsx_runtime57 = require("react/jsx-runtime");
|
|
8668
9243
|
function SeoSection({
|
|
8669
9244
|
values,
|
|
8670
9245
|
onChange
|
|
8671
9246
|
}) {
|
|
8672
9247
|
const inputCls3 = "w-full rounded-md border border-gray-300 px-2 py-1.5 text-sm h-8";
|
|
8673
9248
|
const textareaCls = "w-full rounded-md border border-gray-300 px-2 py-1.5 text-sm min-h-[60px]";
|
|
8674
|
-
return /* @__PURE__ */ (0,
|
|
8675
|
-
/* @__PURE__ */ (0,
|
|
8676
|
-
/* @__PURE__ */ (0,
|
|
8677
|
-
/* @__PURE__ */ (0,
|
|
8678
|
-
/* @__PURE__ */ (0,
|
|
8679
|
-
/* @__PURE__ */ (0,
|
|
9249
|
+
return /* @__PURE__ */ (0, import_jsx_runtime57.jsxs)("div", { className: "border-t border-gray-200 pt-2", children: [
|
|
9250
|
+
/* @__PURE__ */ (0, import_jsx_runtime57.jsx)("div", { className: "text-xs font-semibold text-gray-500 uppercase tracking-wide mb-3", children: "SEO" }),
|
|
9251
|
+
/* @__PURE__ */ (0, import_jsx_runtime57.jsxs)("div", { className: "space-y-3", children: [
|
|
9252
|
+
/* @__PURE__ */ (0, import_jsx_runtime57.jsxs)("div", { children: [
|
|
9253
|
+
/* @__PURE__ */ (0, import_jsx_runtime57.jsx)("label", { className: "block text-xs font-medium text-gray-600 mb-1", children: "Meta Title" }),
|
|
9254
|
+
/* @__PURE__ */ (0, import_jsx_runtime57.jsx)("input", { type: "text", value: values.seoTitle, onChange: (e) => onChange("seoTitle", e.target.value), className: inputCls3 })
|
|
8680
9255
|
] }),
|
|
8681
|
-
/* @__PURE__ */ (0,
|
|
8682
|
-
/* @__PURE__ */ (0,
|
|
8683
|
-
/* @__PURE__ */ (0,
|
|
9256
|
+
/* @__PURE__ */ (0, import_jsx_runtime57.jsxs)("div", { children: [
|
|
9257
|
+
/* @__PURE__ */ (0, import_jsx_runtime57.jsx)("label", { className: "block text-xs font-medium text-gray-600 mb-1", children: "Meta Description" }),
|
|
9258
|
+
/* @__PURE__ */ (0, import_jsx_runtime57.jsx)("textarea", { value: values.seoDescription, onChange: (e) => onChange("seoDescription", e.target.value), className: textareaCls, rows: 2 })
|
|
8684
9259
|
] }),
|
|
8685
|
-
/* @__PURE__ */ (0,
|
|
8686
|
-
/* @__PURE__ */ (0,
|
|
8687
|
-
/* @__PURE__ */ (0,
|
|
9260
|
+
/* @__PURE__ */ (0, import_jsx_runtime57.jsxs)("div", { children: [
|
|
9261
|
+
/* @__PURE__ */ (0, import_jsx_runtime57.jsx)("label", { className: "block text-xs font-medium text-gray-600 mb-1", children: "Keywords" }),
|
|
9262
|
+
/* @__PURE__ */ (0, import_jsx_runtime57.jsx)("input", { type: "text", value: values.seoKeywords, onChange: (e) => onChange("seoKeywords", e.target.value), placeholder: "keyword1, keyword2", className: inputCls3 })
|
|
8688
9263
|
] }),
|
|
8689
|
-
/* @__PURE__ */ (0,
|
|
8690
|
-
/* @__PURE__ */ (0,
|
|
8691
|
-
/* @__PURE__ */ (0,
|
|
9264
|
+
/* @__PURE__ */ (0, import_jsx_runtime57.jsxs)("div", { children: [
|
|
9265
|
+
/* @__PURE__ */ (0, import_jsx_runtime57.jsx)("label", { className: "block text-xs font-medium text-gray-600 mb-1", children: "OG Title" }),
|
|
9266
|
+
/* @__PURE__ */ (0, import_jsx_runtime57.jsx)("input", { type: "text", value: values.seoOgTitle, onChange: (e) => onChange("seoOgTitle", e.target.value), className: inputCls3 })
|
|
8692
9267
|
] }),
|
|
8693
|
-
/* @__PURE__ */ (0,
|
|
8694
|
-
/* @__PURE__ */ (0,
|
|
8695
|
-
/* @__PURE__ */ (0,
|
|
9268
|
+
/* @__PURE__ */ (0, import_jsx_runtime57.jsxs)("div", { children: [
|
|
9269
|
+
/* @__PURE__ */ (0, import_jsx_runtime57.jsx)("label", { className: "block text-xs font-medium text-gray-600 mb-1", children: "OG Description" }),
|
|
9270
|
+
/* @__PURE__ */ (0, import_jsx_runtime57.jsx)("textarea", { value: values.seoOgDescription, onChange: (e) => onChange("seoOgDescription", e.target.value), className: textareaCls, rows: 2 })
|
|
8696
9271
|
] }),
|
|
8697
|
-
/* @__PURE__ */ (0,
|
|
8698
|
-
/* @__PURE__ */ (0,
|
|
8699
|
-
/* @__PURE__ */ (0,
|
|
9272
|
+
/* @__PURE__ */ (0, import_jsx_runtime57.jsxs)("div", { children: [
|
|
9273
|
+
/* @__PURE__ */ (0, import_jsx_runtime57.jsx)("label", { className: "block text-xs font-medium text-gray-600 mb-1", children: "OG Image" }),
|
|
9274
|
+
/* @__PURE__ */ (0, import_jsx_runtime57.jsx)("input", { type: "url", value: values.seoOgImage, onChange: (e) => onChange("seoOgImage", e.target.value), placeholder: "https://...", className: inputCls3 })
|
|
8700
9275
|
] })
|
|
8701
9276
|
] })
|
|
8702
9277
|
] });
|
|
8703
9278
|
}
|
|
8704
9279
|
async function saveSeo(seo, slug, existingSeoId) {
|
|
8705
|
-
const hasSeo = seo.seoTitle || seo.seoDescription || seo.seoKeywords;
|
|
9280
|
+
const hasSeo = seo.seoTitle || seo.seoDescription || seo.seoKeywords || seo.seoOgTitle || seo.seoOgDescription || seo.seoOgImage;
|
|
8706
9281
|
if (!hasSeo) return existingSeoId;
|
|
8707
9282
|
const payload = {
|
|
8708
9283
|
title: seo.seoTitle || null,
|
|
@@ -8752,7 +9327,7 @@ async function fetchSeo(seoId) {
|
|
|
8752
9327
|
}
|
|
8753
9328
|
|
|
8754
9329
|
// src/admin/pages/BrandEditPage.tsx
|
|
8755
|
-
var
|
|
9330
|
+
var import_jsx_runtime58 = require("react/jsx-runtime");
|
|
8756
9331
|
var isCreate = (id) => id === "create";
|
|
8757
9332
|
function BrandEditPage({ brandId }) {
|
|
8758
9333
|
const router = (0, import_navigation16.useRouter)();
|
|
@@ -8838,10 +9413,10 @@ function BrandEditPage({ brandId }) {
|
|
|
8838
9413
|
}
|
|
8839
9414
|
};
|
|
8840
9415
|
if (loading) {
|
|
8841
|
-
return /* @__PURE__ */ (0,
|
|
9416
|
+
return /* @__PURE__ */ (0, import_jsx_runtime58.jsx)("div", { className: "flex items-center justify-center py-12", children: /* @__PURE__ */ (0, import_jsx_runtime58.jsx)("span", { className: "text-gray-500", children: "Loading..." }) });
|
|
8842
9417
|
}
|
|
8843
|
-
return /* @__PURE__ */ (0,
|
|
8844
|
-
/* @__PURE__ */ (0,
|
|
9418
|
+
return /* @__PURE__ */ (0, import_jsx_runtime58.jsxs)("div", { className: "rounded-lg bg-white shadow-md", children: [
|
|
9419
|
+
/* @__PURE__ */ (0, import_jsx_runtime58.jsx)(
|
|
8845
9420
|
DetailPageHeader,
|
|
8846
9421
|
{
|
|
8847
9422
|
title: create ? "Add Brand" : "Edit Brand",
|
|
@@ -8853,23 +9428,23 @@ function BrandEditPage({ brandId }) {
|
|
|
8853
9428
|
]
|
|
8854
9429
|
}
|
|
8855
9430
|
),
|
|
8856
|
-
errors.length > 0 && /* @__PURE__ */ (0,
|
|
8857
|
-
/* @__PURE__ */ (0,
|
|
8858
|
-
/* @__PURE__ */ (0,
|
|
8859
|
-
/* @__PURE__ */ (0,
|
|
8860
|
-
/* @__PURE__ */ (0,
|
|
9431
|
+
errors.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime58.jsx)("div", { className: "bg-red-50 border-l-4 border-red-400 p-4 mx-6 mt-4", children: /* @__PURE__ */ (0, import_jsx_runtime58.jsxs)("div", { className: "flex", children: [
|
|
9432
|
+
/* @__PURE__ */ (0, import_jsx_runtime58.jsx)(import_lucide_react33.AlertCircle, { className: "h-5 w-5 text-red-400 flex-shrink-0" }),
|
|
9433
|
+
/* @__PURE__ */ (0, import_jsx_runtime58.jsxs)("div", { className: "ml-3", children: [
|
|
9434
|
+
/* @__PURE__ */ (0, import_jsx_runtime58.jsx)("h3", { className: "text-sm font-medium text-red-800", children: "Please fix the following errors:" }),
|
|
9435
|
+
/* @__PURE__ */ (0, import_jsx_runtime58.jsx)("ul", { className: "mt-2 text-sm text-red-700 list-disc pl-5 space-y-1", children: errors.map((e, i) => /* @__PURE__ */ (0, import_jsx_runtime58.jsx)("li", { children: e }, i)) })
|
|
8861
9436
|
] })
|
|
8862
9437
|
] }) }),
|
|
8863
|
-
/* @__PURE__ */ (0,
|
|
9438
|
+
/* @__PURE__ */ (0, import_jsx_runtime58.jsx)(
|
|
8864
9439
|
DetailPageLayout,
|
|
8865
9440
|
{
|
|
8866
|
-
main: /* @__PURE__ */ (0,
|
|
8867
|
-
/* @__PURE__ */ (0,
|
|
8868
|
-
/* @__PURE__ */ (0,
|
|
8869
|
-
/* @__PURE__ */ (0,
|
|
8870
|
-
/* @__PURE__ */ (0,
|
|
8871
|
-
/* @__PURE__ */ (0,
|
|
8872
|
-
/* @__PURE__ */ (0,
|
|
9441
|
+
main: /* @__PURE__ */ (0, import_jsx_runtime58.jsxs)(import_jsx_runtime58.Fragment, { children: [
|
|
9442
|
+
/* @__PURE__ */ (0, import_jsx_runtime58.jsxs)("section", { children: [
|
|
9443
|
+
/* @__PURE__ */ (0, import_jsx_runtime58.jsx)("h2", { className: "text-xs font-semibold text-gray-400 uppercase tracking-wider mb-2", children: "Basic info" }),
|
|
9444
|
+
/* @__PURE__ */ (0, import_jsx_runtime58.jsxs)("div", { className: "min-w-0 overflow-hidden border border-gray-200 rounded-lg p-4 bg-gray-50/50 space-y-4", children: [
|
|
9445
|
+
/* @__PURE__ */ (0, import_jsx_runtime58.jsxs)("div", { children: [
|
|
9446
|
+
/* @__PURE__ */ (0, import_jsx_runtime58.jsx)("label", { className: "block text-xs font-medium text-gray-600 mb-1", children: "Name *" }),
|
|
9447
|
+
/* @__PURE__ */ (0, import_jsx_runtime58.jsx)(
|
|
8873
9448
|
"input",
|
|
8874
9449
|
{
|
|
8875
9450
|
type: "text",
|
|
@@ -8880,9 +9455,9 @@ function BrandEditPage({ brandId }) {
|
|
|
8880
9455
|
}
|
|
8881
9456
|
)
|
|
8882
9457
|
] }),
|
|
8883
|
-
/* @__PURE__ */ (0,
|
|
8884
|
-
/* @__PURE__ */ (0,
|
|
8885
|
-
/* @__PURE__ */ (0,
|
|
9458
|
+
/* @__PURE__ */ (0, import_jsx_runtime58.jsxs)("div", { children: [
|
|
9459
|
+
/* @__PURE__ */ (0, import_jsx_runtime58.jsx)("label", { className: "block text-xs font-medium text-gray-600 mb-1", children: "Slug *" }),
|
|
9460
|
+
/* @__PURE__ */ (0, import_jsx_runtime58.jsx)(
|
|
8886
9461
|
"input",
|
|
8887
9462
|
{
|
|
8888
9463
|
type: "text",
|
|
@@ -8893,9 +9468,9 @@ function BrandEditPage({ brandId }) {
|
|
|
8893
9468
|
}
|
|
8894
9469
|
)
|
|
8895
9470
|
] }),
|
|
8896
|
-
/* @__PURE__ */ (0,
|
|
8897
|
-
/* @__PURE__ */ (0,
|
|
8898
|
-
/* @__PURE__ */ (0,
|
|
9471
|
+
/* @__PURE__ */ (0, import_jsx_runtime58.jsxs)("div", { children: [
|
|
9472
|
+
/* @__PURE__ */ (0, import_jsx_runtime58.jsx)("label", { className: "block text-xs font-medium text-gray-600 mb-1", children: "Description" }),
|
|
9473
|
+
/* @__PURE__ */ (0, import_jsx_runtime58.jsx)(
|
|
8899
9474
|
"textarea",
|
|
8900
9475
|
{
|
|
8901
9476
|
value: description,
|
|
@@ -8905,9 +9480,9 @@ function BrandEditPage({ brandId }) {
|
|
|
8905
9480
|
}
|
|
8906
9481
|
)
|
|
8907
9482
|
] }),
|
|
8908
|
-
/* @__PURE__ */ (0,
|
|
8909
|
-
/* @__PURE__ */ (0,
|
|
8910
|
-
/* @__PURE__ */ (0,
|
|
9483
|
+
/* @__PURE__ */ (0, import_jsx_runtime58.jsxs)("div", { children: [
|
|
9484
|
+
/* @__PURE__ */ (0, import_jsx_runtime58.jsx)("label", { className: "block text-xs font-medium text-gray-600 mb-1", children: "Logo URL" }),
|
|
9485
|
+
/* @__PURE__ */ (0, import_jsx_runtime58.jsx)(
|
|
8911
9486
|
"input",
|
|
8912
9487
|
{
|
|
8913
9488
|
type: "url",
|
|
@@ -8917,9 +9492,9 @@ function BrandEditPage({ brandId }) {
|
|
|
8917
9492
|
}
|
|
8918
9493
|
)
|
|
8919
9494
|
] }),
|
|
8920
|
-
/* @__PURE__ */ (0,
|
|
8921
|
-
/* @__PURE__ */ (0,
|
|
8922
|
-
/* @__PURE__ */ (0,
|
|
9495
|
+
/* @__PURE__ */ (0, import_jsx_runtime58.jsxs)("div", { children: [
|
|
9496
|
+
/* @__PURE__ */ (0, import_jsx_runtime58.jsx)("label", { className: "block text-xs font-medium text-gray-600 mb-1", children: "Sort order" }),
|
|
9497
|
+
/* @__PURE__ */ (0, import_jsx_runtime58.jsx)(
|
|
8923
9498
|
"input",
|
|
8924
9499
|
{
|
|
8925
9500
|
type: "number",
|
|
@@ -8931,15 +9506,15 @@ function BrandEditPage({ brandId }) {
|
|
|
8931
9506
|
] })
|
|
8932
9507
|
] })
|
|
8933
9508
|
] }),
|
|
8934
|
-
/* @__PURE__ */ (0,
|
|
8935
|
-
/* @__PURE__ */ (0,
|
|
8936
|
-
/* @__PURE__ */ (0,
|
|
9509
|
+
/* @__PURE__ */ (0, import_jsx_runtime58.jsxs)("section", { children: [
|
|
9510
|
+
/* @__PURE__ */ (0, import_jsx_runtime58.jsx)("h2", { className: "text-xs font-semibold text-gray-400 uppercase tracking-wider mb-2", children: "SEO" }),
|
|
9511
|
+
/* @__PURE__ */ (0, import_jsx_runtime58.jsx)("div", { className: "min-w-0 overflow-hidden border border-gray-200 rounded-lg p-4 bg-gray-50/50", children: /* @__PURE__ */ (0, import_jsx_runtime58.jsx)(SeoSection, { values: seo, onChange: (field, value) => setSeo((s) => ({ ...s, [field]: value })) }) })
|
|
8937
9512
|
] })
|
|
8938
9513
|
] }),
|
|
8939
|
-
sidebar: /* @__PURE__ */ (0,
|
|
8940
|
-
/* @__PURE__ */ (0,
|
|
8941
|
-
/* @__PURE__ */ (0,
|
|
8942
|
-
/* @__PURE__ */ (0,
|
|
9514
|
+
sidebar: /* @__PURE__ */ (0, import_jsx_runtime58.jsx)(import_jsx_runtime58.Fragment, { children: /* @__PURE__ */ (0, import_jsx_runtime58.jsxs)("section", { children: [
|
|
9515
|
+
/* @__PURE__ */ (0, import_jsx_runtime58.jsx)("h2", { className: "text-xs font-semibold text-gray-400 uppercase tracking-wider mb-2", children: "Status" }),
|
|
9516
|
+
/* @__PURE__ */ (0, import_jsx_runtime58.jsx)("div", { className: "min-w-0 overflow-hidden border border-gray-200 rounded-lg p-4 bg-gray-50/50", children: /* @__PURE__ */ (0, import_jsx_runtime58.jsxs)("label", { className: "flex items-center gap-2 cursor-pointer", children: [
|
|
9517
|
+
/* @__PURE__ */ (0, import_jsx_runtime58.jsx)(
|
|
8943
9518
|
"input",
|
|
8944
9519
|
{
|
|
8945
9520
|
type: "checkbox",
|
|
@@ -8948,7 +9523,7 @@ function BrandEditPage({ brandId }) {
|
|
|
8948
9523
|
className: "h-4 w-4 rounded border-gray-300"
|
|
8949
9524
|
}
|
|
8950
9525
|
),
|
|
8951
|
-
/* @__PURE__ */ (0,
|
|
9526
|
+
/* @__PURE__ */ (0, import_jsx_runtime58.jsx)("span", { className: "text-sm font-medium text-gray-900", children: "Active" })
|
|
8952
9527
|
] }) })
|
|
8953
9528
|
] }) })
|
|
8954
9529
|
}
|
|
@@ -8959,11 +9534,11 @@ function BrandEditPage({ brandId }) {
|
|
|
8959
9534
|
// src/admin/pages/ProductEditPage.tsx
|
|
8960
9535
|
var import_react43 = require("react");
|
|
8961
9536
|
var import_navigation17 = require("next/navigation");
|
|
8962
|
-
var
|
|
9537
|
+
var import_lucide_react34 = require("lucide-react");
|
|
8963
9538
|
|
|
8964
9539
|
// src/components/Admin/AttributeFacetNameInput.tsx
|
|
8965
9540
|
var import_react42 = require("react");
|
|
8966
|
-
var
|
|
9541
|
+
var import_jsx_runtime59 = require("react/jsx-runtime");
|
|
8967
9542
|
function slugFromName(name) {
|
|
8968
9543
|
const s = name.toLowerCase().trim().replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "");
|
|
8969
9544
|
return s || "attribute";
|
|
@@ -9031,8 +9606,8 @@ function AttributeFacetNameInput({
|
|
|
9031
9606
|
}
|
|
9032
9607
|
};
|
|
9033
9608
|
const exactMatch = list.some((x) => x.name.toLowerCase() === draft.trim().toLowerCase());
|
|
9034
|
-
return /* @__PURE__ */ (0,
|
|
9035
|
-
/* @__PURE__ */ (0,
|
|
9609
|
+
return /* @__PURE__ */ (0, import_jsx_runtime59.jsxs)("div", { className: "relative min-w-0 flex-1", children: [
|
|
9610
|
+
/* @__PURE__ */ (0, import_jsx_runtime59.jsx)(
|
|
9036
9611
|
"input",
|
|
9037
9612
|
{
|
|
9038
9613
|
type: "text",
|
|
@@ -9063,8 +9638,8 @@ function AttributeFacetNameInput({
|
|
|
9063
9638
|
className: inputClassName
|
|
9064
9639
|
}
|
|
9065
9640
|
),
|
|
9066
|
-
open && (list.length > 0 || draft.trim() && !exactMatch) && /* @__PURE__ */ (0,
|
|
9067
|
-
list.map((a) => /* @__PURE__ */ (0,
|
|
9641
|
+
open && (list.length > 0 || draft.trim() && !exactMatch) && /* @__PURE__ */ (0, import_jsx_runtime59.jsxs)("ul", { className: "absolute z-20 mt-1 w-full rounded-md border border-gray-200 bg-white py-1 shadow-lg max-h-48 overflow-auto", children: [
|
|
9642
|
+
list.map((a) => /* @__PURE__ */ (0, import_jsx_runtime59.jsx)(
|
|
9068
9643
|
"li",
|
|
9069
9644
|
{
|
|
9070
9645
|
onMouseDown: (e) => {
|
|
@@ -9076,7 +9651,7 @@ function AttributeFacetNameInput({
|
|
|
9076
9651
|
},
|
|
9077
9652
|
a.id
|
|
9078
9653
|
)),
|
|
9079
|
-
draft.trim() && !exactMatch && /* @__PURE__ */ (0,
|
|
9654
|
+
draft.trim() && !exactMatch && /* @__PURE__ */ (0, import_jsx_runtime59.jsxs)(
|
|
9080
9655
|
"li",
|
|
9081
9656
|
{
|
|
9082
9657
|
onMouseDown: (e) => {
|
|
@@ -9096,7 +9671,7 @@ function AttributeFacetNameInput({
|
|
|
9096
9671
|
}
|
|
9097
9672
|
|
|
9098
9673
|
// src/admin/pages/ProductEditPage.tsx
|
|
9099
|
-
var
|
|
9674
|
+
var import_jsx_runtime60 = require("react/jsx-runtime");
|
|
9100
9675
|
var isCreate2 = (id) => id === "create";
|
|
9101
9676
|
var sectionCls = "min-w-0 overflow-hidden border border-gray-200 rounded-lg p-4 bg-gray-50/50";
|
|
9102
9677
|
var labelCls = "block text-xs font-medium text-gray-600 mb-1";
|
|
@@ -9139,8 +9714,11 @@ function ProductEditPage({ productId }) {
|
|
|
9139
9714
|
const [brands, setBrands] = (0, import_react43.useState)([]);
|
|
9140
9715
|
const [categories, setCategories] = (0, import_react43.useState)([]);
|
|
9141
9716
|
const [name, setName] = (0, import_react43.useState)("");
|
|
9717
|
+
const [productSlug, setProductSlug] = (0, import_react43.useState)("");
|
|
9142
9718
|
const [sku, setSku] = (0, import_react43.useState)("");
|
|
9143
9719
|
const [hsn, setHsn] = (0, import_react43.useState)("");
|
|
9720
|
+
const [uom, setUom] = (0, import_react43.useState)("");
|
|
9721
|
+
const [productType, setProductType] = (0, import_react43.useState)("product");
|
|
9144
9722
|
const [collectionId, setCollectionId] = (0, import_react43.useState)(null);
|
|
9145
9723
|
const [brandId, setBrandId] = (0, import_react43.useState)(null);
|
|
9146
9724
|
const [categoryId, setCategoryId] = (0, import_react43.useState)(null);
|
|
@@ -9154,6 +9732,8 @@ function ProductEditPage({ productId }) {
|
|
|
9154
9732
|
const [specifications, setSpecifications] = (0, import_react43.useState)([{ key: "", value: "" }]);
|
|
9155
9733
|
const [otherMetadata, setOtherMetadata] = (0, import_react43.useState)({});
|
|
9156
9734
|
const [facetRows, setFacetRows] = (0, import_react43.useState)([{ name: "", value: "" }]);
|
|
9735
|
+
const [taxMasterList, setTaxMasterList] = (0, import_react43.useState)([]);
|
|
9736
|
+
const [taxRows, setTaxRows] = (0, import_react43.useState)([{ taxId: "", rate: "" }]);
|
|
9157
9737
|
const [seoId, setSeoId] = (0, import_react43.useState)(null);
|
|
9158
9738
|
const [seo, setSeo] = (0, import_react43.useState)({
|
|
9159
9739
|
seoTitle: "",
|
|
@@ -9167,11 +9747,12 @@ function ProductEditPage({ productId }) {
|
|
|
9167
9747
|
let cancelled = false;
|
|
9168
9748
|
(async () => {
|
|
9169
9749
|
try {
|
|
9170
|
-
const [colRes, brandRes, catRes, attrRes] = await Promise.all([
|
|
9750
|
+
const [colRes, brandRes, catRes, attrRes, taxesRes] = await Promise.all([
|
|
9171
9751
|
fetch("/api/collections?limit=500"),
|
|
9172
9752
|
fetch("/api/brands?limit=500"),
|
|
9173
9753
|
fetch("/api/product_categories?limit=500"),
|
|
9174
|
-
fetch("/api/attributes?limit=500")
|
|
9754
|
+
fetch("/api/attributes?limit=500"),
|
|
9755
|
+
fetch("/api/taxes?limit=200&sortField=name&sortOrder=asc")
|
|
9175
9756
|
]);
|
|
9176
9757
|
let attrList = [];
|
|
9177
9758
|
if (!cancelled && colRes.ok) {
|
|
@@ -9190,8 +9771,18 @@ function ProductEditPage({ productId }) {
|
|
|
9190
9771
|
const d = await attrRes.json();
|
|
9191
9772
|
if (Array.isArray(d.data)) attrList = d.data;
|
|
9192
9773
|
}
|
|
9774
|
+
if (!cancelled && taxesRes.ok) {
|
|
9775
|
+
const d = await taxesRes.json();
|
|
9776
|
+
const raw = Array.isArray(d.data) ? d.data : [];
|
|
9777
|
+
setTaxMasterList(
|
|
9778
|
+
raw.filter((t) => t.active !== false && t.deleted !== true)
|
|
9779
|
+
);
|
|
9780
|
+
}
|
|
9193
9781
|
if (create) {
|
|
9194
|
-
if (!cancelled)
|
|
9782
|
+
if (!cancelled) {
|
|
9783
|
+
setProductSlug("");
|
|
9784
|
+
setLoading(false);
|
|
9785
|
+
}
|
|
9195
9786
|
return;
|
|
9196
9787
|
}
|
|
9197
9788
|
const res = await fetch(`/api/products/${productId}`);
|
|
@@ -9199,8 +9790,11 @@ function ProductEditPage({ productId }) {
|
|
|
9199
9790
|
const product = await res.json();
|
|
9200
9791
|
if (cancelled) return;
|
|
9201
9792
|
setName(product.name ?? "");
|
|
9793
|
+
setProductSlug(typeof product.slug === "string" ? product.slug : "");
|
|
9202
9794
|
setSku(product.sku ?? "");
|
|
9203
9795
|
setHsn(product.hsn ?? "");
|
|
9796
|
+
setUom(product.uom != null ? String(product.uom) : "");
|
|
9797
|
+
setProductType(product.type === "service" ? "service" : "product");
|
|
9204
9798
|
setCollectionId(product.collectionId ?? null);
|
|
9205
9799
|
setBrandId(product.brandId ?? null);
|
|
9206
9800
|
setCategoryId(product.categoryId ?? null);
|
|
@@ -9231,6 +9825,19 @@ function ProductEditPage({ productId }) {
|
|
|
9231
9825
|
const seoData = await fetchSeo(product.seoId);
|
|
9232
9826
|
if (!cancelled) setSeo(seoData);
|
|
9233
9827
|
}
|
|
9828
|
+
const ptRes = await fetch(`/api/product_taxes?productId=${productId}&limit=100`);
|
|
9829
|
+
if (ptRes.ok && !cancelled) {
|
|
9830
|
+
const ptData = await ptRes.json();
|
|
9831
|
+
const pts = Array.isArray(ptData.data) ? ptData.data : [];
|
|
9832
|
+
if (pts.length > 0) {
|
|
9833
|
+
setTaxRows(
|
|
9834
|
+
pts.map((p) => ({
|
|
9835
|
+
taxId: p.taxId,
|
|
9836
|
+
rate: p.rate != null && p.rate !== "" ? String(p.rate) : ""
|
|
9837
|
+
}))
|
|
9838
|
+
);
|
|
9839
|
+
} else if (!cancelled) setTaxRows([{ taxId: "", rate: "" }]);
|
|
9840
|
+
}
|
|
9234
9841
|
const paRes = await fetch(`/api/product_attributes?productId=${productId}&limit=100`);
|
|
9235
9842
|
if (paRes.ok && !cancelled) {
|
|
9236
9843
|
const paData = await paRes.json();
|
|
@@ -9254,6 +9861,12 @@ function ProductEditPage({ productId }) {
|
|
|
9254
9861
|
cancelled = true;
|
|
9255
9862
|
};
|
|
9256
9863
|
}, [productId, create]);
|
|
9864
|
+
(0, import_react43.useEffect)(() => {
|
|
9865
|
+
if (!create || !name.trim() || productSlug.trim()) return;
|
|
9866
|
+
setProductSlug(
|
|
9867
|
+
name.trim().toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/(^-|-$)/g, "")
|
|
9868
|
+
);
|
|
9869
|
+
}, [create, name, productSlug]);
|
|
9257
9870
|
const handleSave = async () => {
|
|
9258
9871
|
setErrors([]);
|
|
9259
9872
|
if (!name.trim()) {
|
|
@@ -9266,12 +9879,15 @@ function ProductEditPage({ productId }) {
|
|
|
9266
9879
|
}
|
|
9267
9880
|
setSaving(true);
|
|
9268
9881
|
try {
|
|
9269
|
-
const
|
|
9882
|
+
const seoSlug = productSlug.trim() || name.trim().toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/(^-|-$)/g, "");
|
|
9883
|
+
const savedSeoId = await saveSeo(seo, seoSlug, seoId);
|
|
9270
9884
|
const metadata = buildProductMetadata(otherMetadata, { description, images, specifications });
|
|
9271
9885
|
const productPayload = {
|
|
9272
9886
|
name: name.trim(),
|
|
9273
9887
|
sku: sku.trim() || null,
|
|
9274
9888
|
hsn: hsn.trim() || null,
|
|
9889
|
+
uom: uom.trim() || null,
|
|
9890
|
+
type: productType,
|
|
9275
9891
|
collectionId: collectionId || null,
|
|
9276
9892
|
brandId: brandId || null,
|
|
9277
9893
|
categoryId: categoryId || null,
|
|
@@ -9294,6 +9910,9 @@ function ProductEditPage({ productId }) {
|
|
|
9294
9910
|
return;
|
|
9295
9911
|
}
|
|
9296
9912
|
const savedProduct = await res.json();
|
|
9913
|
+
if (typeof savedProduct.slug === "string") {
|
|
9914
|
+
setProductSlug(savedProduct.slug);
|
|
9915
|
+
}
|
|
9297
9916
|
const savedId = create ? savedProduct.id : productId;
|
|
9298
9917
|
const slugify = (n) => n.toLowerCase().trim().replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "") || "attribute";
|
|
9299
9918
|
async function ensureAttributeId(attrName) {
|
|
@@ -9365,6 +9984,55 @@ function ProductEditPage({ productId }) {
|
|
|
9365
9984
|
});
|
|
9366
9985
|
}
|
|
9367
9986
|
}
|
|
9987
|
+
const parseTaxRate = (s) => {
|
|
9988
|
+
const t = s.trim();
|
|
9989
|
+
if (!t) return null;
|
|
9990
|
+
const n = Number(t);
|
|
9991
|
+
return Number.isFinite(n) ? n : null;
|
|
9992
|
+
};
|
|
9993
|
+
const ratesDiffer = (a, b) => {
|
|
9994
|
+
if (a == null && b == null) return false;
|
|
9995
|
+
if (a == null || b == null) return true;
|
|
9996
|
+
return Math.abs(a - b) > 1e-6;
|
|
9997
|
+
};
|
|
9998
|
+
const wantedTax = /* @__PURE__ */ new Map();
|
|
9999
|
+
for (const row of taxRows) {
|
|
10000
|
+
if (row.taxId === "") continue;
|
|
10001
|
+
wantedTax.set(row.taxId, parseTaxRate(row.rate));
|
|
10002
|
+
}
|
|
10003
|
+
const ptListRes = await fetch(`/api/product_taxes?productId=${savedId}&limit=200`);
|
|
10004
|
+
const ptListData = ptListRes.ok ? await ptListRes.json() : { data: [] };
|
|
10005
|
+
const existingPt = Array.isArray(ptListData.data) ? ptListData.data : [];
|
|
10006
|
+
for (const ep of existingPt) {
|
|
10007
|
+
if (!wantedTax.has(ep.taxId)) {
|
|
10008
|
+
await fetch(`/api/product_taxes/${ep.id}`, { method: "DELETE" });
|
|
10009
|
+
}
|
|
10010
|
+
}
|
|
10011
|
+
const survivors = existingPt.filter((ep) => wantedTax.has(ep.taxId));
|
|
10012
|
+
for (const [taxId, rate] of wantedTax) {
|
|
10013
|
+
const ep = survivors.find((e) => e.taxId === taxId);
|
|
10014
|
+
if (!ep) {
|
|
10015
|
+
await fetch("/api/product_taxes", {
|
|
10016
|
+
method: "POST",
|
|
10017
|
+
headers: { "Content-Type": "application/json" },
|
|
10018
|
+
body: JSON.stringify({
|
|
10019
|
+
productId: Number(savedId),
|
|
10020
|
+
taxId,
|
|
10021
|
+
rate
|
|
10022
|
+
})
|
|
10023
|
+
});
|
|
10024
|
+
} else {
|
|
10025
|
+
const existingRate = ep.rate == null || String(ep.rate).trim() === "" ? null : Number(ep.rate);
|
|
10026
|
+
const er = Number.isFinite(existingRate) ? existingRate : null;
|
|
10027
|
+
if (ratesDiffer(er, rate)) {
|
|
10028
|
+
await fetch(`/api/product_taxes/${ep.id}`, {
|
|
10029
|
+
method: "PUT",
|
|
10030
|
+
headers: { "Content-Type": "application/json" },
|
|
10031
|
+
body: JSON.stringify({ rate })
|
|
10032
|
+
});
|
|
10033
|
+
}
|
|
10034
|
+
}
|
|
10035
|
+
}
|
|
9368
10036
|
router.push("/admin/products");
|
|
9369
10037
|
} catch {
|
|
9370
10038
|
setErrors(["Failed to save"]);
|
|
@@ -9382,11 +10050,23 @@ function ProductEditPage({ productId }) {
|
|
|
9382
10050
|
const addFacet = () => setFacetRows((prev) => [...prev, { name: "", value: "" }]);
|
|
9383
10051
|
const removeFacet = (i) => setFacetRows((prev) => prev.length <= 1 ? prev : prev.filter((_, j) => j !== i));
|
|
9384
10052
|
const setFacet = (i, field, value) => setFacetRows((prev) => prev.map((row, j) => j === i ? { ...row, [field]: value } : row));
|
|
10053
|
+
const addTaxRow = () => setTaxRows((prev) => [...prev, { taxId: "", rate: "" }]);
|
|
10054
|
+
const removeTaxRow = (i) => setTaxRows((prev) => prev.length <= 1 ? prev : prev.filter((_, j) => j !== i));
|
|
10055
|
+
const setTaxRow = (i, patch) => setTaxRows((prev) => prev.map((row, j) => j === i ? { ...row, ...patch } : row));
|
|
10056
|
+
const taxesForSelect = (rowIndex) => {
|
|
10057
|
+
const row = taxRows[rowIndex];
|
|
10058
|
+
const selectedElsewhere = new Set(
|
|
10059
|
+
taxRows.map((r, j) => j !== rowIndex && r.taxId !== "" ? r.taxId : null).filter((x) => x != null)
|
|
10060
|
+
);
|
|
10061
|
+
return taxMasterList.filter(
|
|
10062
|
+
(t) => !selectedElsewhere.has(t.id) || row && row.taxId !== "" && t.id === row.taxId
|
|
10063
|
+
);
|
|
10064
|
+
};
|
|
9385
10065
|
if (loading) {
|
|
9386
|
-
return /* @__PURE__ */ (0,
|
|
10066
|
+
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..." }) });
|
|
9387
10067
|
}
|
|
9388
|
-
return /* @__PURE__ */ (0,
|
|
9389
|
-
/* @__PURE__ */ (0,
|
|
10068
|
+
return /* @__PURE__ */ (0, import_jsx_runtime60.jsxs)("div", { className: "rounded-lg bg-white shadow-md", children: [
|
|
10069
|
+
/* @__PURE__ */ (0, import_jsx_runtime60.jsx)(
|
|
9390
10070
|
DetailPageHeader,
|
|
9391
10071
|
{
|
|
9392
10072
|
title: create ? "Add Product" : "Edit Product",
|
|
@@ -9398,90 +10078,192 @@ function ProductEditPage({ productId }) {
|
|
|
9398
10078
|
]
|
|
9399
10079
|
}
|
|
9400
10080
|
),
|
|
9401
|
-
errors.length > 0 && /* @__PURE__ */ (0,
|
|
9402
|
-
/* @__PURE__ */ (0,
|
|
9403
|
-
/* @__PURE__ */ (0,
|
|
9404
|
-
/* @__PURE__ */ (0,
|
|
9405
|
-
/* @__PURE__ */ (0,
|
|
10081
|
+
errors.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime60.jsx)("div", { className: "bg-red-50 border-l-4 border-red-400 p-4 mx-6 mt-4", children: /* @__PURE__ */ (0, import_jsx_runtime60.jsxs)("div", { className: "flex", children: [
|
|
10082
|
+
/* @__PURE__ */ (0, import_jsx_runtime60.jsx)(import_lucide_react34.AlertCircle, { className: "h-5 w-5 text-red-400 flex-shrink-0" }),
|
|
10083
|
+
/* @__PURE__ */ (0, import_jsx_runtime60.jsxs)("div", { className: "ml-3", children: [
|
|
10084
|
+
/* @__PURE__ */ (0, import_jsx_runtime60.jsx)("h3", { className: "text-sm font-medium text-red-800", children: "Please fix the following errors:" }),
|
|
10085
|
+
/* @__PURE__ */ (0, import_jsx_runtime60.jsx)("ul", { className: "mt-2 text-sm text-red-700 list-disc pl-5 space-y-1", children: errors.map((e, i) => /* @__PURE__ */ (0, import_jsx_runtime60.jsx)("li", { children: e }, i)) })
|
|
9406
10086
|
] })
|
|
9407
10087
|
] }) }),
|
|
9408
|
-
/* @__PURE__ */ (0,
|
|
10088
|
+
/* @__PURE__ */ (0, import_jsx_runtime60.jsx)(
|
|
9409
10089
|
DetailPageLayout,
|
|
9410
10090
|
{
|
|
9411
|
-
main: /* @__PURE__ */ (0,
|
|
9412
|
-
/* @__PURE__ */ (0,
|
|
9413
|
-
/* @__PURE__ */ (0,
|
|
9414
|
-
/* @__PURE__ */ (0,
|
|
9415
|
-
/* @__PURE__ */ (0,
|
|
9416
|
-
/* @__PURE__ */ (0,
|
|
9417
|
-
/* @__PURE__ */ (0,
|
|
10091
|
+
main: /* @__PURE__ */ (0, import_jsx_runtime60.jsxs)(import_jsx_runtime60.Fragment, { children: [
|
|
10092
|
+
/* @__PURE__ */ (0, import_jsx_runtime60.jsxs)("section", { children: [
|
|
10093
|
+
/* @__PURE__ */ (0, import_jsx_runtime60.jsx)("h2", { className: "text-xs font-semibold text-gray-400 uppercase tracking-wider mb-2", children: "Product details" }),
|
|
10094
|
+
/* @__PURE__ */ (0, import_jsx_runtime60.jsxs)("div", { className: `${sectionCls} space-y-4`, children: [
|
|
10095
|
+
/* @__PURE__ */ (0, import_jsx_runtime60.jsxs)("div", { children: [
|
|
10096
|
+
/* @__PURE__ */ (0, import_jsx_runtime60.jsx)("label", { className: labelCls, children: "Name *" }),
|
|
10097
|
+
/* @__PURE__ */ (0, import_jsx_runtime60.jsx)("input", { type: "text", value: name, onChange: (e) => setName(e.target.value), className: inputCls, required: true })
|
|
9418
10098
|
] }),
|
|
9419
|
-
/* @__PURE__ */ (0,
|
|
9420
|
-
/* @__PURE__ */ (0,
|
|
9421
|
-
/* @__PURE__ */ (0,
|
|
9422
|
-
/* @__PURE__ */ (0,
|
|
10099
|
+
/* @__PURE__ */ (0, import_jsx_runtime60.jsxs)("div", { className: "grid grid-cols-2 gap-4", children: [
|
|
10100
|
+
/* @__PURE__ */ (0, import_jsx_runtime60.jsxs)("div", { children: [
|
|
10101
|
+
/* @__PURE__ */ (0, import_jsx_runtime60.jsx)("label", { className: labelCls, children: "SKU" }),
|
|
10102
|
+
/* @__PURE__ */ (0, import_jsx_runtime60.jsx)("input", { type: "text", value: sku, onChange: (e) => setSku(e.target.value), className: inputCls })
|
|
10103
|
+
] }),
|
|
10104
|
+
/* @__PURE__ */ (0, import_jsx_runtime60.jsxs)("div", { children: [
|
|
10105
|
+
/* @__PURE__ */ (0, import_jsx_runtime60.jsx)("label", { className: labelCls, children: "HSN" }),
|
|
10106
|
+
/* @__PURE__ */ (0, import_jsx_runtime60.jsx)("input", { type: "text", value: hsn, onChange: (e) => setHsn(e.target.value), className: inputCls })
|
|
10107
|
+
] })
|
|
10108
|
+
] }),
|
|
10109
|
+
/* @__PURE__ */ (0, import_jsx_runtime60.jsxs)("div", { className: "grid grid-cols-2 gap-4", children: [
|
|
10110
|
+
/* @__PURE__ */ (0, import_jsx_runtime60.jsxs)("div", { children: [
|
|
10111
|
+
/* @__PURE__ */ (0, import_jsx_runtime60.jsx)("label", { className: labelCls, children: "UOM" }),
|
|
10112
|
+
/* @__PURE__ */ (0, import_jsx_runtime60.jsx)(
|
|
10113
|
+
"input",
|
|
10114
|
+
{
|
|
10115
|
+
type: "text",
|
|
10116
|
+
value: uom,
|
|
10117
|
+
onChange: (e) => setUom(e.target.value),
|
|
10118
|
+
className: inputCls,
|
|
10119
|
+
placeholder: "e.g. pcs, kg, hrs"
|
|
10120
|
+
}
|
|
10121
|
+
)
|
|
9423
10122
|
] }),
|
|
9424
|
-
/* @__PURE__ */ (0,
|
|
9425
|
-
/* @__PURE__ */ (0,
|
|
9426
|
-
/* @__PURE__ */ (0,
|
|
10123
|
+
/* @__PURE__ */ (0, import_jsx_runtime60.jsxs)("div", { children: [
|
|
10124
|
+
/* @__PURE__ */ (0, import_jsx_runtime60.jsx)("label", { className: labelCls, children: "Product type" }),
|
|
10125
|
+
/* @__PURE__ */ (0, import_jsx_runtime60.jsxs)(
|
|
10126
|
+
"select",
|
|
10127
|
+
{
|
|
10128
|
+
value: productType,
|
|
10129
|
+
onChange: (e) => setProductType(e.target.value === "service" ? "service" : "product"),
|
|
10130
|
+
className: inputCls,
|
|
10131
|
+
children: [
|
|
10132
|
+
/* @__PURE__ */ (0, import_jsx_runtime60.jsx)("option", { value: "product", children: "Product" }),
|
|
10133
|
+
/* @__PURE__ */ (0, import_jsx_runtime60.jsx)("option", { value: "service", children: "Service" })
|
|
10134
|
+
]
|
|
10135
|
+
}
|
|
10136
|
+
)
|
|
9427
10137
|
] })
|
|
9428
10138
|
] }),
|
|
9429
|
-
/* @__PURE__ */ (0,
|
|
9430
|
-
/* @__PURE__ */ (0,
|
|
9431
|
-
/* @__PURE__ */ (0,
|
|
9432
|
-
/* @__PURE__ */ (0,
|
|
9433
|
-
/* @__PURE__ */ (0,
|
|
9434
|
-
brands.map((b) => /* @__PURE__ */ (0,
|
|
10139
|
+
/* @__PURE__ */ (0, import_jsx_runtime60.jsxs)("div", { className: "grid grid-cols-2 gap-4", children: [
|
|
10140
|
+
/* @__PURE__ */ (0, import_jsx_runtime60.jsxs)("div", { children: [
|
|
10141
|
+
/* @__PURE__ */ (0, import_jsx_runtime60.jsx)("label", { className: labelCls, children: "Brand" }),
|
|
10142
|
+
/* @__PURE__ */ (0, import_jsx_runtime60.jsxs)("select", { value: brandId ?? "", onChange: (e) => setBrandId(e.target.value ? Number(e.target.value) : null), className: inputCls, children: [
|
|
10143
|
+
/* @__PURE__ */ (0, import_jsx_runtime60.jsx)("option", { value: "", children: "None" }),
|
|
10144
|
+
brands.map((b) => /* @__PURE__ */ (0, import_jsx_runtime60.jsx)("option", { value: b.id, children: b.name }, b.id))
|
|
9435
10145
|
] })
|
|
9436
10146
|
] }),
|
|
9437
|
-
/* @__PURE__ */ (0,
|
|
9438
|
-
/* @__PURE__ */ (0,
|
|
9439
|
-
/* @__PURE__ */ (0,
|
|
9440
|
-
/* @__PURE__ */ (0,
|
|
9441
|
-
categories.map((c) => /* @__PURE__ */ (0,
|
|
10147
|
+
/* @__PURE__ */ (0, import_jsx_runtime60.jsxs)("div", { children: [
|
|
10148
|
+
/* @__PURE__ */ (0, import_jsx_runtime60.jsx)("label", { className: labelCls, children: "Category" }),
|
|
10149
|
+
/* @__PURE__ */ (0, import_jsx_runtime60.jsxs)("select", { value: categoryId ?? "", onChange: (e) => setCategoryId(e.target.value ? Number(e.target.value) : null), className: inputCls, children: [
|
|
10150
|
+
/* @__PURE__ */ (0, import_jsx_runtime60.jsx)("option", { value: "", children: "None" }),
|
|
10151
|
+
categories.map((c) => /* @__PURE__ */ (0, import_jsx_runtime60.jsx)("option", { value: c.id, children: c.name }, c.id))
|
|
9442
10152
|
] })
|
|
9443
10153
|
] })
|
|
9444
10154
|
] }),
|
|
9445
|
-
/* @__PURE__ */ (0,
|
|
9446
|
-
/* @__PURE__ */ (0,
|
|
9447
|
-
/* @__PURE__ */ (0,
|
|
9448
|
-
/* @__PURE__ */ (0,
|
|
9449
|
-
collections.map((c) => /* @__PURE__ */ (0,
|
|
10155
|
+
/* @__PURE__ */ (0, import_jsx_runtime60.jsxs)("div", { children: [
|
|
10156
|
+
/* @__PURE__ */ (0, import_jsx_runtime60.jsx)("label", { className: labelCls, children: "Collection" }),
|
|
10157
|
+
/* @__PURE__ */ (0, import_jsx_runtime60.jsxs)("select", { value: collectionId ?? "", onChange: (e) => setCollectionId(e.target.value ? Number(e.target.value) : null), className: inputCls, children: [
|
|
10158
|
+
/* @__PURE__ */ (0, import_jsx_runtime60.jsx)("option", { value: "", children: "None" }),
|
|
10159
|
+
collections.map((c) => /* @__PURE__ */ (0, import_jsx_runtime60.jsx)("option", { value: c.id, children: c.name }, c.id))
|
|
9450
10160
|
] })
|
|
9451
10161
|
] }),
|
|
9452
|
-
/* @__PURE__ */ (0,
|
|
9453
|
-
/* @__PURE__ */ (0,
|
|
9454
|
-
/* @__PURE__ */ (0,
|
|
9455
|
-
/* @__PURE__ */ (0,
|
|
10162
|
+
/* @__PURE__ */ (0, import_jsx_runtime60.jsxs)("div", { className: "grid grid-cols-2 gap-4", children: [
|
|
10163
|
+
/* @__PURE__ */ (0, import_jsx_runtime60.jsxs)("div", { children: [
|
|
10164
|
+
/* @__PURE__ */ (0, import_jsx_runtime60.jsx)("label", { className: labelCls, children: "Price *" }),
|
|
10165
|
+
/* @__PURE__ */ (0, import_jsx_runtime60.jsx)("input", { type: "number", value: price, onChange: (e) => setPrice(e.target.value), className: inputCls, required: true })
|
|
9456
10166
|
] }),
|
|
9457
|
-
/* @__PURE__ */ (0,
|
|
9458
|
-
/* @__PURE__ */ (0,
|
|
9459
|
-
/* @__PURE__ */ (0,
|
|
10167
|
+
/* @__PURE__ */ (0, import_jsx_runtime60.jsxs)("div", { children: [
|
|
10168
|
+
/* @__PURE__ */ (0, import_jsx_runtime60.jsx)("label", { className: labelCls, children: "Compare at price" }),
|
|
10169
|
+
/* @__PURE__ */ (0, import_jsx_runtime60.jsx)("input", { type: "number", value: compareAtPrice, onChange: (e) => setCompareAtPrice(e.target.value), className: inputCls })
|
|
9460
10170
|
] })
|
|
9461
10171
|
] }),
|
|
9462
|
-
/* @__PURE__ */ (0,
|
|
9463
|
-
/* @__PURE__ */ (0,
|
|
9464
|
-
/* @__PURE__ */ (0,
|
|
9465
|
-
/* @__PURE__ */ (0,
|
|
10172
|
+
/* @__PURE__ */ (0, import_jsx_runtime60.jsxs)("div", { className: "grid grid-cols-2 gap-4", children: [
|
|
10173
|
+
/* @__PURE__ */ (0, import_jsx_runtime60.jsxs)("div", { children: [
|
|
10174
|
+
/* @__PURE__ */ (0, import_jsx_runtime60.jsx)("label", { className: labelCls, children: "Quantity" }),
|
|
10175
|
+
/* @__PURE__ */ (0, import_jsx_runtime60.jsx)("input", { type: "number", value: quantity, onChange: (e) => setQuantity(Number(e.target.value) || 0), className: inputCls })
|
|
9466
10176
|
] }),
|
|
9467
|
-
/* @__PURE__ */ (0,
|
|
9468
|
-
/* @__PURE__ */ (0,
|
|
9469
|
-
/* @__PURE__ */ (0,
|
|
9470
|
-
/* @__PURE__ */ (0,
|
|
9471
|
-
/* @__PURE__ */ (0,
|
|
9472
|
-
/* @__PURE__ */ (0,
|
|
9473
|
-
/* @__PURE__ */ (0,
|
|
10177
|
+
/* @__PURE__ */ (0, import_jsx_runtime60.jsxs)("div", { children: [
|
|
10178
|
+
/* @__PURE__ */ (0, import_jsx_runtime60.jsx)("label", { className: labelCls, children: "Status" }),
|
|
10179
|
+
/* @__PURE__ */ (0, import_jsx_runtime60.jsxs)("select", { value: status, onChange: (e) => setStatus(e.target.value), className: inputCls, children: [
|
|
10180
|
+
/* @__PURE__ */ (0, import_jsx_runtime60.jsx)("option", { value: "draft", children: "Draft" }),
|
|
10181
|
+
/* @__PURE__ */ (0, import_jsx_runtime60.jsx)("option", { value: "available", children: "Available" }),
|
|
10182
|
+
/* @__PURE__ */ (0, import_jsx_runtime60.jsx)("option", { value: "reserved", children: "Reserved" }),
|
|
10183
|
+
/* @__PURE__ */ (0, import_jsx_runtime60.jsx)("option", { value: "sold", children: "Sold" })
|
|
9474
10184
|
] })
|
|
9475
10185
|
] })
|
|
9476
10186
|
] })
|
|
9477
10187
|
] })
|
|
9478
10188
|
] }),
|
|
9479
|
-
/* @__PURE__ */ (0,
|
|
9480
|
-
/* @__PURE__ */ (0,
|
|
9481
|
-
/* @__PURE__ */ (0,
|
|
9482
|
-
/* @__PURE__ */ (0,
|
|
9483
|
-
|
|
9484
|
-
|
|
10189
|
+
/* @__PURE__ */ (0, import_jsx_runtime60.jsxs)("section", { children: [
|
|
10190
|
+
/* @__PURE__ */ (0, import_jsx_runtime60.jsx)("h2", { className: "text-xs font-semibold text-gray-400 uppercase tracking-wider mb-2", children: "Taxes" }),
|
|
10191
|
+
/* @__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." }),
|
|
10192
|
+
/* @__PURE__ */ (0, import_jsx_runtime60.jsxs)("div", { className: `${sectionCls} space-y-2`, children: [
|
|
10193
|
+
taxRows.map((row, i) => {
|
|
10194
|
+
const options = taxesForSelect(i);
|
|
10195
|
+
const master = row.taxId !== "" ? taxMasterList.find((t) => t.id === row.taxId) : void 0;
|
|
10196
|
+
const defaultRateHint = master != null ? `Default: ${String(master.rate)}%` : void 0;
|
|
10197
|
+
return /* @__PURE__ */ (0, import_jsx_runtime60.jsxs)("div", { className: "flex flex-wrap gap-2 items-end", children: [
|
|
10198
|
+
/* @__PURE__ */ (0, import_jsx_runtime60.jsxs)("div", { className: "min-w-[160px] flex-1", children: [
|
|
10199
|
+
/* @__PURE__ */ (0, import_jsx_runtime60.jsx)("label", { className: labelCls, children: "Tax" }),
|
|
10200
|
+
/* @__PURE__ */ (0, import_jsx_runtime60.jsxs)(
|
|
10201
|
+
"select",
|
|
10202
|
+
{
|
|
10203
|
+
value: row.taxId === "" ? "" : String(row.taxId),
|
|
10204
|
+
onChange: (e) => {
|
|
10205
|
+
const v = e.target.value;
|
|
10206
|
+
setTaxRow(i, { taxId: v === "" ? "" : Number(v) });
|
|
10207
|
+
},
|
|
10208
|
+
className: inputCls,
|
|
10209
|
+
children: [
|
|
10210
|
+
/* @__PURE__ */ (0, import_jsx_runtime60.jsx)("option", { value: "", children: "\u2014" }),
|
|
10211
|
+
options.map((t) => /* @__PURE__ */ (0, import_jsx_runtime60.jsxs)("option", { value: t.id, children: [
|
|
10212
|
+
t.name,
|
|
10213
|
+
" (",
|
|
10214
|
+
String(t.rate),
|
|
10215
|
+
"%)"
|
|
10216
|
+
] }, t.id))
|
|
10217
|
+
]
|
|
10218
|
+
}
|
|
10219
|
+
)
|
|
10220
|
+
] }),
|
|
10221
|
+
/* @__PURE__ */ (0, import_jsx_runtime60.jsxs)("div", { className: "w-28", children: [
|
|
10222
|
+
/* @__PURE__ */ (0, import_jsx_runtime60.jsx)("label", { className: labelCls, children: "Rate %" }),
|
|
10223
|
+
/* @__PURE__ */ (0, import_jsx_runtime60.jsx)(
|
|
10224
|
+
"input",
|
|
10225
|
+
{
|
|
10226
|
+
type: "text",
|
|
10227
|
+
inputMode: "decimal",
|
|
10228
|
+
value: row.rate,
|
|
10229
|
+
onChange: (e) => setTaxRow(i, { rate: e.target.value }),
|
|
10230
|
+
className: inputCls,
|
|
10231
|
+
placeholder: defaultRateHint ?? "optional",
|
|
10232
|
+
title: defaultRateHint
|
|
10233
|
+
}
|
|
10234
|
+
)
|
|
10235
|
+
] }),
|
|
10236
|
+
/* @__PURE__ */ (0, import_jsx_runtime60.jsx)(
|
|
10237
|
+
"button",
|
|
10238
|
+
{
|
|
10239
|
+
type: "button",
|
|
10240
|
+
onClick: () => removeTaxRow(i),
|
|
10241
|
+
className: "p-2 text-gray-400 hover:text-red-600 rounded shrink-0 mb-0.5",
|
|
10242
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime60.jsx)(import_lucide_react34.Trash2, { className: "h-4 w-4" })
|
|
10243
|
+
}
|
|
10244
|
+
)
|
|
10245
|
+
] }, i);
|
|
10246
|
+
}),
|
|
10247
|
+
/* @__PURE__ */ (0, import_jsx_runtime60.jsxs)(
|
|
10248
|
+
"button",
|
|
10249
|
+
{
|
|
10250
|
+
type: "button",
|
|
10251
|
+
onClick: addTaxRow,
|
|
10252
|
+
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",
|
|
10253
|
+
children: [
|
|
10254
|
+
/* @__PURE__ */ (0, import_jsx_runtime60.jsx)(import_lucide_react34.Plus, { className: "h-3.5 w-3.5" }),
|
|
10255
|
+
" Add tax"
|
|
10256
|
+
]
|
|
10257
|
+
}
|
|
10258
|
+
)
|
|
10259
|
+
] })
|
|
10260
|
+
] }),
|
|
10261
|
+
/* @__PURE__ */ (0, import_jsx_runtime60.jsxs)("section", { children: [
|
|
10262
|
+
/* @__PURE__ */ (0, import_jsx_runtime60.jsx)("h2", { className: "text-xs font-semibold text-gray-400 uppercase tracking-wider mb-2", children: "Attributes (facets)" }),
|
|
10263
|
+
/* @__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." }),
|
|
10264
|
+
/* @__PURE__ */ (0, import_jsx_runtime60.jsxs)("div", { className: `${sectionCls} space-y-2`, children: [
|
|
10265
|
+
facetRows.map((row, i) => /* @__PURE__ */ (0, import_jsx_runtime60.jsxs)("div", { className: "flex gap-2 items-start", children: [
|
|
10266
|
+
/* @__PURE__ */ (0, import_jsx_runtime60.jsx)(
|
|
9485
10267
|
AttributeFacetNameInput,
|
|
9486
10268
|
{
|
|
9487
10269
|
value: row.name,
|
|
@@ -9489,7 +10271,7 @@ function ProductEditPage({ productId }) {
|
|
|
9489
10271
|
inputClassName: inputCls
|
|
9490
10272
|
}
|
|
9491
10273
|
),
|
|
9492
|
-
/* @__PURE__ */ (0,
|
|
10274
|
+
/* @__PURE__ */ (0, import_jsx_runtime60.jsx)(
|
|
9493
10275
|
"input",
|
|
9494
10276
|
{
|
|
9495
10277
|
type: "text",
|
|
@@ -9499,21 +10281,21 @@ function ProductEditPage({ productId }) {
|
|
|
9499
10281
|
className: `${inputCls} flex-1 min-w-[120px]`
|
|
9500
10282
|
}
|
|
9501
10283
|
),
|
|
9502
|
-
/* @__PURE__ */ (0,
|
|
10284
|
+
/* @__PURE__ */ (0, import_jsx_runtime60.jsx)("button", { type: "button", onClick: () => removeFacet(i), className: "p-2 text-gray-400 hover:text-red-600 rounded shrink-0 mt-0.5", children: /* @__PURE__ */ (0, import_jsx_runtime60.jsx)(import_lucide_react34.Trash2, { className: "h-4 w-4" }) })
|
|
9503
10285
|
] }, i)),
|
|
9504
|
-
/* @__PURE__ */ (0,
|
|
9505
|
-
/* @__PURE__ */ (0,
|
|
10286
|
+
/* @__PURE__ */ (0, import_jsx_runtime60.jsxs)("button", { type: "button", onClick: addFacet, 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", children: [
|
|
10287
|
+
/* @__PURE__ */ (0, import_jsx_runtime60.jsx)(import_lucide_react34.Plus, { className: "h-3.5 w-3.5" }),
|
|
9506
10288
|
" Add attribute"
|
|
9507
10289
|
] })
|
|
9508
10290
|
] })
|
|
9509
10291
|
] }),
|
|
9510
|
-
/* @__PURE__ */ (0,
|
|
9511
|
-
/* @__PURE__ */ (0,
|
|
9512
|
-
/* @__PURE__ */ (0,
|
|
9513
|
-
images.map((row, i) => /* @__PURE__ */ (0,
|
|
9514
|
-
/* @__PURE__ */ (0,
|
|
9515
|
-
/* @__PURE__ */ (0,
|
|
9516
|
-
/* @__PURE__ */ (0,
|
|
10292
|
+
/* @__PURE__ */ (0, import_jsx_runtime60.jsxs)("section", { children: [
|
|
10293
|
+
/* @__PURE__ */ (0, import_jsx_runtime60.jsx)("h2", { className: "text-xs font-semibold text-gray-400 uppercase tracking-wider mb-2", children: "Media" }),
|
|
10294
|
+
/* @__PURE__ */ (0, import_jsx_runtime60.jsxs)("div", { className: `${sectionCls} space-y-3`, children: [
|
|
10295
|
+
images.map((row, i) => /* @__PURE__ */ (0, import_jsx_runtime60.jsxs)("div", { className: "flex flex-wrap items-start gap-2 p-2 bg-white rounded border border-gray-200", children: [
|
|
10296
|
+
/* @__PURE__ */ (0, import_jsx_runtime60.jsxs)("div", { className: "flex-1 min-w-[200px]", children: [
|
|
10297
|
+
/* @__PURE__ */ (0, import_jsx_runtime60.jsx)("label", { className: labelCls, children: "Image URL" }),
|
|
10298
|
+
/* @__PURE__ */ (0, import_jsx_runtime60.jsx)(
|
|
9517
10299
|
"input",
|
|
9518
10300
|
{
|
|
9519
10301
|
type: "url",
|
|
@@ -9524,9 +10306,9 @@ function ProductEditPage({ productId }) {
|
|
|
9524
10306
|
}
|
|
9525
10307
|
)
|
|
9526
10308
|
] }),
|
|
9527
|
-
/* @__PURE__ */ (0,
|
|
9528
|
-
/* @__PURE__ */ (0,
|
|
9529
|
-
/* @__PURE__ */ (0,
|
|
10309
|
+
/* @__PURE__ */ (0, import_jsx_runtime60.jsxs)("div", { className: "flex-1 min-w-[120px]", children: [
|
|
10310
|
+
/* @__PURE__ */ (0, import_jsx_runtime60.jsx)("label", { className: labelCls, children: "Alt text" }),
|
|
10311
|
+
/* @__PURE__ */ (0, import_jsx_runtime60.jsx)(
|
|
9530
10312
|
"input",
|
|
9531
10313
|
{
|
|
9532
10314
|
type: "text",
|
|
@@ -9536,27 +10318,27 @@ function ProductEditPage({ productId }) {
|
|
|
9536
10318
|
}
|
|
9537
10319
|
)
|
|
9538
10320
|
] }),
|
|
9539
|
-
/* @__PURE__ */ (0,
|
|
10321
|
+
/* @__PURE__ */ (0, import_jsx_runtime60.jsx)(
|
|
9540
10322
|
"button",
|
|
9541
10323
|
{
|
|
9542
10324
|
type: "button",
|
|
9543
10325
|
onClick: () => setDefaultImage(i),
|
|
9544
10326
|
title: "Set as default",
|
|
9545
10327
|
className: "mt-6 p-2 rounded border border-gray-300 hover:bg-gray-100",
|
|
9546
|
-
children: /* @__PURE__ */ (0,
|
|
10328
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime60.jsx)(import_lucide_react34.Star, { className: `h-4 w-4 ${row.isDefault ? "fill-amber-400 text-amber-500" : "text-gray-400"}` })
|
|
9547
10329
|
}
|
|
9548
10330
|
),
|
|
9549
|
-
/* @__PURE__ */ (0,
|
|
10331
|
+
/* @__PURE__ */ (0, import_jsx_runtime60.jsx)("button", { type: "button", onClick: () => removeImage(i), className: "mt-6 p-2 text-gray-400 hover:text-red-600 rounded", children: /* @__PURE__ */ (0, import_jsx_runtime60.jsx)(import_lucide_react34.Trash2, { className: "h-4 w-4" }) })
|
|
9550
10332
|
] }, i)),
|
|
9551
|
-
/* @__PURE__ */ (0,
|
|
9552
|
-
/* @__PURE__ */ (0,
|
|
10333
|
+
/* @__PURE__ */ (0, import_jsx_runtime60.jsxs)("button", { type: "button", onClick: addImage, 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", children: [
|
|
10334
|
+
/* @__PURE__ */ (0, import_jsx_runtime60.jsx)(import_lucide_react34.Plus, { className: "h-3.5 w-3.5" }),
|
|
9553
10335
|
" Add image"
|
|
9554
10336
|
] })
|
|
9555
10337
|
] })
|
|
9556
10338
|
] }),
|
|
9557
|
-
/* @__PURE__ */ (0,
|
|
9558
|
-
/* @__PURE__ */ (0,
|
|
9559
|
-
/* @__PURE__ */ (0,
|
|
10339
|
+
/* @__PURE__ */ (0, import_jsx_runtime60.jsxs)("section", { children: [
|
|
10340
|
+
/* @__PURE__ */ (0, import_jsx_runtime60.jsx)("h2", { className: "text-xs font-semibold text-gray-400 uppercase tracking-wider mb-2", children: "Description" }),
|
|
10341
|
+
/* @__PURE__ */ (0, import_jsx_runtime60.jsx)("div", { className: sectionCls, children: /* @__PURE__ */ (0, import_jsx_runtime60.jsx)(
|
|
9560
10342
|
"textarea",
|
|
9561
10343
|
{
|
|
9562
10344
|
value: description,
|
|
@@ -9567,11 +10349,11 @@ function ProductEditPage({ productId }) {
|
|
|
9567
10349
|
}
|
|
9568
10350
|
) })
|
|
9569
10351
|
] }),
|
|
9570
|
-
/* @__PURE__ */ (0,
|
|
9571
|
-
/* @__PURE__ */ (0,
|
|
9572
|
-
/* @__PURE__ */ (0,
|
|
9573
|
-
specifications.map((row, i) => /* @__PURE__ */ (0,
|
|
9574
|
-
/* @__PURE__ */ (0,
|
|
10352
|
+
/* @__PURE__ */ (0, import_jsx_runtime60.jsxs)("section", { children: [
|
|
10353
|
+
/* @__PURE__ */ (0, import_jsx_runtime60.jsx)("h2", { className: "text-xs font-semibold text-gray-400 uppercase tracking-wider mb-2", children: "Specifications" }),
|
|
10354
|
+
/* @__PURE__ */ (0, import_jsx_runtime60.jsxs)("div", { className: `${sectionCls} space-y-2`, children: [
|
|
10355
|
+
specifications.map((row, i) => /* @__PURE__ */ (0, import_jsx_runtime60.jsxs)("div", { className: "flex gap-2", children: [
|
|
10356
|
+
/* @__PURE__ */ (0, import_jsx_runtime60.jsx)(
|
|
9575
10357
|
"input",
|
|
9576
10358
|
{
|
|
9577
10359
|
type: "text",
|
|
@@ -9581,7 +10363,7 @@ function ProductEditPage({ productId }) {
|
|
|
9581
10363
|
className: `${inputCls} flex-1`
|
|
9582
10364
|
}
|
|
9583
10365
|
),
|
|
9584
|
-
/* @__PURE__ */ (0,
|
|
10366
|
+
/* @__PURE__ */ (0, import_jsx_runtime60.jsx)(
|
|
9585
10367
|
"input",
|
|
9586
10368
|
{
|
|
9587
10369
|
type: "text",
|
|
@@ -9591,18 +10373,18 @@ function ProductEditPage({ productId }) {
|
|
|
9591
10373
|
className: `${inputCls} flex-1`
|
|
9592
10374
|
}
|
|
9593
10375
|
),
|
|
9594
|
-
/* @__PURE__ */ (0,
|
|
10376
|
+
/* @__PURE__ */ (0, import_jsx_runtime60.jsx)("button", { type: "button", onClick: () => removeSpec(i), className: "p-2 text-gray-400 hover:text-red-600 rounded shrink-0", children: /* @__PURE__ */ (0, import_jsx_runtime60.jsx)(import_lucide_react34.Trash2, { className: "h-4 w-4" }) })
|
|
9595
10377
|
] }, i)),
|
|
9596
|
-
/* @__PURE__ */ (0,
|
|
9597
|
-
/* @__PURE__ */ (0,
|
|
10378
|
+
/* @__PURE__ */ (0, import_jsx_runtime60.jsxs)("button", { type: "button", onClick: addSpec, 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", children: [
|
|
10379
|
+
/* @__PURE__ */ (0, import_jsx_runtime60.jsx)(import_lucide_react34.Plus, { className: "h-3.5 w-3.5" }),
|
|
9598
10380
|
" Add row"
|
|
9599
10381
|
] })
|
|
9600
10382
|
] })
|
|
9601
10383
|
] })
|
|
9602
10384
|
] }),
|
|
9603
|
-
sidebar: /* @__PURE__ */ (0,
|
|
9604
|
-
/* @__PURE__ */ (0,
|
|
9605
|
-
/* @__PURE__ */ (0,
|
|
10385
|
+
sidebar: /* @__PURE__ */ (0, import_jsx_runtime60.jsxs)("section", { children: [
|
|
10386
|
+
/* @__PURE__ */ (0, import_jsx_runtime60.jsx)("h2", { className: "text-xs font-semibold text-gray-400 uppercase tracking-wider mb-2", children: "SEO" }),
|
|
10387
|
+
/* @__PURE__ */ (0, import_jsx_runtime60.jsx)("div", { className: sectionCls, children: /* @__PURE__ */ (0, import_jsx_runtime60.jsx)(SeoSection, { values: seo, onChange: (field, value) => setSeo((s) => ({ ...s, [field]: value })) }) })
|
|
9606
10388
|
] })
|
|
9607
10389
|
}
|
|
9608
10390
|
)
|
|
@@ -9612,8 +10394,8 @@ function ProductEditPage({ productId }) {
|
|
|
9612
10394
|
// src/admin/pages/CollectionEditPage.tsx
|
|
9613
10395
|
var import_react44 = require("react");
|
|
9614
10396
|
var import_navigation18 = require("next/navigation");
|
|
9615
|
-
var
|
|
9616
|
-
var
|
|
10397
|
+
var import_lucide_react35 = require("lucide-react");
|
|
10398
|
+
var import_jsx_runtime61 = require("react/jsx-runtime");
|
|
9617
10399
|
var isCreate3 = (id) => id === "create";
|
|
9618
10400
|
var emptySlide = () => ({ url: "", type: "image", caption: "" });
|
|
9619
10401
|
var emptyVariant = () => ({ name: "", price: "", extraSpecs: [] });
|
|
@@ -9814,10 +10596,10 @@ function CollectionEditPage({ collectionId }) {
|
|
|
9814
10596
|
(v) => v.map((x, j) => j === variantIdx ? { ...x, extraSpecs: x.extraSpecs.filter((_, s) => s !== specIdx) } : x)
|
|
9815
10597
|
);
|
|
9816
10598
|
if (loading) {
|
|
9817
|
-
return /* @__PURE__ */ (0,
|
|
10599
|
+
return /* @__PURE__ */ (0, import_jsx_runtime61.jsx)("div", { className: "flex items-center justify-center py-12", children: /* @__PURE__ */ (0, import_jsx_runtime61.jsx)("span", { className: "text-gray-500", children: "Loading..." }) });
|
|
9818
10600
|
}
|
|
9819
|
-
return /* @__PURE__ */ (0,
|
|
9820
|
-
/* @__PURE__ */ (0,
|
|
10601
|
+
return /* @__PURE__ */ (0, import_jsx_runtime61.jsxs)("div", { className: "rounded-lg bg-white shadow-md", children: [
|
|
10602
|
+
/* @__PURE__ */ (0, import_jsx_runtime61.jsx)(
|
|
9821
10603
|
DetailPageHeader,
|
|
9822
10604
|
{
|
|
9823
10605
|
title: create ? "Add Collection" : "Edit Collection",
|
|
@@ -9829,137 +10611,137 @@ function CollectionEditPage({ collectionId }) {
|
|
|
9829
10611
|
]
|
|
9830
10612
|
}
|
|
9831
10613
|
),
|
|
9832
|
-
errors.length > 0 && /* @__PURE__ */ (0,
|
|
9833
|
-
/* @__PURE__ */ (0,
|
|
9834
|
-
/* @__PURE__ */ (0,
|
|
9835
|
-
/* @__PURE__ */ (0,
|
|
9836
|
-
/* @__PURE__ */ (0,
|
|
10614
|
+
errors.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime61.jsx)("div", { className: "bg-red-50 border-l-4 border-red-400 p-4 mx-6 mt-4", children: /* @__PURE__ */ (0, import_jsx_runtime61.jsxs)("div", { className: "flex", children: [
|
|
10615
|
+
/* @__PURE__ */ (0, import_jsx_runtime61.jsx)(import_lucide_react35.AlertCircle, { className: "h-5 w-5 text-red-400 flex-shrink-0" }),
|
|
10616
|
+
/* @__PURE__ */ (0, import_jsx_runtime61.jsxs)("div", { className: "ml-3", children: [
|
|
10617
|
+
/* @__PURE__ */ (0, import_jsx_runtime61.jsx)("h3", { className: "text-sm font-medium text-red-800", children: "Please fix the following errors:" }),
|
|
10618
|
+
/* @__PURE__ */ (0, import_jsx_runtime61.jsx)("ul", { className: "mt-2 text-sm text-red-700 list-disc pl-5 space-y-1", children: errors.map((e, i) => /* @__PURE__ */ (0, import_jsx_runtime61.jsx)("li", { children: e }, i)) })
|
|
9837
10619
|
] })
|
|
9838
10620
|
] }) }),
|
|
9839
|
-
/* @__PURE__ */ (0,
|
|
10621
|
+
/* @__PURE__ */ (0, import_jsx_runtime61.jsx)(
|
|
9840
10622
|
DetailPageLayout,
|
|
9841
10623
|
{
|
|
9842
|
-
main: /* @__PURE__ */ (0,
|
|
9843
|
-
/* @__PURE__ */ (0,
|
|
9844
|
-
/* @__PURE__ */ (0,
|
|
9845
|
-
/* @__PURE__ */ (0,
|
|
9846
|
-
/* @__PURE__ */ (0,
|
|
9847
|
-
/* @__PURE__ */ (0,
|
|
9848
|
-
/* @__PURE__ */ (0,
|
|
10624
|
+
main: /* @__PURE__ */ (0, import_jsx_runtime61.jsxs)(import_jsx_runtime61.Fragment, { children: [
|
|
10625
|
+
/* @__PURE__ */ (0, import_jsx_runtime61.jsxs)("section", { children: [
|
|
10626
|
+
/* @__PURE__ */ (0, import_jsx_runtime61.jsx)("h2", { className: "text-xs font-semibold text-gray-400 uppercase tracking-wider mb-2", children: "Basic info" }),
|
|
10627
|
+
/* @__PURE__ */ (0, import_jsx_runtime61.jsxs)("div", { className: `${sectionCls2} space-y-4`, children: [
|
|
10628
|
+
/* @__PURE__ */ (0, import_jsx_runtime61.jsxs)("div", { children: [
|
|
10629
|
+
/* @__PURE__ */ (0, import_jsx_runtime61.jsx)("label", { className: labelCls2, children: "Name *" }),
|
|
10630
|
+
/* @__PURE__ */ (0, import_jsx_runtime61.jsx)("input", { type: "text", value: name, onChange: (e) => setName(e.target.value), className: inputCls2, required: true })
|
|
9849
10631
|
] }),
|
|
9850
|
-
/* @__PURE__ */ (0,
|
|
9851
|
-
/* @__PURE__ */ (0,
|
|
9852
|
-
/* @__PURE__ */ (0,
|
|
10632
|
+
/* @__PURE__ */ (0, import_jsx_runtime61.jsxs)("div", { children: [
|
|
10633
|
+
/* @__PURE__ */ (0, import_jsx_runtime61.jsx)("label", { className: labelCls2, children: "Slug *" }),
|
|
10634
|
+
/* @__PURE__ */ (0, import_jsx_runtime61.jsx)("input", { type: "text", value: slug, onChange: (e) => setSlug(e.target.value), className: inputCls2, required: true })
|
|
9853
10635
|
] }),
|
|
9854
|
-
/* @__PURE__ */ (0,
|
|
9855
|
-
/* @__PURE__ */ (0,
|
|
9856
|
-
/* @__PURE__ */ (0,
|
|
10636
|
+
/* @__PURE__ */ (0, import_jsx_runtime61.jsxs)("div", { children: [
|
|
10637
|
+
/* @__PURE__ */ (0, import_jsx_runtime61.jsx)("label", { className: labelCls2, children: "HSN" }),
|
|
10638
|
+
/* @__PURE__ */ (0, import_jsx_runtime61.jsx)("input", { type: "text", value: hsn, onChange: (e) => setHsn(e.target.value), className: inputCls2 })
|
|
9857
10639
|
] }),
|
|
9858
|
-
/* @__PURE__ */ (0,
|
|
9859
|
-
/* @__PURE__ */ (0,
|
|
9860
|
-
/* @__PURE__ */ (0,
|
|
9861
|
-
/* @__PURE__ */ (0,
|
|
9862
|
-
/* @__PURE__ */ (0,
|
|
9863
|
-
categories.map((c) => /* @__PURE__ */ (0,
|
|
10640
|
+
/* @__PURE__ */ (0, import_jsx_runtime61.jsxs)("div", { className: "grid grid-cols-2 gap-4", children: [
|
|
10641
|
+
/* @__PURE__ */ (0, import_jsx_runtime61.jsxs)("div", { children: [
|
|
10642
|
+
/* @__PURE__ */ (0, import_jsx_runtime61.jsx)("label", { className: labelCls2, children: "Category" }),
|
|
10643
|
+
/* @__PURE__ */ (0, import_jsx_runtime61.jsxs)("select", { value: categoryId ?? "", onChange: (e) => setCategoryId(e.target.value ? Number(e.target.value) : null), className: inputCls2, children: [
|
|
10644
|
+
/* @__PURE__ */ (0, import_jsx_runtime61.jsx)("option", { value: "", children: "None" }),
|
|
10645
|
+
categories.map((c) => /* @__PURE__ */ (0, import_jsx_runtime61.jsx)("option", { value: c.id, children: c.name }, c.id))
|
|
9864
10646
|
] })
|
|
9865
10647
|
] }),
|
|
9866
|
-
/* @__PURE__ */ (0,
|
|
9867
|
-
/* @__PURE__ */ (0,
|
|
9868
|
-
/* @__PURE__ */ (0,
|
|
9869
|
-
/* @__PURE__ */ (0,
|
|
9870
|
-
brands.map((b) => /* @__PURE__ */ (0,
|
|
10648
|
+
/* @__PURE__ */ (0, import_jsx_runtime61.jsxs)("div", { children: [
|
|
10649
|
+
/* @__PURE__ */ (0, import_jsx_runtime61.jsx)("label", { className: labelCls2, children: "Brand" }),
|
|
10650
|
+
/* @__PURE__ */ (0, import_jsx_runtime61.jsxs)("select", { value: brandId ?? "", onChange: (e) => setBrandId(e.target.value ? Number(e.target.value) : null), className: inputCls2, children: [
|
|
10651
|
+
/* @__PURE__ */ (0, import_jsx_runtime61.jsx)("option", { value: "", children: "None" }),
|
|
10652
|
+
brands.map((b) => /* @__PURE__ */ (0, import_jsx_runtime61.jsx)("option", { value: b.id, children: b.name }, b.id))
|
|
9871
10653
|
] })
|
|
9872
10654
|
] })
|
|
9873
10655
|
] }),
|
|
9874
|
-
/* @__PURE__ */ (0,
|
|
9875
|
-
/* @__PURE__ */ (0,
|
|
9876
|
-
/* @__PURE__ */ (0,
|
|
10656
|
+
/* @__PURE__ */ (0, import_jsx_runtime61.jsxs)("div", { children: [
|
|
10657
|
+
/* @__PURE__ */ (0, import_jsx_runtime61.jsx)("label", { className: labelCls2, children: "Description" }),
|
|
10658
|
+
/* @__PURE__ */ (0, import_jsx_runtime61.jsx)("textarea", { value: description, onChange: (e) => setDescription(e.target.value), className: `${inputCls2} min-h-[80px]`, rows: 3 })
|
|
9877
10659
|
] }),
|
|
9878
|
-
/* @__PURE__ */ (0,
|
|
9879
|
-
/* @__PURE__ */ (0,
|
|
9880
|
-
/* @__PURE__ */ (0,
|
|
10660
|
+
/* @__PURE__ */ (0, import_jsx_runtime61.jsxs)("div", { children: [
|
|
10661
|
+
/* @__PURE__ */ (0, import_jsx_runtime61.jsx)("label", { className: labelCls2, children: "Cover image URL" }),
|
|
10662
|
+
/* @__PURE__ */ (0, import_jsx_runtime61.jsx)("input", { type: "url", value: image, onChange: (e) => setImage(e.target.value), className: inputCls2, placeholder: "https://..." })
|
|
9881
10663
|
] }),
|
|
9882
|
-
/* @__PURE__ */ (0,
|
|
9883
|
-
/* @__PURE__ */ (0,
|
|
9884
|
-
/* @__PURE__ */ (0,
|
|
10664
|
+
/* @__PURE__ */ (0, import_jsx_runtime61.jsxs)("div", { children: [
|
|
10665
|
+
/* @__PURE__ */ (0, import_jsx_runtime61.jsx)("label", { className: labelCls2, children: "Sort order" }),
|
|
10666
|
+
/* @__PURE__ */ (0, import_jsx_runtime61.jsx)("input", { type: "number", value: sortOrder, onChange: (e) => setSortOrder(Number(e.target.value) || 0), className: inputCls2, style: { width: "6rem" } })
|
|
9885
10667
|
] })
|
|
9886
10668
|
] })
|
|
9887
10669
|
] }),
|
|
9888
|
-
/* @__PURE__ */ (0,
|
|
9889
|
-
/* @__PURE__ */ (0,
|
|
10670
|
+
/* @__PURE__ */ (0, import_jsx_runtime61.jsxs)("section", { children: [
|
|
10671
|
+
/* @__PURE__ */ (0, import_jsx_runtime61.jsxs)(
|
|
9890
10672
|
"button",
|
|
9891
10673
|
{
|
|
9892
10674
|
type: "button",
|
|
9893
10675
|
onClick: () => setAdvancedOpen((o) => !o),
|
|
9894
10676
|
className: "flex items-center gap-2 w-full text-left text-xs font-semibold text-gray-400 uppercase tracking-wider mb-2",
|
|
9895
10677
|
children: [
|
|
9896
|
-
advancedOpen ? /* @__PURE__ */ (0,
|
|
10678
|
+
advancedOpen ? /* @__PURE__ */ (0, import_jsx_runtime61.jsx)(import_lucide_react35.ChevronUp, { className: "h-4 w-4" }) : /* @__PURE__ */ (0, import_jsx_runtime61.jsx)(import_lucide_react35.ChevronDown, { className: "h-4 w-4" }),
|
|
9897
10679
|
"Advanced page content"
|
|
9898
10680
|
]
|
|
9899
10681
|
}
|
|
9900
10682
|
),
|
|
9901
|
-
advancedOpen && /* @__PURE__ */ (0,
|
|
9902
|
-
/* @__PURE__ */ (0,
|
|
9903
|
-
/* @__PURE__ */ (0,
|
|
9904
|
-
heroSlides.map((slide, i) => /* @__PURE__ */ (0,
|
|
9905
|
-
/* @__PURE__ */ (0,
|
|
9906
|
-
/* @__PURE__ */ (0,
|
|
9907
|
-
/* @__PURE__ */ (0,
|
|
9908
|
-
/* @__PURE__ */ (0,
|
|
10683
|
+
advancedOpen && /* @__PURE__ */ (0, import_jsx_runtime61.jsxs)("div", { className: "space-y-4", children: [
|
|
10684
|
+
/* @__PURE__ */ (0, import_jsx_runtime61.jsxs)("div", { className: sectionCls2, children: [
|
|
10685
|
+
/* @__PURE__ */ (0, import_jsx_runtime61.jsx)("h3", { className: "text-xs font-medium text-gray-700 mb-2", children: "Hero carousel" }),
|
|
10686
|
+
heroSlides.map((slide, i) => /* @__PURE__ */ (0, import_jsx_runtime61.jsxs)("div", { className: "flex flex-wrap gap-2 mb-3 p-2 bg-white rounded border", children: [
|
|
10687
|
+
/* @__PURE__ */ (0, import_jsx_runtime61.jsx)("input", { type: "url", value: slide.url, onChange: (e) => updateHeroSlide(i, "url", e.target.value), placeholder: "Media URL", className: `${inputCls2} flex-1 min-w-[200px]` }),
|
|
10688
|
+
/* @__PURE__ */ (0, import_jsx_runtime61.jsxs)("select", { value: slide.type, onChange: (e) => updateHeroSlide(i, "type", e.target.value), className: `${inputCls2} w-24`, children: [
|
|
10689
|
+
/* @__PURE__ */ (0, import_jsx_runtime61.jsx)("option", { value: "image", children: "Image" }),
|
|
10690
|
+
/* @__PURE__ */ (0, import_jsx_runtime61.jsx)("option", { value: "video", children: "Video" })
|
|
9909
10691
|
] }),
|
|
9910
|
-
/* @__PURE__ */ (0,
|
|
9911
|
-
/* @__PURE__ */ (0,
|
|
10692
|
+
/* @__PURE__ */ (0, import_jsx_runtime61.jsx)("input", { type: "text", value: slide.caption, onChange: (e) => updateHeroSlide(i, "caption", e.target.value), placeholder: "Caption", className: `${inputCls2} flex-1 min-w-[120px]` }),
|
|
10693
|
+
/* @__PURE__ */ (0, import_jsx_runtime61.jsx)("button", { type: "button", onClick: () => removeHeroSlide(i), className: "p-2 text-gray-400 hover:text-red-600 rounded shrink-0", children: /* @__PURE__ */ (0, import_jsx_runtime61.jsx)(import_lucide_react35.Trash2, { className: "h-4 w-4" }) })
|
|
9912
10694
|
] }, i)),
|
|
9913
|
-
/* @__PURE__ */ (0,
|
|
9914
|
-
/* @__PURE__ */ (0,
|
|
10695
|
+
/* @__PURE__ */ (0, import_jsx_runtime61.jsxs)("button", { type: "button", onClick: addHeroSlide, 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", children: [
|
|
10696
|
+
/* @__PURE__ */ (0, import_jsx_runtime61.jsx)(import_lucide_react35.Plus, { className: "h-3.5 w-3.5" }),
|
|
9915
10697
|
" Add slide"
|
|
9916
10698
|
] })
|
|
9917
10699
|
] }),
|
|
9918
|
-
/* @__PURE__ */ (0,
|
|
9919
|
-
/* @__PURE__ */ (0,
|
|
9920
|
-
variants.map((v, i) => /* @__PURE__ */ (0,
|
|
9921
|
-
/* @__PURE__ */ (0,
|
|
9922
|
-
/* @__PURE__ */ (0,
|
|
9923
|
-
/* @__PURE__ */ (0,
|
|
9924
|
-
/* @__PURE__ */ (0,
|
|
10700
|
+
/* @__PURE__ */ (0, import_jsx_runtime61.jsxs)("div", { className: sectionCls2, children: [
|
|
10701
|
+
/* @__PURE__ */ (0, import_jsx_runtime61.jsx)("h3", { className: "text-xs font-medium text-gray-700 mb-2", children: "Variants" }),
|
|
10702
|
+
variants.map((v, i) => /* @__PURE__ */ (0, import_jsx_runtime61.jsxs)("div", { className: "mb-4 p-3 bg-white rounded border space-y-2", children: [
|
|
10703
|
+
/* @__PURE__ */ (0, import_jsx_runtime61.jsxs)("div", { className: "flex gap-2", children: [
|
|
10704
|
+
/* @__PURE__ */ (0, import_jsx_runtime61.jsx)("input", { type: "text", value: v.name, onChange: (e) => updateVariant(i, "name", e.target.value), placeholder: "Name", className: `${inputCls2} w-40` }),
|
|
10705
|
+
/* @__PURE__ */ (0, import_jsx_runtime61.jsx)("input", { type: "number", value: v.price, onChange: (e) => updateVariant(i, "price", e.target.value), placeholder: "Price", className: `${inputCls2} w-28` }),
|
|
10706
|
+
/* @__PURE__ */ (0, import_jsx_runtime61.jsx)("button", { type: "button", onClick: () => removeVariant(i), className: "p-2 text-gray-400 hover:text-red-600 rounded shrink-0", children: /* @__PURE__ */ (0, import_jsx_runtime61.jsx)(import_lucide_react35.Trash2, { className: "h-4 w-4" }) })
|
|
9925
10707
|
] }),
|
|
9926
|
-
v.extraSpecs.map((s, si) => /* @__PURE__ */ (0,
|
|
9927
|
-
/* @__PURE__ */ (0,
|
|
9928
|
-
/* @__PURE__ */ (0,
|
|
9929
|
-
/* @__PURE__ */ (0,
|
|
10708
|
+
v.extraSpecs.map((s, si) => /* @__PURE__ */ (0, import_jsx_runtime61.jsxs)("div", { className: "flex gap-2", children: [
|
|
10709
|
+
/* @__PURE__ */ (0, import_jsx_runtime61.jsx)("input", { type: "text", value: s.key, onChange: (e) => updateVariantExtraSpec(i, si, "key", e.target.value), placeholder: "Key", className: `${inputCls2} flex-1` }),
|
|
10710
|
+
/* @__PURE__ */ (0, import_jsx_runtime61.jsx)("input", { type: "text", value: s.value, onChange: (e) => updateVariantExtraSpec(i, si, "value", e.target.value), placeholder: "Value", className: `${inputCls2} flex-1` }),
|
|
10711
|
+
/* @__PURE__ */ (0, import_jsx_runtime61.jsx)("button", { type: "button", onClick: () => removeVariantExtraSpec(i, si), className: "p-2 text-gray-400 hover:text-red-600 rounded shrink-0", children: /* @__PURE__ */ (0, import_jsx_runtime61.jsx)(import_lucide_react35.Trash2, { className: "h-4 w-4" }) })
|
|
9930
10712
|
] }, si)),
|
|
9931
|
-
/* @__PURE__ */ (0,
|
|
9932
|
-
/* @__PURE__ */ (0,
|
|
10713
|
+
/* @__PURE__ */ (0, import_jsx_runtime61.jsxs)("button", { type: "button", onClick: () => addVariantExtraSpec(i), className: "inline-flex items-center gap-1 rounded border border-gray-300 bg-white px-2 py-1 text-xs text-gray-700 hover:bg-gray-50", children: [
|
|
10714
|
+
/* @__PURE__ */ (0, import_jsx_runtime61.jsx)(import_lucide_react35.Plus, { className: "h-3 w-3" }),
|
|
9933
10715
|
" Add spec"
|
|
9934
10716
|
] })
|
|
9935
10717
|
] }, i)),
|
|
9936
|
-
/* @__PURE__ */ (0,
|
|
9937
|
-
/* @__PURE__ */ (0,
|
|
10718
|
+
/* @__PURE__ */ (0, import_jsx_runtime61.jsxs)("button", { type: "button", onClick: addVariant, 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", children: [
|
|
10719
|
+
/* @__PURE__ */ (0, import_jsx_runtime61.jsx)(import_lucide_react35.Plus, { className: "h-3.5 w-3.5" }),
|
|
9938
10720
|
" Add variant"
|
|
9939
10721
|
] })
|
|
9940
10722
|
] }),
|
|
9941
|
-
/* @__PURE__ */ (0,
|
|
9942
|
-
/* @__PURE__ */ (0,
|
|
9943
|
-
/* @__PURE__ */ (0,
|
|
10723
|
+
/* @__PURE__ */ (0, import_jsx_runtime61.jsxs)("div", { className: sectionCls2, children: [
|
|
10724
|
+
/* @__PURE__ */ (0, import_jsx_runtime61.jsx)("label", { className: labelCls2, children: "Experience description" }),
|
|
10725
|
+
/* @__PURE__ */ (0, import_jsx_runtime61.jsx)("textarea", { value: experienceDescription, onChange: (e) => setExperienceDescription(e.target.value), className: `${inputCls2} min-h-[60px]`, rows: 2, placeholder: "Optional" })
|
|
9944
10726
|
] }),
|
|
9945
|
-
/* @__PURE__ */ (0,
|
|
9946
|
-
/* @__PURE__ */ (0,
|
|
9947
|
-
/* @__PURE__ */ (0,
|
|
10727
|
+
/* @__PURE__ */ (0, import_jsx_runtime61.jsxs)("div", { className: sectionCls2, children: [
|
|
10728
|
+
/* @__PURE__ */ (0, import_jsx_runtime61.jsx)("label", { className: labelCls2, children: "Brochure URL" }),
|
|
10729
|
+
/* @__PURE__ */ (0, import_jsx_runtime61.jsx)("input", { type: "url", value: brochureUrl, onChange: (e) => setBrochureUrl(e.target.value), className: inputCls2, placeholder: "https://..." })
|
|
9948
10730
|
] })
|
|
9949
10731
|
] })
|
|
9950
10732
|
] })
|
|
9951
10733
|
] }),
|
|
9952
|
-
sidebar: /* @__PURE__ */ (0,
|
|
9953
|
-
/* @__PURE__ */ (0,
|
|
9954
|
-
/* @__PURE__ */ (0,
|
|
9955
|
-
/* @__PURE__ */ (0,
|
|
9956
|
-
/* @__PURE__ */ (0,
|
|
9957
|
-
/* @__PURE__ */ (0,
|
|
10734
|
+
sidebar: /* @__PURE__ */ (0, import_jsx_runtime61.jsxs)(import_jsx_runtime61.Fragment, { children: [
|
|
10735
|
+
/* @__PURE__ */ (0, import_jsx_runtime61.jsxs)("section", { children: [
|
|
10736
|
+
/* @__PURE__ */ (0, import_jsx_runtime61.jsx)("h2", { className: "text-xs font-semibold text-gray-400 uppercase tracking-wider mb-2", children: "Status" }),
|
|
10737
|
+
/* @__PURE__ */ (0, import_jsx_runtime61.jsx)("div", { className: sectionCls2, children: /* @__PURE__ */ (0, import_jsx_runtime61.jsxs)("label", { className: "flex items-center gap-2 cursor-pointer", children: [
|
|
10738
|
+
/* @__PURE__ */ (0, import_jsx_runtime61.jsx)("input", { type: "checkbox", checked: active, onChange: (e) => setActive(e.target.checked), className: "h-4 w-4 rounded border-gray-300" }),
|
|
10739
|
+
/* @__PURE__ */ (0, import_jsx_runtime61.jsx)("span", { className: "text-sm font-medium text-gray-900", children: "Active" })
|
|
9958
10740
|
] }) })
|
|
9959
10741
|
] }),
|
|
9960
|
-
/* @__PURE__ */ (0,
|
|
9961
|
-
/* @__PURE__ */ (0,
|
|
9962
|
-
/* @__PURE__ */ (0,
|
|
10742
|
+
/* @__PURE__ */ (0, import_jsx_runtime61.jsxs)("section", { children: [
|
|
10743
|
+
/* @__PURE__ */ (0, import_jsx_runtime61.jsx)("h2", { className: "text-xs font-semibold text-gray-400 uppercase tracking-wider mb-2", children: "SEO" }),
|
|
10744
|
+
/* @__PURE__ */ (0, import_jsx_runtime61.jsx)("div", { className: sectionCls2, children: /* @__PURE__ */ (0, import_jsx_runtime61.jsx)(SeoSection, { values: seo, onChange: (field, value) => setSeo((s) => ({ ...s, [field]: value })) }) })
|
|
9963
10745
|
] })
|
|
9964
10746
|
] })
|
|
9965
10747
|
}
|
|
@@ -9970,7 +10752,7 @@ function CollectionEditPage({ collectionId }) {
|
|
|
9970
10752
|
// src/admin/pages/RolesPage.tsx
|
|
9971
10753
|
var import_react45 = require("react");
|
|
9972
10754
|
var import_react46 = require("next-auth/react");
|
|
9973
|
-
var
|
|
10755
|
+
var import_lucide_react36 = require("lucide-react");
|
|
9974
10756
|
|
|
9975
10757
|
// src/auth/permission-entities.ts
|
|
9976
10758
|
var ADMIN_GROUP_NAME = "Administrator";
|
|
@@ -9979,22 +10761,22 @@ function isSuperAdminGroupName(name) {
|
|
|
9979
10761
|
}
|
|
9980
10762
|
|
|
9981
10763
|
// src/admin/pages/RolesPage.tsx
|
|
9982
|
-
var
|
|
10764
|
+
var import_jsx_runtime62 = require("react/jsx-runtime");
|
|
9983
10765
|
function RoleListItem({
|
|
9984
10766
|
group,
|
|
9985
10767
|
selected,
|
|
9986
10768
|
onSelect
|
|
9987
10769
|
}) {
|
|
9988
10770
|
const superG = isSuperAdminGroupName(group.name);
|
|
9989
|
-
return /* @__PURE__ */ (0,
|
|
10771
|
+
return /* @__PURE__ */ (0, import_jsx_runtime62.jsxs)(
|
|
9990
10772
|
"button",
|
|
9991
10773
|
{
|
|
9992
10774
|
type: "button",
|
|
9993
10775
|
onClick: onSelect,
|
|
9994
10776
|
className: `flex w-full items-center gap-3 rounded-lg border px-3 py-2.5 text-left transition-colors ${selected ? "border-gray-300 bg-gray-50 dark:border-gray-600 dark:bg-gray-700/50" : "border-transparent hover:bg-gray-50 dark:hover:bg-gray-800/50"}`,
|
|
9995
10777
|
children: [
|
|
9996
|
-
/* @__PURE__ */ (0,
|
|
9997
|
-
/* @__PURE__ */ (0,
|
|
10778
|
+
/* @__PURE__ */ (0, import_jsx_runtime62.jsx)(import_lucide_react36.Shield, { className: "h-5 w-5 shrink-0 text-gray-500" }),
|
|
10779
|
+
/* @__PURE__ */ (0, import_jsx_runtime62.jsx)("div", { className: "min-w-0 flex-1", children: /* @__PURE__ */ (0, import_jsx_runtime62.jsx)("div", { className: "font-medium text-gray-900 dark:text-white truncate", children: group.name }) })
|
|
9998
10780
|
]
|
|
9999
10781
|
}
|
|
10000
10782
|
);
|
|
@@ -10128,27 +10910,27 @@ function RolesPage() {
|
|
|
10128
10910
|
}
|
|
10129
10911
|
};
|
|
10130
10912
|
if (status === "loading" || loading) {
|
|
10131
|
-
return /* @__PURE__ */ (0,
|
|
10913
|
+
return /* @__PURE__ */ (0, import_jsx_runtime62.jsx)("div", { className: "flex items-center justify-center py-12 text-gray-600", children: "Loading\u2026" });
|
|
10132
10914
|
}
|
|
10133
10915
|
if (!canManage) {
|
|
10134
|
-
return /* @__PURE__ */ (0,
|
|
10916
|
+
return /* @__PURE__ */ (0, import_jsx_runtime62.jsx)("p", { className: "text-gray-600 p-6", children: "You do not have permission to manage roles." });
|
|
10135
10917
|
}
|
|
10136
|
-
return /* @__PURE__ */ (0,
|
|
10137
|
-
/* @__PURE__ */ (0,
|
|
10138
|
-
/* @__PURE__ */ (0,
|
|
10139
|
-
/* @__PURE__ */ (0,
|
|
10918
|
+
return /* @__PURE__ */ (0, import_jsx_runtime62.jsxs)("div", { className: "min-w-0 rounded-lg bg-white shadow-md dark:bg-gray-800", children: [
|
|
10919
|
+
/* @__PURE__ */ (0, import_jsx_runtime62.jsxs)("div", { className: "rounded-t-lg border-b border-gray-700 bg-gray-800 px-4 py-2.5 dark:border-gray-700 dark:bg-gray-900", children: [
|
|
10920
|
+
/* @__PURE__ */ (0, import_jsx_runtime62.jsx)("h1", { className: "text-base font-semibold text-white", children: "Roles" }),
|
|
10921
|
+
/* @__PURE__ */ (0, import_jsx_runtime62.jsx)("p", { className: "mt-0.5 text-xs text-gray-300", children: "Only the Administrator group can open this page. All roles use the matrix for entity access (Administrator also has users / roles plumbing without matrix rows)." })
|
|
10140
10922
|
] }),
|
|
10141
|
-
/* @__PURE__ */ (0,
|
|
10142
|
-
error ? /* @__PURE__ */ (0,
|
|
10143
|
-
/* @__PURE__ */ (0,
|
|
10144
|
-
/* @__PURE__ */ (0,
|
|
10145
|
-
] }) : /* @__PURE__ */ (0,
|
|
10146
|
-
/* @__PURE__ */ (0,
|
|
10147
|
-
groups.map((g) => /* @__PURE__ */ (0,
|
|
10148
|
-
/* @__PURE__ */ (0,
|
|
10149
|
-
/* @__PURE__ */ (0,
|
|
10150
|
-
/* @__PURE__ */ (0,
|
|
10151
|
-
/* @__PURE__ */ (0,
|
|
10923
|
+
/* @__PURE__ */ (0, import_jsx_runtime62.jsxs)("div", { className: "min-w-0 p-6", children: [
|
|
10924
|
+
error ? /* @__PURE__ */ (0, import_jsx_runtime62.jsx)("div", { className: "py-8 text-center", children: /* @__PURE__ */ (0, import_jsx_runtime62.jsx)("p", { className: "text-sm text-red-600 dark:text-red-400", children: error }) }) : groups.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime62.jsxs)("div", { className: "py-12 text-center", children: [
|
|
10925
|
+
/* @__PURE__ */ (0, import_jsx_runtime62.jsx)(import_lucide_react36.Shield, { className: "mx-auto h-10 w-10 text-gray-400" }),
|
|
10926
|
+
/* @__PURE__ */ (0, import_jsx_runtime62.jsx)("p", { className: "mt-3 text-sm text-gray-500 dark:text-gray-400", children: "No roles yet. Add one below." })
|
|
10927
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime62.jsxs)("div", { className: "flex gap-6", children: [
|
|
10928
|
+
/* @__PURE__ */ (0, import_jsx_runtime62.jsxs)("div", { className: "w-56 shrink-0 space-y-1", children: [
|
|
10929
|
+
groups.map((g) => /* @__PURE__ */ (0, import_jsx_runtime62.jsx)(RoleListItem, { group: g, selected: selectedId === g.id, onSelect: () => setSelectedId(g.id) }, g.id)),
|
|
10930
|
+
/* @__PURE__ */ (0, import_jsx_runtime62.jsxs)("div", { className: "space-y-2 border-t border-gray-200 pt-3 dark:border-gray-700", children: [
|
|
10931
|
+
/* @__PURE__ */ (0, import_jsx_runtime62.jsx)(Label3, { className: "text-xs text-gray-500", children: "New role" }),
|
|
10932
|
+
/* @__PURE__ */ (0, import_jsx_runtime62.jsxs)("div", { className: "flex gap-2", children: [
|
|
10933
|
+
/* @__PURE__ */ (0, import_jsx_runtime62.jsx)(
|
|
10152
10934
|
Input,
|
|
10153
10935
|
{
|
|
10154
10936
|
className: "h-8 text-sm",
|
|
@@ -10158,42 +10940,42 @@ function RolesPage() {
|
|
|
10158
10940
|
onKeyDown: (e) => e.key === "Enter" && createGroup()
|
|
10159
10941
|
}
|
|
10160
10942
|
),
|
|
10161
|
-
/* @__PURE__ */ (0,
|
|
10943
|
+
/* @__PURE__ */ (0, import_jsx_runtime62.jsx)(Button, { type: "button", size: "sm", variant: "outline", className: "shrink-0", onClick: createGroup, children: "Add" })
|
|
10162
10944
|
] })
|
|
10163
10945
|
] })
|
|
10164
10946
|
] }),
|
|
10165
|
-
/* @__PURE__ */ (0,
|
|
10166
|
-
/* @__PURE__ */ (0,
|
|
10167
|
-
/* @__PURE__ */ (0,
|
|
10168
|
-
] }) : /* @__PURE__ */ (0,
|
|
10169
|
-
/* @__PURE__ */ (0,
|
|
10170
|
-
/* @__PURE__ */ (0,
|
|
10947
|
+
/* @__PURE__ */ (0, import_jsx_runtime62.jsx)("div", { className: "min-w-0 flex-1", children: !selectedId ? /* @__PURE__ */ (0, import_jsx_runtime62.jsxs)("div", { className: "flex flex-col items-center justify-center py-12 text-center", children: [
|
|
10948
|
+
/* @__PURE__ */ (0, import_jsx_runtime62.jsx)(import_lucide_react36.Shield, { className: "h-10 w-10 text-gray-300 dark:text-gray-600" }),
|
|
10949
|
+
/* @__PURE__ */ (0, import_jsx_runtime62.jsx)("p", { className: "mt-3 text-sm text-gray-500 dark:text-gray-400", children: "Select a role to view or edit permissions." })
|
|
10950
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime62.jsxs)("div", { className: "rounded-lg border border-gray-200 bg-gray-50/50 p-5 dark:border-gray-700 dark:bg-gray-800/50", children: [
|
|
10951
|
+
/* @__PURE__ */ (0, import_jsx_runtime62.jsxs)("div", { className: "mb-4 flex flex-wrap items-center gap-2", children: [
|
|
10952
|
+
/* @__PURE__ */ (0, import_jsx_runtime62.jsxs)("h2", { className: "text-sm font-medium text-gray-700 dark:text-gray-300", children: [
|
|
10171
10953
|
selected?.name,
|
|
10172
10954
|
" \u2014 Permissions"
|
|
10173
10955
|
] }),
|
|
10174
|
-
/* @__PURE__ */ (0,
|
|
10175
|
-
/* @__PURE__ */ (0,
|
|
10956
|
+
/* @__PURE__ */ (0, import_jsx_runtime62.jsxs)(Button, { size: "sm", onClick: saveMatrix, disabled: saving, className: "gap-1", children: [
|
|
10957
|
+
/* @__PURE__ */ (0, import_jsx_runtime62.jsx)(import_lucide_react36.Save, { className: "h-3.5 w-3.5" }),
|
|
10176
10958
|
saving ? "Saving\u2026" : "Save"
|
|
10177
10959
|
] }),
|
|
10178
|
-
selected && !isSuperAdminGroupName(selected.name) && /* @__PURE__ */ (0,
|
|
10179
|
-
/* @__PURE__ */ (0,
|
|
10960
|
+
selected && !isSuperAdminGroupName(selected.name) && /* @__PURE__ */ (0, import_jsx_runtime62.jsxs)(Button, { size: "sm", variant: "outline", className: "gap-1 text-red-600", onClick: deleteGroup, children: [
|
|
10961
|
+
/* @__PURE__ */ (0, import_jsx_runtime62.jsx)(import_lucide_react36.Trash2, { className: "h-3.5 w-3.5" }),
|
|
10180
10962
|
"Delete role"
|
|
10181
10963
|
] })
|
|
10182
10964
|
] }),
|
|
10183
|
-
entities.length > 0 && /* @__PURE__ */ (0,
|
|
10184
|
-
/* @__PURE__ */ (0,
|
|
10185
|
-
/* @__PURE__ */ (0,
|
|
10186
|
-
/* @__PURE__ */ (0,
|
|
10187
|
-
/* @__PURE__ */ (0,
|
|
10188
|
-
/* @__PURE__ */ (0,
|
|
10189
|
-
/* @__PURE__ */ (0,
|
|
10965
|
+
entities.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime62.jsx)("div", { className: "overflow-x-auto rounded-md border border-gray-200 dark:border-gray-600", children: /* @__PURE__ */ (0, import_jsx_runtime62.jsxs)("table", { className: "w-full text-sm", children: [
|
|
10966
|
+
/* @__PURE__ */ (0, import_jsx_runtime62.jsx)("thead", { children: /* @__PURE__ */ (0, import_jsx_runtime62.jsxs)("tr", { className: "border-b bg-gray-50 dark:bg-gray-900/50", children: [
|
|
10967
|
+
/* @__PURE__ */ (0, import_jsx_runtime62.jsx)("th", { className: "p-3 text-left font-medium", children: "Resource" }),
|
|
10968
|
+
/* @__PURE__ */ (0, import_jsx_runtime62.jsx)("th", { className: "p-2", children: "C" }),
|
|
10969
|
+
/* @__PURE__ */ (0, import_jsx_runtime62.jsx)("th", { className: "p-2", children: "R" }),
|
|
10970
|
+
/* @__PURE__ */ (0, import_jsx_runtime62.jsx)("th", { className: "p-2", children: "U" }),
|
|
10971
|
+
/* @__PURE__ */ (0, import_jsx_runtime62.jsx)("th", { className: "p-2", children: "D" })
|
|
10190
10972
|
] }) }),
|
|
10191
|
-
/* @__PURE__ */ (0,
|
|
10973
|
+
/* @__PURE__ */ (0, import_jsx_runtime62.jsx)("tbody", { children: entities.map((entity) => {
|
|
10192
10974
|
const row = matrix[entity];
|
|
10193
10975
|
if (!row) return null;
|
|
10194
|
-
return /* @__PURE__ */ (0,
|
|
10195
|
-
/* @__PURE__ */ (0,
|
|
10196
|
-
["canCreate", "canRead", "canUpdate", "canDelete"].map((k) => /* @__PURE__ */ (0,
|
|
10976
|
+
return /* @__PURE__ */ (0, import_jsx_runtime62.jsxs)("tr", { className: "border-b border-gray-100 hover:bg-gray-50/50 dark:border-gray-700 dark:hover:bg-gray-800/30", children: [
|
|
10977
|
+
/* @__PURE__ */ (0, import_jsx_runtime62.jsx)("td", { className: "p-3 font-mono text-xs", children: entity }),
|
|
10978
|
+
["canCreate", "canRead", "canUpdate", "canDelete"].map((k) => /* @__PURE__ */ (0, import_jsx_runtime62.jsx)("td", { className: "p-2 text-center", children: /* @__PURE__ */ (0, import_jsx_runtime62.jsx)(
|
|
10197
10979
|
"input",
|
|
10198
10980
|
{
|
|
10199
10981
|
type: "checkbox",
|
|
@@ -10206,9 +10988,9 @@ function RolesPage() {
|
|
|
10206
10988
|
] }) })
|
|
10207
10989
|
] }) })
|
|
10208
10990
|
] }),
|
|
10209
|
-
!error && groups.length === 0 && /* @__PURE__ */ (0,
|
|
10210
|
-
/* @__PURE__ */ (0,
|
|
10211
|
-
/* @__PURE__ */ (0,
|
|
10991
|
+
!error && groups.length === 0 && /* @__PURE__ */ (0, import_jsx_runtime62.jsxs)("div", { className: "mt-6 flex max-w-md gap-2", children: [
|
|
10992
|
+
/* @__PURE__ */ (0, import_jsx_runtime62.jsx)(Input, { placeholder: "New role name", value: newName, onChange: (e) => setNewName(e.target.value), onKeyDown: (e) => e.key === "Enter" && createGroup() }),
|
|
10993
|
+
/* @__PURE__ */ (0, import_jsx_runtime62.jsx)(Button, { type: "button", onClick: createGroup, children: "Add role" })
|
|
10212
10994
|
] })
|
|
10213
10995
|
] })
|
|
10214
10996
|
] });
|
|
@@ -10370,7 +11152,7 @@ var STORE_CRUD_CONFIGS = {
|
|
|
10370
11152
|
};
|
|
10371
11153
|
|
|
10372
11154
|
// src/admin/pages/AdminPageResolver.tsx
|
|
10373
|
-
var
|
|
11155
|
+
var import_jsx_runtime63 = require("react/jsx-runtime");
|
|
10374
11156
|
var PAGE_MAP = {
|
|
10375
11157
|
dashboard: DashboardPage,
|
|
10376
11158
|
signin: SignInPage_default,
|
|
@@ -10495,12 +11277,12 @@ function BlogEditorWrapper({ blogId }) {
|
|
|
10495
11277
|
fetch(`/api/blogs/${blogId}`).then((res) => res.ok ? res.json() : null).then((data) => setBlog(data)).finally(() => setLoading(false));
|
|
10496
11278
|
}, [blogId]);
|
|
10497
11279
|
if (loading) {
|
|
10498
|
-
return /* @__PURE__ */ (0,
|
|
10499
|
-
/* @__PURE__ */ (0,
|
|
10500
|
-
/* @__PURE__ */ (0,
|
|
11280
|
+
return /* @__PURE__ */ (0, import_jsx_runtime63.jsxs)("div", { className: "flex items-center justify-center py-8", children: [
|
|
11281
|
+
/* @__PURE__ */ (0, import_jsx_runtime63.jsx)("div", { className: "animate-spin rounded-full h-6 w-6 border-2 border-gray-300 border-t-gray-600" }),
|
|
11282
|
+
/* @__PURE__ */ (0, import_jsx_runtime63.jsx)("span", { className: "ml-2", children: "Loading..." })
|
|
10501
11283
|
] });
|
|
10502
11284
|
}
|
|
10503
|
-
return /* @__PURE__ */ (0,
|
|
11285
|
+
return /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(BlogEditor, { existingBlog: blog });
|
|
10504
11286
|
}
|
|
10505
11287
|
function AdminPageResolver({ slug }) {
|
|
10506
11288
|
const router = (0, import_navigation19.useRouter)();
|
|
@@ -10512,53 +11294,53 @@ function AdminPageResolver({ slug }) {
|
|
|
10512
11294
|
}
|
|
10513
11295
|
}, [key, router]);
|
|
10514
11296
|
if (key === "layout-settings") {
|
|
10515
|
-
return /* @__PURE__ */ (0,
|
|
10516
|
-
/* @__PURE__ */ (0,
|
|
10517
|
-
/* @__PURE__ */ (0,
|
|
11297
|
+
return /* @__PURE__ */ (0, import_jsx_runtime63.jsxs)("div", { className: "flex justify-center py-8", children: [
|
|
11298
|
+
/* @__PURE__ */ (0, import_jsx_runtime63.jsx)("div", { className: "animate-spin rounded-full h-6 w-6 border-2 border-gray-300 border-t-gray-600" }),
|
|
11299
|
+
/* @__PURE__ */ (0, import_jsx_runtime63.jsx)("span", { className: "ml-2", children: "Redirecting..." })
|
|
10518
11300
|
] });
|
|
10519
11301
|
}
|
|
10520
11302
|
const Page = PAGE_MAP[key];
|
|
10521
11303
|
if (Page) {
|
|
10522
|
-
return /* @__PURE__ */ (0,
|
|
11304
|
+
return /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(Page, {});
|
|
10523
11305
|
}
|
|
10524
11306
|
if (key === "form-submissions" && slug && slug.length === 3 && slug[2] === "view") {
|
|
10525
|
-
return /* @__PURE__ */ (0,
|
|
11307
|
+
return /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(SubmissionDetailPage, { submissionId: slug[1] });
|
|
10526
11308
|
}
|
|
10527
11309
|
if (key === "orders" && slug && slug.length === 3 && slug[2] === "view") {
|
|
10528
|
-
return /* @__PURE__ */ (0,
|
|
11310
|
+
return /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(OrderDetailPage, { orderId: slug[1] });
|
|
10529
11311
|
}
|
|
10530
11312
|
if (key === "payments" && slug && slug.length === 3 && slug[2] === "view") {
|
|
10531
|
-
return /* @__PURE__ */ (0,
|
|
11313
|
+
return /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(PaymentDetailPage, { paymentId: slug[1] });
|
|
10532
11314
|
}
|
|
10533
11315
|
if (key === "contacts" && slug && slug.length === 3 && slug[2] === "view") {
|
|
10534
|
-
return /* @__PURE__ */ (0,
|
|
11316
|
+
return /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(ContactDetailPage, { contactId: slug[1] });
|
|
10535
11317
|
}
|
|
10536
11318
|
const crud = { ...CRUD_CONFIGS, ...STORE_CRUD_CONFIGS, ...customCrudConfigs }[key];
|
|
10537
11319
|
if (crud && slug && slug.length >= 2) {
|
|
10538
11320
|
const subPath = slug[1];
|
|
10539
11321
|
const isCreate4 = subPath === "create";
|
|
10540
11322
|
if (key === "blogs") {
|
|
10541
|
-
return /* @__PURE__ */ (0,
|
|
11323
|
+
return /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(BlogEditorWrapper, { blogId: isCreate4 ? void 0 : subPath });
|
|
10542
11324
|
}
|
|
10543
11325
|
if (key === "forms") {
|
|
10544
|
-
return /* @__PURE__ */ (0,
|
|
11326
|
+
return /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(FormBuilder, { formId: isCreate4 ? void 0 : subPath });
|
|
10545
11327
|
}
|
|
10546
11328
|
if (key === "pages") {
|
|
10547
|
-
return /* @__PURE__ */ (0,
|
|
11329
|
+
return /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(PageBuilderPage, { pageId: isCreate4 ? void 0 : subPath });
|
|
10548
11330
|
}
|
|
10549
11331
|
if (key === "brands") {
|
|
10550
|
-
return /* @__PURE__ */ (0,
|
|
11332
|
+
return /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(BrandEditPage, { brandId: subPath });
|
|
10551
11333
|
}
|
|
10552
11334
|
if (key === "products") {
|
|
10553
|
-
return /* @__PURE__ */ (0,
|
|
11335
|
+
return /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(ProductEditPage, { productId: subPath });
|
|
10554
11336
|
}
|
|
10555
11337
|
if (key === "collections") {
|
|
10556
|
-
return /* @__PURE__ */ (0,
|
|
11338
|
+
return /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(CollectionEditPage, { collectionId: subPath });
|
|
10557
11339
|
}
|
|
10558
11340
|
}
|
|
10559
11341
|
if (crud) {
|
|
10560
11342
|
if (key === "media") {
|
|
10561
|
-
return /* @__PURE__ */ (0,
|
|
11343
|
+
return /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(MediaLibraryPage, {});
|
|
10562
11344
|
}
|
|
10563
11345
|
const isContactsWithStore = key === "contacts" && storeEnabled;
|
|
10564
11346
|
const columns = isContactsWithStore ? [
|
|
@@ -10570,7 +11352,7 @@ function AdminPageResolver({ slug }) {
|
|
|
10570
11352
|
() => isContactsWithStore ? { includeSummary: "1" } : void 0,
|
|
10571
11353
|
[isContactsWithStore]
|
|
10572
11354
|
);
|
|
10573
|
-
return /* @__PURE__ */ (0,
|
|
11355
|
+
return /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(
|
|
10574
11356
|
AdminCRUD,
|
|
10575
11357
|
{
|
|
10576
11358
|
title: crud.title,
|
|
@@ -10585,13 +11367,13 @@ function AdminPageResolver({ slug }) {
|
|
|
10585
11367
|
}
|
|
10586
11368
|
);
|
|
10587
11369
|
}
|
|
10588
|
-
return /* @__PURE__ */ (0,
|
|
11370
|
+
return /* @__PURE__ */ (0, import_jsx_runtime63.jsx)("div", { className: "flex items-center justify-center min-h-[50vh]", children: /* @__PURE__ */ (0, import_jsx_runtime63.jsx)("p", { className: "text-gray-500", children: "Page not found" }) });
|
|
10589
11371
|
}
|
|
10590
11372
|
|
|
10591
11373
|
// src/admin/pages/LayoutSettingsPage.tsx
|
|
10592
11374
|
var import_react48 = require("react");
|
|
10593
|
-
var
|
|
10594
|
-
var
|
|
11375
|
+
var import_lucide_react37 = require("lucide-react");
|
|
11376
|
+
var import_jsx_runtime64 = require("react/jsx-runtime");
|
|
10595
11377
|
function LayoutSettingsPage() {
|
|
10596
11378
|
const { theme } = (0, import_react48.useContext)(AdminConfigContext);
|
|
10597
11379
|
const [activeTab, setActiveTab] = (0, import_react48.useState)("navbar");
|
|
@@ -10647,29 +11429,29 @@ function LayoutSettingsPage() {
|
|
|
10647
11429
|
props: footerLayout.fields
|
|
10648
11430
|
} : null;
|
|
10649
11431
|
if (loading) {
|
|
10650
|
-
return /* @__PURE__ */ (0,
|
|
11432
|
+
return /* @__PURE__ */ (0, import_jsx_runtime64.jsx)("div", { className: "flex items-center justify-center py-12", children: /* @__PURE__ */ (0, import_jsx_runtime64.jsx)("div", { className: "animate-spin rounded-full h-6 w-6 border-2 border-gray-300 border-t-gray-600" }) });
|
|
10651
11433
|
}
|
|
10652
|
-
return /* @__PURE__ */ (0,
|
|
10653
|
-
/* @__PURE__ */ (0,
|
|
10654
|
-
/* @__PURE__ */ (0,
|
|
10655
|
-
/* @__PURE__ */ (0,
|
|
10656
|
-
/* @__PURE__ */ (0,
|
|
11434
|
+
return /* @__PURE__ */ (0, import_jsx_runtime64.jsxs)("div", { className: "min-w-0 rounded-lg bg-white shadow-md", children: [
|
|
11435
|
+
/* @__PURE__ */ (0, import_jsx_runtime64.jsxs)("div", { className: "bg-gray-800 px-4 py-2.5 rounded-t-lg flex items-center justify-between", children: [
|
|
11436
|
+
/* @__PURE__ */ (0, import_jsx_runtime64.jsxs)("div", { children: [
|
|
11437
|
+
/* @__PURE__ */ (0, import_jsx_runtime64.jsx)("h1", { className: "text-xl font-bold text-white", children: "Layout Settings" }),
|
|
11438
|
+
/* @__PURE__ */ (0, import_jsx_runtime64.jsx)("p", { className: "text-xs text-gray-300 mt-0.5", children: "Configure your site navbar and footer" })
|
|
10657
11439
|
] }),
|
|
10658
|
-
/* @__PURE__ */ (0,
|
|
11440
|
+
/* @__PURE__ */ (0, import_jsx_runtime64.jsxs)(
|
|
10659
11441
|
Button,
|
|
10660
11442
|
{
|
|
10661
11443
|
onClick: handleSave,
|
|
10662
11444
|
disabled: saving,
|
|
10663
11445
|
className: "bg-white text-gray-800 hover:bg-gray-100 border-0 text-xs",
|
|
10664
11446
|
children: [
|
|
10665
|
-
/* @__PURE__ */ (0,
|
|
11447
|
+
/* @__PURE__ */ (0, import_jsx_runtime64.jsx)(import_lucide_react37.Save, { className: "h-4 w-4 mr-2" }),
|
|
10666
11448
|
saving ? "Saving..." : "Save"
|
|
10667
11449
|
]
|
|
10668
11450
|
}
|
|
10669
11451
|
)
|
|
10670
11452
|
] }),
|
|
10671
|
-
/* @__PURE__ */ (0,
|
|
10672
|
-
/* @__PURE__ */ (0,
|
|
11453
|
+
/* @__PURE__ */ (0, import_jsx_runtime64.jsx)("div", { className: "border-b", children: /* @__PURE__ */ (0, import_jsx_runtime64.jsxs)("div", { className: "flex", children: [
|
|
11454
|
+
/* @__PURE__ */ (0, import_jsx_runtime64.jsx)(
|
|
10673
11455
|
"button",
|
|
10674
11456
|
{
|
|
10675
11457
|
className: `px-4 py-2.5 text-sm font-medium border-b-2 ${activeTab === "navbar" ? "border-gray-800 text-gray-800" : "border-transparent text-gray-500 hover:text-gray-700"}`,
|
|
@@ -10677,7 +11459,7 @@ function LayoutSettingsPage() {
|
|
|
10677
11459
|
children: "Navbar"
|
|
10678
11460
|
}
|
|
10679
11461
|
),
|
|
10680
|
-
/* @__PURE__ */ (0,
|
|
11462
|
+
/* @__PURE__ */ (0, import_jsx_runtime64.jsx)(
|
|
10681
11463
|
"button",
|
|
10682
11464
|
{
|
|
10683
11465
|
className: `px-4 py-2.5 text-sm font-medium border-b-2 ${activeTab === "footer" ? "border-gray-800 text-gray-800" : "border-transparent text-gray-500 hover:text-gray-700"}`,
|
|
@@ -10686,9 +11468,9 @@ function LayoutSettingsPage() {
|
|
|
10686
11468
|
}
|
|
10687
11469
|
)
|
|
10688
11470
|
] }) }),
|
|
10689
|
-
/* @__PURE__ */ (0,
|
|
10690
|
-
activeTab === "navbar" && /* @__PURE__ */ (0,
|
|
10691
|
-
activeTab === "footer" && footerMeta && /* @__PURE__ */ (0,
|
|
11471
|
+
/* @__PURE__ */ (0, import_jsx_runtime64.jsxs)("div", { className: "min-w-0 p-6", children: [
|
|
11472
|
+
activeTab === "navbar" && /* @__PURE__ */ (0, import_jsx_runtime64.jsx)(NavbarEditor, { config: navbarConfig, onChange: setNavbarConfig }),
|
|
11473
|
+
activeTab === "footer" && footerMeta && /* @__PURE__ */ (0, import_jsx_runtime64.jsx)(
|
|
10692
11474
|
ComponentSettings,
|
|
10693
11475
|
{
|
|
10694
11476
|
meta: footerMeta,
|
|
@@ -10696,7 +11478,7 @@ function LayoutSettingsPage() {
|
|
|
10696
11478
|
onChange: (name, val) => setFooterValues((prev) => ({ ...prev, [name]: val }))
|
|
10697
11479
|
}
|
|
10698
11480
|
),
|
|
10699
|
-
activeTab === "footer" && !footerMeta && /* @__PURE__ */ (0,
|
|
11481
|
+
activeTab === "footer" && !footerMeta && /* @__PURE__ */ (0, import_jsx_runtime64.jsx)("p", { className: "text-sm text-gray-500", children: "No footer configuration defined in the current theme." })
|
|
10700
11482
|
] })
|
|
10701
11483
|
] });
|
|
10702
11484
|
}
|
|
@@ -10717,11 +11499,11 @@ var DEFAULT_ADMIN_NAV = [
|
|
|
10717
11499
|
var import_react49 = require("next-auth/react");
|
|
10718
11500
|
var import_next_themes = require("next-themes");
|
|
10719
11501
|
var import_sonner7 = require("sonner");
|
|
10720
|
-
var
|
|
11502
|
+
var import_jsx_runtime65 = require("react/jsx-runtime");
|
|
10721
11503
|
function CmsProviders({ children }) {
|
|
10722
|
-
return /* @__PURE__ */ (0,
|
|
11504
|
+
return /* @__PURE__ */ (0, import_jsx_runtime65.jsx)(import_react49.SessionProvider, { children: /* @__PURE__ */ (0, import_jsx_runtime65.jsxs)(import_next_themes.ThemeProvider, { attribute: "class", defaultTheme: "system", enableSystem: true, children: [
|
|
10723
11505
|
children,
|
|
10724
|
-
/* @__PURE__ */ (0,
|
|
11506
|
+
/* @__PURE__ */ (0, import_jsx_runtime65.jsx)(import_sonner7.Toaster, { position: "top-right" })
|
|
10725
11507
|
] }) });
|
|
10726
11508
|
}
|
|
10727
11509
|
// Annotate the CommonJS export names for ESM import in node:
|