@shapio/cms 0.5.8 → 0.5.10
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/assets/{AssetTile-BrMzsUZD.js → AssetTile-DecaDqjj.js} +2 -2
- package/dist/admin/assets/{AssetTile-BrMzsUZD.js.map → AssetTile-DecaDqjj.js.map} +1 -1
- package/dist/admin/assets/AssistError-rslPtgWB.js +2 -0
- package/dist/admin/assets/{AssistError-Cs-r9Ssc.js.map → AssistError-rslPtgWB.js.map} +1 -1
- package/dist/admin/assets/{BlockMenuItems-DsccXMc_.js → BlockMenuItems-JHFue7Qt.js} +2 -2
- package/dist/admin/assets/{BlockMenuItems-DsccXMc_.js.map → BlockMenuItems-JHFue7Qt.js.map} +1 -1
- package/dist/admin/assets/Body-7NgJl9Pi.js +2 -0
- package/dist/admin/assets/Body-7NgJl9Pi.js.map +1 -0
- package/dist/admin/assets/Builder-DmlYcgiP.js +2 -0
- package/dist/admin/assets/Builder-DmlYcgiP.js.map +1 -0
- package/dist/admin/assets/{CodeEditor-CBCR73Wd.js → CodeEditor-Dv1FtkvI.js} +2 -2
- package/dist/admin/assets/{CodeEditor-CBCR73Wd.js.map → CodeEditor-Dv1FtkvI.js.map} +1 -1
- package/dist/admin/assets/{CopyButton-CxFsBHfF.js → CopyButton-Brnpfqe0.js} +2 -2
- package/dist/admin/assets/{CopyButton-CxFsBHfF.js.map → CopyButton-Brnpfqe0.js.map} +1 -1
- package/dist/admin/assets/{CursorPager-BW2U3v6l.js → CursorPager-C7cAK5Qe.js} +2 -2
- package/dist/admin/assets/{CursorPager-BW2U3v6l.js.map → CursorPager-C7cAK5Qe.js.map} +1 -1
- package/dist/admin/assets/{ExternalLink-BITMgS1K.js → ExternalLink-D80sb5Jj.js} +2 -2
- package/dist/admin/assets/{ExternalLink-BITMgS1K.js.map → ExternalLink-D80sb5Jj.js.map} +1 -1
- package/dist/admin/assets/{FocalPoint-CpZTve1E.js → FocalPoint-Bhtb1gUa.js} +2 -2
- package/dist/admin/assets/{FocalPoint-CpZTve1E.js.map → FocalPoint-Bhtb1gUa.js.map} +1 -1
- package/dist/admin/assets/Form-Cf1ephPH.js +2 -0
- package/dist/admin/assets/Form-Cf1ephPH.js.map +1 -0
- package/dist/admin/assets/FormCheckboxGroup-BzVZFR3W.js +2 -0
- package/dist/admin/assets/FormCheckboxGroup-BzVZFR3W.js.map +1 -0
- package/dist/admin/assets/{FormRadioGroup-Cfx5pvzU.js → FormRadioGroup-BzmLzRnI.js} +2 -2
- package/dist/admin/assets/{FormRadioGroup-Cfx5pvzU.js.map → FormRadioGroup-BzmLzRnI.js.map} +1 -1
- package/dist/admin/assets/FormSelectField-Cl7EjXc3.js +2 -0
- package/dist/admin/assets/FormSelectField-Cl7EjXc3.js.map +1 -0
- package/dist/admin/assets/FormSheet-CLZpd_7B.js +2 -0
- package/dist/admin/assets/FormSheet-CLZpd_7B.js.map +1 -0
- package/dist/admin/assets/{FormSwitchField-BLOh7qei.js → FormSwitchField-BbqQ3tx_.js} +2 -2
- package/dist/admin/assets/{FormSwitchField-BLOh7qei.js.map → FormSwitchField-BbqQ3tx_.js.map} +1 -1
- package/dist/admin/assets/{FormTextareaField-CO115n_u.js → FormTextareaField-9RN5Pt3B.js} +2 -2
- package/dist/admin/assets/{FormTextareaField-CO115n_u.js.map → FormTextareaField-9RN5Pt3B.js.map} +1 -1
- package/dist/admin/assets/{HintedLabel-DzHnEdIK.js → HintedLabel-D9IVF0EE.js} +2 -2
- package/dist/admin/assets/{HintedLabel-DzHnEdIK.js.map → HintedLabel-D9IVF0EE.js.map} +1 -1
- package/dist/admin/assets/{InfoHint-CSEtcHjL.js → InfoHint-tlSeZB9U.js} +2 -2
- package/dist/admin/assets/{InfoHint-CSEtcHjL.js.map → InfoHint-tlSeZB9U.js.map} +1 -1
- package/dist/admin/assets/{InlineConfirm-yW-iUKFC.js → InlineConfirm-Kj9AOIFO.js} +2 -2
- package/dist/admin/assets/{InlineConfirm-yW-iUKFC.js.map → InlineConfirm-Kj9AOIFO.js.map} +1 -1
- package/dist/admin/assets/{InsertMenuItem-CCr9e0qY.js → InsertMenuItem-CHAp2tH7.js} +2 -2
- package/dist/admin/assets/{InsertMenuItem-CCr9e0qY.js.map → InsertMenuItem-CHAp2tH7.js.map} +1 -1
- package/dist/admin/assets/{LinkTabs-8SmS1vCd.js → LinkTabs-oQXsy1I3.js} +2 -2
- package/dist/admin/assets/{LinkTabs-8SmS1vCd.js.map → LinkTabs-oQXsy1I3.js.map} +1 -1
- package/dist/admin/assets/{Match-CcD9KxHH.js → Match-BfNRwPfR.js} +2 -2
- package/dist/admin/assets/{Match-CcD9KxHH.js.map → Match-BfNRwPfR.js.map} +1 -1
- package/dist/admin/assets/{NoAccess-C8RLPN0I.js → NoAccess-DnEpYj9l.js} +2 -2
- package/dist/admin/assets/{NoAccess-C8RLPN0I.js.map → NoAccess-DnEpYj9l.js.map} +1 -1
- package/dist/admin/assets/Panel-Bcl09TtM.js.map +1 -1
- package/dist/admin/assets/{QueryView-xMP_uJ_t.js → QueryView-B86NcRt5.js} +2 -2
- package/dist/admin/assets/{QueryView-xMP_uJ_t.js.map → QueryView-B86NcRt5.js.map} +1 -1
- package/dist/admin/assets/{RadioTile-DQFmni5A.js → RadioTile-Bwd2Pmlk.js} +2 -2
- package/dist/admin/assets/RadioTile-Bwd2Pmlk.js.map +1 -0
- package/dist/admin/assets/{RichTextField-CVHRIbnu.js → RichTextField-Dou79MHF.js} +4 -4
- package/dist/admin/assets/RichTextField-Dou79MHF.js.map +1 -0
- package/dist/admin/assets/{RowTitle-Bqt6evG9.js → RowTitle-DH9OZs3g.js} +2 -2
- package/dist/admin/assets/{RowTitle-Bqt6evG9.js.map → RowTitle-DH9OZs3g.js.map} +1 -1
- package/dist/admin/assets/{SecretReveal-Bm6nYg5J.js → SecretReveal-D95oACLj.js} +2 -2
- package/dist/admin/assets/{SecretReveal-Bm6nYg5J.js.map → SecretReveal-D95oACLj.js.map} +1 -1
- package/dist/admin/assets/{SharedGlyph-cUmTh0_C.js → SharedGlyph-Chwb1EIS.js} +2 -2
- package/dist/admin/assets/{SharedGlyph-cUmTh0_C.js.map → SharedGlyph-Chwb1EIS.js.map} +1 -1
- package/dist/admin/assets/StepList-D9iHsUZJ.js +2 -0
- package/dist/admin/assets/StepList-D9iHsUZJ.js.map +1 -0
- package/dist/admin/assets/Structure-CewJL1b3.js +2 -0
- package/dist/admin/assets/{Structure-D8csgrIt.js.map → Structure-CewJL1b3.js.map} +1 -1
- package/dist/admin/assets/{SubNavLink-CiCaVV8U.js → SubNavLink-7Cs1LqMv.js} +2 -2
- package/dist/admin/assets/SubNavLink-7Cs1LqMv.js.map +1 -0
- package/dist/admin/assets/{SuggestAltButton-CvIoirnz.js → SuggestAltButton-BK1uo4yC.js} +2 -2
- package/dist/admin/assets/{SuggestAltButton-CvIoirnz.js.map → SuggestAltButton-BK1uo4yC.js.map} +1 -1
- package/dist/admin/assets/{TextLink-HRn66VL1.js → TextLink-Dfs5wsc5.js} +2 -2
- package/dist/admin/assets/{TextLink-HRn66VL1.js.map → TextLink-Dfs5wsc5.js.map} +1 -1
- package/dist/admin/assets/{Thumbnail-DNj5TRBI.js → Thumbnail-C2A_Ub77.js} +2 -2
- package/dist/admin/assets/{Thumbnail-DNj5TRBI.js.map → Thumbnail-C2A_Ub77.js.map} +1 -1
- package/dist/admin/assets/Trans-CPoNNUK1.js +2 -0
- package/dist/admin/assets/Trans-CPoNNUK1.js.map +1 -0
- package/dist/admin/assets/{UnsavedChangesGuard-CUiuMklN.js → UnsavedChangesGuard-BsEyn9oH.js} +2 -2
- package/dist/admin/assets/{UnsavedChangesGuard-CUiuMklN.js.map → UnsavedChangesGuard-BsEyn9oH.js.map} +1 -1
- package/dist/admin/assets/{UserAvatar-p-jV-LoD.js → UserAvatar-CgGKOFfP.js} +2 -2
- package/dist/admin/assets/{UserAvatar-p-jV-LoD.js.map → UserAvatar-CgGKOFfP.js.map} +1 -1
- package/dist/admin/assets/auth-BFSvtV59.js +2 -0
- package/dist/admin/assets/{auth-CQO4MBUj.js.map → auth-BFSvtV59.js.map} +1 -1
- package/dist/admin/assets/{badge-CqKF1pwz.js → badge-DGqA_yr_.js} +2 -2
- package/dist/admin/assets/{badge-CqKF1pwz.js.map → badge-DGqA_yr_.js.map} +1 -1
- package/dist/admin/assets/baseExtensions-TVKN1UwW.js.map +1 -1
- package/dist/admin/assets/{boxes-CAygw8zF.js → boxes-_5klpWNM.js} +2 -2
- package/dist/admin/assets/{boxes-CAygw8zF.js.map → boxes-_5klpWNM.js.map} +1 -1
- package/dist/admin/assets/{calendar-clock-BZGtAvWR.js → calendar-clock-VXok22Xj.js} +2 -2
- package/dist/admin/assets/{calendar-clock-BZGtAvWR.js.map → calendar-clock-VXok22Xj.js.map} +1 -1
- package/dist/admin/assets/changeSets-B6HxCJ4A.js +2 -0
- package/dist/admin/assets/{changeSets-8EburmT0.js.map → changeSets-B6HxCJ4A.js.map} +1 -1
- package/dist/admin/assets/chevron-left-CkRxDtvO.js +2 -0
- package/dist/admin/assets/{chevron-left-DGU3HGYG.js.map → chevron-left-CkRxDtvO.js.map} +1 -1
- package/dist/admin/assets/{circle-check-C37MSJqX.js → circle-check-DtDq7QMo.js} +2 -2
- package/dist/admin/assets/{circle-check-C37MSJqX.js.map → circle-check-DtDq7QMo.js.map} +1 -1
- package/dist/admin/assets/{clock-2arjsgZ4.js → clock-BtvZR9KD.js} +2 -2
- package/dist/admin/assets/{clock-2arjsgZ4.js.map → clock-BtvZR9KD.js.map} +1 -1
- package/dist/admin/assets/cn-DVhJ55Mo.js.map +1 -1
- package/dist/admin/assets/{constants-a_15vqOh.js → constants-DY3YJAKH.js} +2 -2
- package/dist/admin/assets/{constants-a_15vqOh.js.map → constants-DY3YJAKH.js.map} +1 -1
- package/dist/admin/assets/content-BNZF26Ve.js +3 -0
- package/dist/admin/assets/content-BNZF26Ve.js.map +1 -0
- package/dist/admin/assets/{contentCounts-DP7YYeZZ.js → contentCounts-BzC7IQqP.js} +2 -2
- package/dist/admin/assets/{contentCounts-DP7YYeZZ.js.map → contentCounts-BzC7IQqP.js.map} +1 -1
- package/dist/admin/assets/{contentTypes-84uc0bjR.js → contentTypes-Bz2xpqGf.js} +2 -2
- package/dist/admin/assets/{contentTypes-84uc0bjR.js.map → contentTypes-Bz2xpqGf.js.map} +1 -1
- package/dist/admin/assets/{context-IKYdzQJ-.js → context-CEVKblBl.js} +2 -2
- package/dist/admin/assets/{context-IKYdzQJ-.js.map → context-CEVKblBl.js.map} +1 -1
- package/dist/admin/assets/{copy-CsSRHgKZ.js → copy-B7vIq8DS.js} +2 -2
- package/dist/admin/assets/{copy-CsSRHgKZ.js.map → copy-B7vIq8DS.js.map} +1 -1
- package/dist/admin/assets/createLucideIcon-BOsNKleB.js +2 -0
- package/dist/admin/assets/createLucideIcon-BOsNKleB.js.map +1 -0
- package/dist/admin/assets/develop-D6CtwuYj.js +11 -0
- package/dist/admin/assets/develop-D6CtwuYj.js.map +1 -0
- package/dist/admin/assets/{dropdown-menu-_xfaEp5C.js → dropdown-menu-Bz7CLcRK.js} +2 -2
- package/dist/admin/assets/{dropdown-menu-_xfaEp5C.js.map → dropdown-menu-Bz7CLcRK.js.map} +1 -1
- package/dist/admin/assets/{ellipsis-F91991on.js → ellipsis-Ci0rsbCJ.js} +2 -2
- package/dist/admin/assets/{ellipsis-F91991on.js.map → ellipsis-Ci0rsbCJ.js.map} +1 -1
- package/dist/admin/assets/{entryLink-CVB-TdIn.js → entryLink-B0hSb_dN.js} +2 -2
- package/dist/admin/assets/{entryLink-CVB-TdIn.js.map → entryLink-B0hSb_dN.js.map} +1 -1
- package/dist/admin/assets/es2015-Cv57ynE1.js +42 -0
- package/dist/admin/assets/es2015-Cv57ynE1.js.map +1 -0
- package/dist/admin/assets/{external-link-CdG6kHfA.js → external-link-Bs9YRzvY.js} +2 -2
- package/dist/admin/assets/{external-link-CdG6kHfA.js.map → external-link-Bs9YRzvY.js.map} +1 -1
- package/dist/admin/assets/{field-COOzRptX.js → field-D-xWW2E7.js} +2 -2
- package/dist/admin/assets/{field-COOzRptX.js.map → field-D-xWW2E7.js.map} +1 -1
- package/dist/admin/assets/{file-stack-28ZtO1xW.js → file-stack-X4OGmkLA.js} +2 -2
- package/dist/admin/assets/{file-stack-28ZtO1xW.js.map → file-stack-X4OGmkLA.js.map} +1 -1
- package/dist/admin/assets/{fileRoute-s7mCMYUJ.js → fileRoute-DMal-zYL.js} +2 -2
- package/dist/admin/assets/{fileRoute-s7mCMYUJ.js.map → fileRoute-DMal-zYL.js.map} +1 -1
- package/dist/admin/assets/{folder-plus-DIk0pWkP.js → folder-plus-De2GNvry.js} +2 -2
- package/dist/admin/assets/{folder-plus-DIk0pWkP.js.map → folder-plus-De2GNvry.js.map} +1 -1
- package/dist/admin/assets/followPlural-CsgeALTW.js +2 -0
- package/dist/admin/assets/followPlural-CsgeALTW.js.map +1 -0
- package/dist/admin/assets/{globe-DFr3Gd2w.js → globe-DBw84s8Z.js} +2 -2
- package/dist/admin/assets/{globe-DFr3Gd2w.js.map → globe-DBw84s8Z.js.map} +1 -1
- package/dist/admin/assets/{image-DT79QFa_.js → image-CX4mT-_R.js} +2 -2
- package/dist/admin/assets/{image-DT79QFa_.js.map → image-CX4mT-_R.js.map} +1 -1
- package/dist/admin/assets/{image-off-DFs5upyX.js → image-off-CVaH_qKf.js} +2 -2
- package/dist/admin/assets/{image-off-DFs5upyX.js.map → image-off-CVaH_qKf.js.map} +1 -1
- package/dist/admin/assets/inbox-C0PVc6UI.js +2 -0
- package/dist/admin/assets/inbox-C0PVc6UI.js.map +1 -0
- package/dist/admin/assets/{inbox-CySnQydm.js → inbox-D9SmWt5L.js} +2 -2
- package/dist/admin/assets/{inbox-CySnQydm.js.map → inbox-D9SmWt5L.js.map} +1 -1
- package/dist/admin/assets/index-BqtCXB0u.js +4 -0
- package/dist/admin/assets/index-BqtCXB0u.js.map +1 -0
- package/dist/admin/assets/index-DZsQq6fY.css +2 -0
- package/dist/admin/assets/{key-round-D36CePnN.js → key-round-C8sd9CLN.js} +2 -2
- package/dist/admin/assets/{key-round-D36CePnN.js.map → key-round-C8sd9CLN.js.map} +1 -1
- package/dist/admin/assets/{labels-DQckbLGW.js → labels-BtktCNGw.js} +2 -2
- package/dist/admin/assets/{labels-DQckbLGW.js.map → labels-BtktCNGw.js.map} +1 -1
- package/dist/admin/assets/{languages-CzbTaQv9.js → languages-DLjdz6gb.js} +2 -2
- package/dist/admin/assets/{languages-CzbTaQv9.js.map → languages-DLjdz6gb.js.map} +1 -1
- package/dist/admin/assets/{layers-BmcodiaH.js → layers-swLuw-3a.js} +2 -2
- package/dist/admin/assets/{layers-BmcodiaH.js.map → layers-swLuw-3a.js.map} +1 -1
- package/dist/admin/assets/{link-2-off-CoJNwrxm.js → link-2-off-CEsI5T8h.js} +2 -2
- package/dist/admin/assets/{link-2-off-CoJNwrxm.js.map → link-2-off-CEsI5T8h.js.map} +1 -1
- package/dist/admin/assets/{link-Pyr2Y35S.js → link-C98FG_p5.js} +2 -2
- package/dist/admin/assets/{link-Pyr2Y35S.js.map → link-C98FG_p5.js.map} +1 -1
- package/dist/admin/assets/locales-CkuC7TJ1.js +2 -0
- package/dist/admin/assets/{locales-Bg3htKo8.js.map → locales-CkuC7TJ1.js.map} +1 -1
- package/dist/admin/assets/media-CbGSd_Mw.js +2 -0
- package/dist/admin/assets/{media-BCnVhaDH.js.map → media-CbGSd_Mw.js.map} +1 -1
- package/dist/admin/assets/{media-CURizGns.js → media-CeZGDGh7.js} +2 -2
- package/dist/admin/assets/{media-CURizGns.js.map → media-CeZGDGh7.js.map} +1 -1
- package/dist/admin/assets/network-BflLSKFO.js +2 -0
- package/dist/admin/assets/network-BflLSKFO.js.map +1 -0
- package/dist/admin/assets/{plus-BoDtdLCo.js → plus-cr9ZfO6j.js} +2 -2
- package/dist/admin/assets/{plus-BoDtdLCo.js.map → plus-cr9ZfO6j.js.map} +1 -1
- package/dist/admin/assets/publishing-BkxBplUZ.js +2 -0
- package/dist/admin/assets/publishing-BkxBplUZ.js.map +1 -0
- package/dist/admin/assets/{radio-group-4ok5evXq.js → radio-group-CRuWQnuV.js} +2 -2
- package/dist/admin/assets/{radio-group-4ok5evXq.js.map → radio-group-CRuWQnuV.js.map} +1 -1
- package/dist/admin/assets/{rotate-ccw-DL6TzcZh.js → rotate-ccw-BP8Ba-mY.js} +2 -2
- package/dist/admin/assets/{rotate-ccw-DL6TzcZh.js.map → rotate-ccw-BP8Ba-mY.js.map} +1 -1
- package/dist/admin/assets/schedules-BIyBlsYZ.js +2 -0
- package/dist/admin/assets/{schedules-BmB9Y73z.js.map → schedules-BIyBlsYZ.js.map} +1 -1
- package/dist/admin/assets/schema-6eUoC8fJ.js +2 -0
- package/dist/admin/assets/schema-6eUoC8fJ.js.map +1 -0
- package/dist/admin/assets/{scroll-text-PqeZm472.js → scroll-text-B5vfi9fD.js} +2 -2
- package/dist/admin/assets/{scroll-text-PqeZm472.js.map → scroll-text-B5vfi9fD.js.map} +1 -1
- package/dist/admin/assets/{search-BdwIwOzC.js → search-wj7zbkx1.js} +2 -2
- package/dist/admin/assets/{search-BdwIwOzC.js.map → search-wj7zbkx1.js.map} +1 -1
- package/dist/admin/assets/{searchSchemas-CSScloG8.js → searchSchemas-DAnwh3I3.js} +2 -2
- package/dist/admin/assets/{searchSchemas-CSScloG8.js.map → searchSchemas-DAnwh3I3.js.map} +1 -1
- package/dist/admin/assets/{sections-DqBzSKMP.js → sections-CWL-XD6m.js} +2 -2
- package/dist/admin/assets/sections-CWL-XD6m.js.map +1 -0
- package/dist/admin/assets/{sections-BTS683ur.js → sections-DBQpB0uv.js} +2 -2
- package/dist/admin/assets/{sections-BTS683ur.js.map → sections-DBQpB0uv.js.map} +1 -1
- package/dist/admin/assets/{select-C0USI-Ox.js → select-DVrPV1b3.js} +2 -2
- package/dist/admin/assets/{select-C0USI-Ox.js.map → select-DVrPV1b3.js.map} +1 -1
- package/dist/admin/assets/{send-XPWo3m4u.js → send-CzFdgUc_.js} +2 -2
- package/dist/admin/assets/{send-XPWo3m4u.js.map → send-CzFdgUc_.js.map} +1 -1
- package/dist/admin/assets/seo-Bd0sWQMo.js +2 -0
- package/dist/admin/assets/{seo-CceGYTIX.js.map → seo-Bd0sWQMo.js.map} +1 -1
- package/dist/admin/assets/settings-CqnrPmzR.js +2 -0
- package/dist/admin/assets/{settings-B60vHpZd.js.map → settings-CqnrPmzR.js.map} +1 -1
- package/dist/admin/assets/shapes-ZAkMBB-Z.js +6 -0
- package/dist/admin/assets/shapes-ZAkMBB-Z.js.map +1 -0
- package/dist/admin/assets/{skeleton-B5MP72Kw.js → skeleton-CiX26LnL.js} +2 -2
- package/dist/admin/assets/{skeleton-B5MP72Kw.js.map → skeleton-CiX26LnL.js.map} +1 -1
- package/dist/admin/assets/{snapshots-DUI2t-qF.js → snapshots-DbFQNJgN.js} +2 -2
- package/dist/admin/assets/{snapshots-DUI2t-qF.js.map → snapshots-DbFQNJgN.js.map} +1 -1
- package/dist/admin/assets/{sparkles-CvT-jxrW.js → sparkles-D_kmZJVd.js} +2 -2
- package/dist/admin/assets/{sparkles-CvT-jxrW.js.map → sparkles-D_kmZJVd.js.map} +1 -1
- package/dist/admin/assets/src-CMor9izq.js +7 -0
- package/dist/admin/assets/src-CMor9izq.js.map +1 -0
- package/dist/admin/assets/{stableId-BrtQedPy.js → stableId-g1uxJGSz.js} +2 -2
- package/dist/admin/assets/{stableId-BrtQedPy.js.map → stableId-g1uxJGSz.js.map} +1 -1
- package/dist/admin/assets/{store-CdIFG90N.js → store-CznhNKEi.js} +2 -2
- package/dist/admin/assets/{store-CdIFG90N.js.map → store-CznhNKEi.js.map} +1 -1
- package/dist/admin/assets/{switch-Dp6WYNam.js → switch-CiVf05NF.js} +2 -2
- package/dist/admin/assets/{switch-Dp6WYNam.js.map → switch-CiVf05NF.js.map} +1 -1
- package/dist/admin/assets/{theme-65PB8uAu.js → theme-Cv-MfOv8.js} +2 -2
- package/dist/admin/assets/theme-Cv-MfOv8.js.map +1 -0
- package/dist/admin/assets/titles-DrQhW8z3.js +2 -0
- package/dist/admin/assets/titles-DrQhW8z3.js.map +1 -0
- package/dist/admin/assets/tokens-B1S81Epe.js +2 -0
- package/dist/admin/assets/{tokens-ixHjAkDK.js.map → tokens-B1S81Epe.js.map} +1 -1
- package/dist/admin/assets/{tooltip-BGP1DVBt.js → tooltip-Bqf3oyqC.js} +2 -2
- package/dist/admin/assets/{tooltip-BGP1DVBt.js.map → tooltip-Bqf3oyqC.js.map} +1 -1
- package/dist/admin/assets/{undo-2-BiTANHFz.js → undo-2-DpwwRQTf.js} +2 -2
- package/dist/admin/assets/{undo-2-BiTANHFz.js.map → undo-2-DpwwRQTf.js.map} +1 -1
- package/dist/admin/assets/useContentSchema-B_q1rMrG.js +2 -0
- package/dist/admin/assets/useContentSchema-B_q1rMrG.js.map +1 -0
- package/dist/admin/assets/useCursorPager-BHYqHb3M.js +2 -0
- package/dist/admin/assets/{useCursorPager-0zHjlm-7.js.map → useCursorPager-BHYqHb3M.js.map} +1 -1
- package/dist/admin/assets/{useDiscardGuard-BskWSlbT.js → useDiscardGuard-C4QTfiU4.js} +2 -2
- package/dist/admin/assets/{useDiscardGuard-BskWSlbT.js.map → useDiscardGuard-C4QTfiU4.js.map} +1 -1
- package/dist/admin/assets/{useMediaPickerDialog-CU-ekPqX.js → useMediaPickerDialog-BLrVV1Kn.js} +2 -2
- package/dist/admin/assets/{useMediaPickerDialog-CU-ekPqX.js.map → useMediaPickerDialog-BLrVV1Kn.js.map} +1 -1
- package/dist/admin/assets/{useMediaUploader-CBcq1ICg.js → useMediaUploader-CFy6lasO.js} +2 -2
- package/dist/admin/assets/useMediaUploader-CFy6lasO.js.map +1 -0
- package/dist/admin/assets/useModelIndex-NU-WlHQY.js +2 -0
- package/dist/admin/assets/useModelIndex-NU-WlHQY.js.map +1 -0
- package/dist/admin/assets/useNetworkPermission-DehDln-U.js +2 -0
- package/dist/admin/assets/{useNetworkPermission-Cts98h9d.js.map → useNetworkPermission-DehDln-U.js.map} +1 -1
- package/dist/admin/assets/{usePaletteItems-DtReWmkd.js → usePaletteItems-CFpNlSOs.js} +2 -2
- package/dist/admin/assets/{usePaletteItems-DtReWmkd.js.map → usePaletteItems-CFpNlSOs.js.map} +1 -1
- package/dist/admin/assets/usePlaces-BA4x6503.js +2 -0
- package/dist/admin/assets/usePlaces-BA4x6503.js.map +1 -0
- package/dist/admin/assets/useResolvedDefinitions-30lnwFQ1.js +2 -0
- package/dist/admin/assets/useResolvedDefinitions-30lnwFQ1.js.map +1 -0
- package/dist/admin/assets/{useResolvedScheme-C8vcQVko.js → useResolvedScheme-BVM4qLct.js} +2 -2
- package/dist/admin/assets/{useResolvedScheme-C8vcQVko.js.map → useResolvedScheme-BVM4qLct.js.map} +1 -1
- package/dist/admin/assets/useSaveShortcut-DQuNL1uJ.js +2 -0
- package/dist/admin/assets/useSaveShortcut-DQuNL1uJ.js.map +1 -0
- package/dist/admin/assets/{useSchemaScopeAccess-ByrxIdKM.js → useSchemaScopeAccess-JXOMx51q.js} +2 -2
- package/dist/admin/assets/{useSchemaScopeAccess-ByrxIdKM.js.map → useSchemaScopeAccess-JXOMx51q.js.map} +1 -1
- package/dist/admin/assets/users-38jLQ7zr.js +2 -0
- package/dist/admin/assets/users-38jLQ7zr.js.map +1 -0
- package/dist/admin/assets/{users-DM7CXUBJ.js → users-DYwcVDqp.js} +2 -2
- package/dist/admin/assets/{users-DM7CXUBJ.js.map → users-DYwcVDqp.js.map} +1 -1
- package/dist/admin/assets/{zod-Cry7YvLY.js → zod-ZaQjjiAq.js} +2 -2
- package/dist/admin/assets/{zod-Cry7YvLY.js.map → zod-ZaQjjiAq.js.map} +1 -1
- package/dist/admin/index.html +60 -58
- package/dist/cli.js +1 -1
- package/dist/{cliMain-papyXJDd.js → cliMain-CTntiVc2.js} +107 -30
- package/dist/cliMain-CTntiVc2.js.map +1 -0
- package/dist/config.d.ts +2 -2
- package/dist/config.js +1 -1
- package/dist/{contentDisposition-DOL2Xt0l.js → contentDisposition-DzhPhncr.js} +2 -2
- package/dist/{contentDisposition-DOL2Xt0l.js.map → contentDisposition-DzhPhncr.js.map} +1 -1
- package/dist/index.d.ts +43 -6
- package/dist/index.js +2 -2
- package/dist/{public-COKbHR-N.d.ts → public-CMFaGDyf.d.ts} +50 -8
- package/dist/{public-B57h4F7Y.js → public-sJCQaNaP.js} +2 -2
- package/dist/public-sJCQaNaP.js.map +1 -0
- package/dist/{s3Adapter-U01iEAcK.js → s3Adapter-CZcCl0sy.js} +2 -2
- package/dist/{s3Adapter-U01iEAcK.js.map → s3Adapter-CZcCl0sy.js.map} +1 -1
- package/dist/{worker-B-sC-eY2.js → worker-DHm2JwMZ.js} +3140 -1292
- package/dist/worker-DHm2JwMZ.js.map +1 -0
- package/package.json +5 -5
- package/dist/admin/assets/AssistError-Cs-r9Ssc.js +0 -2
- package/dist/admin/assets/Body-BzZD-TZT.js +0 -2
- package/dist/admin/assets/Body-BzZD-TZT.js.map +0 -1
- package/dist/admin/assets/Builder-DW-GJA_q.js +0 -2
- package/dist/admin/assets/Builder-DW-GJA_q.js.map +0 -1
- package/dist/admin/assets/Form-lNrRHc0I.js +0 -2
- package/dist/admin/assets/Form-lNrRHc0I.js.map +0 -1
- package/dist/admin/assets/FormCheckboxGroup-DeeaYnzB.js +0 -2
- package/dist/admin/assets/FormCheckboxGroup-DeeaYnzB.js.map +0 -1
- package/dist/admin/assets/FormSelectField-BzE9Lq9i.js +0 -2
- package/dist/admin/assets/FormSelectField-BzE9Lq9i.js.map +0 -1
- package/dist/admin/assets/RadioTile-DQFmni5A.js.map +0 -1
- package/dist/admin/assets/RichTextField-CVHRIbnu.js.map +0 -1
- package/dist/admin/assets/StepList-BXGYD9eJ.js +0 -2
- package/dist/admin/assets/StepList-BXGYD9eJ.js.map +0 -1
- package/dist/admin/assets/Structure-D8csgrIt.js +0 -2
- package/dist/admin/assets/SubNavLink-CiCaVV8U.js.map +0 -1
- package/dist/admin/assets/auth-CQO4MBUj.js +0 -2
- package/dist/admin/assets/changeSets-8EburmT0.js +0 -2
- package/dist/admin/assets/chevron-left-DGU3HGYG.js +0 -2
- package/dist/admin/assets/content-CAjkbZEY.js +0 -3
- package/dist/admin/assets/content-CAjkbZEY.js.map +0 -1
- package/dist/admin/assets/createLucideIcon-CLmh7Go-.js +0 -2
- package/dist/admin/assets/createLucideIcon-CLmh7Go-.js.map +0 -1
- package/dist/admin/assets/develop-BOqvnlgt.js +0 -11
- package/dist/admin/assets/develop-BOqvnlgt.js.map +0 -1
- package/dist/admin/assets/es2015-BHmI7wjK.js +0 -42
- package/dist/admin/assets/es2015-BHmI7wjK.js.map +0 -1
- package/dist/admin/assets/followPlural-Cm7v_Udv.js +0 -2
- package/dist/admin/assets/followPlural-Cm7v_Udv.js.map +0 -1
- package/dist/admin/assets/inbox-DGO2D8fa.js +0 -2
- package/dist/admin/assets/inbox-DGO2D8fa.js.map +0 -1
- package/dist/admin/assets/index-BIIU9ZI6.js +0 -4
- package/dist/admin/assets/index-BIIU9ZI6.js.map +0 -1
- package/dist/admin/assets/index-lxe7WimO.css +0 -2
- package/dist/admin/assets/locales-Bg3htKo8.js +0 -2
- package/dist/admin/assets/media-BCnVhaDH.js +0 -2
- package/dist/admin/assets/network-BixABr0o.js +0 -2
- package/dist/admin/assets/network-BixABr0o.js.map +0 -1
- package/dist/admin/assets/publishing-Dke9bSKp.js +0 -2
- package/dist/admin/assets/publishing-Dke9bSKp.js.map +0 -1
- package/dist/admin/assets/schedules-BmB9Y73z.js +0 -2
- package/dist/admin/assets/schema-D-qo7XSF.js +0 -2
- package/dist/admin/assets/schema-D-qo7XSF.js.map +0 -1
- package/dist/admin/assets/sections-DqBzSKMP.js.map +0 -1
- package/dist/admin/assets/seo-CceGYTIX.js +0 -2
- package/dist/admin/assets/settings-B60vHpZd.js +0 -2
- package/dist/admin/assets/shapes-B5twqZcp.js +0 -6
- package/dist/admin/assets/shapes-B5twqZcp.js.map +0 -1
- package/dist/admin/assets/src-ndgTSYLX.js +0 -7
- package/dist/admin/assets/src-ndgTSYLX.js.map +0 -1
- package/dist/admin/assets/theme-65PB8uAu.js.map +0 -1
- package/dist/admin/assets/titles-CQiqqDw-.js +0 -2
- package/dist/admin/assets/titles-CQiqqDw-.js.map +0 -1
- package/dist/admin/assets/tokens-ixHjAkDK.js +0 -2
- package/dist/admin/assets/useContentSchema-DtYfhsd2.js +0 -2
- package/dist/admin/assets/useContentSchema-DtYfhsd2.js.map +0 -1
- package/dist/admin/assets/useCursorPager-0zHjlm-7.js +0 -2
- package/dist/admin/assets/useMediaUploader-CBcq1ICg.js.map +0 -1
- package/dist/admin/assets/useNetworkPermission-Cts98h9d.js +0 -2
- package/dist/admin/assets/usePlaces-DC47wVeU.js +0 -2
- package/dist/admin/assets/usePlaces-DC47wVeU.js.map +0 -1
- package/dist/admin/assets/useQueries-CirW3Mvp.js +0 -2
- package/dist/admin/assets/useQueries-CirW3Mvp.js.map +0 -1
- package/dist/admin/assets/useSaveShortcut-rKtp1qK7.js +0 -2
- package/dist/admin/assets/useSaveShortcut-rKtp1qK7.js.map +0 -1
- package/dist/admin/assets/users-2iJYwlJb.js +0 -2
- package/dist/admin/assets/users-2iJYwlJb.js.map +0 -1
- package/dist/cliMain-papyXJDd.js.map +0 -1
- package/dist/public-B57h4F7Y.js.map +0 -1
- package/dist/worker-B-sC-eY2.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"settings-B60vHpZd.js","names":["z.object","z.string","z.enum","EMPTY","zodResolver","Table","TableRoot","useState","Table","useId","useState","_Fragment","i18next","useState","useState","z.object","z.string","z.array","useMemo","zodResolver","i18next","useState","MoreHorizontal","_Fragment","Trash2","Table","TableRoot","useState","Table","z.object","zodResolver","i18next","z.string","zodResolver","i18next","useState","useCallback","z.string","z.object","z.record","useState","zodResolver","i18next","TableRoot","__toESM","require_jsx_runtime","useQuery","LOCALE_CODE_PATTERN","queryKeys","useMutation","useQueryClient","withCsrf","adminApi","SEO_TWITTER_HANDLE_PATTERN","useMediaAsset","isConflict","hasErrorCode","useUpdateProfile","useChangePassword","useHasGlobalPermission","useMe","X","Page","PageHeader","StatusChip","EmptyState","Badge","Outlet","useTranslation","createLucideIcon","formatRelativeTime","formatDateTime","formatMonth","RowTitle","createLazyRoute","UnsavedChangesGuard","isValidTitleTemplate","useSiteSeo","siteSeoQueryOptions","useUpdateSiteSeo","InfoHint","reportError","instance","describeError","ArrowDown","ImagePlus","ArrowUp","AssetTile","Button","Input","Label","SelectValue","SelectTrigger","SelectContent","SelectItem","Select","FormError","ConfirmDialog","InlineConfirm","Trash","FieldGroup","FieldSet","FieldLegend","Field","Ellipsis","useMediaPermissions","Pencil","Globe","KeyRound","DropdownMenuItem","DropdownMenuTrigger","DropdownMenuContent","DropdownMenu","MonitorSmartphone","ThemeSwatches","useLookSelection","SETTINGS_GROUPS","Plus","RadioGroup","newPasswordField","useController","useWatch","FormTextField","requiredText","FormFieldError","withPasswordConfirmation","u","useForm","describedBy","settle","record","TableHeader","object","TableHead","_enum","TableBody","TableRow","TableCell","TableCard","Table$3","array","string","HintedLabel","QueryView","FormRadioGroup","useNetworkPermission","useUpdateLocale","useSetDefaultLocale","useDeleteLocale","useLocales","useCreateLocale","LocaleSelect","useMediaPickerDialog","useAssistStatus","useRewriteText","REWRITE_MAX_TEXT","ASSIST_DOCS_URL","AssistButton","AssistError","Textarea","Panel","ExternalLink","NoAccess","RadioTile","FormTextareaField","SubNav","SubNavGroup","SubNavLink","FormSheet","FormSelectField","useCreateApiToken","useRevokeApiToken","useApiTokens","useDraftRoleIds","useRoleNames","useRoles","SecretReveal","useConfirmTarget","__iconData","Star","import_jsx_runtime","Nav","permissions","t","sections","group","section","Icon","Settings","import_react","require_react","TOKEN_EXPIRY_OPTIONS","DAY_MS","expiryToDate","option","now","createTokenSchema","EMPTY$1","useCreateTokenForm","createToken","form","open","reset","network","scope","canChooseNetwork","roleId","created","expiry","onCreated","CreateSheet","roles","me","mayCreateNetwork","role","scopeOptions","roleOptions","expiryOptions","onCloseAutoFocus","onSubmit","event","TokenStatus","token","Table$2","tokens","roleNames","draftRoleIds","siteName","onRevoke","Manage","revoke","creating","setCreating","secret","setSecret","revokeToken","toast","createButton","data","ApiTokens","Appearance","selectedLook","selectLook","looks","look","TryIt","id","text","setText","instruction","setInstruction","rewrite","ready","Usage","rows","usage","row","Assist","status","impactOf","impact","error","count","value","announceDeleted","locale","useDeleteLocaleFlow","deleteLocale","withContent","setWithContent","setOpen","LEGEND_ID","FallbackChain","adding","setAdding","chain","field","labelOf","locales","available","code","move","next","moved","from","to","index","entry","fieldState","MAX_CODE_LENGTH","localeSchemaFor","existing","context","valuesFor","useLocaleForm","createLocale","updateLocale","item","onDone","mutation","LocaleSheet","onOpenChange","Row","deleting","setDeleting","canManage","onDelete","onEdit","onMakeDefault","Table$1","defaultLocale","Locales","setDefault","makeDefault","deletion","sheet","setSheet","currentDefault","current","target","profileSchema","useProfileDetailsForm","updateProfile","name","formState","saved","values","EMAIL_ID","EMAIL_HINT_ID","Details","onDirtyChange","isDirty","email","SubmitButton","changePasswordSchema","EMPTY","useChangePasswordForm","changePassword","password","Password","Profile","detailsDirty","setDetailsDirty","passwordDirty","setPasswordDirty","onDetailsDirtyChange","dirty","onPasswordDirtyChange","BUTTON_ID","HINT_ID","ERROR_ID","DefaultImage","imagePrivate","picker","choose","first","canWrite","SHORT_MAX","DESCRIPTION_MAX","optionalText","max","localeTextsSchema","seoSettingsSchema","EMPTY_TEXTS","toSeoSettingsValues","codes","seo","toSeoDefaults","texts","kept","key","handle","firstLocaleWithErrors","errors","SEO_IMAGE_INVALID","useSeoSettingsForm","queryClient","update","setLocale","version","setVersion","siteSeo","imageId","image","clearErrors","reload","fresh","invalid","LocaleTexts","onLocaleChange","SeoForm","Seo","list","useSessions","useRevokeSession","BROWSERS","SYSTEMS","firstMatch","table","pattern","describeUserAgent","userAgent","browser","system","Table","sessions","session","settingsLazyRoutes","revokeSession"],"sources":["../../../../node_modules/.pnpm/lucide-react@1.49.0_@types+react@19.3.0_react@19.3.0/node_modules/lucide-react/dist/esm/icons/star.mjs","../../src/features/Settings/Nav/index.tsx","../../src/features/Settings/index.tsx","../../src/features/Settings/ApiTokens/constants.ts","../../src/features/Settings/ApiTokens/hooks/useCreateTokenForm.ts","../../src/features/Settings/ApiTokens/CreateSheet/index.tsx","../../src/features/Settings/ApiTokens/Table/TokenStatus/index.tsx","../../src/features/Settings/ApiTokens/Table/index.tsx","../../src/features/Settings/ApiTokens/Manage/index.tsx","../../src/features/Settings/ApiTokens/index.tsx","../../src/features/Settings/Appearance/index.tsx","../../src/features/Settings/Assist/TryIt/index.tsx","../../src/features/Settings/Assist/Usage/index.tsx","../../src/features/Settings/Assist/index.tsx","../../src/features/Settings/Locales/hooks/useDeleteLocaleFlow.ts","../../src/features/Settings/Locales/FallbackChain/index.tsx","../../src/features/Settings/Locales/helpers/localeSchema.ts","../../src/features/Settings/Locales/hooks/useLocaleForm.ts","../../src/features/Settings/Locales/LocaleSheet/index.tsx","../../src/features/Settings/Locales/Table/Row/index.tsx","../../src/features/Settings/Locales/Table/index.tsx","../../src/features/Settings/Locales/index.tsx","../../src/features/Settings/Profile/hooks/useProfileDetailsForm.ts","../../src/features/Settings/Profile/Details/index.tsx","../../src/features/Settings/Profile/hooks/useChangePasswordForm.ts","../../src/features/Settings/Profile/Password/index.tsx","../../src/features/Settings/Profile/index.tsx","../../src/features/Settings/Seo/DefaultImage/index.tsx","../../src/features/Settings/Seo/helpers.ts","../../src/features/Settings/Seo/hooks/useSeoSettingsForm.ts","../../src/features/Settings/Seo/LocaleTexts/index.tsx","../../src/features/Settings/Seo/index.tsx","../../src/api/sessions.ts","../../src/helpers/describeUserAgent.ts","../../src/features/Settings/Sessions/Table/index.tsx","../../src/features/Settings/Sessions/index.tsx","../../src/app/lazyRoutes/settings.tsx"],"sourcesContent":["/**\n * @license lucide-react v1.49.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.mjs';\n\nconst __iconData = {\n name: \"star\",\n size: 24,\n node: [\n [\n \"path\",\n {\n d: \"M11.525 2.295a.53.53 0 0 1 .95 0l2.31 4.679a2.123 2.123 0 0 0 1.595 1.16l5.166.756a.53.53 0 0 1 .294.904l-3.736 3.638a2.123 2.123 0 0 0-.611 1.878l.882 5.14a.53.53 0 0 1-.771.56l-4.618-2.428a2.122 2.122 0 0 0-1.973 0L6.396 21.01a.53.53 0 0 1-.77-.56l.881-5.139a2.122 2.122 0 0 0-.611-1.879L2.16 9.795a.53.53 0 0 1 .294-.906l5.165-.755a2.122 2.122 0 0 0 1.597-1.16z\",\n key: \"r04s7s\"\n }\n ]\n ]\n};\n__iconData.node;\nconst Star = createLucideIcon(__iconData);\n\nexport { __iconData, Star as default };\n//# sourceMappingURL=star.mjs.map\n","import { useTranslation } from 'react-i18next';\nimport { useMe } from '@/api/auth';\nimport { SubNav, SubNavGroup } from '@/components/SubNav';\nimport { SubNavLink } from '@/components/SubNavLink';\nimport { SETTINGS_GROUPS } from '../sections';\n\n/** Settings sections, grouped (Account, Workspace, Developer); groups the admin can't use are hidden. */\nexport const Nav = () => {\n const { t } = useTranslation();\n const permissions = useMe().data?.globalPermissions ?? [];\n return (\n <SubNav label={t('settings.sections')}>\n {SETTINGS_GROUPS.map((group) => {\n const sections = group.sections.filter(\n (section) => !section.permission || permissions.includes(section.permission),\n );\n return sections.length === 0 ? null : (\n <SubNavGroup key={group.key} label={t(`settings.${group.key}`)}>\n {sections.map((section) => {\n const Icon = section.icon;\n return (\n <SubNavLink key={section.key} to={section.to}>\n <Icon aria-hidden=\"true\" />\n {t(`settings.${section.key}`)}\n </SubNavLink>\n );\n })}\n </SubNavGroup>\n );\n })}\n </SubNav>\n );\n};\n","import { Outlet } from '@tanstack/react-router';\nimport { Page } from '@/components/Page';\nimport { Nav } from './Nav';\n\n/** Settings: the section navigation beside the current section's screen. */\nexport const Settings = () => (\n <Page>\n <div className=\"flex flex-col gap-6 lg:flex-row lg:items-start lg:gap-8\">\n <Nav />\n <div className=\"min-w-0 flex-1\">\n <Outlet />\n </div>\n </div>\n </Page>\n);\n","/** Expiry choices in days; `never` keeps the token until it's revoked. */\nexport const TOKEN_EXPIRY_OPTIONS = ['never', '30', '90', '365'] as const;\n\nexport type TokenExpiryOption = (typeof TOKEN_EXPIRY_OPTIONS)[number];\n\nconst DAY_MS = 24 * 60 * 60 * 1000;\n\nexport const expiryToDate = (option: TokenExpiryOption, now: Date = new Date()): string | null =>\n option === 'never' ? null : new Date(now.getTime() + Number(option) * DAY_MS).toISOString();\n","import { zodResolver } from '@hookform/resolvers/zod';\nimport type { CreatedApiToken } from '@shapio/client';\nimport { useEffect } from 'react';\nimport { useForm } from 'react-hook-form';\nimport { z } from 'zod';\nimport { useCreateApiToken } from '@/api/tokens';\nimport { settle } from '@/helpers/settle';\nimport { requiredText } from '@/helpers/validation';\nimport { expiryToDate, TOKEN_EXPIRY_OPTIONS } from '../constants';\n\n/** `site`: the token works on this site only (the default). `network`: every site and network actions. */\nexport const TOKEN_SCOPES = ['site', 'network'] as const;\n\nconst createTokenSchema = z.object({\n name: requiredText(),\n roleId: z.string().min(1, 'validation.selectRole'),\n expiry: z.enum(TOKEN_EXPIRY_OPTIONS),\n scope: z.enum(TOKEN_SCOPES),\n});\n\nexport type CreateTokenValues = z.infer<typeof createTokenSchema>;\n\nconst EMPTY: CreateTokenValues = { name: '', roleId: '', expiry: '90', scope: 'site' };\n\n/**\n * `canChooseNetwork(roleId)`: whether a network token may be made with that role (the creator holds\n * `users.manage` and it is an admin role; delivery tokens always belong to a site). `network` is always sent,\n * so the server never picks the kind on its own.\n */\nexport const useCreateTokenForm = (\n open: boolean,\n onCreated: (created: CreatedApiToken) => void,\n canChooseNetwork: (roleId: string) => boolean,\n) => {\n const createToken = useCreateApiToken();\n const form = useForm<CreateTokenValues>({ resolver: zodResolver(createTokenSchema), defaultValues: EMPTY });\n const { reset } = form;\n useEffect(() => {\n if (open) {\n reset(EMPTY);\n }\n }, [open, reset]);\n const onSubmit = form.handleSubmit(async ({ name, roleId, expiry, scope }) => {\n const network = scope === 'network' && canChooseNetwork(roleId);\n const created = await settle(\n createToken.mutateAsync({ name, roleId, expiresAt: expiryToDate(expiry), network }),\n );\n if (!created.ok) {\n return;\n }\n reset(EMPTY);\n onCreated(created.value);\n });\n return { form, onSubmit, createToken };\n};\n","import type { CreatedApiToken } from '@shapio/client';\nimport { useWatch } from 'react-hook-form';\nimport { useTranslation } from 'react-i18next';\nimport { useMe } from '@/api/auth';\nimport { useRoles } from '@/api/roles';\nimport { FormError } from '@/components/FormError';\nimport { FormRadioGroup } from '@/components/FormRadioGroup';\nimport { FormSelectField } from '@/components/FormSelectField';\nimport { FormSheet } from '@/components/FormSheet';\nimport { FormTextField } from '@/components/FormTextField';\nimport { TOKEN_EXPIRY_OPTIONS } from '../constants';\nimport { useCreateTokenForm } from '../hooks/useCreateTokenForm';\n\ntype CreateSheetProps = {\n open: boolean;\n onOpenChange: (open: boolean) => void;\n onCreated: (created: CreatedApiToken) => void;\n /** See `FormSheet`: lets the page keep focus on the secret that replaces the sheet. */\n onCloseAutoFocus?: (event: Event) => void;\n};\n\nexport const CreateSheet = ({ open, onOpenChange, onCreated, onCloseAutoFocus }: CreateSheetProps) => {\n const { t } = useTranslation();\n const roles = useRoles();\n const { data: me } = useMe();\n const mayCreateNetwork = me?.networkPermissions.includes('users.manage') ?? false;\n const canChooseNetwork = (roleId: string) =>\n mayCreateNetwork && roles.data?.find((role) => role.id === roleId)?.kind === 'admin';\n const { form, onSubmit, createToken } = useCreateTokenForm(open, onCreated, canChooseNetwork);\n const roleId = useWatch({ control: form.control, name: 'roleId' });\n const scopeOptions = [\n {\n value: 'site',\n label: t('apiTokens.scopeSite', { name: me?.site.name ?? '' }),\n description: t('apiTokens.scopeSiteDescription'),\n },\n {\n value: 'network',\n label: t('apiTokens.scopeNetwork'),\n description: t('apiTokens.scopeNetworkDescription'),\n },\n ];\n const roleOptions = (roles.data ?? []).map((role) => ({ value: role.id, label: role.name }));\n const expiryOptions = TOKEN_EXPIRY_OPTIONS.map((option) => ({\n value: option,\n label:\n option === 'never' ? t('apiTokens.expiryNever') : t('apiTokens.expiryDays', { count: Number(option) }),\n }));\n return (\n <FormSheet\n open={open}\n onOpenChange={onOpenChange}\n size=\"md\"\n {...(onCloseAutoFocus ? { onCloseAutoFocus } : {})}\n title={t('apiTokens.createTitle')}\n dirty={form.formState.isDirty}\n pending={createToken.isPending}\n submitLabel={t('common.create')}\n pendingLabel={t('common.saving')}\n onSubmit={(event) => void onSubmit(event)}\n >\n <FormTextField control={form.control} name=\"name\" label={t('apiTokens.name')} autoComplete=\"off\" />\n <FormSelectField\n control={form.control}\n name=\"roleId\"\n label={t('apiTokens.role')}\n options={roleOptions}\n />\n {canChooseNetwork(roleId) ? (\n <FormRadioGroup\n control={form.control}\n name=\"scope\"\n legend={t('apiTokens.scope')}\n options={scopeOptions}\n />\n ) : null}\n <FormSelectField\n control={form.control}\n name=\"expiry\"\n label={t('apiTokens.expiry')}\n options={expiryOptions}\n />\n <FormError error={createToken.error ?? roles.error} />\n </FormSheet>\n );\n};\n","import type { ApiToken } from '@shapio/client';\nimport { useTranslation } from 'react-i18next';\nimport { StatusChip } from '@/components/StatusChip';\n\ntype TokenStatusProps = { token: ApiToken };\n\n/** Revoked, paused (its creator's account is disabled, so it is refused until they are enabled) or active. */\nexport const TokenStatus = ({ token }: TokenStatusProps) => {\n const { t } = useTranslation();\n if (token.revokedAt) {\n return <StatusChip tone=\"muted\" label={t('apiTokens.revokedBadge')} />;\n }\n if (token.creatorDisabled) {\n return <StatusChip tone=\"warning\" label={t('apiTokens.pausedBadge')} />;\n }\n return <StatusChip tone=\"success\" label={t('apiTokens.active')} />;\n};\n","import type { ApiToken } from '@shapio/client';\nimport { useTranslation } from 'react-i18next';\nimport { InlineConfirm } from '@/components/InlineConfirm';\nimport { RowTitle } from '@/components/RowTitle';\nimport { StatusChip } from '@/components/StatusChip';\nimport { TableCard } from '@/components/TableCard';\nimport { Button } from '@/components/ui/button';\nimport {\n Table as TableRoot,\n TableBody,\n TableCell,\n TableHead,\n TableHeader,\n TableRow,\n} from '@/components/ui/table';\nimport { formatDateTime, formatRelativeTime } from '@/helpers/formatDate';\nimport { TokenStatus } from './TokenStatus';\n\ntype TableProps = {\n tokens: ApiToken[];\n roleNames: ReadonlyMap<string, string>;\n /** Roles that grant Read drafts: their tokens get a Drafts chip (development tokens). */\n draftRoleIds: ReadonlySet<string>;\n /** This site's name: every token not marked \"Every site\" belongs to it. */\n siteName: string;\n /** Resolves once the token is revoked (the confirmation waits for it). */\n onRevoke: (token: ApiToken) => Promise<unknown>;\n};\n\nexport const Table = ({ tokens, roleNames, draftRoleIds, siteName, onRevoke }: TableProps) => {\n const { t } = useTranslation();\n return (\n <TableCard>\n <TableRoot>\n <TableHeader>\n <TableRow>\n <TableHead>{t('apiTokens.name')}</TableHead>\n <TableHead>{t('apiTokens.prefix')}</TableHead>\n <TableHead>{t('apiTokens.role')}</TableHead>\n <TableHead>{t('apiTokens.appliesTo')}</TableHead>\n <TableHead>{t('apiTokens.status')}</TableHead>\n <TableHead>{t('apiTokens.lastUsed')}</TableHead>\n <TableHead>{t('apiTokens.expires')}</TableHead>\n <TableHead>\n <span className=\"sr-only\">{t('common.actions')}</span>\n </TableHead>\n </TableRow>\n </TableHeader>\n <TableBody>\n {tokens.map((token) => (\n <TableRow key={token.id}>\n <TableCell>\n <RowTitle>{token.name}</RowTitle>\n </TableCell>\n <TableCell className=\"font-mono text-xs\">{`${token.tokenPrefix}…`}</TableCell>\n <TableCell>\n <span className=\"flex items-center gap-2\">\n {roleNames.get(token.roleId) ?? t('common.unknown')}\n {draftRoleIds.has(token.roleId) ? (\n <StatusChip tone=\"warning\" size=\"sm\" label={t('apiTokens.draftsChip')} />\n ) : null}\n </span>\n </TableCell>\n <TableCell>{token.siteId === null ? t('sites.everySite') : siteName}</TableCell>\n <TableCell>\n <TokenStatus token={token} />\n </TableCell>\n <TableCell title={formatDateTime(token.lastUsedAt) || undefined}>\n {token.lastUsedAt ? formatRelativeTime(token.lastUsedAt) : t('common.never')}\n </TableCell>\n <TableCell>{token.expiresAt ? formatDateTime(token.expiresAt) : t('common.never')}</TableCell>\n <TableCell className=\"text-right\">\n {token.revokedAt ? null : (\n <InlineConfirm\n tone=\"danger\"\n title={t('apiTokens.revokeTitle', { name: token.name })}\n description={t('apiTokens.revokeDescription')}\n confirmLabel={t('common.revoke')}\n onConfirm={() => onRevoke(token)}\n trigger={\n <Button variant=\"outline\" size=\"sm\" aria-label={`${t('common.revoke')}: ${token.name}`}>\n {t('common.revoke')}\n </Button>\n }\n />\n )}\n </TableCell>\n </TableRow>\n ))}\n </TableBody>\n </TableRoot>\n </TableCard>\n );\n};\n","import type { ApiToken } from '@shapio/client';\nimport { KeyRound, Plus } from 'lucide-react';\nimport { useState } from 'react';\nimport { useTranslation } from 'react-i18next';\nimport { toast } from 'sonner';\nimport { useMe } from '@/api/auth';\nimport { useDraftRoleIds, useRoleNames } from '@/api/roles';\nimport { useApiTokens, useRevokeApiToken } from '@/api/tokens';\nimport { EmptyState } from '@/components/EmptyState';\nimport { Page } from '@/components/Page';\nimport { PageHeader } from '@/components/PageHeader';\nimport { QueryView } from '@/components/QueryView';\nimport { SecretReveal } from '@/components/SecretReveal';\nimport { Button } from '@/components/ui/button';\nimport { CreateSheet } from '../CreateSheet';\nimport { Table } from '../Table';\n\n/** API tokens for admins with `tokens.manage`: the list, New token, and the one-time secret. */\nexport const Manage = () => {\n const { t } = useTranslation();\n const tokens = useApiTokens();\n const { names: roleNames } = useRoleNames();\n const { draftRoleIds } = useDraftRoleIds();\n const siteName = useMe().data?.site.name ?? '';\n const revoke = useRevokeApiToken();\n const [creating, setCreating] = useState(false);\n // The new token's secret, held only in memory until the admin says they've copied it.\n const [secret, setSecret] = useState<string | undefined>(undefined);\n const revokeToken = async (token: ApiToken) => {\n await revoke.mutateAsync(token.id);\n toast.success(t('apiTokens.revoked'));\n };\n const createButton = (\n <Button onClick={() => setCreating(true)}>\n <Plus aria-hidden=\"true\" />\n {t('apiTokens.create')}\n </Button>\n );\n return (\n <Page width=\"full\">\n <PageHeader title={t('apiTokens.title')} actions={createButton} />\n {secret ? (\n <SecretReveal\n title={t('apiTokens.secretTitle')}\n description={t('apiTokens.secretDescription')}\n label={t('apiTokens.secretLabel')}\n secret={secret}\n dismissLabel={t('apiTokens.secretDone')}\n onDismiss={() => setSecret(undefined)}\n />\n ) : null}\n <QueryView\n query={tokens}\n isEmpty={(data) => data.length === 0}\n empty={\n <EmptyState\n icon={KeyRound}\n title={t('apiTokens.empty')}\n description={t('apiTokens.emptyDescription')}\n action={createButton}\n />\n }\n >\n {(data) => (\n <Table\n tokens={data}\n roleNames={roleNames}\n draftRoleIds={draftRoleIds}\n siteName={siteName}\n onRevoke={revokeToken}\n />\n )}\n </QueryView>\n <CreateSheet\n open={creating}\n onOpenChange={setCreating}\n onCreated={(created) => {\n setSecret(created.token);\n setCreating(false);\n }}\n // The secret took focus as it appeared; don't hand it back to the \"New token\" button.\n onCloseAutoFocus={(event) => secret !== undefined && event.preventDefault()}\n />\n </Page>\n );\n};\n","import { useTranslation } from 'react-i18next';\nimport { useHasGlobalPermission } from '@/api/auth';\nimport { NoAccess } from '@/components/NoAccess';\nimport { Page } from '@/components/Page';\nimport { PageHeader } from '@/components/PageHeader';\nimport { Manage } from './Manage';\n\n/** Settings → API tokens. Reached by URL without `tokens.manage`: the reason, and no New token. */\nexport const ApiTokens = () => {\n const { t } = useTranslation();\n const canManage = useHasGlobalPermission('tokens.manage');\n if (canManage) {\n return <Manage />;\n }\n return (\n <Page width=\"full\">\n <PageHeader title={t('apiTokens.title')} />\n <NoAccess />\n </Page>\n );\n};\n","import { useTranslation } from 'react-i18next';\nimport { Page } from '@/components/Page';\nimport { PageHeader } from '@/components/PageHeader';\nimport { Panel } from '@/components/Panel';\nimport { RadioTile } from '@/components/RadioTile';\nimport { useLookSelection } from '@/components/ThemeMenu/hooks/useLookSelection';\nimport { ThemeSwatches } from '@/components/ThemeSwatches';\nimport { RadioGroup } from '@/components/ui/radio-group';\n\nexport const Appearance = () => {\n const { t } = useTranslation();\n const { looks, selectedLook, selectLook } = useLookSelection();\n return (\n <Page width=\"full\">\n <PageHeader title={t('appearance.title')} />\n <Panel title={t('appearance.theme')} description={t('appearance.storedHere')}>\n <RadioGroup\n aria-label={t('appearance.theme')}\n value={selectedLook}\n onValueChange={selectLook}\n className=\"sm:grid-cols-2 xl:grid-cols-3\"\n >\n {looks.map((look) => (\n <RadioTile\n key={look.value}\n value={look.value}\n label={look.name}\n description={look.description}\n media={<ThemeSwatches themeKey={look.themeKey} variant={look.variant} size=\"lg\" />}\n />\n ))}\n </RadioGroup>\n </Panel>\n </Page>\n );\n};\n","import { useId, useState } from 'react';\nimport { useTranslation } from 'react-i18next';\nimport { useRewriteText } from '@/api/assist';\nimport { AssistButton } from '@/components/AssistButton';\nimport { AssistError } from '@/components/AssistError';\nimport { Panel } from '@/components/Panel';\nimport { Input } from '@/components/ui/input';\nimport { Label } from '@/components/ui/label';\nimport { Textarea } from '@/components/ui/textarea';\nimport { REWRITE_MAX_INSTRUCTION, REWRITE_MAX_TEXT } from '@/constants/assist';\n\n/** A rewrite to check the configured model answers (writes nothing anywhere). */\nexport const TryIt = () => {\n const { t } = useTranslation();\n const id = useId();\n const [text, setText] = useState('');\n const [instruction, setInstruction] = useState('');\n const rewrite = useRewriteText();\n const ready = text.trim() !== '' && instruction.trim() !== '';\n return (\n <Panel title={t('assist.settings.tryIt')} titleAs=\"h2\">\n <form\n className=\"space-y-4\"\n onSubmit={(event) => {\n event.preventDefault();\n if (ready) {\n rewrite.mutate({ text: text.trim(), instruction: instruction.trim() });\n }\n }}\n >\n <div className=\"space-y-2\">\n <Label htmlFor={`${id}-text`}>{t('assist.settings.tryText')}</Label>\n <Textarea\n id={`${id}-text`}\n value={text}\n rows={3}\n maxLength={REWRITE_MAX_TEXT}\n onChange={(event) => setText(event.target.value)}\n />\n </div>\n <div className=\"space-y-2\">\n <Label htmlFor={`${id}-instruction`}>{t('assist.rewrite.instruction')}</Label>\n <Input\n id={`${id}-instruction`}\n value={instruction}\n maxLength={REWRITE_MAX_INSTRUCTION}\n placeholder={t('assist.rewrite.instructionPlaceholder')}\n onChange={(event) => setInstruction(event.target.value)}\n />\n </div>\n <AssistError error={rewrite.error} />\n <div className=\"flex justify-end\">\n <AssistButton\n type=\"submit\"\n variant=\"default\"\n size=\"default\"\n pending={rewrite.isPending}\n pendingLabel={t('assist.working')}\n disabled={!ready}\n >\n {t('assist.rewrite.run')}\n </AssistButton>\n </div>\n <div aria-live=\"polite\">\n {rewrite.data ? (\n <figure className=\"space-y-1 rounded-lg border bg-muted/40 p-3\">\n <figcaption className=\"text-meta text-muted-foreground\">\n {t('assist.rewrite.proposal', { model: rewrite.data.model })}\n </figcaption>\n <p className=\"text-sm whitespace-pre-wrap\">{rewrite.data.text}</p>\n </figure>\n ) : null}\n </div>\n </form>\n </Panel>\n );\n};\n","import type { AssistUsage } from '@shapio/client';\nimport { useTranslation } from 'react-i18next';\nimport { Panel } from '@/components/Panel';\nimport { formatMonth } from '@/helpers/formatDate';\n\ntype UsageProps = { usage: AssistUsage };\n\n/** This month's assist runs and tokens on this site (only for those who manage changes). */\nexport const Usage = ({ usage }: UsageProps) => {\n const { t } = useTranslation();\n const rows = [\n { key: 'runs', label: t('assist.settings.runs'), value: usage.runs },\n { key: 'input', label: t('assist.settings.inputTokens'), value: usage.inputTokens },\n { key: 'output', label: t('assist.settings.outputTokens'), value: usage.outputTokens },\n ];\n return (\n <Panel title={t('assist.settings.usage', { month: formatMonth(usage.month) })} titleAs=\"h2\">\n <dl className=\"grid gap-4 sm:grid-cols-3\">\n {rows.map((row) => (\n <div key={row.key} className=\"space-y-1\">\n <dt className=\"text-meta text-muted-foreground\">{row.label}</dt>\n <dd className=\"text-2xl font-semibold tabular-nums\">{row.value.toLocaleString()}</dd>\n </div>\n ))}\n </dl>\n </Panel>\n );\n};\n","import { useTranslation } from 'react-i18next';\nimport { useAssistStatus } from '@/api/assist';\nimport { Page } from '@/components/Page';\nimport { PageHeader } from '@/components/PageHeader';\nimport { Panel } from '@/components/Panel';\nimport { QueryView } from '@/components/QueryView';\nimport { StatusChip } from '@/components/StatusChip';\nimport { ASSIST_DOCS_URL } from '@/constants/assist';\nimport { ExternalLink } from '@/features/Publishing/ExternalLink';\nimport { TryIt } from './TryIt';\nimport { Usage } from './Usage';\n\n/**\n * Settings → Assist: whether editor assists are on, with which provider and model, this month's usage\n * (for those who manage changes) and a place to try a rewrite. Configuration is environment-only (no key\n * entry here, by design), so the page links to the guide.\n */\nexport const Assist = () => {\n const { t } = useTranslation();\n const status = useAssistStatus();\n return (\n <Page width=\"narrow\">\n <PageHeader title={t('settings.assist')} />\n <QueryView query={status} loadingRows={3}>\n {(data) => (\n <>\n <Panel\n title={t('assist.settings.status')}\n titleAs=\"h2\"\n actions={\n <StatusChip\n tone={data.enabled ? 'success' : 'muted'}\n label={data.enabled ? t('assist.settings.on') : t('assist.settings.off')}\n />\n }\n >\n {data.enabled ? (\n <dl className=\"space-y-2 text-sm\">\n <div className=\"flex justify-between gap-3\">\n <dt className=\"text-muted-foreground\">{t('assist.settings.provider')}</dt>\n <dd className=\"font-mono\">{data.provider}</dd>\n </div>\n <div className=\"flex justify-between gap-3\">\n <dt className=\"text-muted-foreground\">{t('assist.settings.model')}</dt>\n <dd className=\"min-w-0 font-mono break-all\">{data.model}</dd>\n </div>\n </dl>\n ) : (\n <p className=\"text-sm\">{t('assist.settings.offDescription')}</p>\n )}\n <p className=\"mt-4 text-meta\">\n <ExternalLink href={ASSIST_DOCS_URL}>{t('assist.settings.guide')}</ExternalLink>\n </p>\n </Panel>\n {data.enabled && data.usage ? <Usage usage={data.usage} /> : null}\n {data.enabled ? <TryIt /> : null}\n </>\n )}\n </QueryView>\n </Page>\n );\n};\n","import type { Locale } from '@shapio/client';\nimport { useState } from 'react';\nimport { toast } from 'sonner';\nimport { hasErrorCode } from '@/api/errors';\nimport { useDeleteLocale } from '@/api/locales';\nimport { i18next } from '@/app/i18n';\n\ntype WithContent = { locale: Locale; affectedHeads: number; deletedEntries: number };\n\n/**\n * The content counts the server reports when a locale with content is deleted without acknowledgement:\n * entry versions purged, and entries that exist only in that locale (deleted outright).\n */\nconst impactOf = (error: unknown): Omit<WithContent, 'locale'> => {\n const impact = (error as { details?: { plan?: { impact?: Record<string, unknown> } } }).details?.plan\n ?.impact;\n const count = (value: unknown) => (typeof value === 'number' ? value : 0);\n return { affectedHeads: count(impact?.affectedHeads), deletedEntries: count(impact?.deletedEntries) };\n};\n\nconst announceDeleted = (locale: Locale) =>\n toast.success(i18next.t('locales.deleted', { label: locale.label }));\n\n/**\n * Deleting a locale purges its content. The first attempt, from the row's inline confirmation, goes without\n * acknowledgement: an empty locale is simply removed. One holding content is refused with its content counts,\n * and the question moves to a blocking dialog where the admin acknowledges them.\n */\nexport const useDeleteLocaleFlow = () => {\n const deleteLocale = useDeleteLocale();\n const [withContent, setWithContent] = useState<WithContent | undefined>(undefined);\n const [open, setOpen] = useState(false);\n const attempt = async (locale: Locale) => {\n try {\n await deleteLocale.mutateAsync({ code: locale.code, acknowledged: false });\n } catch (error) {\n if (!hasErrorCode(error, 'SCHEMA_CHANGE_NOT_ACKNOWLEDGED')) {\n throw error;\n }\n deleteLocale.reset();\n setWithContent({ locale, ...impactOf(error) });\n setOpen(true);\n return;\n }\n announceDeleted(locale);\n };\n const confirm = () => {\n if (!withContent) {\n return;\n }\n deleteLocale.mutate(\n { code: withContent.locale.code, acknowledged: true },\n {\n onSuccess: () => {\n announceDeleted(withContent.locale);\n setOpen(false);\n },\n },\n );\n };\n return {\n attempt,\n withContent,\n open,\n onOpenChange: setOpen,\n confirm,\n pending: deleteLocale.isPending,\n error: deleteLocale.error,\n };\n};\n","import type { Locale } from '@shapio/client';\nimport { MAX_FALLBACK_CHAIN } from '@shapio/schema';\nimport { ArrowDown, ArrowUp, X } from 'lucide-react';\nimport { useState } from 'react';\nimport { useController, type Control } from 'react-hook-form';\nimport { useTranslation } from 'react-i18next';\nimport { FormFieldError } from '@/components/FormFieldError';\nimport { InfoHint } from '@/components/InfoHint';\nimport { Button } from '@/components/ui/button';\nimport { FieldLegend, FieldSet } from '@/components/ui/field';\nimport { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select';\nimport type { LocaleValues } from '../helpers/localeSchema';\n\nconst LEGEND_ID = 'locale-fallbacks-legend';\n\ntype FallbackChainProps = {\n control: Control<LocaleValues>;\n /** Every configured locale; the one being edited is excluded from the choices. */\n locales: readonly Locale[];\n code: string;\n};\n\n/** The ordered locales delivery tries when content is missing in this one (the default is always last). */\nexport const FallbackChain = ({ control, locales, code }: FallbackChainProps) => {\n const { t } = useTranslation();\n const { field, fieldState } = useController({ control, name: 'fallbacks' });\n const [adding, setAdding] = useState('');\n const chain = field.value;\n const labelOf = (value: string) => locales.find((locale) => locale.code === value)?.label ?? value;\n const available = locales.filter((locale) => locale.code !== code && !chain.includes(locale.code));\n const move = (from: number, to: number) => {\n const next = [...chain];\n const [moved] = next.splice(from, 1);\n next.splice(to, 0, moved as string);\n field.onChange(next);\n };\n return (\n <FieldSet className=\"gap-3\" aria-labelledby={LEGEND_ID}>\n <FieldLegend variant=\"label\" className=\"mb-0 flex items-center gap-1\">\n <span id={LEGEND_ID}>{t('locales.fallbacks')}</span>\n <InfoHint about={t('locales.fallbacks')}>{t('locales.fallbacksHint')}</InfoHint>\n </FieldLegend>\n {chain.length > 0 ? (\n <ol className=\"space-y-1\">\n {chain.map((value, index) => (\n <li key={value} className=\"flex items-center gap-2 rounded-lg border py-1 pr-1 pl-3 text-sm\">\n <span className=\"w-5 text-muted-foreground\">{index + 1}.</span>\n <span className=\"flex-1\">\n {labelOf(value)} <span className=\"font-mono text-xs text-muted-foreground\">{value}</span>\n </span>\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"icon-sm\"\n aria-label={t('locales.moveUp', { locale: labelOf(value) })}\n disabled={index === 0}\n onClick={() => move(index, index - 1)}\n >\n <ArrowUp aria-hidden=\"true\" />\n </Button>\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"icon-sm\"\n aria-label={t('locales.moveDown', { locale: labelOf(value) })}\n disabled={index === chain.length - 1}\n onClick={() => move(index, index + 1)}\n >\n <ArrowDown aria-hidden=\"true\" />\n </Button>\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"icon-sm\"\n aria-label={t('locales.removeFallback', { locale: labelOf(value) })}\n onClick={() => field.onChange(chain.filter((entry) => entry !== value))}\n >\n <X aria-hidden=\"true\" />\n </Button>\n </li>\n ))}\n </ol>\n ) : (\n <p className=\"text-sm text-muted-foreground\">{t('locales.noFallbacks')}</p>\n )}\n {available.length > 0 && chain.length < MAX_FALLBACK_CHAIN ? (\n <Select\n value={adding}\n onValueChange={(value) => {\n field.onChange([...chain, value]);\n setAdding('');\n }}\n >\n <SelectTrigger className=\"w-full sm:w-64\" aria-label={t('locales.addFallback')}>\n <SelectValue placeholder={t('locales.addFallback')} />\n </SelectTrigger>\n <SelectContent>\n {available.map((locale) => (\n <SelectItem key={locale.code} value={locale.code}>\n {locale.label} ({locale.code})\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n ) : null}\n <FormFieldError message={fieldState.error?.message} />\n </FieldSet>\n );\n};\n","import { LOCALE_CODE_PATTERN } from '@shapio/schema';\nimport { z } from 'zod';\nimport { requiredText } from '@/helpers/validation';\n\nconst MAX_CODE_LENGTH = 35;\n\n/**\n * `existing`: the codes already in use. A code that differs from one only in case (`FR` beside `fr`) is\n * refused as taken, not as badly written: codes are compared case-insensitively.\n */\nexport const localeSchemaFor = (existing: readonly string[]) =>\n z.object({\n code: z\n .string()\n .trim()\n .min(1, 'validation.required')\n .superRefine((code, context) => {\n if (existing.includes(code.toLowerCase())) {\n context.addIssue({ code: 'custom', message: 'validation.localeExists' });\n } else if (code.length > MAX_CODE_LENGTH || !LOCALE_CODE_PATTERN.test(code)) {\n context.addIssue({ code: 'custom', message: 'validation.localeCode' });\n }\n }),\n label: requiredText(),\n fallbacks: z.array(z.string()),\n });\n\nexport type LocaleValues = z.infer<ReturnType<typeof localeSchemaFor>>;\n","import { zodResolver } from '@hookform/resolvers/zod';\nimport type { Locale } from '@shapio/client';\nimport { useEffect, useMemo } from 'react';\nimport { useForm } from 'react-hook-form';\nimport { toast } from 'sonner';\nimport { useCreateLocale, useUpdateLocale } from '@/api/locales';\nimport { i18next } from '@/app/i18n';\nimport { settle } from '@/helpers/settle';\nimport { localeSchemaFor, type LocaleValues } from '../helpers/localeSchema';\n\nconst valuesFor = (locale: Locale | undefined): LocaleValues => ({\n code: locale?.code ?? '',\n label: locale?.label ?? '',\n fallbacks: locale?.fallbacks ?? [],\n});\n\n/** Adds a locale, or edits one's label and fallback chain (the code is its identity and never changes). */\nexport const useLocaleForm = (\n open: boolean,\n locale: Locale | undefined,\n locales: readonly Locale[],\n onDone: () => void,\n) => {\n const createLocale = useCreateLocale();\n const updateLocale = useUpdateLocale();\n // Editing keeps the locale's own code, which is not a clash.\n const existing = useMemo(\n () => (locale ? [] : locales.map((item) => item.code.toLowerCase())),\n [locale, locales],\n );\n const form = useForm<LocaleValues>({\n resolver: zodResolver(localeSchemaFor(existing)),\n defaultValues: valuesFor(locale),\n });\n const { reset } = form;\n useEffect(() => {\n if (open) {\n reset(valuesFor(locale));\n createLocale.reset();\n updateLocale.reset();\n }\n // Only when the dialog opens; the mutation objects change identity on every render.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [open, locale, reset]);\n const onSubmit = form.handleSubmit(async ({ code, label, fallbacks }) => {\n const result = await settle(\n locale\n ? updateLocale.mutateAsync({ code: locale.code, input: { label, fallbacks } })\n : createLocale.mutateAsync({ code, label, fallbacks }),\n );\n if (!result.ok) {\n return;\n }\n toast.success(i18next.t(locale ? 'locales.saved' : 'locales.created', { label }));\n onDone();\n });\n const mutation = locale ? updateLocale : createLocale;\n return { form, onSubmit, pending: mutation.isPending, error: mutation.error };\n};\n","import type { Locale } from '@shapio/client';\nimport { useTranslation } from 'react-i18next';\nimport { FormError } from '@/components/FormError';\nimport { FormSheet } from '@/components/FormSheet';\nimport { FormTextField } from '@/components/FormTextField';\nimport { FallbackChain } from '../FallbackChain';\nimport { useLocaleForm } from '../hooks/useLocaleForm';\n\ntype LocaleSheetProps = {\n open: boolean;\n onOpenChange: (open: boolean) => void;\n /** Edit this locale; add a new one when undefined. */\n locale: Locale | undefined;\n locales: readonly Locale[];\n};\n\nexport const LocaleSheet = ({ open, onOpenChange, locale, locales }: LocaleSheetProps) => {\n const { t } = useTranslation();\n const { form, onSubmit, pending, error } = useLocaleForm(open, locale, locales, () => onOpenChange(false));\n const code = form.watch('code');\n return (\n <FormSheet\n open={open}\n onOpenChange={onOpenChange}\n size=\"md\"\n title={locale ? t('locales.editTitle', { label: locale.label }) : t('locales.addTitle')}\n dirty={form.formState.isDirty}\n pending={pending}\n submitLabel={locale ? t('common.saveChanges') : t('locales.add')}\n pendingLabel={t('common.saving')}\n onSubmit={(event) => void onSubmit(event)}\n >\n <FormTextField\n control={form.control}\n name=\"code\"\n label={t('locales.code')}\n hint={t('locales.codeHint')}\n autoComplete=\"off\"\n spellCheck={false}\n className=\"font-mono\"\n disabled={locale !== undefined}\n />\n <FormTextField control={form.control} name=\"label\" label={t('locales.label')} autoComplete=\"off\" />\n <FallbackChain control={form.control} locales={locales} code={code} />\n <FormError error={error} />\n </FormSheet>\n );\n};\n","import type { Locale } from '@shapio/client';\nimport { MoreHorizontal, Pencil, Star, Trash2 } from 'lucide-react';\nimport { useState } from 'react';\nimport { useTranslation } from 'react-i18next';\nimport { InlineConfirm } from '@/components/InlineConfirm';\nimport { RowTitle } from '@/components/RowTitle';\nimport { Badge } from '@/components/ui/badge';\nimport { Button } from '@/components/ui/button';\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuTrigger,\n} from '@/components/ui/dropdown-menu';\nimport { TableCell, TableRow } from '@/components/ui/table';\n\ntype RowProps = {\n locale: Locale;\n /** The fallbacks delivery tries, the default locale last. */\n chain: readonly string[];\n canManage: boolean;\n onEdit: (locale: Locale) => void;\n onMakeDefault: (locale: Locale) => void;\n /** The first delete attempt; resolves once it's done or handed to the content acknowledgement. */\n onDelete: (locale: Locale) => Promise<unknown>;\n};\n\n/** One locale. Delete asks inline, anchored to the row's menu button. */\nexport const Row = ({ locale, chain, canManage, onEdit, onMakeDefault, onDelete }: RowProps) => {\n const { t } = useTranslation();\n const [deleting, setDeleting] = useState(false);\n return (\n <TableRow>\n <TableCell>\n <span className=\"flex items-center gap-2\">\n <RowTitle>{locale.label}</RowTitle>\n {locale.isDefault ? <Badge variant=\"secondary\">{t('locales.default')}</Badge> : null}\n </span>\n </TableCell>\n <TableCell className=\"font-mono text-xs\">{locale.code}</TableCell>\n <TableCell className=\"font-mono text-xs\">\n {chain.length > 0 ? chain.join(' → ') : t('common.none')}\n </TableCell>\n <TableCell className=\"text-right\">\n {canManage ? (\n <DropdownMenu>\n <InlineConfirm\n tone=\"danger\"\n open={deleting}\n onOpenChange={setDeleting}\n title={t('locales.deleteTitle', { label: locale.label })}\n description={t('locales.deleteDescription')}\n confirmLabel={t('common.delete')}\n pendingLabel={t('locales.deleting')}\n onConfirm={() => onDelete(locale)}\n >\n <DropdownMenuTrigger asChild>\n <Button variant=\"ghost\" size=\"icon-sm\" aria-label={`${t('common.actions')}: ${locale.label}`}>\n <MoreHorizontal aria-hidden=\"true\" />\n </Button>\n </DropdownMenuTrigger>\n </InlineConfirm>\n <DropdownMenuContent align=\"end\" onCloseAutoFocus={(event) => deleting && event.preventDefault()}>\n <DropdownMenuItem onSelect={() => onEdit(locale)}>\n <Pencil aria-hidden=\"true\" />\n {t('common.edit')}\n </DropdownMenuItem>\n {locale.isDefault ? null : (\n <>\n <DropdownMenuItem onSelect={() => onMakeDefault(locale)}>\n <Star aria-hidden=\"true\" />\n {t('locales.makeDefault')}\n </DropdownMenuItem>\n <DropdownMenuItem variant=\"destructive\" onSelect={() => setDeleting(true)}>\n <Trash2 aria-hidden=\"true\" />\n {t('common.delete')}\n </DropdownMenuItem>\n </>\n )}\n </DropdownMenuContent>\n </DropdownMenu>\n ) : null}\n </TableCell>\n </TableRow>\n );\n};\n","import type { Locale } from '@shapio/client';\nimport { useTranslation } from 'react-i18next';\nimport { TableCard } from '@/components/TableCard';\nimport { Table as TableRoot, TableBody, TableHead, TableHeader, TableRow } from '@/components/ui/table';\nimport { Row } from './Row';\n\ntype TableProps = {\n locales: readonly Locale[];\n canManage: boolean;\n onEdit: (locale: Locale) => void;\n onMakeDefault: (locale: Locale) => void;\n onDelete: (locale: Locale) => Promise<unknown>;\n};\n\nexport const Table = ({ locales, canManage, onEdit, onMakeDefault, onDelete }: TableProps) => {\n const { t } = useTranslation();\n const defaultLocale = locales.find((locale) => locale.isDefault);\n return (\n <TableCard>\n <TableRoot>\n <TableHeader>\n <TableRow>\n <TableHead>{t('locales.label')}</TableHead>\n <TableHead>{t('locales.code')}</TableHead>\n <TableHead>{t('locales.fallbacks')}</TableHead>\n <TableHead>\n <span className=\"sr-only\">{t('common.actions')}</span>\n </TableHead>\n </TableRow>\n </TableHeader>\n <TableBody>\n {locales.map((locale) => (\n <Row\n key={locale.code}\n locale={locale}\n chain={[\n ...locale.fallbacks,\n ...(defaultLocale && !locale.isDefault && !locale.fallbacks.includes(defaultLocale.code)\n ? [defaultLocale.code]\n : []),\n ]}\n canManage={canManage}\n onEdit={onEdit}\n onMakeDefault={onMakeDefault}\n onDelete={onDelete}\n />\n ))}\n </TableBody>\n </TableRoot>\n </TableCard>\n );\n};\n","import type { Locale } from '@shapio/client';\nimport { Globe, Plus } from 'lucide-react';\nimport { useState } from 'react';\nimport { useTranslation } from 'react-i18next';\nimport { toast } from 'sonner';\nimport { useLocales, useSetDefaultLocale } from '@/api/locales';\nimport { ConfirmDialog } from '@/components/ConfirmDialog';\nimport { EmptyState } from '@/components/EmptyState';\nimport { Page } from '@/components/Page';\nimport { PageHeader } from '@/components/PageHeader';\nimport { QueryView } from '@/components/QueryView';\nimport { Button } from '@/components/ui/button';\nimport { useNetworkPermission } from '@/features/Network/hooks/useNetworkPermission';\nimport { useConfirmTarget } from '@/hooks/useConfirmTarget';\nimport { useDeleteLocaleFlow } from './hooks/useDeleteLocaleFlow';\nimport { LocaleSheet } from './LocaleSheet';\nimport { Table } from './Table';\n\n/** Content locales (ADR 0004): code, label, the default locale and each locale's fallback chain. */\nexport const Locales = () => {\n const { t } = useTranslation();\n const locales = useLocales();\n // Locales are shared by every site: a role granting schema.create on one site doesn't manage them.\n const canManage = useNetworkPermission('schema.create');\n const setDefault = useSetDefaultLocale();\n const makeDefault = useConfirmTarget<Locale>();\n const deletion = useDeleteLocaleFlow();\n const [sheet, setSheet] = useState<{ open: boolean; locale: Locale | undefined }>({\n open: false,\n locale: undefined,\n });\n const currentDefault = locales.data?.find((locale) => locale.isDefault);\n const withContent = deletion.withContent;\n return (\n <Page width=\"full\">\n <PageHeader\n title={t('locales.title')}\n actions={\n canManage ? (\n <Button onClick={() => setSheet({ open: true, locale: undefined })}>\n <Plus aria-hidden=\"true\" />\n {t('locales.add')}\n </Button>\n ) : null\n }\n />\n <QueryView\n query={locales}\n isEmpty={(data) => data.length === 0}\n empty={<EmptyState icon={Globe} title={t('locales.empty')} />}\n >\n {(data) => (\n <Table\n locales={data}\n canManage={canManage}\n onEdit={(locale) => setSheet({ open: true, locale })}\n onMakeDefault={(locale) => {\n setDefault.reset();\n makeDefault.ask(locale);\n }}\n onDelete={deletion.attempt}\n />\n )}\n </QueryView>\n <LocaleSheet\n open={sheet.open}\n onOpenChange={(open) => setSheet((current) => ({ ...current, open }))}\n locale={sheet.locale}\n locales={locales.data ?? []}\n />\n <ConfirmDialog\n open={makeDefault.open}\n onOpenChange={makeDefault.onOpenChange}\n title={t('locales.defaultTitle', { label: makeDefault.target?.label ?? '' })}\n description={t('locales.defaultDescription', {\n label: makeDefault.target?.label ?? '',\n current: currentDefault?.label ?? '',\n })}\n acknowledgement={t('locales.defaultAcknowledge')}\n confirmLabel={t('locales.makeDefault')}\n destructive\n pending={setDefault.isPending}\n pendingLabel={t('common.saving')}\n error={setDefault.error}\n onConfirm={() => {\n const target = makeDefault.target;\n if (target) {\n setDefault.mutate(target.code, {\n onSuccess: () => {\n toast.success(t('locales.defaultChanged', { label: target.label }));\n makeDefault.close();\n },\n });\n }\n }}\n />\n <ConfirmDialog\n open={deletion.open}\n onOpenChange={deletion.onOpenChange}\n title={t('locales.deleteTitle', { label: withContent?.locale.label ?? '' })}\n description={[\n t('locales.deleteContent', {\n count: withContent?.affectedHeads ?? 0,\n label: withContent?.locale.label ?? '',\n }),\n withContent?.deletedEntries\n ? t('locales.deleteEntries', {\n count: withContent.deletedEntries,\n label: withContent.locale.label,\n })\n : '',\n ]\n .filter(Boolean)\n .join(' ')}\n acknowledgement={t('locales.deleteAcknowledge', { count: withContent?.affectedHeads ?? 0 })}\n confirmLabel={t('common.delete')}\n destructive\n pending={deletion.pending}\n pendingLabel={t('locales.deleting')}\n error={deletion.error}\n onConfirm={deletion.confirm}\n />\n </Page>\n );\n};\n","import { zodResolver } from '@hookform/resolvers/zod';\nimport { useEffect } from 'react';\nimport { useForm } from 'react-hook-form';\nimport { toast } from 'sonner';\nimport { z } from 'zod';\nimport { useMe, useUpdateProfile } from '@/api/auth';\nimport { i18next } from '@/app/i18n';\nimport { settle } from '@/helpers/settle';\nimport { requiredText } from '@/helpers/validation';\n\nconst profileSchema = z.object({ name: requiredText() });\n\nexport type ProfileValues = z.infer<typeof profileSchema>;\n\n/** The signed-in admin's display name. Email changes go through an owner (Users), not self-service. */\nexport const useProfileDetailsForm = () => {\n const { data: me } = useMe();\n const updateProfile = useUpdateProfile();\n const form = useForm<ProfileValues>({\n resolver: zodResolver(profileSchema),\n defaultValues: { name: me?.user.name ?? '' },\n });\n const { reset, formState } = form;\n const name = me?.user.name;\n // Follow the server's value when it changes elsewhere, unless the user is mid-edit.\n useEffect(() => {\n if (!formState.isDirty && name !== undefined) {\n reset({ name });\n }\n }, [name, reset, formState.isDirty]);\n const onSubmit = form.handleSubmit(async (values) => {\n const saved = await settle(updateProfile.mutateAsync(values));\n if (!saved.ok) {\n return;\n }\n reset({ name: saved.value.name });\n toast.success(i18next.t('profile.detailsSaved'));\n });\n return { form, onSubmit, updateProfile, email: me?.user.email ?? '' };\n};\n","import { useEffect } from 'react';\nimport { useTranslation } from 'react-i18next';\nimport { FormError } from '@/components/FormError';\nimport { FormTextField } from '@/components/FormTextField';\nimport { HintedLabel } from '@/components/HintedLabel';\nimport { Panel } from '@/components/Panel';\nimport { SubmitButton } from '@/components/SubmitButton';\nimport { Field, FieldGroup } from '@/components/ui/field';\nimport { Input } from '@/components/ui/input';\nimport { useProfileDetailsForm } from '../hooks/useProfileDetailsForm';\n\ntype DetailsProps = { onDirtyChange: (dirty: boolean) => void };\n\nconst EMAIL_ID = 'profile-email';\nconst EMAIL_HINT_ID = 'profile-email-hint';\n\nexport const Details = ({ onDirtyChange }: DetailsProps) => {\n const { t } = useTranslation();\n const { form, onSubmit, updateProfile, email } = useProfileDetailsForm();\n const { isDirty } = form.formState;\n useEffect(() => onDirtyChange(isDirty), [isDirty, onDirtyChange]);\n return (\n <Panel title={t('profile.detailsTitle')}>\n <form noValidate onSubmit={(event) => void onSubmit(event)} className=\"max-w-md\">\n <FieldGroup>\n <FormTextField control={form.control} name=\"name\" label={t('auth.name')} autoComplete=\"name\" />\n <Field>\n <HintedLabel\n htmlFor={EMAIL_ID}\n label={t('auth.email')}\n hint={t('profile.emailHint')}\n hintId={EMAIL_HINT_ID}\n />\n <Input id={EMAIL_ID} value={email} readOnly aria-describedby={EMAIL_HINT_ID} />\n </Field>\n <FormError error={updateProfile.error} />\n <div>\n <SubmitButton\n pending={updateProfile.isPending}\n pendingLabel={t('common.saving')}\n disabled={!isDirty}\n >\n {t('common.saveChanges')}\n </SubmitButton>\n </div>\n </FieldGroup>\n </form>\n </Panel>\n );\n};\n","import { zodResolver } from '@hookform/resolvers/zod';\nimport { useForm } from 'react-hook-form';\nimport { toast } from 'sonner';\nimport { z } from 'zod';\nimport { useChangePassword } from '@/api/auth';\nimport { i18next } from '@/app/i18n';\nimport { settle } from '@/helpers/settle';\nimport { newPasswordField, withPasswordConfirmation } from '@/helpers/validation';\n\nconst changePasswordSchema = withPasswordConfirmation({\n currentPassword: z.string().min(1, 'validation.required'),\n password: newPasswordField(),\n});\n\nexport type ChangePasswordValues = z.infer<typeof changePasswordSchema>;\n\nconst EMPTY: ChangePasswordValues = { currentPassword: '', password: '', confirmPassword: '' };\n\nexport const useChangePasswordForm = () => {\n const changePassword = useChangePassword();\n const form = useForm<ChangePasswordValues>({\n resolver: zodResolver(changePasswordSchema),\n defaultValues: EMPTY,\n });\n const onSubmit = form.handleSubmit(async ({ currentPassword, password }) => {\n if (!(await settle(changePassword.mutateAsync({ currentPassword, newPassword: password }))).ok) {\n return;\n }\n form.reset(EMPTY);\n toast.success(i18next.t('profile.passwordChanged'));\n });\n return { form, onSubmit, changePassword };\n};\n","import { useEffect } from 'react';\nimport { useTranslation } from 'react-i18next';\nimport { FormError } from '@/components/FormError';\nimport { FormTextField } from '@/components/FormTextField';\nimport { Panel } from '@/components/Panel';\nimport { SubmitButton } from '@/components/SubmitButton';\nimport { FieldGroup } from '@/components/ui/field';\nimport { useChangePasswordForm } from '../hooks/useChangePasswordForm';\n\ntype PasswordProps = { onDirtyChange: (dirty: boolean) => void };\n\nexport const Password = ({ onDirtyChange }: PasswordProps) => {\n const { t } = useTranslation();\n const { form, onSubmit, changePassword } = useChangePasswordForm();\n const { isDirty } = form.formState;\n useEffect(() => onDirtyChange(isDirty), [isDirty, onDirtyChange]);\n return (\n <Panel title={t('profile.passwordTitle')} description={t('profile.passwordDescription')}>\n <form noValidate onSubmit={(event) => void onSubmit(event)} className=\"max-w-md\">\n <FieldGroup>\n <FormTextField\n control={form.control}\n name=\"currentPassword\"\n label={t('profile.currentPassword')}\n type=\"password\"\n autoComplete=\"current-password\"\n />\n <FormTextField\n control={form.control}\n name=\"password\"\n label={t('auth.newPassword')}\n description={t('auth.passwordHint')}\n type=\"password\"\n autoComplete=\"new-password\"\n />\n <FormTextField\n control={form.control}\n name=\"confirmPassword\"\n label={t('auth.confirmPassword')}\n type=\"password\"\n autoComplete=\"new-password\"\n />\n <FormError error={changePassword.error} />\n <div>\n <SubmitButton pending={changePassword.isPending} pendingLabel={t('common.saving')}>\n {t('profile.changePassword')}\n </SubmitButton>\n </div>\n </FieldGroup>\n </form>\n </Panel>\n );\n};\n","import { useCallback, useState } from 'react';\nimport { useTranslation } from 'react-i18next';\nimport { Page } from '@/components/Page';\nimport { PageHeader } from '@/components/PageHeader';\nimport { UnsavedChangesGuard } from '@/components/UnsavedChangesGuard';\nimport { Details } from './Details';\nimport { Password } from './Password';\n\nexport const Profile = () => {\n const { t } = useTranslation();\n const [detailsDirty, setDetailsDirty] = useState(false);\n const [passwordDirty, setPasswordDirty] = useState(false);\n const onDetailsDirtyChange = useCallback((dirty: boolean) => setDetailsDirty(dirty), []);\n const onPasswordDirtyChange = useCallback((dirty: boolean) => setPasswordDirty(dirty), []);\n return (\n <Page width=\"full\">\n <PageHeader title={t('profile.title')} />\n <Details onDirtyChange={onDetailsDirtyChange} />\n <Password onDirtyChange={onPasswordDirtyChange} />\n <UnsavedChangesGuard when={detailsDirty || passwordDirty} />\n </Page>\n );\n};\n","import { ImagePlus } from 'lucide-react';\nimport { useController, type Control } from 'react-hook-form';\nimport { useTranslation } from 'react-i18next';\nimport { FormFieldError } from '@/components/FormFieldError';\nimport { HintedLabel } from '@/components/HintedLabel';\nimport { Button } from '@/components/ui/button';\nimport { Field } from '@/components/ui/field';\nimport { useMediaPickerDialog } from '@/fields/hooks/useMediaPickerDialog';\nimport { AssetTile } from '@/fields/MediaField/AssetTile';\nimport { describedBy } from '@/helpers/describedBy';\nimport { useMediaPermissions } from '@/hooks/useMediaPermissions';\nimport type { SeoSettingsValues } from '../helpers';\n\ntype DefaultImageProps = {\n control: Control<SeoSettingsValues>;\n /** The chosen asset is private: delivery would never show it. */\n imagePrivate: boolean;\n};\n\nconst BUTTON_ID = 'seo-default-image';\nconst HINT_ID = `${BUTTON_ID}-hint`;\nconst ERROR_ID = `${BUTTON_ID}-error`;\n\n/** The site's default social image: one public image from the library, chosen in the media sheet. */\nexport const DefaultImage = ({ control, imagePrivate }: DefaultImageProps) => {\n const { t } = useTranslation();\n const { field, fieldState } = useController({ control, name: 'imageId' });\n // A private choice is caught here; anything else the server refuses (SEO_IMAGE_INVALID) arrives as an error.\n const error = imagePrivate ? t('seo.settings.imagePrivate') : fieldState.error?.message;\n const { canWrite } = useMediaPermissions();\n const picker = useMediaPickerDialog();\n const choose = async () => {\n const picked = await picker.pickMedia({ multiple: false, allowedKinds: ['image'] });\n const first = picked?.[0];\n if (first) {\n field.onChange(first.id);\n }\n };\n return (\n <Field data-invalid={error ? true : undefined}>\n <HintedLabel\n htmlFor={BUTTON_ID}\n label={t('seo.settings.image')}\n hint={t('seo.settings.imageHint')}\n hintId={HINT_ID}\n />\n {field.value ? (\n <ul>\n <AssetTile\n assetId={field.value}\n inputId={BUTTON_ID}\n index={0}\n count={1}\n editable\n canEditAlt={canWrite}\n onRemove={() => field.onChange(null)}\n />\n </ul>\n ) : null}\n <div>\n <Button\n id={BUTTON_ID}\n type=\"button\"\n variant=\"outline\"\n size=\"sm\"\n aria-describedby={describedBy(HINT_ID, error ? ERROR_ID : undefined)}\n onClick={() => void choose()}\n >\n <ImagePlus aria-hidden=\"true\" />\n {field.value ? t('seo.settings.changeImage') : t('seo.settings.chooseImage')}\n </Button>\n </div>\n <FormFieldError id={error ? ERROR_ID : undefined} message={error} />\n {picker.dialog}\n </Field>\n );\n};\n","import type { Locale } from '@shapio/client';\nimport {\n isValidTitleTemplate,\n SEO_TWITTER_HANDLE_PATTERN,\n type SeoDefaults,\n type SeoLocaleDefaults,\n} from '@shapio/schema';\nimport { z } from 'zod';\n\n/** Lengths from `SeoLocaleDefaultsSchema` (the server checks them too). */\nconst SHORT_MAX = 200;\nconst DESCRIPTION_MAX = 1000;\n\nconst optionalText = (max: number) => z.string().trim().max(max, 'validation.tooLong');\n\nconst localeTextsSchema = z.object({\n siteName: optionalText(SHORT_MAX),\n titleTemplate: optionalText(SHORT_MAX).refine(\n (value) => value === '' || isValidTitleTemplate(value),\n 'validation.titleTemplate',\n ),\n description: optionalText(DESCRIPTION_MAX),\n});\n\nexport const seoSettingsSchema = z.object({\n locales: z.record(z.string(), localeTextsSchema),\n imageId: z.string().nullable(),\n twitterHandle: z\n .string()\n .trim()\n .refine((value) => value === '' || SEO_TWITTER_HANDLE_PATTERN.test(value), 'validation.twitterHandle'),\n});\n\nexport type SeoLocaleTexts = z.infer<typeof localeTextsSchema>;\nexport type SeoSettingsValues = z.infer<typeof seoSettingsSchema>;\n\nconst EMPTY_TEXTS: SeoLocaleTexts = { siteName: '', titleTemplate: '', description: '' };\n\n/**\n * The form's values: every locale of the instance (and any other locale the defaults still hold) with all\n * three texts, empty strings for unset ones, so switching locale never loses an edit.\n */\nexport const toSeoSettingsValues = (seo: SeoDefaults, locales: readonly Locale[]): SeoSettingsValues => {\n const codes = [...new Set([...locales.map((locale) => locale.code), ...Object.keys(seo.locales)])];\n return {\n locales: Object.fromEntries(codes.map((code) => [code, { ...EMPTY_TEXTS, ...seo.locales[code] }])),\n imageId: seo.imageId,\n twitterHandle: seo.twitterHandle ?? '',\n };\n};\n\n/** What is saved: unset texts and locales without any text are left out. */\nexport const toSeoDefaults = (values: SeoSettingsValues): SeoDefaults => {\n const locales: Record<string, SeoLocaleDefaults> = {};\n for (const [code, texts] of Object.entries(values.locales)) {\n const kept = Object.fromEntries(\n Object.entries(texts)\n .map(([key, value]) => [key, value.trim()] as const)\n .filter(([, value]) => value !== ''),\n ) as SeoLocaleDefaults;\n if (Object.keys(kept).length > 0) {\n locales[code] = kept;\n }\n }\n const handle = values.twitterHandle.trim();\n return { locales, imageId: values.imageId, twitterHandle: handle === '' ? null : handle };\n};\n\n/** The first locale with an invalid text, so a refused save can show it. */\nexport const firstLocaleWithErrors = (errors: { locales?: Record<string, unknown> }): string | undefined =>\n Object.keys(errors.locales ?? {})[0];\n","import { zodResolver } from '@hookform/resolvers/zod';\nimport type { Locale } from '@shapio/client';\nimport { useQueryClient } from '@tanstack/react-query';\nimport { useEffect, useState } from 'react';\nimport { useForm, useWatch, type FieldErrors } from 'react-hook-form';\nimport { toast } from 'sonner';\nimport { hasErrorCode, isConflict } from '@/api/errors';\nimport { useMediaAsset } from '@/api/media';\nimport { siteSeoQueryOptions, useUpdateSiteSeo, type SiteSeo } from '@/api/seo';\nimport { i18next } from '@/app/i18n';\nimport { describeError } from '@/helpers/describeError';\nimport { reportError } from '@/helpers/reportError';\nimport {\n firstLocaleWithErrors,\n seoSettingsSchema,\n toSeoDefaults,\n toSeoSettingsValues,\n type SeoSettingsValues,\n} from '../helpers';\n\n/** The server refused the default image (another site's, not an image, or private). */\nconst SEO_IMAGE_INVALID = 'SEO_IMAGE_INVALID';\n\n/**\n * Settings → SEO: the site's default texts per locale, default social image and Twitter handle, saved with\n * the site version they were read at (a conflict asks to reload). The image must be public: a private one is\n * refused here before the server would.\n */\nexport const useSeoSettingsForm = (siteSeo: SiteSeo, locales: readonly Locale[]) => {\n const queryClient = useQueryClient();\n const update = useUpdateSiteSeo();\n const defaultLocale = locales.find((locale) => locale.isDefault)?.code ?? locales[0]?.code ?? '';\n const [locale, setLocale] = useState(defaultLocale);\n const [version, setVersion] = useState(siteSeo.version);\n const form = useForm<SeoSettingsValues>({\n resolver: zodResolver(seoSettingsSchema),\n defaultValues: toSeoSettingsValues(siteSeo.seo, locales),\n });\n const imageId = useWatch({ control: form.control, name: 'imageId' });\n const image = useMediaAsset(imageId ?? undefined);\n const imagePrivate = imageId !== null && image.data?.visibility === 'private';\n const { clearErrors } = form;\n // The server's verdict on an image is about that image: another choice clears it.\n useEffect(() => clearErrors('imageId'), [imageId, clearErrors]);\n\n const reload = async () => {\n try {\n const fresh = await queryClient.fetchQuery({ ...siteSeoQueryOptions, staleTime: 0 });\n form.reset(toSeoSettingsValues(fresh.seo, locales));\n setVersion(fresh.version);\n } catch (error) {\n reportError(error, 'reloading the SEO settings');\n }\n };\n\n const save = async (values: SeoSettingsValues) => {\n if (imagePrivate) {\n return;\n }\n try {\n const saved = await update.mutateAsync({ expectedVersion: version, seo: toSeoDefaults(values) });\n form.reset(toSeoSettingsValues(saved.seo, locales));\n setVersion(saved.version);\n toast.success(i18next.t('seo.settings.saved'));\n } catch (error) {\n if (isConflict(error)) {\n toast.error(i18next.t('seo.settings.conflict'), {\n action: { label: i18next.t('seo.settings.reload'), onClick: () => void reload() },\n });\n return;\n }\n if (hasErrorCode(error, SEO_IMAGE_INVALID)) {\n form.setError('imageId', { message: describeError(error) }, { shouldFocus: false });\n return;\n }\n toast.error(describeError(error));\n }\n };\n\n const showInvalidLocale = (errors: FieldErrors<SeoSettingsValues>) => {\n const invalid = firstLocaleWithErrors(errors);\n if (invalid !== undefined) {\n setLocale(invalid);\n }\n };\n\n return {\n form,\n locale,\n setLocale,\n imagePrivate,\n pending: update.isPending,\n onSubmit: form.handleSubmit(save, showInvalidLocale),\n };\n};\n","import type { Locale } from '@shapio/client';\nimport type { Control } from 'react-hook-form';\nimport { useTranslation } from 'react-i18next';\nimport { FormTextareaField } from '@/components/FormTextareaField';\nimport { FormTextField } from '@/components/FormTextField';\nimport { Panel } from '@/components/Panel';\nimport { FieldGroup } from '@/components/ui/field';\nimport { LocaleSelect } from '@/features/Content/LocaleSelect';\nimport type { SeoSettingsValues } from '../helpers';\n\ntype LocaleTextsProps = {\n control: Control<SeoSettingsValues>;\n locales: readonly Locale[];\n locale: string;\n onLocaleChange: (code: string) => void;\n};\n\n/** Site name, title template and description for one locale at a time; empty ones follow the fallbacks. */\nexport const LocaleTexts = ({ control, locales, locale, onLocaleChange }: LocaleTextsProps) => {\n const { t } = useTranslation();\n return (\n <Panel\n title={t('seo.settings.textsTitle')}\n titleAs=\"h2\"\n actions={\n locales.length > 1 ? (\n <LocaleSelect locales={locales} value={locale} onChange={onLocaleChange} size=\"sm\" />\n ) : null\n }\n >\n <FieldGroup key={locale} className=\"max-w-xl\">\n <FormTextField\n control={control}\n name={`locales.${locale}.siteName`}\n label={t('seo.settings.siteName')}\n hint={t('seo.settings.siteNameHint')}\n />\n <FormTextField\n control={control}\n name={`locales.${locale}.titleTemplate`}\n label={t('seo.settings.titleTemplate')}\n hint={t('seo.settings.titleTemplateHint')}\n placeholder={t('seo.settings.titleTemplatePlaceholder')}\n />\n <FormTextareaField\n control={control}\n name={`locales.${locale}.description`}\n label={t('seo.settings.description')}\n hint={t('seo.settings.descriptionHint')}\n rows={3}\n />\n </FieldGroup>\n </Panel>\n );\n};\n","import type { Locale } from '@shapio/client';\nimport { useTranslation } from 'react-i18next';\nimport { useLocales } from '@/api/locales';\nimport { useSiteSeo, type SiteSeo } from '@/api/seo';\nimport { FormTextField } from '@/components/FormTextField';\nimport { Page } from '@/components/Page';\nimport { PageHeader } from '@/components/PageHeader';\nimport { Panel } from '@/components/Panel';\nimport { QueryView } from '@/components/QueryView';\nimport { SubmitButton } from '@/components/SubmitButton';\nimport { FieldGroup } from '@/components/ui/field';\nimport { UnsavedChangesGuard } from '@/components/UnsavedChangesGuard';\nimport { DefaultImage } from './DefaultImage';\nimport { useSeoSettingsForm } from './hooks/useSeoSettingsForm';\nimport { LocaleTexts } from './LocaleTexts';\n\ntype SeoFormProps = { siteSeo: SiteSeo; locales: readonly Locale[] };\n\nconst SeoForm = ({ siteSeo, locales }: SeoFormProps) => {\n const { t } = useTranslation();\n const { form, locale, setLocale, imagePrivate, pending, onSubmit } = useSeoSettingsForm(siteSeo, locales);\n const { isDirty } = form.formState;\n return (\n <form noValidate onSubmit={(event) => void onSubmit(event)} className=\"space-y-6\">\n <UnsavedChangesGuard when={isDirty} />\n <LocaleTexts control={form.control} locales={locales} locale={locale} onLocaleChange={setLocale} />\n <Panel title={t('seo.settings.socialTitle')} titleAs=\"h2\">\n <FieldGroup className=\"max-w-xl\">\n <DefaultImage control={form.control} imagePrivate={imagePrivate} />\n <FormTextField\n control={form.control}\n name=\"twitterHandle\"\n label={t('seo.settings.twitterHandle')}\n hint={t('seo.settings.twitterHandleHint')}\n placeholder={t('seo.settings.twitterHandlePlaceholder')}\n autoComplete=\"off\"\n />\n </FieldGroup>\n </Panel>\n <div>\n <SubmitButton pending={pending} pendingLabel={t('common.saving')} disabled={!isDirty || imagePrivate}>\n {t('common.saveChanges')}\n </SubmitButton>\n </div>\n </form>\n );\n};\n\n/** Settings → SEO: the current site's search and social defaults (`site.settings`). */\nexport const Seo = () => {\n const { t } = useTranslation();\n const siteSeo = useSiteSeo();\n const locales = useLocales();\n return (\n <Page width=\"full\">\n <PageHeader title={t('seo.settings.title')} />\n <QueryView query={siteSeo} loadingRows={4}>\n {(seo) => (\n <QueryView query={locales} loadingRows={4}>\n {(list) => <SeoForm siteSeo={seo} locales={list} />}\n </QueryView>\n )}\n </QueryView>\n </Page>\n );\n};\n","import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';\nimport { adminApi } from './client';\nimport { withCsrf } from './csrf';\nimport { queryKeys } from './queryKeys';\n\nexport const useSessions = () =>\n useQuery({ queryKey: queryKeys.sessions, queryFn: () => adminApi.sessions.list(), meta: { silent: true } });\n\nexport const useRevokeSession = () => {\n const queryClient = useQueryClient();\n return useMutation({\n mutationKey: ['sessions', 'revoke'],\n mutationFn: (id: string) => withCsrf(() => adminApi.sessions.revoke(id)),\n onSettled: () => queryClient.invalidateQueries({ queryKey: queryKeys.sessions }),\n });\n};\n","const BROWSERS: readonly [RegExp, string][] = [\n [/Edg\\//, 'Edge'],\n [/OPR\\//, 'Opera'],\n [/Firefox\\//, 'Firefox'],\n [/Chrome\\//, 'Chrome'],\n [/Safari\\//, 'Safari'],\n];\n\nconst SYSTEMS: readonly [RegExp, string][] = [\n [/iPhone|iPad/, 'iOS'],\n [/Android/, 'Android'],\n [/Mac OS X|Macintosh/, 'macOS'],\n [/Windows/, 'Windows'],\n [/Linux/, 'Linux'],\n];\n\nconst firstMatch = (value: string, table: readonly [RegExp, string][]) =>\n table.find(([pattern]) => pattern.test(value))?.[1];\n\n/**\n * \"Chrome on macOS\" from a user-agent string (product names are not translated). `undefined` when nothing\n * is recognised, so the caller can show its own \"unknown device\" label.\n */\nexport const describeUserAgent = (userAgent: string | null): string | undefined => {\n if (!userAgent) {\n return undefined;\n }\n const browser = firstMatch(userAgent, BROWSERS);\n const system = firstMatch(userAgent, SYSTEMS);\n if (browser && system) {\n return `${browser} · ${system}`;\n }\n return browser ?? system;\n};\n","import type { AdminSession } from '@shapio/client';\nimport { useTranslation } from 'react-i18next';\nimport { InlineConfirm } from '@/components/InlineConfirm';\nimport { RowTitle } from '@/components/RowTitle';\nimport { TableCard } from '@/components/TableCard';\nimport { Badge } from '@/components/ui/badge';\nimport { Button } from '@/components/ui/button';\nimport {\n Table as TableRoot,\n TableBody,\n TableCell,\n TableHead,\n TableHeader,\n TableRow,\n} from '@/components/ui/table';\nimport { describeUserAgent } from '@/helpers/describeUserAgent';\nimport { formatDateTime, formatRelativeTime } from '@/helpers/formatDate';\n\ntype TableProps = {\n sessions: readonly AdminSession[];\n /** Resolves once the session is revoked (the confirmation waits for it). */\n onRevoke: (session: AdminSession) => Promise<unknown>;\n};\n\nexport const Table = ({ sessions, onRevoke }: TableProps) => {\n const { t } = useTranslation();\n return (\n <TableCard>\n <TableRoot>\n <TableHeader>\n <TableRow>\n <TableHead>{t('sessions.device')}</TableHead>\n <TableHead>{t('sessions.ipAddress')}</TableHead>\n <TableHead>{t('sessions.signedIn')}</TableHead>\n <TableHead>{t('sessions.lastActive')}</TableHead>\n <TableHead>\n <span className=\"sr-only\">{t('common.actions')}</span>\n </TableHead>\n </TableRow>\n </TableHeader>\n <TableBody>\n {sessions.map((session) => (\n <TableRow key={session.id}>\n <TableCell>\n <span className=\"flex items-center gap-2\">\n <RowTitle>{describeUserAgent(session.userAgent) ?? t('sessions.unknownDevice')}</RowTitle>\n {session.current ? <Badge variant=\"secondary\">{t('sessions.current')}</Badge> : null}\n </span>\n </TableCell>\n <TableCell className=\"font-mono text-xs\">{session.ip ?? t('common.unknown')}</TableCell>\n <TableCell title={formatDateTime(session.createdAt)}>\n {formatRelativeTime(session.createdAt)}\n </TableCell>\n <TableCell title={formatDateTime(session.lastSeenAt)}>\n {formatRelativeTime(session.lastSeenAt)}\n </TableCell>\n <TableCell className=\"text-right\">\n {session.current ? null : (\n <InlineConfirm\n tone=\"danger\"\n title={t('sessions.revokeTitle')}\n description={t('sessions.revokeDescription')}\n confirmLabel={t('common.revoke')}\n onConfirm={() => onRevoke(session)}\n trigger={\n <Button variant=\"outline\" size=\"sm\">\n {t('common.revoke')}\n </Button>\n }\n />\n )}\n </TableCell>\n </TableRow>\n ))}\n </TableBody>\n </TableRoot>\n </TableCard>\n );\n};\n","import type { AdminSession } from '@shapio/client';\nimport { MonitorSmartphone } from 'lucide-react';\nimport { useTranslation } from 'react-i18next';\nimport { toast } from 'sonner';\nimport { useRevokeSession, useSessions } from '@/api/sessions';\nimport { EmptyState } from '@/components/EmptyState';\nimport { Page } from '@/components/Page';\nimport { PageHeader } from '@/components/PageHeader';\nimport { QueryView } from '@/components/QueryView';\nimport { Table } from './Table';\n\nexport const Sessions = () => {\n const { t } = useTranslation();\n const sessions = useSessions();\n const revoke = useRevokeSession();\n const revokeSession = async (session: AdminSession) => {\n await revoke.mutateAsync(session.id);\n toast.success(t('sessions.revoked'));\n };\n return (\n <Page width=\"full\">\n <PageHeader title={t('sessions.title')} />\n <QueryView\n query={sessions}\n isEmpty={(data) => data.length === 0}\n empty={<EmptyState icon={MonitorSmartphone} title={t('sessions.empty')} />}\n >\n {(data) => <Table sessions={data} onRevoke={revokeSession} />}\n </QueryView>\n </Page>\n );\n};\n","import { createLazyRoute } from '@tanstack/react-router';\nimport { Settings } from '@/features/Settings';\nimport { ApiTokens } from '@/features/Settings/ApiTokens';\nimport { Appearance } from '@/features/Settings/Appearance';\nimport { Assist } from '@/features/Settings/Assist';\nimport { Locales } from '@/features/Settings/Locales';\nimport { Profile } from '@/features/Settings/Profile';\nimport { Seo } from '@/features/Settings/Seo';\nimport { Sessions } from '@/features/Settings/Sessions';\n\n/** Every settings screen, loaded together on the first visit to Settings. */\nexport const settingsLazyRoutes = {\n settings: createLazyRoute('/app/settings')({ component: Settings }),\n profile: createLazyRoute('/app/settings/profile')({ component: Profile }),\n sessions: createLazyRoute('/app/settings/sessions')({ component: Sessions }),\n theme: createLazyRoute('/app/settings/theme')({ component: Appearance }),\n locales: createLazyRoute('/app/settings/locales')({ component: Locales }),\n seo: createLazyRoute('/app/settings/seo')({ component: Seo }),\n assist: createLazyRoute('/app/settings/assist')({ component: Assist }),\n apiTokens: createLazyRoute('/app/settings/api-tokens')({ component: ApiTokens }),\n};\n"],"ignoreList":[0],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"settings-CqnrPmzR.js","names":["z.object","z.string","z.enum","EMPTY","zodResolver","Table","TableRoot","useState","Table","useId","useState","_Fragment","i18next","useState","useState","z.object","z.string","z.array","useMemo","zodResolver","i18next","useState","MoreHorizontal","_Fragment","Trash2","Table","TableRoot","useState","Table","z.object","zodResolver","i18next","z.string","zodResolver","i18next","useState","useCallback","z.string","z.object","z.record","useState","zodResolver","i18next","TableRoot","__toESM","require_jsx_runtime","queryKeys","useQueryClient","SEO_TWITTER_HANDLE_PATTERN","useQuery","LOCALE_CODE_PATTERN","adminApi","withCsrf","useMutation","useMediaAsset","isConflict","hasErrorCode","useUpdateProfile","useChangePassword","useHasGlobalPermission","useMe","X","Page","PageHeader","StatusChip","EmptyState","Badge","Outlet","useTranslation","createLucideIcon","formatRelativeTime","formatDateTime","formatMonth","RowTitle","createLazyRoute","UnsavedChangesGuard","isValidTitleTemplate","useSiteSeo","siteSeoQueryOptions","useUpdateSiteSeo","InfoHint","reportError","instance","describeError","ArrowDown","ImagePlus","ArrowUp","AssetTile","Button","Input","Label","SelectValue","SelectTrigger","SelectContent","SelectItem","Select","FormError","ConfirmDialog","InlineConfirm","Trash","FieldGroup","FieldSet","FieldLegend","Field","Ellipsis","useMediaPermissions","Pencil","Globe","KeyRound","DropdownMenuItem","DropdownMenuTrigger","DropdownMenuContent","DropdownMenu","MonitorSmartphone","ThemeSwatches","useLookSelection","SETTINGS_GROUPS","Plus","RadioGroup","newPasswordField","useController","useWatch","FormTextField","requiredText","FormFieldError","withPasswordConfirmation","u","useForm","describedBy","settle","record","TableHeader","object","TableHead","_enum","TableBody","TableRow","TableCell","TableCard","Table$3","array","string","HintedLabel","QueryView","FormRadioGroup","useNetworkPermission","useUpdateLocale","useSetDefaultLocale","useDeleteLocale","useLocales","useCreateLocale","LocaleSelect","useMediaPickerDialog","useAssistStatus","useRewriteText","REWRITE_MAX_TEXT","ASSIST_DOCS_URL","AssistButton","AssistError","Textarea","Panel","ExternalLink","NoAccess","RadioTile","FormTextareaField","FormSelectField","SubNav","SubNavGroup","SubNavLink","FormSheet","useCreateApiToken","useRevokeApiToken","useApiTokens","useDraftRoleIds","useRoleNames","useRoles","SecretReveal","useConfirmTarget","__iconData","Star","import_jsx_runtime","Nav","permissions","t","sections","group","section","Icon","Settings","import_react","require_react","TOKEN_EXPIRY_OPTIONS","DAY_MS","expiryToDate","option","now","createTokenSchema","EMPTY$1","useCreateTokenForm","createToken","form","open","reset","network","scope","canChooseNetwork","roleId","created","expiry","onCreated","CreateSheet","roles","me","mayCreateNetwork","role","scopeOptions","roleOptions","expiryOptions","onCloseAutoFocus","onSubmit","event","TokenStatus","token","Table$2","tokens","roleNames","draftRoleIds","siteName","onRevoke","Manage","revoke","creating","setCreating","secret","setSecret","revokeToken","toast","createButton","data","ApiTokens","Appearance","selectedLook","selectLook","looks","look","TryIt","id","text","setText","instruction","setInstruction","rewrite","ready","Usage","rows","usage","row","Assist","status","impactOf","impact","error","count","value","announceDeleted","locale","useDeleteLocaleFlow","deleteLocale","withContent","setWithContent","setOpen","LEGEND_ID","FallbackChain","adding","setAdding","chain","field","labelOf","locales","available","code","move","next","moved","from","to","index","entry","fieldState","MAX_CODE_LENGTH","localeSchemaFor","existing","context","valuesFor","useLocaleForm","createLocale","updateLocale","item","onDone","mutation","LocaleSheet","onOpenChange","Row","deleting","setDeleting","canManage","onDelete","onEdit","onMakeDefault","Table$1","defaultLocale","Locales","setDefault","makeDefault","deletion","sheet","setSheet","currentDefault","current","target","profileSchema","useProfileDetailsForm","updateProfile","name","formState","saved","values","EMAIL_ID","EMAIL_HINT_ID","Details","onDirtyChange","isDirty","email","SubmitButton","changePasswordSchema","EMPTY","useChangePasswordForm","changePassword","password","Password","Profile","detailsDirty","setDetailsDirty","passwordDirty","setPasswordDirty","onDetailsDirtyChange","dirty","onPasswordDirtyChange","BUTTON_ID","HINT_ID","ERROR_ID","DefaultImage","imagePrivate","picker","choose","first","canWrite","SHORT_MAX","DESCRIPTION_MAX","optionalText","max","localeTextsSchema","seoSettingsSchema","EMPTY_TEXTS","toSeoSettingsValues","codes","seo","toSeoDefaults","texts","kept","key","handle","firstLocaleWithErrors","errors","SEO_IMAGE_INVALID","useSeoSettingsForm","queryClient","update","setLocale","version","setVersion","siteSeo","imageId","image","clearErrors","reload","fresh","invalid","LocaleTexts","onLocaleChange","SeoForm","Seo","list","useSessions","useRevokeSession","BROWSERS","SYSTEMS","firstMatch","table","pattern","describeUserAgent","userAgent","browser","system","Table","sessions","session","settingsLazyRoutes","revokeSession"],"sources":["../../../../node_modules/.pnpm/lucide-react@1.49.0_@types+react@19.3.0_react@19.3.0/node_modules/lucide-react/dist/esm/icons/star.mjs","../../src/features/Settings/Nav/index.tsx","../../src/features/Settings/index.tsx","../../src/features/Settings/ApiTokens/constants.ts","../../src/features/Settings/ApiTokens/hooks/useCreateTokenForm.ts","../../src/features/Settings/ApiTokens/CreateSheet/index.tsx","../../src/features/Settings/ApiTokens/Table/TokenStatus/index.tsx","../../src/features/Settings/ApiTokens/Table/index.tsx","../../src/features/Settings/ApiTokens/Manage/index.tsx","../../src/features/Settings/ApiTokens/index.tsx","../../src/features/Settings/Appearance/index.tsx","../../src/features/Settings/Assist/TryIt/index.tsx","../../src/features/Settings/Assist/Usage/index.tsx","../../src/features/Settings/Assist/index.tsx","../../src/features/Settings/Locales/hooks/useDeleteLocaleFlow.ts","../../src/features/Settings/Locales/FallbackChain/index.tsx","../../src/features/Settings/Locales/helpers/localeSchema.ts","../../src/features/Settings/Locales/hooks/useLocaleForm.ts","../../src/features/Settings/Locales/LocaleSheet/index.tsx","../../src/features/Settings/Locales/Table/Row/index.tsx","../../src/features/Settings/Locales/Table/index.tsx","../../src/features/Settings/Locales/index.tsx","../../src/features/Settings/Profile/hooks/useProfileDetailsForm.ts","../../src/features/Settings/Profile/Details/index.tsx","../../src/features/Settings/Profile/hooks/useChangePasswordForm.ts","../../src/features/Settings/Profile/Password/index.tsx","../../src/features/Settings/Profile/index.tsx","../../src/features/Settings/Seo/DefaultImage/index.tsx","../../src/features/Settings/Seo/helpers.ts","../../src/features/Settings/Seo/hooks/useSeoSettingsForm.ts","../../src/features/Settings/Seo/LocaleTexts/index.tsx","../../src/features/Settings/Seo/index.tsx","../../src/api/sessions.ts","../../src/helpers/describeUserAgent.ts","../../src/features/Settings/Sessions/Table/index.tsx","../../src/features/Settings/Sessions/index.tsx","../../src/app/lazyRoutes/settings.tsx"],"sourcesContent":["/**\n * @license lucide-react v1.49.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.mjs';\n\nconst __iconData = {\n name: \"star\",\n size: 24,\n node: [\n [\n \"path\",\n {\n d: \"M11.525 2.295a.53.53 0 0 1 .95 0l2.31 4.679a2.123 2.123 0 0 0 1.595 1.16l5.166.756a.53.53 0 0 1 .294.904l-3.736 3.638a2.123 2.123 0 0 0-.611 1.878l.882 5.14a.53.53 0 0 1-.771.56l-4.618-2.428a2.122 2.122 0 0 0-1.973 0L6.396 21.01a.53.53 0 0 1-.77-.56l.881-5.139a2.122 2.122 0 0 0-.611-1.879L2.16 9.795a.53.53 0 0 1 .294-.906l5.165-.755a2.122 2.122 0 0 0 1.597-1.16z\",\n key: \"r04s7s\"\n }\n ]\n ]\n};\n__iconData.node;\nconst Star = createLucideIcon(__iconData);\n\nexport { __iconData, Star as default };\n//# sourceMappingURL=star.mjs.map\n","import { useTranslation } from 'react-i18next';\nimport { useMe } from '@/api/auth';\nimport { SubNav, SubNavGroup } from '@/components/SubNav';\nimport { SubNavLink } from '@/components/SubNavLink';\nimport { SETTINGS_GROUPS } from '../sections';\n\n/** Settings sections, grouped (Account, Workspace, Developer); groups the admin can't use are hidden. */\nexport const Nav = () => {\n const { t } = useTranslation();\n const permissions = useMe().data?.globalPermissions ?? [];\n return (\n <SubNav label={t('settings.sections')}>\n {SETTINGS_GROUPS.map((group) => {\n const sections = group.sections.filter(\n (section) => !section.permission || permissions.includes(section.permission),\n );\n return sections.length === 0 ? null : (\n <SubNavGroup key={group.key} label={t(`settings.${group.key}`)}>\n {sections.map((section) => {\n const Icon = section.icon;\n return (\n <SubNavLink key={section.key} to={section.to}>\n <Icon aria-hidden=\"true\" />\n {t(`settings.${section.key}`)}\n </SubNavLink>\n );\n })}\n </SubNavGroup>\n );\n })}\n </SubNav>\n );\n};\n","import { Outlet } from '@tanstack/react-router';\nimport { Page } from '@/components/Page';\nimport { Nav } from './Nav';\n\n/** Settings: the section navigation beside the current section's screen. */\nexport const Settings = () => (\n <Page>\n <div className=\"flex flex-col gap-6 lg:flex-row lg:items-start lg:gap-8\">\n <Nav />\n <div className=\"min-w-0 flex-1\">\n <Outlet />\n </div>\n </div>\n </Page>\n);\n","/** Expiry choices in days; `never` keeps the token until it's revoked. */\nexport const TOKEN_EXPIRY_OPTIONS = ['never', '30', '90', '365'] as const;\n\nexport type TokenExpiryOption = (typeof TOKEN_EXPIRY_OPTIONS)[number];\n\nconst DAY_MS = 24 * 60 * 60 * 1000;\n\nexport const expiryToDate = (option: TokenExpiryOption, now: Date = new Date()): string | null =>\n option === 'never' ? null : new Date(now.getTime() + Number(option) * DAY_MS).toISOString();\n","import { zodResolver } from '@hookform/resolvers/zod';\nimport type { CreatedApiToken } from '@shapio/client';\nimport { useEffect } from 'react';\nimport { useForm } from 'react-hook-form';\nimport { z } from 'zod';\nimport { useCreateApiToken } from '@/api/tokens';\nimport { settle } from '@/helpers/settle';\nimport { requiredText } from '@/helpers/validation';\nimport { expiryToDate, TOKEN_EXPIRY_OPTIONS } from '../constants';\n\n/** `site`: the token works on this site only (the default). `network`: every site and network actions. */\nexport const TOKEN_SCOPES = ['site', 'network'] as const;\n\nconst createTokenSchema = z.object({\n name: requiredText(),\n roleId: z.string().min(1, 'validation.selectRole'),\n expiry: z.enum(TOKEN_EXPIRY_OPTIONS),\n scope: z.enum(TOKEN_SCOPES),\n});\n\nexport type CreateTokenValues = z.infer<typeof createTokenSchema>;\n\nconst EMPTY: CreateTokenValues = { name: '', roleId: '', expiry: '90', scope: 'site' };\n\n/**\n * `canChooseNetwork(roleId)`: whether a network token may be made with that role (the creator holds\n * `users.manage` and it is an admin role; delivery tokens always belong to a site). `network` is always sent,\n * so the server never picks the kind on its own.\n */\nexport const useCreateTokenForm = (\n open: boolean,\n onCreated: (created: CreatedApiToken) => void,\n canChooseNetwork: (roleId: string) => boolean,\n) => {\n const createToken = useCreateApiToken();\n const form = useForm<CreateTokenValues>({ resolver: zodResolver(createTokenSchema), defaultValues: EMPTY });\n const { reset } = form;\n useEffect(() => {\n if (open) {\n reset(EMPTY);\n }\n }, [open, reset]);\n const onSubmit = form.handleSubmit(async ({ name, roleId, expiry, scope }) => {\n const network = scope === 'network' && canChooseNetwork(roleId);\n const created = await settle(\n createToken.mutateAsync({ name, roleId, expiresAt: expiryToDate(expiry), network }),\n );\n if (!created.ok) {\n return;\n }\n reset(EMPTY);\n onCreated(created.value);\n });\n return { form, onSubmit, createToken };\n};\n","import type { CreatedApiToken } from '@shapio/client';\nimport { useWatch } from 'react-hook-form';\nimport { useTranslation } from 'react-i18next';\nimport { useMe } from '@/api/auth';\nimport { useRoles } from '@/api/roles';\nimport { FormError } from '@/components/FormError';\nimport { FormRadioGroup } from '@/components/FormRadioGroup';\nimport { FormSelectField } from '@/components/FormSelectField';\nimport { FormSheet } from '@/components/FormSheet';\nimport { FormTextField } from '@/components/FormTextField';\nimport { TOKEN_EXPIRY_OPTIONS } from '../constants';\nimport { useCreateTokenForm } from '../hooks/useCreateTokenForm';\n\ntype CreateSheetProps = {\n open: boolean;\n onOpenChange: (open: boolean) => void;\n onCreated: (created: CreatedApiToken) => void;\n /** See `FormSheet`: lets the page keep focus on the secret that replaces the sheet. */\n onCloseAutoFocus?: (event: Event) => void;\n};\n\nexport const CreateSheet = ({ open, onOpenChange, onCreated, onCloseAutoFocus }: CreateSheetProps) => {\n const { t } = useTranslation();\n const roles = useRoles();\n const { data: me } = useMe();\n const mayCreateNetwork = me?.networkPermissions.includes('users.manage') ?? false;\n const canChooseNetwork = (roleId: string) =>\n mayCreateNetwork && roles.data?.find((role) => role.id === roleId)?.kind === 'admin';\n const { form, onSubmit, createToken } = useCreateTokenForm(open, onCreated, canChooseNetwork);\n const roleId = useWatch({ control: form.control, name: 'roleId' });\n const scopeOptions = [\n {\n value: 'site',\n label: t('apiTokens.scopeSite', { name: me?.site.name ?? '' }),\n description: t('apiTokens.scopeSiteDescription'),\n },\n {\n value: 'network',\n label: t('apiTokens.scopeNetwork'),\n description: t('apiTokens.scopeNetworkDescription'),\n },\n ];\n const roleOptions = (roles.data ?? []).map((role) => ({ value: role.id, label: role.name }));\n const expiryOptions = TOKEN_EXPIRY_OPTIONS.map((option) => ({\n value: option,\n label:\n option === 'never' ? t('apiTokens.expiryNever') : t('apiTokens.expiryDays', { count: Number(option) }),\n }));\n return (\n <FormSheet\n open={open}\n onOpenChange={onOpenChange}\n size=\"md\"\n {...(onCloseAutoFocus ? { onCloseAutoFocus } : {})}\n title={t('apiTokens.createTitle')}\n dirty={form.formState.isDirty}\n pending={createToken.isPending}\n submitLabel={t('common.create')}\n pendingLabel={t('common.saving')}\n onSubmit={(event) => void onSubmit(event)}\n >\n <FormTextField control={form.control} name=\"name\" label={t('apiTokens.name')} autoComplete=\"off\" />\n <FormSelectField\n control={form.control}\n name=\"roleId\"\n label={t('apiTokens.role')}\n options={roleOptions}\n />\n {canChooseNetwork(roleId) ? (\n <FormRadioGroup\n control={form.control}\n name=\"scope\"\n legend={t('apiTokens.scope')}\n options={scopeOptions}\n />\n ) : null}\n <FormSelectField\n control={form.control}\n name=\"expiry\"\n label={t('apiTokens.expiry')}\n options={expiryOptions}\n />\n <FormError error={createToken.error ?? roles.error} />\n </FormSheet>\n );\n};\n","import type { ApiToken } from '@shapio/client';\nimport { useTranslation } from 'react-i18next';\nimport { StatusChip } from '@/components/StatusChip';\n\ntype TokenStatusProps = { token: ApiToken };\n\n/** Revoked, paused (its creator's account is disabled, so it is refused until they are enabled) or active. */\nexport const TokenStatus = ({ token }: TokenStatusProps) => {\n const { t } = useTranslation();\n if (token.revokedAt) {\n return <StatusChip tone=\"muted\" label={t('apiTokens.revokedBadge')} />;\n }\n if (token.creatorDisabled) {\n return <StatusChip tone=\"warning\" label={t('apiTokens.pausedBadge')} />;\n }\n return <StatusChip tone=\"success\" label={t('apiTokens.active')} />;\n};\n","import type { ApiToken } from '@shapio/client';\nimport { useTranslation } from 'react-i18next';\nimport { InlineConfirm } from '@/components/InlineConfirm';\nimport { RowTitle } from '@/components/RowTitle';\nimport { StatusChip } from '@/components/StatusChip';\nimport { TableCard } from '@/components/TableCard';\nimport { Button } from '@/components/ui/button';\nimport {\n Table as TableRoot,\n TableBody,\n TableCell,\n TableHead,\n TableHeader,\n TableRow,\n} from '@/components/ui/table';\nimport { formatDateTime, formatRelativeTime } from '@/helpers/formatDate';\nimport { TokenStatus } from './TokenStatus';\n\ntype TableProps = {\n tokens: ApiToken[];\n roleNames: ReadonlyMap<string, string>;\n /** Roles that grant Read drafts: their tokens get a Drafts chip (development tokens). */\n draftRoleIds: ReadonlySet<string>;\n /** This site's name: every token not marked \"Every site\" belongs to it. */\n siteName: string;\n /** Resolves once the token is revoked (the confirmation waits for it). */\n onRevoke: (token: ApiToken) => Promise<unknown>;\n};\n\nexport const Table = ({ tokens, roleNames, draftRoleIds, siteName, onRevoke }: TableProps) => {\n const { t } = useTranslation();\n return (\n <TableCard>\n <TableRoot>\n <TableHeader>\n <TableRow>\n <TableHead>{t('apiTokens.name')}</TableHead>\n <TableHead>{t('apiTokens.prefix')}</TableHead>\n <TableHead>{t('apiTokens.role')}</TableHead>\n <TableHead>{t('apiTokens.appliesTo')}</TableHead>\n <TableHead>{t('apiTokens.status')}</TableHead>\n <TableHead>{t('apiTokens.lastUsed')}</TableHead>\n <TableHead>{t('apiTokens.expires')}</TableHead>\n <TableHead>\n <span className=\"sr-only\">{t('common.actions')}</span>\n </TableHead>\n </TableRow>\n </TableHeader>\n <TableBody>\n {tokens.map((token) => (\n <TableRow key={token.id}>\n <TableCell>\n <RowTitle>{token.name}</RowTitle>\n </TableCell>\n <TableCell className=\"font-mono text-xs\">{`${token.tokenPrefix}…`}</TableCell>\n <TableCell>\n <span className=\"flex items-center gap-2\">\n {roleNames.get(token.roleId) ?? t('common.unknown')}\n {draftRoleIds.has(token.roleId) ? (\n <StatusChip tone=\"warning\" size=\"sm\" label={t('apiTokens.draftsChip')} />\n ) : null}\n </span>\n </TableCell>\n <TableCell>{token.siteId === null ? t('sites.everySite') : siteName}</TableCell>\n <TableCell>\n <TokenStatus token={token} />\n </TableCell>\n <TableCell title={formatDateTime(token.lastUsedAt) || undefined}>\n {token.lastUsedAt ? formatRelativeTime(token.lastUsedAt) : t('common.never')}\n </TableCell>\n <TableCell>{token.expiresAt ? formatDateTime(token.expiresAt) : t('common.never')}</TableCell>\n <TableCell className=\"text-right\">\n {token.revokedAt ? null : (\n <InlineConfirm\n tone=\"danger\"\n title={t('apiTokens.revokeTitle', { name: token.name })}\n description={t('apiTokens.revokeDescription')}\n confirmLabel={t('common.revoke')}\n onConfirm={() => onRevoke(token)}\n trigger={\n <Button variant=\"outline\" size=\"sm\" aria-label={`${t('common.revoke')}: ${token.name}`}>\n {t('common.revoke')}\n </Button>\n }\n />\n )}\n </TableCell>\n </TableRow>\n ))}\n </TableBody>\n </TableRoot>\n </TableCard>\n );\n};\n","import type { ApiToken } from '@shapio/client';\nimport { KeyRound, Plus } from 'lucide-react';\nimport { useState } from 'react';\nimport { useTranslation } from 'react-i18next';\nimport { toast } from 'sonner';\nimport { useMe } from '@/api/auth';\nimport { useDraftRoleIds, useRoleNames } from '@/api/roles';\nimport { useApiTokens, useRevokeApiToken } from '@/api/tokens';\nimport { EmptyState } from '@/components/EmptyState';\nimport { Page } from '@/components/Page';\nimport { PageHeader } from '@/components/PageHeader';\nimport { QueryView } from '@/components/QueryView';\nimport { SecretReveal } from '@/components/SecretReveal';\nimport { Button } from '@/components/ui/button';\nimport { CreateSheet } from '../CreateSheet';\nimport { Table } from '../Table';\n\n/** API tokens for admins with `tokens.manage`: the list, New token, and the one-time secret. */\nexport const Manage = () => {\n const { t } = useTranslation();\n const tokens = useApiTokens();\n const { names: roleNames } = useRoleNames();\n const { draftRoleIds } = useDraftRoleIds();\n const siteName = useMe().data?.site.name ?? '';\n const revoke = useRevokeApiToken();\n const [creating, setCreating] = useState(false);\n // The new token's secret, held only in memory until the admin says they've copied it.\n const [secret, setSecret] = useState<string | undefined>(undefined);\n const revokeToken = async (token: ApiToken) => {\n await revoke.mutateAsync(token.id);\n toast.success(t('apiTokens.revoked'));\n };\n const createButton = (\n <Button onClick={() => setCreating(true)}>\n <Plus aria-hidden=\"true\" />\n {t('apiTokens.create')}\n </Button>\n );\n return (\n <Page width=\"full\">\n <PageHeader title={t('apiTokens.title')} actions={createButton} />\n {secret ? (\n <SecretReveal\n title={t('apiTokens.secretTitle')}\n description={t('apiTokens.secretDescription')}\n label={t('apiTokens.secretLabel')}\n secret={secret}\n dismissLabel={t('apiTokens.secretDone')}\n onDismiss={() => setSecret(undefined)}\n />\n ) : null}\n <QueryView\n query={tokens}\n isEmpty={(data) => data.length === 0}\n empty={\n <EmptyState\n icon={KeyRound}\n title={t('apiTokens.empty')}\n description={t('apiTokens.emptyDescription')}\n action={createButton}\n />\n }\n >\n {(data) => (\n <Table\n tokens={data}\n roleNames={roleNames}\n draftRoleIds={draftRoleIds}\n siteName={siteName}\n onRevoke={revokeToken}\n />\n )}\n </QueryView>\n <CreateSheet\n open={creating}\n onOpenChange={setCreating}\n onCreated={(created) => {\n setSecret(created.token);\n setCreating(false);\n }}\n // The secret took focus as it appeared; don't hand it back to the \"New token\" button.\n onCloseAutoFocus={(event) => secret !== undefined && event.preventDefault()}\n />\n </Page>\n );\n};\n","import { useTranslation } from 'react-i18next';\nimport { useHasGlobalPermission } from '@/api/auth';\nimport { NoAccess } from '@/components/NoAccess';\nimport { Page } from '@/components/Page';\nimport { PageHeader } from '@/components/PageHeader';\nimport { Manage } from './Manage';\n\n/** Settings → API tokens. Reached by URL without `tokens.manage`: the reason, and no New token. */\nexport const ApiTokens = () => {\n const { t } = useTranslation();\n const canManage = useHasGlobalPermission('tokens.manage');\n if (canManage) {\n return <Manage />;\n }\n return (\n <Page width=\"full\">\n <PageHeader title={t('apiTokens.title')} />\n <NoAccess />\n </Page>\n );\n};\n","import { useTranslation } from 'react-i18next';\nimport { Page } from '@/components/Page';\nimport { PageHeader } from '@/components/PageHeader';\nimport { Panel } from '@/components/Panel';\nimport { RadioTile } from '@/components/RadioTile';\nimport { useLookSelection } from '@/components/ThemeMenu/hooks/useLookSelection';\nimport { ThemeSwatches } from '@/components/ThemeSwatches';\nimport { RadioGroup } from '@/components/ui/radio-group';\n\nexport const Appearance = () => {\n const { t } = useTranslation();\n const { looks, selectedLook, selectLook } = useLookSelection();\n return (\n <Page width=\"full\">\n <PageHeader title={t('appearance.title')} />\n <Panel title={t('appearance.theme')} description={t('appearance.storedHere')}>\n <RadioGroup\n aria-label={t('appearance.theme')}\n value={selectedLook}\n onValueChange={selectLook}\n className=\"sm:grid-cols-2 xl:grid-cols-3\"\n >\n {looks.map((look) => (\n <RadioTile\n key={look.value}\n value={look.value}\n label={look.name}\n description={look.description}\n media={<ThemeSwatches themeKey={look.themeKey} variant={look.variant} size=\"lg\" />}\n />\n ))}\n </RadioGroup>\n </Panel>\n </Page>\n );\n};\n","import { useId, useState } from 'react';\nimport { useTranslation } from 'react-i18next';\nimport { useRewriteText } from '@/api/assist';\nimport { AssistButton } from '@/components/AssistButton';\nimport { AssistError } from '@/components/AssistError';\nimport { Panel } from '@/components/Panel';\nimport { Input } from '@/components/ui/input';\nimport { Label } from '@/components/ui/label';\nimport { Textarea } from '@/components/ui/textarea';\nimport { REWRITE_MAX_INSTRUCTION, REWRITE_MAX_TEXT } from '@/constants/assist';\n\n/** A rewrite to check the configured model answers (writes nothing anywhere). */\nexport const TryIt = () => {\n const { t } = useTranslation();\n const id = useId();\n const [text, setText] = useState('');\n const [instruction, setInstruction] = useState('');\n const rewrite = useRewriteText();\n const ready = text.trim() !== '' && instruction.trim() !== '';\n return (\n <Panel title={t('assist.settings.tryIt')} titleAs=\"h2\">\n <form\n className=\"space-y-4\"\n onSubmit={(event) => {\n event.preventDefault();\n if (ready) {\n rewrite.mutate({ text: text.trim(), instruction: instruction.trim() });\n }\n }}\n >\n <div className=\"space-y-2\">\n <Label htmlFor={`${id}-text`}>{t('assist.settings.tryText')}</Label>\n <Textarea\n id={`${id}-text`}\n value={text}\n rows={3}\n maxLength={REWRITE_MAX_TEXT}\n onChange={(event) => setText(event.target.value)}\n />\n </div>\n <div className=\"space-y-2\">\n <Label htmlFor={`${id}-instruction`}>{t('assist.rewrite.instruction')}</Label>\n <Input\n id={`${id}-instruction`}\n value={instruction}\n maxLength={REWRITE_MAX_INSTRUCTION}\n placeholder={t('assist.rewrite.instructionPlaceholder')}\n onChange={(event) => setInstruction(event.target.value)}\n />\n </div>\n <AssistError error={rewrite.error} />\n <div className=\"flex justify-end\">\n <AssistButton\n type=\"submit\"\n variant=\"default\"\n size=\"default\"\n pending={rewrite.isPending}\n pendingLabel={t('assist.working')}\n disabled={!ready}\n >\n {t('assist.rewrite.run')}\n </AssistButton>\n </div>\n <div aria-live=\"polite\">\n {rewrite.data ? (\n <figure className=\"space-y-1 rounded-lg border bg-muted/40 p-3\">\n <figcaption className=\"text-meta text-muted-foreground\">\n {t('assist.rewrite.proposal', { model: rewrite.data.model })}\n </figcaption>\n <p className=\"text-sm whitespace-pre-wrap\">{rewrite.data.text}</p>\n </figure>\n ) : null}\n </div>\n </form>\n </Panel>\n );\n};\n","import type { AssistUsage } from '@shapio/client';\nimport { useTranslation } from 'react-i18next';\nimport { Panel } from '@/components/Panel';\nimport { formatMonth } from '@/helpers/formatDate';\n\ntype UsageProps = { usage: AssistUsage };\n\n/** This month's assist runs and tokens on this site (only for those who manage changes). */\nexport const Usage = ({ usage }: UsageProps) => {\n const { t } = useTranslation();\n const rows = [\n { key: 'runs', label: t('assist.settings.runs'), value: usage.runs },\n { key: 'input', label: t('assist.settings.inputTokens'), value: usage.inputTokens },\n { key: 'output', label: t('assist.settings.outputTokens'), value: usage.outputTokens },\n ];\n return (\n <Panel title={t('assist.settings.usage', { month: formatMonth(usage.month) })} titleAs=\"h2\">\n <dl className=\"grid gap-4 sm:grid-cols-3\">\n {rows.map((row) => (\n <div key={row.key} className=\"space-y-1\">\n <dt className=\"text-meta text-muted-foreground\">{row.label}</dt>\n <dd className=\"text-2xl font-semibold tabular-nums\">{row.value.toLocaleString()}</dd>\n </div>\n ))}\n </dl>\n </Panel>\n );\n};\n","import { useTranslation } from 'react-i18next';\nimport { useAssistStatus } from '@/api/assist';\nimport { Page } from '@/components/Page';\nimport { PageHeader } from '@/components/PageHeader';\nimport { Panel } from '@/components/Panel';\nimport { QueryView } from '@/components/QueryView';\nimport { StatusChip } from '@/components/StatusChip';\nimport { ASSIST_DOCS_URL } from '@/constants/assist';\nimport { ExternalLink } from '@/features/Publishing/ExternalLink';\nimport { TryIt } from './TryIt';\nimport { Usage } from './Usage';\n\n/**\n * Settings → Assist: whether editor assists are on, with which provider and model, this month's usage\n * (for those who manage changes) and a place to try a rewrite. Configuration is environment-only (no key\n * entry here, by design), so the page links to the guide.\n */\nexport const Assist = () => {\n const { t } = useTranslation();\n const status = useAssistStatus();\n return (\n <Page width=\"narrow\">\n <PageHeader title={t('settings.assist')} />\n <QueryView query={status} loadingRows={3}>\n {(data) => (\n <>\n <Panel\n title={t('assist.settings.status')}\n titleAs=\"h2\"\n actions={\n <StatusChip\n tone={data.enabled ? 'success' : 'muted'}\n label={data.enabled ? t('assist.settings.on') : t('assist.settings.off')}\n />\n }\n >\n {data.enabled ? (\n <dl className=\"space-y-2 text-sm\">\n <div className=\"flex justify-between gap-3\">\n <dt className=\"text-muted-foreground\">{t('assist.settings.provider')}</dt>\n <dd className=\"font-mono\">{data.provider}</dd>\n </div>\n <div className=\"flex justify-between gap-3\">\n <dt className=\"text-muted-foreground\">{t('assist.settings.model')}</dt>\n <dd className=\"min-w-0 font-mono break-all\">{data.model}</dd>\n </div>\n </dl>\n ) : (\n <p className=\"text-sm\">{t('assist.settings.offDescription')}</p>\n )}\n <p className=\"mt-4 text-meta\">\n <ExternalLink href={ASSIST_DOCS_URL}>{t('assist.settings.guide')}</ExternalLink>\n </p>\n </Panel>\n {data.enabled && data.usage ? <Usage usage={data.usage} /> : null}\n {data.enabled ? <TryIt /> : null}\n </>\n )}\n </QueryView>\n </Page>\n );\n};\n","import type { Locale } from '@shapio/client';\nimport { useState } from 'react';\nimport { toast } from 'sonner';\nimport { hasErrorCode } from '@/api/errors';\nimport { useDeleteLocale } from '@/api/locales';\nimport { i18next } from '@/app/i18n';\n\ntype WithContent = { locale: Locale; affectedHeads: number; deletedEntries: number };\n\n/**\n * The content counts the server reports when a locale with content is deleted without acknowledgement:\n * entry versions purged, and entries that exist only in that locale (deleted outright).\n */\nconst impactOf = (error: unknown): Omit<WithContent, 'locale'> => {\n const impact = (error as { details?: { plan?: { impact?: Record<string, unknown> } } }).details?.plan\n ?.impact;\n const count = (value: unknown) => (typeof value === 'number' ? value : 0);\n return { affectedHeads: count(impact?.affectedHeads), deletedEntries: count(impact?.deletedEntries) };\n};\n\nconst announceDeleted = (locale: Locale) =>\n toast.success(i18next.t('locales.deleted', { label: locale.label }));\n\n/**\n * Deleting a locale purges its content. The first attempt, from the row's inline confirmation, goes without\n * acknowledgement: an empty locale is simply removed. One holding content is refused with its content counts,\n * and the question moves to a blocking dialog where the admin acknowledges them.\n */\nexport const useDeleteLocaleFlow = () => {\n const deleteLocale = useDeleteLocale();\n const [withContent, setWithContent] = useState<WithContent | undefined>(undefined);\n const [open, setOpen] = useState(false);\n const attempt = async (locale: Locale) => {\n try {\n await deleteLocale.mutateAsync({ code: locale.code, acknowledged: false });\n } catch (error) {\n if (!hasErrorCode(error, 'SCHEMA_CHANGE_NOT_ACKNOWLEDGED')) {\n throw error;\n }\n deleteLocale.reset();\n setWithContent({ locale, ...impactOf(error) });\n setOpen(true);\n return;\n }\n announceDeleted(locale);\n };\n const confirm = () => {\n if (!withContent) {\n return;\n }\n deleteLocale.mutate(\n { code: withContent.locale.code, acknowledged: true },\n {\n onSuccess: () => {\n announceDeleted(withContent.locale);\n setOpen(false);\n },\n },\n );\n };\n return {\n attempt,\n withContent,\n open,\n onOpenChange: setOpen,\n confirm,\n pending: deleteLocale.isPending,\n error: deleteLocale.error,\n };\n};\n","import type { Locale } from '@shapio/client';\nimport { MAX_FALLBACK_CHAIN } from '@shapio/schema';\nimport { ArrowDown, ArrowUp, X } from 'lucide-react';\nimport { useState } from 'react';\nimport { useController, type Control } from 'react-hook-form';\nimport { useTranslation } from 'react-i18next';\nimport { FormFieldError } from '@/components/FormFieldError';\nimport { InfoHint } from '@/components/InfoHint';\nimport { Button } from '@/components/ui/button';\nimport { FieldLegend, FieldSet } from '@/components/ui/field';\nimport { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select';\nimport type { LocaleValues } from '../helpers/localeSchema';\n\nconst LEGEND_ID = 'locale-fallbacks-legend';\n\ntype FallbackChainProps = {\n control: Control<LocaleValues>;\n /** Every configured locale; the one being edited is excluded from the choices. */\n locales: readonly Locale[];\n code: string;\n};\n\n/** The ordered locales delivery tries when content is missing in this one (the default is always last). */\nexport const FallbackChain = ({ control, locales, code }: FallbackChainProps) => {\n const { t } = useTranslation();\n const { field, fieldState } = useController({ control, name: 'fallbacks' });\n const [adding, setAdding] = useState('');\n const chain = field.value;\n const labelOf = (value: string) => locales.find((locale) => locale.code === value)?.label ?? value;\n const available = locales.filter((locale) => locale.code !== code && !chain.includes(locale.code));\n const move = (from: number, to: number) => {\n const next = [...chain];\n const [moved] = next.splice(from, 1);\n next.splice(to, 0, moved as string);\n field.onChange(next);\n };\n return (\n <FieldSet className=\"gap-3\" aria-labelledby={LEGEND_ID}>\n <FieldLegend variant=\"label\" className=\"mb-0 flex items-center gap-1\">\n <span id={LEGEND_ID}>{t('locales.fallbacks')}</span>\n <InfoHint about={t('locales.fallbacks')}>{t('locales.fallbacksHint')}</InfoHint>\n </FieldLegend>\n {chain.length > 0 ? (\n <ol className=\"space-y-1\">\n {chain.map((value, index) => (\n <li key={value} className=\"flex items-center gap-2 rounded-lg border py-1 pr-1 pl-3 text-sm\">\n <span className=\"w-5 text-muted-foreground\">{index + 1}.</span>\n <span className=\"flex-1\">\n {labelOf(value)} <span className=\"font-mono text-xs text-muted-foreground\">{value}</span>\n </span>\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"icon-sm\"\n aria-label={t('locales.moveUp', { locale: labelOf(value) })}\n disabled={index === 0}\n onClick={() => move(index, index - 1)}\n >\n <ArrowUp aria-hidden=\"true\" />\n </Button>\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"icon-sm\"\n aria-label={t('locales.moveDown', { locale: labelOf(value) })}\n disabled={index === chain.length - 1}\n onClick={() => move(index, index + 1)}\n >\n <ArrowDown aria-hidden=\"true\" />\n </Button>\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"icon-sm\"\n aria-label={t('locales.removeFallback', { locale: labelOf(value) })}\n onClick={() => field.onChange(chain.filter((entry) => entry !== value))}\n >\n <X aria-hidden=\"true\" />\n </Button>\n </li>\n ))}\n </ol>\n ) : (\n <p className=\"text-sm text-muted-foreground\">{t('locales.noFallbacks')}</p>\n )}\n {available.length > 0 && chain.length < MAX_FALLBACK_CHAIN ? (\n <Select\n value={adding}\n onValueChange={(value) => {\n field.onChange([...chain, value]);\n setAdding('');\n }}\n >\n <SelectTrigger className=\"w-full sm:w-64\" aria-label={t('locales.addFallback')}>\n <SelectValue placeholder={t('locales.addFallback')} />\n </SelectTrigger>\n <SelectContent>\n {available.map((locale) => (\n <SelectItem key={locale.code} value={locale.code}>\n {locale.label} ({locale.code})\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n ) : null}\n <FormFieldError message={fieldState.error?.message} />\n </FieldSet>\n );\n};\n","import { LOCALE_CODE_PATTERN } from '@shapio/schema';\nimport { z } from 'zod';\nimport { requiredText } from '@/helpers/validation';\n\nconst MAX_CODE_LENGTH = 35;\n\n/**\n * `existing`: the codes already in use. A code that differs from one only in case (`FR` beside `fr`) is\n * refused as taken, not as badly written: codes are compared case-insensitively.\n */\nexport const localeSchemaFor = (existing: readonly string[]) =>\n z.object({\n code: z\n .string()\n .trim()\n .min(1, 'validation.required')\n .superRefine((code, context) => {\n if (existing.includes(code.toLowerCase())) {\n context.addIssue({ code: 'custom', message: 'validation.localeExists' });\n } else if (code.length > MAX_CODE_LENGTH || !LOCALE_CODE_PATTERN.test(code)) {\n context.addIssue({ code: 'custom', message: 'validation.localeCode' });\n }\n }),\n label: requiredText(),\n fallbacks: z.array(z.string()),\n });\n\nexport type LocaleValues = z.infer<ReturnType<typeof localeSchemaFor>>;\n","import { zodResolver } from '@hookform/resolvers/zod';\nimport type { Locale } from '@shapio/client';\nimport { useEffect, useMemo } from 'react';\nimport { useForm } from 'react-hook-form';\nimport { toast } from 'sonner';\nimport { useCreateLocale, useUpdateLocale } from '@/api/locales';\nimport { i18next } from '@/app/i18n';\nimport { settle } from '@/helpers/settle';\nimport { localeSchemaFor, type LocaleValues } from '../helpers/localeSchema';\n\nconst valuesFor = (locale: Locale | undefined): LocaleValues => ({\n code: locale?.code ?? '',\n label: locale?.label ?? '',\n fallbacks: locale?.fallbacks ?? [],\n});\n\n/** Adds a locale, or edits one's label and fallback chain (the code is its identity and never changes). */\nexport const useLocaleForm = (\n open: boolean,\n locale: Locale | undefined,\n locales: readonly Locale[],\n onDone: () => void,\n) => {\n const createLocale = useCreateLocale();\n const updateLocale = useUpdateLocale();\n // Editing keeps the locale's own code, which is not a clash.\n const existing = useMemo(\n () => (locale ? [] : locales.map((item) => item.code.toLowerCase())),\n [locale, locales],\n );\n const form = useForm<LocaleValues>({\n resolver: zodResolver(localeSchemaFor(existing)),\n defaultValues: valuesFor(locale),\n });\n const { reset } = form;\n useEffect(() => {\n if (open) {\n reset(valuesFor(locale));\n createLocale.reset();\n updateLocale.reset();\n }\n // Only when the dialog opens; the mutation objects change identity on every render.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [open, locale, reset]);\n const onSubmit = form.handleSubmit(async ({ code, label, fallbacks }) => {\n const result = await settle(\n locale\n ? updateLocale.mutateAsync({ code: locale.code, input: { label, fallbacks } })\n : createLocale.mutateAsync({ code, label, fallbacks }),\n );\n if (!result.ok) {\n return;\n }\n toast.success(i18next.t(locale ? 'locales.saved' : 'locales.created', { label }));\n onDone();\n });\n const mutation = locale ? updateLocale : createLocale;\n return { form, onSubmit, pending: mutation.isPending, error: mutation.error };\n};\n","import type { Locale } from '@shapio/client';\nimport { useTranslation } from 'react-i18next';\nimport { FormError } from '@/components/FormError';\nimport { FormSheet } from '@/components/FormSheet';\nimport { FormTextField } from '@/components/FormTextField';\nimport { FallbackChain } from '../FallbackChain';\nimport { useLocaleForm } from '../hooks/useLocaleForm';\n\ntype LocaleSheetProps = {\n open: boolean;\n onOpenChange: (open: boolean) => void;\n /** Edit this locale; add a new one when undefined. */\n locale: Locale | undefined;\n locales: readonly Locale[];\n};\n\nexport const LocaleSheet = ({ open, onOpenChange, locale, locales }: LocaleSheetProps) => {\n const { t } = useTranslation();\n const { form, onSubmit, pending, error } = useLocaleForm(open, locale, locales, () => onOpenChange(false));\n const code = form.watch('code');\n return (\n <FormSheet\n open={open}\n onOpenChange={onOpenChange}\n size=\"md\"\n title={locale ? t('locales.editTitle', { label: locale.label }) : t('locales.addTitle')}\n dirty={form.formState.isDirty}\n pending={pending}\n submitLabel={locale ? t('common.saveChanges') : t('locales.add')}\n pendingLabel={t('common.saving')}\n onSubmit={(event) => void onSubmit(event)}\n >\n <FormTextField\n control={form.control}\n name=\"code\"\n label={t('locales.code')}\n hint={t('locales.codeHint')}\n autoComplete=\"off\"\n spellCheck={false}\n className=\"font-mono\"\n disabled={locale !== undefined}\n />\n <FormTextField control={form.control} name=\"label\" label={t('locales.label')} autoComplete=\"off\" />\n <FallbackChain control={form.control} locales={locales} code={code} />\n <FormError error={error} />\n </FormSheet>\n );\n};\n","import type { Locale } from '@shapio/client';\nimport { MoreHorizontal, Pencil, Star, Trash2 } from 'lucide-react';\nimport { useState } from 'react';\nimport { useTranslation } from 'react-i18next';\nimport { InlineConfirm } from '@/components/InlineConfirm';\nimport { RowTitle } from '@/components/RowTitle';\nimport { Badge } from '@/components/ui/badge';\nimport { Button } from '@/components/ui/button';\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuTrigger,\n} from '@/components/ui/dropdown-menu';\nimport { TableCell, TableRow } from '@/components/ui/table';\n\ntype RowProps = {\n locale: Locale;\n /** The fallbacks delivery tries, the default locale last. */\n chain: readonly string[];\n canManage: boolean;\n onEdit: (locale: Locale) => void;\n onMakeDefault: (locale: Locale) => void;\n /** The first delete attempt; resolves once it's done or handed to the content acknowledgement. */\n onDelete: (locale: Locale) => Promise<unknown>;\n};\n\n/** One locale. Delete asks inline, anchored to the row's menu button. */\nexport const Row = ({ locale, chain, canManage, onEdit, onMakeDefault, onDelete }: RowProps) => {\n const { t } = useTranslation();\n const [deleting, setDeleting] = useState(false);\n return (\n <TableRow>\n <TableCell>\n <span className=\"flex items-center gap-2\">\n <RowTitle>{locale.label}</RowTitle>\n {locale.isDefault ? <Badge variant=\"secondary\">{t('locales.default')}</Badge> : null}\n </span>\n </TableCell>\n <TableCell className=\"font-mono text-xs\">{locale.code}</TableCell>\n <TableCell className=\"font-mono text-xs\">\n {chain.length > 0 ? chain.join(' → ') : t('common.none')}\n </TableCell>\n <TableCell className=\"text-right\">\n {canManage ? (\n <DropdownMenu>\n <InlineConfirm\n tone=\"danger\"\n open={deleting}\n onOpenChange={setDeleting}\n title={t('locales.deleteTitle', { label: locale.label })}\n description={t('locales.deleteDescription')}\n confirmLabel={t('common.delete')}\n pendingLabel={t('locales.deleting')}\n onConfirm={() => onDelete(locale)}\n >\n <DropdownMenuTrigger asChild>\n <Button variant=\"ghost\" size=\"icon-sm\" aria-label={`${t('common.actions')}: ${locale.label}`}>\n <MoreHorizontal aria-hidden=\"true\" />\n </Button>\n </DropdownMenuTrigger>\n </InlineConfirm>\n <DropdownMenuContent align=\"end\" onCloseAutoFocus={(event) => deleting && event.preventDefault()}>\n <DropdownMenuItem onSelect={() => onEdit(locale)}>\n <Pencil aria-hidden=\"true\" />\n {t('common.edit')}\n </DropdownMenuItem>\n {locale.isDefault ? null : (\n <>\n <DropdownMenuItem onSelect={() => onMakeDefault(locale)}>\n <Star aria-hidden=\"true\" />\n {t('locales.makeDefault')}\n </DropdownMenuItem>\n <DropdownMenuItem variant=\"destructive\" onSelect={() => setDeleting(true)}>\n <Trash2 aria-hidden=\"true\" />\n {t('common.delete')}\n </DropdownMenuItem>\n </>\n )}\n </DropdownMenuContent>\n </DropdownMenu>\n ) : null}\n </TableCell>\n </TableRow>\n );\n};\n","import type { Locale } from '@shapio/client';\nimport { useTranslation } from 'react-i18next';\nimport { TableCard } from '@/components/TableCard';\nimport { Table as TableRoot, TableBody, TableHead, TableHeader, TableRow } from '@/components/ui/table';\nimport { Row } from './Row';\n\ntype TableProps = {\n locales: readonly Locale[];\n canManage: boolean;\n onEdit: (locale: Locale) => void;\n onMakeDefault: (locale: Locale) => void;\n onDelete: (locale: Locale) => Promise<unknown>;\n};\n\nexport const Table = ({ locales, canManage, onEdit, onMakeDefault, onDelete }: TableProps) => {\n const { t } = useTranslation();\n const defaultLocale = locales.find((locale) => locale.isDefault);\n return (\n <TableCard>\n <TableRoot>\n <TableHeader>\n <TableRow>\n <TableHead>{t('locales.label')}</TableHead>\n <TableHead>{t('locales.code')}</TableHead>\n <TableHead>{t('locales.fallbacks')}</TableHead>\n <TableHead>\n <span className=\"sr-only\">{t('common.actions')}</span>\n </TableHead>\n </TableRow>\n </TableHeader>\n <TableBody>\n {locales.map((locale) => (\n <Row\n key={locale.code}\n locale={locale}\n chain={[\n ...locale.fallbacks,\n ...(defaultLocale && !locale.isDefault && !locale.fallbacks.includes(defaultLocale.code)\n ? [defaultLocale.code]\n : []),\n ]}\n canManage={canManage}\n onEdit={onEdit}\n onMakeDefault={onMakeDefault}\n onDelete={onDelete}\n />\n ))}\n </TableBody>\n </TableRoot>\n </TableCard>\n );\n};\n","import type { Locale } from '@shapio/client';\nimport { Globe, Plus } from 'lucide-react';\nimport { useState } from 'react';\nimport { useTranslation } from 'react-i18next';\nimport { toast } from 'sonner';\nimport { useLocales, useSetDefaultLocale } from '@/api/locales';\nimport { ConfirmDialog } from '@/components/ConfirmDialog';\nimport { EmptyState } from '@/components/EmptyState';\nimport { Page } from '@/components/Page';\nimport { PageHeader } from '@/components/PageHeader';\nimport { QueryView } from '@/components/QueryView';\nimport { Button } from '@/components/ui/button';\nimport { useNetworkPermission } from '@/features/Network/hooks/useNetworkPermission';\nimport { useConfirmTarget } from '@/hooks/useConfirmTarget';\nimport { useDeleteLocaleFlow } from './hooks/useDeleteLocaleFlow';\nimport { LocaleSheet } from './LocaleSheet';\nimport { Table } from './Table';\n\n/** Content locales (ADR 0004): code, label, the default locale and each locale's fallback chain. */\nexport const Locales = () => {\n const { t } = useTranslation();\n const locales = useLocales();\n // Locales are shared by every site: a role granting schema.create on one site doesn't manage them.\n const canManage = useNetworkPermission('schema.create');\n const setDefault = useSetDefaultLocale();\n const makeDefault = useConfirmTarget<Locale>();\n const deletion = useDeleteLocaleFlow();\n const [sheet, setSheet] = useState<{ open: boolean; locale: Locale | undefined }>({\n open: false,\n locale: undefined,\n });\n const currentDefault = locales.data?.find((locale) => locale.isDefault);\n const withContent = deletion.withContent;\n return (\n <Page width=\"full\">\n <PageHeader\n title={t('locales.title')}\n actions={\n canManage ? (\n <Button onClick={() => setSheet({ open: true, locale: undefined })}>\n <Plus aria-hidden=\"true\" />\n {t('locales.add')}\n </Button>\n ) : null\n }\n />\n <QueryView\n query={locales}\n isEmpty={(data) => data.length === 0}\n empty={<EmptyState icon={Globe} title={t('locales.empty')} />}\n >\n {(data) => (\n <Table\n locales={data}\n canManage={canManage}\n onEdit={(locale) => setSheet({ open: true, locale })}\n onMakeDefault={(locale) => {\n setDefault.reset();\n makeDefault.ask(locale);\n }}\n onDelete={deletion.attempt}\n />\n )}\n </QueryView>\n <LocaleSheet\n open={sheet.open}\n onOpenChange={(open) => setSheet((current) => ({ ...current, open }))}\n locale={sheet.locale}\n locales={locales.data ?? []}\n />\n <ConfirmDialog\n open={makeDefault.open}\n onOpenChange={makeDefault.onOpenChange}\n title={t('locales.defaultTitle', { label: makeDefault.target?.label ?? '' })}\n description={t('locales.defaultDescription', {\n label: makeDefault.target?.label ?? '',\n current: currentDefault?.label ?? '',\n })}\n acknowledgement={t('locales.defaultAcknowledge')}\n confirmLabel={t('locales.makeDefault')}\n destructive\n pending={setDefault.isPending}\n pendingLabel={t('common.saving')}\n error={setDefault.error}\n onConfirm={() => {\n const target = makeDefault.target;\n if (target) {\n setDefault.mutate(target.code, {\n onSuccess: () => {\n toast.success(t('locales.defaultChanged', { label: target.label }));\n makeDefault.close();\n },\n });\n }\n }}\n />\n <ConfirmDialog\n open={deletion.open}\n onOpenChange={deletion.onOpenChange}\n title={t('locales.deleteTitle', { label: withContent?.locale.label ?? '' })}\n description={[\n t('locales.deleteContent', {\n count: withContent?.affectedHeads ?? 0,\n label: withContent?.locale.label ?? '',\n }),\n withContent?.deletedEntries\n ? t('locales.deleteEntries', {\n count: withContent.deletedEntries,\n label: withContent.locale.label,\n })\n : '',\n ]\n .filter(Boolean)\n .join(' ')}\n acknowledgement={t('locales.deleteAcknowledge', { count: withContent?.affectedHeads ?? 0 })}\n confirmLabel={t('common.delete')}\n destructive\n pending={deletion.pending}\n pendingLabel={t('locales.deleting')}\n error={deletion.error}\n onConfirm={deletion.confirm}\n />\n </Page>\n );\n};\n","import { zodResolver } from '@hookform/resolvers/zod';\nimport { useEffect } from 'react';\nimport { useForm } from 'react-hook-form';\nimport { toast } from 'sonner';\nimport { z } from 'zod';\nimport { useMe, useUpdateProfile } from '@/api/auth';\nimport { i18next } from '@/app/i18n';\nimport { settle } from '@/helpers/settle';\nimport { requiredText } from '@/helpers/validation';\n\nconst profileSchema = z.object({ name: requiredText() });\n\nexport type ProfileValues = z.infer<typeof profileSchema>;\n\n/** The signed-in admin's display name. Email changes go through an owner (Users), not self-service. */\nexport const useProfileDetailsForm = () => {\n const { data: me } = useMe();\n const updateProfile = useUpdateProfile();\n const form = useForm<ProfileValues>({\n resolver: zodResolver(profileSchema),\n defaultValues: { name: me?.user.name ?? '' },\n });\n const { reset, formState } = form;\n const name = me?.user.name;\n // Follow the server's value when it changes elsewhere, unless the user is mid-edit.\n useEffect(() => {\n if (!formState.isDirty && name !== undefined) {\n reset({ name });\n }\n }, [name, reset, formState.isDirty]);\n const onSubmit = form.handleSubmit(async (values) => {\n const saved = await settle(updateProfile.mutateAsync(values));\n if (!saved.ok) {\n return;\n }\n reset({ name: saved.value.name });\n toast.success(i18next.t('profile.detailsSaved'));\n });\n return { form, onSubmit, updateProfile, email: me?.user.email ?? '' };\n};\n","import { useEffect } from 'react';\nimport { useTranslation } from 'react-i18next';\nimport { FormError } from '@/components/FormError';\nimport { FormTextField } from '@/components/FormTextField';\nimport { HintedLabel } from '@/components/HintedLabel';\nimport { Panel } from '@/components/Panel';\nimport { SubmitButton } from '@/components/SubmitButton';\nimport { Field, FieldGroup } from '@/components/ui/field';\nimport { Input } from '@/components/ui/input';\nimport { useProfileDetailsForm } from '../hooks/useProfileDetailsForm';\n\ntype DetailsProps = { onDirtyChange: (dirty: boolean) => void };\n\nconst EMAIL_ID = 'profile-email';\nconst EMAIL_HINT_ID = 'profile-email-hint';\n\nexport const Details = ({ onDirtyChange }: DetailsProps) => {\n const { t } = useTranslation();\n const { form, onSubmit, updateProfile, email } = useProfileDetailsForm();\n const { isDirty } = form.formState;\n useEffect(() => onDirtyChange(isDirty), [isDirty, onDirtyChange]);\n return (\n <Panel title={t('profile.detailsTitle')}>\n <form noValidate onSubmit={(event) => void onSubmit(event)} className=\"max-w-md\">\n <FieldGroup>\n <FormTextField control={form.control} name=\"name\" label={t('auth.name')} autoComplete=\"name\" />\n <Field>\n <HintedLabel\n htmlFor={EMAIL_ID}\n label={t('auth.email')}\n hint={t('profile.emailHint')}\n hintId={EMAIL_HINT_ID}\n />\n <Input id={EMAIL_ID} value={email} readOnly aria-describedby={EMAIL_HINT_ID} />\n </Field>\n <FormError error={updateProfile.error} />\n <div>\n <SubmitButton\n pending={updateProfile.isPending}\n pendingLabel={t('common.saving')}\n disabled={!isDirty}\n >\n {t('common.saveChanges')}\n </SubmitButton>\n </div>\n </FieldGroup>\n </form>\n </Panel>\n );\n};\n","import { zodResolver } from '@hookform/resolvers/zod';\nimport { useForm } from 'react-hook-form';\nimport { toast } from 'sonner';\nimport { z } from 'zod';\nimport { useChangePassword } from '@/api/auth';\nimport { i18next } from '@/app/i18n';\nimport { settle } from '@/helpers/settle';\nimport { newPasswordField, withPasswordConfirmation } from '@/helpers/validation';\n\nconst changePasswordSchema = withPasswordConfirmation({\n currentPassword: z.string().min(1, 'validation.required'),\n password: newPasswordField(),\n});\n\nexport type ChangePasswordValues = z.infer<typeof changePasswordSchema>;\n\nconst EMPTY: ChangePasswordValues = { currentPassword: '', password: '', confirmPassword: '' };\n\nexport const useChangePasswordForm = () => {\n const changePassword = useChangePassword();\n const form = useForm<ChangePasswordValues>({\n resolver: zodResolver(changePasswordSchema),\n defaultValues: EMPTY,\n });\n const onSubmit = form.handleSubmit(async ({ currentPassword, password }) => {\n if (!(await settle(changePassword.mutateAsync({ currentPassword, newPassword: password }))).ok) {\n return;\n }\n form.reset(EMPTY);\n toast.success(i18next.t('profile.passwordChanged'));\n });\n return { form, onSubmit, changePassword };\n};\n","import { useEffect } from 'react';\nimport { useTranslation } from 'react-i18next';\nimport { FormError } from '@/components/FormError';\nimport { FormTextField } from '@/components/FormTextField';\nimport { Panel } from '@/components/Panel';\nimport { SubmitButton } from '@/components/SubmitButton';\nimport { FieldGroup } from '@/components/ui/field';\nimport { useChangePasswordForm } from '../hooks/useChangePasswordForm';\n\ntype PasswordProps = { onDirtyChange: (dirty: boolean) => void };\n\nexport const Password = ({ onDirtyChange }: PasswordProps) => {\n const { t } = useTranslation();\n const { form, onSubmit, changePassword } = useChangePasswordForm();\n const { isDirty } = form.formState;\n useEffect(() => onDirtyChange(isDirty), [isDirty, onDirtyChange]);\n return (\n <Panel title={t('profile.passwordTitle')} description={t('profile.passwordDescription')}>\n <form noValidate onSubmit={(event) => void onSubmit(event)} className=\"max-w-md\">\n <FieldGroup>\n <FormTextField\n control={form.control}\n name=\"currentPassword\"\n label={t('profile.currentPassword')}\n type=\"password\"\n autoComplete=\"current-password\"\n />\n <FormTextField\n control={form.control}\n name=\"password\"\n label={t('auth.newPassword')}\n description={t('auth.passwordHint')}\n type=\"password\"\n autoComplete=\"new-password\"\n />\n <FormTextField\n control={form.control}\n name=\"confirmPassword\"\n label={t('auth.confirmPassword')}\n type=\"password\"\n autoComplete=\"new-password\"\n />\n <FormError error={changePassword.error} />\n <div>\n <SubmitButton pending={changePassword.isPending} pendingLabel={t('common.saving')}>\n {t('profile.changePassword')}\n </SubmitButton>\n </div>\n </FieldGroup>\n </form>\n </Panel>\n );\n};\n","import { useCallback, useState } from 'react';\nimport { useTranslation } from 'react-i18next';\nimport { Page } from '@/components/Page';\nimport { PageHeader } from '@/components/PageHeader';\nimport { UnsavedChangesGuard } from '@/components/UnsavedChangesGuard';\nimport { Details } from './Details';\nimport { Password } from './Password';\n\nexport const Profile = () => {\n const { t } = useTranslation();\n const [detailsDirty, setDetailsDirty] = useState(false);\n const [passwordDirty, setPasswordDirty] = useState(false);\n const onDetailsDirtyChange = useCallback((dirty: boolean) => setDetailsDirty(dirty), []);\n const onPasswordDirtyChange = useCallback((dirty: boolean) => setPasswordDirty(dirty), []);\n return (\n <Page width=\"full\">\n <PageHeader title={t('profile.title')} />\n <Details onDirtyChange={onDetailsDirtyChange} />\n <Password onDirtyChange={onPasswordDirtyChange} />\n <UnsavedChangesGuard when={detailsDirty || passwordDirty} />\n </Page>\n );\n};\n","import { ImagePlus } from 'lucide-react';\nimport { useController, type Control } from 'react-hook-form';\nimport { useTranslation } from 'react-i18next';\nimport { FormFieldError } from '@/components/FormFieldError';\nimport { HintedLabel } from '@/components/HintedLabel';\nimport { Button } from '@/components/ui/button';\nimport { Field } from '@/components/ui/field';\nimport { useMediaPickerDialog } from '@/fields/hooks/useMediaPickerDialog';\nimport { AssetTile } from '@/fields/MediaField/AssetTile';\nimport { describedBy } from '@/helpers/describedBy';\nimport { useMediaPermissions } from '@/hooks/useMediaPermissions';\nimport type { SeoSettingsValues } from '../helpers';\n\ntype DefaultImageProps = {\n control: Control<SeoSettingsValues>;\n /** The chosen asset is private: delivery would never show it. */\n imagePrivate: boolean;\n};\n\nconst BUTTON_ID = 'seo-default-image';\nconst HINT_ID = `${BUTTON_ID}-hint`;\nconst ERROR_ID = `${BUTTON_ID}-error`;\n\n/** The site's default social image: one public image from the library, chosen in the media sheet. */\nexport const DefaultImage = ({ control, imagePrivate }: DefaultImageProps) => {\n const { t } = useTranslation();\n const { field, fieldState } = useController({ control, name: 'imageId' });\n // A private choice is caught here; anything else the server refuses (SEO_IMAGE_INVALID) arrives as an error.\n const error = imagePrivate ? t('seo.settings.imagePrivate') : fieldState.error?.message;\n const { canWrite } = useMediaPermissions();\n const picker = useMediaPickerDialog();\n const choose = async () => {\n const picked = await picker.pickMedia({ multiple: false, allowedKinds: ['image'] });\n const first = picked?.[0];\n if (first) {\n field.onChange(first.id);\n }\n };\n return (\n <Field data-invalid={error ? true : undefined}>\n <HintedLabel\n htmlFor={BUTTON_ID}\n label={t('seo.settings.image')}\n hint={t('seo.settings.imageHint')}\n hintId={HINT_ID}\n />\n {field.value ? (\n <ul>\n <AssetTile\n assetId={field.value}\n inputId={BUTTON_ID}\n index={0}\n count={1}\n editable\n canEditAlt={canWrite}\n onRemove={() => field.onChange(null)}\n />\n </ul>\n ) : null}\n <div>\n <Button\n id={BUTTON_ID}\n type=\"button\"\n variant=\"outline\"\n size=\"sm\"\n aria-describedby={describedBy(HINT_ID, error ? ERROR_ID : undefined)}\n onClick={() => void choose()}\n >\n <ImagePlus aria-hidden=\"true\" />\n {field.value ? t('seo.settings.changeImage') : t('seo.settings.chooseImage')}\n </Button>\n </div>\n <FormFieldError id={error ? ERROR_ID : undefined} message={error} />\n {picker.dialog}\n </Field>\n );\n};\n","import type { Locale } from '@shapio/client';\nimport {\n isValidTitleTemplate,\n SEO_TWITTER_HANDLE_PATTERN,\n type SeoDefaults,\n type SeoLocaleDefaults,\n} from '@shapio/schema';\nimport { z } from 'zod';\n\n/** Lengths from `SeoLocaleDefaultsSchema` (the server checks them too). */\nconst SHORT_MAX = 200;\nconst DESCRIPTION_MAX = 1000;\n\nconst optionalText = (max: number) => z.string().trim().max(max, 'validation.tooLong');\n\nconst localeTextsSchema = z.object({\n siteName: optionalText(SHORT_MAX),\n titleTemplate: optionalText(SHORT_MAX).refine(\n (value) => value === '' || isValidTitleTemplate(value),\n 'validation.titleTemplate',\n ),\n description: optionalText(DESCRIPTION_MAX),\n});\n\nexport const seoSettingsSchema = z.object({\n locales: z.record(z.string(), localeTextsSchema),\n imageId: z.string().nullable(),\n twitterHandle: z\n .string()\n .trim()\n .refine((value) => value === '' || SEO_TWITTER_HANDLE_PATTERN.test(value), 'validation.twitterHandle'),\n});\n\nexport type SeoLocaleTexts = z.infer<typeof localeTextsSchema>;\nexport type SeoSettingsValues = z.infer<typeof seoSettingsSchema>;\n\nconst EMPTY_TEXTS: SeoLocaleTexts = { siteName: '', titleTemplate: '', description: '' };\n\n/**\n * The form's values: every locale of the instance (and any other locale the defaults still hold) with all\n * three texts, empty strings for unset ones, so switching locale never loses an edit.\n */\nexport const toSeoSettingsValues = (seo: SeoDefaults, locales: readonly Locale[]): SeoSettingsValues => {\n const codes = [...new Set([...locales.map((locale) => locale.code), ...Object.keys(seo.locales)])];\n return {\n locales: Object.fromEntries(codes.map((code) => [code, { ...EMPTY_TEXTS, ...seo.locales[code] }])),\n imageId: seo.imageId,\n twitterHandle: seo.twitterHandle ?? '',\n };\n};\n\n/** What is saved: unset texts and locales without any text are left out. */\nexport const toSeoDefaults = (values: SeoSettingsValues): SeoDefaults => {\n const locales: Record<string, SeoLocaleDefaults> = {};\n for (const [code, texts] of Object.entries(values.locales)) {\n const kept = Object.fromEntries(\n Object.entries(texts)\n .map(([key, value]) => [key, value.trim()] as const)\n .filter(([, value]) => value !== ''),\n ) as SeoLocaleDefaults;\n if (Object.keys(kept).length > 0) {\n locales[code] = kept;\n }\n }\n const handle = values.twitterHandle.trim();\n return { locales, imageId: values.imageId, twitterHandle: handle === '' ? null : handle };\n};\n\n/** The first locale with an invalid text, so a refused save can show it. */\nexport const firstLocaleWithErrors = (errors: { locales?: Record<string, unknown> }): string | undefined =>\n Object.keys(errors.locales ?? {})[0];\n","import { zodResolver } from '@hookform/resolvers/zod';\nimport type { Locale } from '@shapio/client';\nimport { useQueryClient } from '@tanstack/react-query';\nimport { useEffect, useState } from 'react';\nimport { useForm, useWatch, type FieldErrors } from 'react-hook-form';\nimport { toast } from 'sonner';\nimport { hasErrorCode, isConflict } from '@/api/errors';\nimport { useMediaAsset } from '@/api/media';\nimport { siteSeoQueryOptions, useUpdateSiteSeo, type SiteSeo } from '@/api/seo';\nimport { i18next } from '@/app/i18n';\nimport { describeError } from '@/helpers/describeError';\nimport { reportError } from '@/helpers/reportError';\nimport {\n firstLocaleWithErrors,\n seoSettingsSchema,\n toSeoDefaults,\n toSeoSettingsValues,\n type SeoSettingsValues,\n} from '../helpers';\n\n/** The server refused the default image (another site's, not an image, or private). */\nconst SEO_IMAGE_INVALID = 'SEO_IMAGE_INVALID';\n\n/**\n * Settings → SEO: the site's default texts per locale, default social image and Twitter handle, saved with\n * the site version they were read at (a conflict asks to reload). The image must be public: a private one is\n * refused here before the server would.\n */\nexport const useSeoSettingsForm = (siteSeo: SiteSeo, locales: readonly Locale[]) => {\n const queryClient = useQueryClient();\n const update = useUpdateSiteSeo();\n const defaultLocale = locales.find((locale) => locale.isDefault)?.code ?? locales[0]?.code ?? '';\n const [locale, setLocale] = useState(defaultLocale);\n const [version, setVersion] = useState(siteSeo.version);\n const form = useForm<SeoSettingsValues>({\n resolver: zodResolver(seoSettingsSchema),\n defaultValues: toSeoSettingsValues(siteSeo.seo, locales),\n });\n const imageId = useWatch({ control: form.control, name: 'imageId' });\n const image = useMediaAsset(imageId ?? undefined);\n const imagePrivate = imageId !== null && image.data?.visibility === 'private';\n const { clearErrors } = form;\n // The server's verdict on an image is about that image: another choice clears it.\n useEffect(() => clearErrors('imageId'), [imageId, clearErrors]);\n\n const reload = async () => {\n try {\n const fresh = await queryClient.fetchQuery({ ...siteSeoQueryOptions, staleTime: 0 });\n form.reset(toSeoSettingsValues(fresh.seo, locales));\n setVersion(fresh.version);\n } catch (error) {\n reportError(error, 'reloading the SEO settings');\n }\n };\n\n const save = async (values: SeoSettingsValues) => {\n if (imagePrivate) {\n return;\n }\n try {\n const saved = await update.mutateAsync({ expectedVersion: version, seo: toSeoDefaults(values) });\n form.reset(toSeoSettingsValues(saved.seo, locales));\n setVersion(saved.version);\n toast.success(i18next.t('seo.settings.saved'));\n } catch (error) {\n if (isConflict(error)) {\n toast.error(i18next.t('seo.settings.conflict'), {\n action: { label: i18next.t('seo.settings.reload'), onClick: () => void reload() },\n });\n return;\n }\n if (hasErrorCode(error, SEO_IMAGE_INVALID)) {\n form.setError('imageId', { message: describeError(error) }, { shouldFocus: false });\n return;\n }\n toast.error(describeError(error));\n }\n };\n\n const showInvalidLocale = (errors: FieldErrors<SeoSettingsValues>) => {\n const invalid = firstLocaleWithErrors(errors);\n if (invalid !== undefined) {\n setLocale(invalid);\n }\n };\n\n return {\n form,\n locale,\n setLocale,\n imagePrivate,\n pending: update.isPending,\n onSubmit: form.handleSubmit(save, showInvalidLocale),\n };\n};\n","import type { Locale } from '@shapio/client';\nimport type { Control } from 'react-hook-form';\nimport { useTranslation } from 'react-i18next';\nimport { FormTextareaField } from '@/components/FormTextareaField';\nimport { FormTextField } from '@/components/FormTextField';\nimport { Panel } from '@/components/Panel';\nimport { FieldGroup } from '@/components/ui/field';\nimport { LocaleSelect } from '@/features/Content/LocaleSelect';\nimport type { SeoSettingsValues } from '../helpers';\n\ntype LocaleTextsProps = {\n control: Control<SeoSettingsValues>;\n locales: readonly Locale[];\n locale: string;\n onLocaleChange: (code: string) => void;\n};\n\n/** Site name, title template and description for one locale at a time; empty ones follow the fallbacks. */\nexport const LocaleTexts = ({ control, locales, locale, onLocaleChange }: LocaleTextsProps) => {\n const { t } = useTranslation();\n return (\n <Panel\n title={t('seo.settings.textsTitle')}\n titleAs=\"h2\"\n actions={\n locales.length > 1 ? (\n <LocaleSelect locales={locales} value={locale} onChange={onLocaleChange} size=\"sm\" />\n ) : null\n }\n >\n <FieldGroup key={locale} className=\"max-w-xl\">\n <FormTextField\n control={control}\n name={`locales.${locale}.siteName`}\n label={t('seo.settings.siteName')}\n hint={t('seo.settings.siteNameHint')}\n />\n <FormTextField\n control={control}\n name={`locales.${locale}.titleTemplate`}\n label={t('seo.settings.titleTemplate')}\n hint={t('seo.settings.titleTemplateHint')}\n placeholder={t('seo.settings.titleTemplatePlaceholder')}\n />\n <FormTextareaField\n control={control}\n name={`locales.${locale}.description`}\n label={t('seo.settings.description')}\n hint={t('seo.settings.descriptionHint')}\n rows={3}\n />\n </FieldGroup>\n </Panel>\n );\n};\n","import type { Locale } from '@shapio/client';\nimport { useTranslation } from 'react-i18next';\nimport { useLocales } from '@/api/locales';\nimport { useSiteSeo, type SiteSeo } from '@/api/seo';\nimport { FormTextField } from '@/components/FormTextField';\nimport { Page } from '@/components/Page';\nimport { PageHeader } from '@/components/PageHeader';\nimport { Panel } from '@/components/Panel';\nimport { QueryView } from '@/components/QueryView';\nimport { SubmitButton } from '@/components/SubmitButton';\nimport { FieldGroup } from '@/components/ui/field';\nimport { UnsavedChangesGuard } from '@/components/UnsavedChangesGuard';\nimport { DefaultImage } from './DefaultImage';\nimport { useSeoSettingsForm } from './hooks/useSeoSettingsForm';\nimport { LocaleTexts } from './LocaleTexts';\n\ntype SeoFormProps = { siteSeo: SiteSeo; locales: readonly Locale[] };\n\nconst SeoForm = ({ siteSeo, locales }: SeoFormProps) => {\n const { t } = useTranslation();\n const { form, locale, setLocale, imagePrivate, pending, onSubmit } = useSeoSettingsForm(siteSeo, locales);\n const { isDirty } = form.formState;\n return (\n <form noValidate onSubmit={(event) => void onSubmit(event)} className=\"space-y-6\">\n <UnsavedChangesGuard when={isDirty} />\n <LocaleTexts control={form.control} locales={locales} locale={locale} onLocaleChange={setLocale} />\n <Panel title={t('seo.settings.socialTitle')} titleAs=\"h2\">\n <FieldGroup className=\"max-w-xl\">\n <DefaultImage control={form.control} imagePrivate={imagePrivate} />\n <FormTextField\n control={form.control}\n name=\"twitterHandle\"\n label={t('seo.settings.twitterHandle')}\n hint={t('seo.settings.twitterHandleHint')}\n placeholder={t('seo.settings.twitterHandlePlaceholder')}\n autoComplete=\"off\"\n />\n </FieldGroup>\n </Panel>\n <div>\n <SubmitButton pending={pending} pendingLabel={t('common.saving')} disabled={!isDirty || imagePrivate}>\n {t('common.saveChanges')}\n </SubmitButton>\n </div>\n </form>\n );\n};\n\n/** Settings → SEO: the current site's search and social defaults (`site.settings`). */\nexport const Seo = () => {\n const { t } = useTranslation();\n const siteSeo = useSiteSeo();\n const locales = useLocales();\n return (\n <Page width=\"full\">\n <PageHeader title={t('seo.settings.title')} />\n <QueryView query={siteSeo} loadingRows={4}>\n {(seo) => (\n <QueryView query={locales} loadingRows={4}>\n {(list) => <SeoForm siteSeo={seo} locales={list} />}\n </QueryView>\n )}\n </QueryView>\n </Page>\n );\n};\n","import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';\nimport { adminApi } from './client';\nimport { withCsrf } from './csrf';\nimport { queryKeys } from './queryKeys';\n\nexport const useSessions = () =>\n useQuery({ queryKey: queryKeys.sessions, queryFn: () => adminApi.sessions.list(), meta: { silent: true } });\n\nexport const useRevokeSession = () => {\n const queryClient = useQueryClient();\n return useMutation({\n mutationKey: ['sessions', 'revoke'],\n mutationFn: (id: string) => withCsrf(() => adminApi.sessions.revoke(id)),\n onSettled: () => queryClient.invalidateQueries({ queryKey: queryKeys.sessions }),\n });\n};\n","const BROWSERS: readonly [RegExp, string][] = [\n [/Edg\\//, 'Edge'],\n [/OPR\\//, 'Opera'],\n [/Firefox\\//, 'Firefox'],\n [/Chrome\\//, 'Chrome'],\n [/Safari\\//, 'Safari'],\n];\n\nconst SYSTEMS: readonly [RegExp, string][] = [\n [/iPhone|iPad/, 'iOS'],\n [/Android/, 'Android'],\n [/Mac OS X|Macintosh/, 'macOS'],\n [/Windows/, 'Windows'],\n [/Linux/, 'Linux'],\n];\n\nconst firstMatch = (value: string, table: readonly [RegExp, string][]) =>\n table.find(([pattern]) => pattern.test(value))?.[1];\n\n/**\n * \"Chrome on macOS\" from a user-agent string (product names are not translated). `undefined` when nothing\n * is recognized, so the caller can show its own \"unknown device\" label.\n */\nexport const describeUserAgent = (userAgent: string | null): string | undefined => {\n if (!userAgent) {\n return undefined;\n }\n const browser = firstMatch(userAgent, BROWSERS);\n const system = firstMatch(userAgent, SYSTEMS);\n if (browser && system) {\n return `${browser} · ${system}`;\n }\n return browser ?? system;\n};\n","import type { AdminSession } from '@shapio/client';\nimport { useTranslation } from 'react-i18next';\nimport { InlineConfirm } from '@/components/InlineConfirm';\nimport { RowTitle } from '@/components/RowTitle';\nimport { TableCard } from '@/components/TableCard';\nimport { Badge } from '@/components/ui/badge';\nimport { Button } from '@/components/ui/button';\nimport {\n Table as TableRoot,\n TableBody,\n TableCell,\n TableHead,\n TableHeader,\n TableRow,\n} from '@/components/ui/table';\nimport { describeUserAgent } from '@/helpers/describeUserAgent';\nimport { formatDateTime, formatRelativeTime } from '@/helpers/formatDate';\n\ntype TableProps = {\n sessions: readonly AdminSession[];\n /** Resolves once the session is revoked (the confirmation waits for it). */\n onRevoke: (session: AdminSession) => Promise<unknown>;\n};\n\nexport const Table = ({ sessions, onRevoke }: TableProps) => {\n const { t } = useTranslation();\n return (\n <TableCard>\n <TableRoot>\n <TableHeader>\n <TableRow>\n <TableHead>{t('sessions.device')}</TableHead>\n <TableHead>{t('sessions.ipAddress')}</TableHead>\n <TableHead>{t('sessions.signedIn')}</TableHead>\n <TableHead>{t('sessions.lastActive')}</TableHead>\n <TableHead>\n <span className=\"sr-only\">{t('common.actions')}</span>\n </TableHead>\n </TableRow>\n </TableHeader>\n <TableBody>\n {sessions.map((session) => (\n <TableRow key={session.id}>\n <TableCell>\n <span className=\"flex items-center gap-2\">\n <RowTitle>{describeUserAgent(session.userAgent) ?? t('sessions.unknownDevice')}</RowTitle>\n {session.current ? <Badge variant=\"secondary\">{t('sessions.current')}</Badge> : null}\n </span>\n </TableCell>\n <TableCell className=\"font-mono text-xs\">{session.ip ?? t('common.unknown')}</TableCell>\n <TableCell title={formatDateTime(session.createdAt)}>\n {formatRelativeTime(session.createdAt)}\n </TableCell>\n <TableCell title={formatDateTime(session.lastSeenAt)}>\n {formatRelativeTime(session.lastSeenAt)}\n </TableCell>\n <TableCell className=\"text-right\">\n {session.current ? null : (\n <InlineConfirm\n tone=\"danger\"\n title={t('sessions.revokeTitle')}\n description={t('sessions.revokeDescription')}\n confirmLabel={t('common.revoke')}\n onConfirm={() => onRevoke(session)}\n trigger={\n <Button variant=\"outline\" size=\"sm\">\n {t('common.revoke')}\n </Button>\n }\n />\n )}\n </TableCell>\n </TableRow>\n ))}\n </TableBody>\n </TableRoot>\n </TableCard>\n );\n};\n","import type { AdminSession } from '@shapio/client';\nimport { MonitorSmartphone } from 'lucide-react';\nimport { useTranslation } from 'react-i18next';\nimport { toast } from 'sonner';\nimport { useRevokeSession, useSessions } from '@/api/sessions';\nimport { EmptyState } from '@/components/EmptyState';\nimport { Page } from '@/components/Page';\nimport { PageHeader } from '@/components/PageHeader';\nimport { QueryView } from '@/components/QueryView';\nimport { Table } from './Table';\n\nexport const Sessions = () => {\n const { t } = useTranslation();\n const sessions = useSessions();\n const revoke = useRevokeSession();\n const revokeSession = async (session: AdminSession) => {\n await revoke.mutateAsync(session.id);\n toast.success(t('sessions.revoked'));\n };\n return (\n <Page width=\"full\">\n <PageHeader title={t('sessions.title')} />\n <QueryView\n query={sessions}\n isEmpty={(data) => data.length === 0}\n empty={<EmptyState icon={MonitorSmartphone} title={t('sessions.empty')} />}\n >\n {(data) => <Table sessions={data} onRevoke={revokeSession} />}\n </QueryView>\n </Page>\n );\n};\n","import { createLazyRoute } from '@tanstack/react-router';\nimport { Settings } from '@/features/Settings';\nimport { ApiTokens } from '@/features/Settings/ApiTokens';\nimport { Appearance } from '@/features/Settings/Appearance';\nimport { Assist } from '@/features/Settings/Assist';\nimport { Locales } from '@/features/Settings/Locales';\nimport { Profile } from '@/features/Settings/Profile';\nimport { Seo } from '@/features/Settings/Seo';\nimport { Sessions } from '@/features/Settings/Sessions';\n\n/** Every settings screen, loaded together on the first visit to Settings. */\nexport const settingsLazyRoutes = {\n settings: createLazyRoute('/app/settings')({ component: Settings }),\n profile: createLazyRoute('/app/settings/profile')({ component: Profile }),\n sessions: createLazyRoute('/app/settings/sessions')({ component: Sessions }),\n theme: createLazyRoute('/app/settings/theme')({ component: Appearance }),\n locales: createLazyRoute('/app/settings/locales')({ component: Locales }),\n seo: createLazyRoute('/app/settings/seo')({ component: Seo }),\n assist: createLazyRoute('/app/settings/assist')({ component: Assist }),\n apiTokens: createLazyRoute('/app/settings/api-tokens')({ component: ApiTokens }),\n};\n"],"ignoreList":[0],"mappings":"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"}
|