includio-cms 0.25.0 → 0.26.0

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.
Files changed (349) hide show
  1. package/API.md +57 -4
  2. package/CHANGELOG.md +53 -0
  3. package/DOCS.md +1 -1
  4. package/README.md +2 -0
  5. package/ROADMAP.md +6 -0
  6. package/dist/admin/client/account/lang.d.ts +1 -0
  7. package/dist/admin/client/account/lang.js +4 -2
  8. package/dist/admin/client/account/profile-section.svelte +2 -2
  9. package/dist/admin/client/account/security-section.svelte +27 -4
  10. package/dist/admin/client/account/sessions-section.svelte +1 -1
  11. package/dist/admin/client/admin/admin-after-login-layout-content.svelte +1 -1
  12. package/dist/admin/client/admin/dashboard-page.svelte +34 -10
  13. package/dist/admin/client/collection/bulk-actions-bar.svelte +86 -44
  14. package/dist/admin/client/collection/bulk-actions-bar.svelte.d.ts +3 -1
  15. package/dist/admin/client/collection/collection-entries.svelte +52 -36
  16. package/dist/admin/client/collection/collection-entries.svelte.d.ts +3 -0
  17. package/dist/admin/client/collection/collection.svelte +28 -14
  18. package/dist/admin/client/collection/collection.svelte.d.ts +3 -0
  19. package/dist/admin/client/collection/data-table.svelte +279 -130
  20. package/dist/admin/client/collection/data-table.svelte.d.ts +11 -0
  21. package/dist/admin/client/collection/date-cell.svelte +4 -4
  22. package/dist/admin/client/collection/row-actions.svelte +2 -1
  23. package/dist/admin/client/collection/sortable-header.svelte +33 -9
  24. package/dist/admin/client/collection/state-display.svelte +102 -0
  25. package/dist/admin/client/collection/state-display.svelte.d.ts +12 -0
  26. package/dist/admin/client/collection/status-badge.svelte +99 -11
  27. package/dist/admin/client/collection/status-badge.svelte.d.ts +15 -1
  28. package/dist/admin/client/collection/table-pagination.svelte +21 -6
  29. package/dist/admin/client/collection/table-toolbar.svelte +105 -80
  30. package/dist/admin/client/collection/table-toolbar.svelte.d.ts +11 -8
  31. package/dist/admin/client/entry/entry-form.svelte +36 -11
  32. package/dist/admin/client/entry/entry-form.svelte.d.ts +1 -0
  33. package/dist/admin/client/entry/entry-header.svelte +22 -15
  34. package/dist/admin/client/entry/entry-header.svelte.d.ts +1 -0
  35. package/dist/admin/client/entry/entry.svelte +269 -165
  36. package/dist/admin/client/entry/header/a11y-header-badge.svelte +47 -0
  37. package/dist/admin/client/entry/header/a11y-header-badge.svelte.d.ts +8 -0
  38. package/dist/admin/client/entry/header/publish-panel.svelte +69 -13
  39. package/dist/admin/client/entry/header/save-indicator.svelte +57 -28
  40. package/dist/admin/client/entry/header/save-indicator.svelte.d.ts +1 -0
  41. package/dist/admin/client/entry/header/status-badge.svelte +60 -15
  42. package/dist/admin/client/entry/header/status-badge.svelte.d.ts +1 -2
  43. package/dist/admin/client/entry/header/version-history-sheet.svelte +1 -1
  44. package/dist/admin/client/entry/hybrid/hybrid-layout.svelte +74 -23
  45. package/dist/admin/client/entry/hybrid/hybrid-preview.svelte +1 -1
  46. package/dist/admin/client/entry/utils.d.ts +14 -0
  47. package/dist/admin/client/entry/utils.js +28 -0
  48. package/dist/admin/client/form/form-submission/form-submission.svelte +2 -2
  49. package/dist/admin/client/form/form-submissions.svelte +143 -194
  50. package/dist/admin/client/form/form-submissions.svelte.d.ts +2 -0
  51. package/dist/admin/client/login/lang.d.ts +3 -0
  52. package/dist/admin/client/login/lang.js +10 -4
  53. package/dist/admin/client/login/login-form.svelte +8 -1
  54. package/dist/admin/client/login/reset-password-page.svelte +24 -3
  55. package/dist/admin/client/login/schema.d.ts +14 -2
  56. package/dist/admin/client/login/schema.js +19 -8
  57. package/dist/admin/client/maintenance/maintenance-page.svelte +16 -17
  58. package/dist/admin/client/media/media-page.svelte +1 -1
  59. package/dist/admin/client/shop/coupon-edit-page.svelte +117 -13
  60. package/dist/admin/client/shop/coupon-form.svelte +282 -138
  61. package/dist/admin/client/shop/coupon-form.svelte.d.ts +1 -9
  62. package/dist/admin/client/shop/coupon-new-page.svelte +40 -10
  63. package/dist/admin/client/shop/coupon-new-page.svelte.d.ts +2 -17
  64. package/dist/admin/client/shop/coupon-schema.d.ts +28 -0
  65. package/dist/admin/client/shop/coupon-schema.js +53 -0
  66. package/dist/admin/client/shop/coupons-list-page.svelte +262 -118
  67. package/dist/admin/client/shop/coupons-list-page.svelte.d.ts +16 -1
  68. package/dist/admin/client/shop/shipping-method-edit-page.svelte +108 -59
  69. package/dist/admin/client/shop/shipping-method-form.svelte +36 -9
  70. package/dist/admin/client/shop/shipping-method-new-page.svelte +44 -13
  71. package/dist/admin/client/shop/shipping-methods-list-page.svelte +101 -59
  72. package/dist/admin/client/shop/shop-order-detail-page.svelte +113 -84
  73. package/dist/admin/client/shop/shop-orders-list-page.svelte +302 -152
  74. package/dist/admin/client/shop/shop-orders-list-page.svelte.d.ts +18 -1
  75. package/dist/admin/client/shop/shop-products-list-page.svelte +355 -118
  76. package/dist/admin/client/shop/shop-products-list-page.svelte.d.ts +19 -1
  77. package/dist/admin/client/users/accept-invite-page.svelte +24 -3
  78. package/dist/admin/client/users/create-user-dialog.svelte +3 -8
  79. package/dist/admin/client/users/lang.d.ts +2 -0
  80. package/dist/admin/client/users/lang.js +4 -0
  81. package/dist/admin/client/users/pending-invitations.svelte +2 -9
  82. package/dist/admin/client/users/user-name-cell.svelte +20 -0
  83. package/dist/admin/client/users/user-name-cell.svelte.d.ts +9 -0
  84. package/dist/admin/client/users/user-role-badge.svelte +16 -0
  85. package/dist/admin/client/users/user-role-badge.svelte.d.ts +7 -0
  86. package/dist/admin/client/users/user-row-actions.svelte +72 -0
  87. package/dist/admin/client/users/user-row-actions.svelte.d.ts +20 -0
  88. package/dist/admin/client/users/user-sessions-sheet.svelte +2 -11
  89. package/dist/admin/client/users/users-page.svelte +283 -497
  90. package/dist/admin/client/users/users-page.svelte.d.ts +12 -1
  91. package/dist/admin/components/dashboard/form-submissions-widget.svelte +59 -74
  92. package/dist/admin/components/dashboard/recent-activity.svelte +17 -5
  93. package/dist/admin/components/dashboard/recent-entries.svelte +19 -7
  94. package/dist/admin/components/dialogs/confirmation-dialog.svelte +105 -0
  95. package/dist/admin/components/dialogs/confirmation-dialog.svelte.d.ts +13 -0
  96. package/dist/admin/components/fields/block-picker-modal.svelte +6 -0
  97. package/dist/admin/components/fields/blocks-field.svelte +46 -1
  98. package/dist/admin/components/fields/boolean-field.svelte +1 -1
  99. package/dist/admin/components/fields/field-renderer.svelte +23 -21
  100. package/dist/admin/components/fields/file-field.svelte +344 -30
  101. package/dist/admin/components/fields/media-field.svelte +16 -2
  102. package/dist/admin/components/fields/radio-field.svelte +22 -0
  103. package/dist/admin/components/fields/relation-field.svelte +123 -97
  104. package/dist/admin/components/fields/relation-picker-dialog.svelte +2 -2
  105. package/dist/admin/components/fields/seo-field.svelte +60 -30
  106. package/dist/admin/components/fields/shop-field.svelte +9 -4
  107. package/dist/admin/components/fields/simple-array-field.svelte +321 -151
  108. package/dist/admin/components/fields/simple-array-field.svelte.d.ts +3 -0
  109. package/dist/admin/components/fields/slug-field.svelte +146 -21
  110. package/dist/admin/components/fields/text-field-wrapper.svelte +37 -20
  111. package/dist/admin/components/fields/text-field.svelte +7 -2
  112. package/dist/admin/components/fields/url-field-wrapper.svelte +10 -0
  113. package/dist/admin/components/fields/url-field.svelte +36 -23
  114. package/dist/admin/components/forms/form-error-summary.svelte +143 -0
  115. package/dist/admin/components/forms/form-error-summary.svelte.d.ts +27 -0
  116. package/dist/admin/components/layout/app-sidebar.svelte +7 -2
  117. package/dist/admin/components/layout/detail-page-shell.svelte +71 -0
  118. package/dist/admin/components/layout/detail-page-shell.svelte.d.ts +24 -0
  119. package/dist/admin/components/layout/lang.d.ts +5 -0
  120. package/dist/admin/components/layout/lang.js +10 -0
  121. package/dist/admin/components/layout/layout-renderer.svelte +71 -2
  122. package/dist/admin/components/layout/layout-renderer.svelte.d.ts +1 -0
  123. package/dist/admin/components/layout/layout-tabs.svelte +172 -0
  124. package/dist/admin/components/layout/layout-tabs.svelte.d.ts +24 -0
  125. package/dist/admin/components/layout/nav-breadcrumbs.svelte +25 -7
  126. package/dist/admin/components/layout/nav-collections.svelte +23 -36
  127. package/dist/admin/components/layout/nav-forms.svelte +19 -35
  128. package/dist/admin/components/layout/nav-main.svelte +3 -28
  129. package/dist/admin/components/layout/nav-search.svelte +70 -2
  130. package/dist/admin/components/layout/nav-section.svelte +77 -0
  131. package/dist/admin/components/layout/nav-section.svelte.d.ts +22 -0
  132. package/dist/admin/components/layout/nav-shop.svelte +3 -27
  133. package/dist/admin/components/layout/nav-singletons.svelte +16 -28
  134. package/dist/admin/components/layout/page-header.stories.svelte +93 -0
  135. package/dist/admin/components/layout/page-header.stories.svelte.d.ts +27 -0
  136. package/dist/admin/components/layout/page-header.svelte +68 -0
  137. package/dist/admin/components/layout/page-header.svelte.d.ts +17 -0
  138. package/dist/admin/components/layout/site-header.svelte +9 -0
  139. package/dist/admin/components/layout/site-header.svelte.d.ts +2 -17
  140. package/dist/admin/components/media/file/file-name-input.svelte +6 -2
  141. package/dist/admin/components/media/file/file-preview.svelte +130 -17
  142. package/dist/admin/components/media/file-upload.svelte +16 -7
  143. package/dist/admin/components/media/file-upload.svelte.d.ts +1 -0
  144. package/dist/admin/components/media/files-list.svelte +153 -53
  145. package/dist/admin/components/media/files-list.svelte.d.ts +1 -0
  146. package/dist/admin/components/media/media-library.svelte +577 -198
  147. package/dist/admin/components/media/media-library.svelte.d.ts +4 -0
  148. package/dist/admin/components/media/media-selector.svelte +4 -2
  149. package/dist/admin/components/media/media-selector.svelte.d.ts +1 -0
  150. package/dist/admin/components/media/tag-sidebar.svelte +4 -4
  151. package/dist/admin/components/tiptap/FigureNodeView.svelte +10 -0
  152. package/dist/admin/components/tiptap/bubble-menu.svelte +104 -0
  153. package/dist/admin/components/tiptap/bubble-menu.svelte.d.ts +19 -0
  154. package/dist/admin/components/tiptap/content-editor.svelte +28 -24
  155. package/dist/admin/components/tiptap/editor-toolbar.svelte +7 -7
  156. package/dist/admin/components/tiptap/extensions.js +5 -1
  157. package/dist/admin/components/tiptap/image-dialog.svelte +5 -1
  158. package/dist/admin/components/tiptap/link-dialog.svelte +2 -0
  159. package/dist/admin/components/tiptap/tiptap-editor.svelte +18 -20
  160. package/dist/admin/components/tiptap/video-dialog.svelte +1 -1
  161. package/dist/admin/i18n/errors.d.ts +140 -0
  162. package/dist/admin/i18n/errors.js +151 -0
  163. package/dist/admin/remote/entry.remote.d.ts +59 -4
  164. package/dist/admin/remote/entry.remote.js +239 -62
  165. package/dist/admin/remote/shop.remote.d.ts +37 -32
  166. package/dist/admin/remote/shop.remote.js +9 -2
  167. package/dist/admin/shared/password-generate.d.ts +6 -0
  168. package/dist/admin/shared/password-generate.js +40 -0
  169. package/dist/admin/shared/password-schema.d.ts +6 -0
  170. package/dist/admin/shared/password-schema.js +10 -3
  171. package/dist/admin/styles/admin.css +23 -6
  172. package/dist/admin/styles/tokens.md +244 -0
  173. package/dist/admin/utils/accordionActivation.d.ts +13 -0
  174. package/dist/admin/utils/accordionActivation.js +35 -0
  175. package/dist/admin/utils/entryLabel.d.ts +23 -0
  176. package/dist/admin/utils/entryLabel.js +51 -12
  177. package/dist/admin/utils/field-a11y.d.ts +29 -0
  178. package/dist/admin/utils/field-a11y.js +23 -0
  179. package/dist/admin/utils/fieldPathElement.d.ts +9 -0
  180. package/dist/admin/utils/fieldPathElement.js +18 -0
  181. package/dist/admin/utils/fileDisplay.d.ts +10 -0
  182. package/dist/admin/utils/fileDisplay.js +26 -0
  183. package/dist/admin/utils/flattenFormErrors.d.ts +19 -0
  184. package/dist/admin/utils/flattenFormErrors.js +102 -0
  185. package/dist/admin/utils/formatters.d.ts +12 -0
  186. package/dist/admin/utils/{formatDate.js → formatters.js} +23 -2
  187. package/dist/admin/utils/scrollWithin.d.ts +9 -0
  188. package/dist/admin/utils/scrollWithin.js +32 -0
  189. package/dist/admin/utils/tabActivation.d.ts +12 -0
  190. package/dist/admin/utils/tabActivation.js +24 -0
  191. package/dist/cms/runtime/schema.d.ts +1 -0
  192. package/dist/cms/runtime/schema.js +1 -0
  193. package/dist/cms/runtime/types.d.ts +80 -7
  194. package/dist/components/ui/accordion/accordion-content.svelte +17 -3
  195. package/dist/components/ui/accordion/accordion.stories.svelte +21 -1
  196. package/dist/components/ui/alert/alert.stories.svelte +14 -0
  197. package/dist/components/ui/alert-dialog/alert-dialog.stories.svelte +45 -0
  198. package/dist/components/ui/alert-dialog/alert-dialog.stories.svelte.d.ts +27 -0
  199. package/dist/components/ui/avatar/avatar.stories.svelte +27 -0
  200. package/dist/components/ui/badge/badge.stories.svelte +15 -0
  201. package/dist/components/ui/breadcrumb/breadcrumb.stories.svelte +47 -0
  202. package/dist/components/ui/breadcrumb/breadcrumb.svelte +1 -1
  203. package/dist/components/ui/button/button.stories.svelte +53 -6
  204. package/dist/components/ui/button/button.svelte +39 -5
  205. package/dist/components/ui/button/button.svelte.d.ts +4 -0
  206. package/dist/components/ui/button-group/button-group.stories.svelte +44 -0
  207. package/dist/components/ui/button-group/button-group.stories.svelte.d.ts +27 -0
  208. package/dist/components/ui/calendar/calendar.stories.svelte +36 -0
  209. package/dist/components/ui/calendar/calendar.stories.svelte.d.ts +27 -0
  210. package/dist/components/ui/card/card.stories.svelte +7 -0
  211. package/dist/components/ui/carousel/carousel.stories.svelte +43 -0
  212. package/dist/components/ui/carousel/carousel.stories.svelte.d.ts +27 -0
  213. package/dist/components/ui/checkbox/checkbox.stories.svelte +67 -0
  214. package/dist/components/ui/checkbox/checkbox.stories.svelte.d.ts +27 -0
  215. package/dist/components/ui/checkbox/checkbox.svelte +3 -3
  216. package/dist/components/ui/command/command.stories.svelte +18 -0
  217. package/dist/components/ui/data-table/data-table.stories.svelte +61 -0
  218. package/dist/components/ui/data-table/data-table.stories.svelte.d.ts +18 -0
  219. package/dist/components/ui/dialog/dialog-content.svelte +5 -0
  220. package/dist/components/ui/dialog/dialog-content.svelte.d.ts +2 -0
  221. package/dist/components/ui/dialog/dialog.stories.svelte +35 -0
  222. package/dist/components/ui/dropdown-menu/dropdown-menu.stories.svelte +74 -0
  223. package/dist/components/ui/dropdown-menu/dropdown-menu.stories.svelte.d.ts +27 -0
  224. package/dist/components/ui/field/field-context.svelte.d.ts +22 -0
  225. package/dist/components/ui/field/field-context.svelte.js +9 -0
  226. package/dist/components/ui/field/field-control.svelte +18 -0
  227. package/dist/components/ui/field/field-control.svelte.d.ts +8 -0
  228. package/dist/components/ui/field/field-description.svelte +12 -0
  229. package/dist/components/ui/field/field-error.svelte +14 -6
  230. package/dist/components/ui/field/field-label.svelte +10 -0
  231. package/dist/components/ui/field/field.stories.svelte +95 -9
  232. package/dist/components/ui/field/field.svelte +57 -0
  233. package/dist/components/ui/field/field.svelte.d.ts +2 -0
  234. package/dist/components/ui/field/index.d.ts +3 -1
  235. package/dist/components/ui/field/index.js +4 -2
  236. package/dist/components/ui/form/form-field-errors.svelte +1 -1
  237. package/dist/components/ui/form/form.stories.svelte +25 -0
  238. package/dist/components/ui/form/form.stories.svelte.d.ts +26 -0
  239. package/dist/components/ui/input/input.stories.svelte +26 -0
  240. package/dist/components/ui/input-group/input-group-input.svelte.d.ts +1 -1
  241. package/dist/components/ui/input-group/input-group.stories.svelte +43 -0
  242. package/dist/components/ui/input-group/input-group.stories.svelte.d.ts +27 -0
  243. package/dist/components/ui/item/item.stories.svelte +61 -0
  244. package/dist/components/ui/item/item.stories.svelte.d.ts +27 -0
  245. package/dist/components/ui/label/label.stories.svelte +7 -0
  246. package/dist/components/ui/live-region/index.d.ts +1 -0
  247. package/dist/components/ui/live-region/index.js +1 -0
  248. package/dist/components/ui/live-region/live-region-demo.svelte +32 -0
  249. package/dist/components/ui/live-region/live-region-demo.svelte.d.ts +7 -0
  250. package/dist/components/ui/live-region/live-region.stories.svelte +23 -0
  251. package/dist/components/ui/live-region/live-region.stories.svelte.d.ts +26 -0
  252. package/dist/components/ui/live-region/live-region.svelte +12 -0
  253. package/dist/components/ui/live-region/live-region.svelte.d.ts +8 -0
  254. package/dist/components/ui/popover/popover.stories.svelte +34 -0
  255. package/dist/components/ui/radio-group/radio-group.stories.svelte +58 -0
  256. package/dist/components/ui/radio-group/radio-group.stories.svelte.d.ts +27 -0
  257. package/dist/components/ui/resizable/resizable.stories.svelte +56 -0
  258. package/dist/components/ui/resizable/resizable.stories.svelte.d.ts +27 -0
  259. package/dist/components/ui/select/select.stories.svelte +49 -0
  260. package/dist/components/ui/separator/separator.stories.svelte +18 -0
  261. package/dist/components/ui/sheet/sheet.stories.svelte +34 -0
  262. package/dist/components/ui/sidebar/sidebar-input.svelte.d.ts +1 -1
  263. package/dist/components/ui/sidebar/sidebar-menu-button.svelte +1 -0
  264. package/dist/components/ui/sidebar/sidebar-trigger.svelte +1 -1
  265. package/dist/components/ui/sidebar/sidebar.stories.svelte +72 -0
  266. package/dist/components/ui/sidebar/sidebar.stories.svelte.d.ts +27 -0
  267. package/dist/components/ui/skeleton/skeleton.stories.svelte +39 -0
  268. package/dist/components/ui/skeleton/skeleton.stories.svelte.d.ts +27 -0
  269. package/dist/components/ui/skeleton/skeleton.svelte +6 -0
  270. package/dist/components/ui/sonner/index.d.ts +1 -1
  271. package/dist/components/ui/sonner/index.js +1 -1
  272. package/dist/components/ui/sonner/sonner.stories.svelte +7 -0
  273. package/dist/components/ui/sonner/sonner.svelte +17 -1
  274. package/dist/components/ui/sonner/sonner.svelte.d.ts +6 -0
  275. package/dist/components/ui/spinner/spinner.stories.svelte +30 -0
  276. package/dist/components/ui/spinner/spinner.stories.svelte.d.ts +27 -0
  277. package/dist/components/ui/switch/switch.stories.svelte +56 -0
  278. package/dist/components/ui/switch/switch.stories.svelte.d.ts +27 -0
  279. package/dist/components/ui/table/table-cell.svelte +1 -1
  280. package/dist/components/ui/table/table-head.svelte +1 -1
  281. package/dist/components/ui/table/table.stories.svelte +68 -0
  282. package/dist/components/ui/table/table.stories.svelte.d.ts +27 -0
  283. package/dist/components/ui/table/table.svelte +1 -1
  284. package/dist/components/ui/tabs/tabs.stories.svelte +48 -0
  285. package/dist/components/ui/tabs/tabs.stories.svelte.d.ts +27 -0
  286. package/dist/components/ui/textarea/textarea.stories.svelte +21 -0
  287. package/dist/components/ui/toggle/toggle.stories.svelte +23 -0
  288. package/dist/components/ui/toggle-group/toggle-group.stories.svelte +43 -0
  289. package/dist/components/ui/tooltip/tooltip.stories.svelte +46 -6
  290. package/dist/core/fields/fieldSchemaToTs.d.ts +7 -0
  291. package/dist/core/fields/fieldSchemaToTs.js +234 -90
  292. package/dist/core/fields/layoutUtils.d.ts +4 -1
  293. package/dist/core/fields/layoutUtils.js +41 -4
  294. package/dist/core/fields/resolveSeo.d.ts +70 -0
  295. package/dist/core/fields/resolveSeo.js +88 -0
  296. package/dist/core/fields/seoFieldDescriptor.d.ts +43 -0
  297. package/dist/core/fields/seoFieldDescriptor.js +74 -0
  298. package/dist/core/fields/slugPath.d.ts +13 -0
  299. package/dist/core/fields/slugPath.js +32 -0
  300. package/dist/core/fields/urlUtils.d.ts +8 -0
  301. package/dist/core/fields/urlUtils.js +27 -0
  302. package/dist/core/index.d.ts +1 -0
  303. package/dist/core/index.js +1 -0
  304. package/dist/core/server/entries/operations/create.js +13 -0
  305. package/dist/core/server/entries/operations/get.d.ts +7 -0
  306. package/dist/core/server/entries/operations/get.js +10 -6
  307. package/dist/core/server/entries/operations/slugUniqueness.d.ts +37 -0
  308. package/dist/core/server/entries/operations/slugUniqueness.js +116 -0
  309. package/dist/core/server/entries/operations/update.d.ts +6 -1
  310. package/dist/core/server/entries/operations/update.js +24 -1
  311. package/dist/core/server/fields/slugResolver.d.ts +3 -13
  312. package/dist/core/server/fields/slugResolver.js +8 -37
  313. package/dist/core/server/generator/fields.js +10 -17
  314. package/dist/core/server/generator/formFields.js +2 -1
  315. package/dist/core/server/generator/generator.js +4 -4
  316. package/dist/core/server/generator/utils.d.ts +1 -0
  317. package/dist/core/server/generator/utils.js +4 -0
  318. package/dist/paraglide/messages/_index.d.ts +3 -36
  319. package/dist/paraglide/messages/_index.js +3 -71
  320. package/dist/paraglide/messages/hello_world.d.ts +5 -0
  321. package/dist/paraglide/messages/hello_world.js +33 -0
  322. package/dist/paraglide/messages/login_hello.d.ts +16 -0
  323. package/dist/paraglide/messages/login_hello.js +34 -0
  324. package/dist/paraglide/messages/login_please_login.d.ts +16 -0
  325. package/dist/paraglide/messages/login_please_login.js +34 -0
  326. package/dist/shop/server/orders.d.ts +1 -0
  327. package/dist/shop/server/orders.js +14 -0
  328. package/dist/shop/server/shop-data.d.ts +2 -0
  329. package/dist/shop/server/shop-data.js +20 -5
  330. package/dist/sveltekit/server/handle.js +17 -0
  331. package/dist/types/cms.schema.js +4 -2
  332. package/dist/types/fields.d.ts +35 -0
  333. package/dist/types/index.d.ts +1 -1
  334. package/dist/types/layout.d.ts +35 -2
  335. package/dist/updates/0.26.0/index.d.ts +2 -0
  336. package/dist/updates/0.26.0/index.js +51 -0
  337. package/dist/updates/index.js +3 -1
  338. package/package.json +29 -7
  339. package/dist/admin/client/collection/empty-state.svelte +0 -28
  340. package/dist/admin/client/collection/empty-state.svelte.d.ts +0 -9
  341. package/dist/admin/client/form/submission-status-badge.svelte +0 -41
  342. package/dist/admin/client/form/submission-status-badge.svelte.d.ts +0 -7
  343. package/dist/admin/components/media/file-preview.svelte +0 -51
  344. package/dist/admin/components/media/file-preview.svelte.d.ts +0 -6
  345. package/dist/admin/utils/formatDate.d.ts +0 -5
  346. package/dist/paraglide/messages/en.d.ts +0 -5
  347. package/dist/paraglide/messages/en.js +0 -14
  348. package/dist/paraglide/messages/pl.d.ts +0 -5
  349. package/dist/paraglide/messages/pl.js +0 -14
@@ -1,135 +1,279 @@
1
1
  <script lang="ts">
2
2
  import { getRemotes } from '../../../sveltekit/index.js';
3
+ import { useInterfaceLanguage } from '../../state/interface-language.svelte.js';
4
+ import { getBreadcrumbs } from '../../state/breadcrumbs.svelte.js';
5
+ import { sidebarLang } from '../../components/layout/lang.js';
3
6
  import { Button } from '../../../components/ui/button/index.js';
4
7
  import PlusIcon from '@tabler/icons-svelte/icons/plus';
5
- import EditIcon from '@tabler/icons-svelte/icons/edit';
6
- import TrashIcon from '@tabler/icons-svelte/icons/trash';
8
+ import { formatPlnPrice, formatShortDateOnly } from '../../utils/formatters.js';
9
+ import PageHeader from '../../components/layout/page-header.svelte';
10
+ import DataTable from '../collection/data-table.svelte';
11
+ import TableToolbar from '../collection/table-toolbar.svelte';
12
+ import TablePagination from '../collection/table-pagination.svelte';
13
+ import StateDisplay from '../collection/state-display.svelte';
14
+ import StatusBadge from '../collection/status-badge.svelte';
15
+ import EntryLink from '../collection/entry-link.svelte';
16
+ import { renderComponent } from '../../../components/ui/data-table/render-helpers.js';
17
+ import type { ColumnDef, PaginationState } from '@tanstack/table-core';
18
+ import type { InterfaceLanguage } from '../../../types/languages.js';
19
+
20
+ type CouponRow = {
21
+ id: string;
22
+ code: string;
23
+ type: string;
24
+ value: string | number;
25
+ minOrderAmount: number | null;
26
+ usedCount: number;
27
+ maxUses: number | null;
28
+ expiresAt: Date | string | null;
29
+ isActive: boolean;
30
+ };
31
+
32
+ type Props = {
33
+ data?: CouponRow[];
34
+ state?: 'loading' | 'error' | 'ok';
35
+ };
36
+
37
+ let { data: injectedData, state: injectedState }: Props = $props();
38
+ const useInjectedData = $derived(injectedData !== undefined);
7
39
 
8
40
  const remotes = getRemotes();
9
- const query = $derived(remotes.listCouponsAdmin());
41
+ const interfaceLanguage = useInterfaceLanguage();
42
+ const breadcrumbs = getBreadcrumbs();
43
+
44
+ $effect(() => {
45
+ const s = sidebarLang[interfaceLanguage.current].shop;
46
+ breadcrumbs.state = [{ label: s.title }, { label: s.coupons }];
47
+ });
48
+
49
+ const couponsQuery = $derived(useInjectedData ? null : remotes.listCouponsAdmin());
50
+
51
+ const allRows = $derived<CouponRow[]>(
52
+ useInjectedData
53
+ ? (injectedData ?? [])
54
+ : ((couponsQuery?.current as CouponRow[] | undefined) ?? [])
55
+ );
56
+ const isLoading = $derived(
57
+ useInjectedData ? injectedState === 'loading' : !(couponsQuery?.ready ?? false)
58
+ );
59
+ const isError = $derived(
60
+ useInjectedData ? injectedState === 'error' : Boolean(couponsQuery?.error)
61
+ );
10
62
 
11
- function formatValue(type: string, value: string): string {
12
- const num = Number(value);
63
+ let searchQuery = $state('');
64
+ let activeFilter = $state<string | null>(null);
65
+ let pagination = $state<PaginationState>({ pageIndex: 0, pageSize: 20 });
66
+
67
+ const lang: Record<
68
+ InterfaceLanguage,
69
+ {
70
+ title: string;
71
+ search: string;
72
+ searchPlaceholder: string;
73
+ filterActive: string;
74
+ activeYes: string;
75
+ activeNo: string;
76
+ addCoupon: string;
77
+ emptyTitle: string;
78
+ emptyDescription: string;
79
+ columnCode: string;
80
+ columnValue: string;
81
+ columnMinOrder: string;
82
+ columnUsed: string;
83
+ columnExpires: string;
84
+ columnStatus: string;
85
+ noResults: string;
86
+ never: string;
87
+ }
88
+ > = {
89
+ en: {
90
+ title: 'Coupons',
91
+ search: 'Search',
92
+ searchPlaceholder: 'Search by code…',
93
+ filterActive: 'Active',
94
+ activeYes: 'Active',
95
+ activeNo: 'Paused',
96
+ addCoupon: 'Add coupon',
97
+ emptyTitle: 'No coupons yet',
98
+ emptyDescription: 'Add your first coupon to offer discounts at checkout.',
99
+ columnCode: 'Code',
100
+ columnValue: 'Value',
101
+ columnMinOrder: 'Min. order',
102
+ columnUsed: 'Used',
103
+ columnExpires: 'Expires',
104
+ columnStatus: 'Status',
105
+ noResults: 'No results.',
106
+ never: '—'
107
+ },
108
+ pl: {
109
+ title: 'Kody rabatowe',
110
+ search: 'Szukaj',
111
+ searchPlaceholder: 'Szukaj po kodzie…',
112
+ filterActive: 'Aktywność',
113
+ activeYes: 'Aktywny',
114
+ activeNo: 'Wstrzymany',
115
+ addCoupon: 'Dodaj kod',
116
+ emptyTitle: 'Brak kodów rabatowych',
117
+ emptyDescription: 'Dodaj pierwszy kod, aby oferować zniżki przy zakupie.',
118
+ columnCode: 'Kod',
119
+ columnValue: 'Wartość',
120
+ columnMinOrder: 'Min. zamów.',
121
+ columnUsed: 'Wykorzystano',
122
+ columnExpires: 'Wygasa',
123
+ columnStatus: 'Status',
124
+ noResults: 'Brak wyników.',
125
+ never: '—'
126
+ }
127
+ };
128
+ const t = $derived(lang[interfaceLanguage.current]);
129
+
130
+ function formatValue(type: string, value: string | number): string {
131
+ const num = typeof value === 'string' ? Number(value) : value;
13
132
  if (type === 'percent') return `${num}%`;
14
- return new Intl.NumberFormat('pl-PL', {
15
- style: 'currency',
16
- currency: 'PLN',
17
- minimumFractionDigits: 2
18
- }).format(num);
133
+ return formatPlnPrice(num);
19
134
  }
20
135
 
21
- function formatDate(d: Date | string | null): string {
22
- if (!d) return '—';
23
- return new Intl.DateTimeFormat('pl-PL', {
24
- dateStyle: 'short'
25
- }).format(new Date(d));
136
+ function formatMinOrder(amountInCents: number | null): string {
137
+ if (amountInCents == null) return t.never;
138
+ return formatPlnPrice(amountInCents / 100);
26
139
  }
27
140
 
28
- async function handleDelete(id: string, code: string) {
29
- if (!confirm(`Usunąć kod „${code}”? Tej operacji nie można cofnąć.`)) return;
30
- try {
31
- await remotes.deleteCouponCmd(id);
32
- await query.refresh();
33
- } catch (err) {
34
- alert(err instanceof Error ? err.message : 'Nie udało się usunąć kodu.');
141
+ const filteredRows = $derived.by(() => {
142
+ const q = searchQuery.trim().toLowerCase();
143
+ let list = allRows;
144
+ if (q) list = list.filter((c) => c.code.toLowerCase().includes(q));
145
+ if (activeFilter !== null) {
146
+ const wantActive = activeFilter === 'active';
147
+ list = list.filter((c) => c.isActive === wantActive);
35
148
  }
36
- }
149
+ return list;
150
+ });
151
+
152
+ const totalItems = $derived(filteredRows.length);
153
+ const pageCount = $derived(Math.max(1, Math.ceil(totalItems / pagination.pageSize)));
154
+
155
+ const dataFilters = $derived([
156
+ {
157
+ slug: 'isActive',
158
+ label: t.filterActive,
159
+ options: [
160
+ { value: 'active', label: t.activeYes },
161
+ { value: 'inactive', label: t.activeNo }
162
+ ]
163
+ }
164
+ ]);
165
+ const activeDataFilters = $derived({ isActive: activeFilter });
166
+
167
+ const columns = $derived.by<ColumnDef<CouponRow>[]>(() => [
168
+ {
169
+ accessorKey: 'code',
170
+ header: t.columnCode,
171
+ cell: (info) =>
172
+ renderComponent(EntryLink, {
173
+ name: info.row.original.code,
174
+ url: `/admin/shop/coupons/${info.row.original.id}`
175
+ })
176
+ },
177
+ {
178
+ accessorKey: 'value',
179
+ header: t.columnValue,
180
+ cell: (info) => formatValue(info.row.original.type, info.row.original.value)
181
+ },
182
+ {
183
+ accessorKey: 'minOrderAmount',
184
+ header: t.columnMinOrder,
185
+ cell: (info) => formatMinOrder(info.row.original.minOrderAmount)
186
+ },
187
+ {
188
+ accessorKey: 'usedCount',
189
+ header: t.columnUsed,
190
+ cell: (info) => {
191
+ const r = info.row.original;
192
+ return r.maxUses != null ? `${r.usedCount} / ${r.maxUses}` : `${r.usedCount}`;
193
+ }
194
+ },
195
+ {
196
+ accessorKey: 'expiresAt',
197
+ header: t.columnExpires,
198
+ cell: (info) =>
199
+ info.row.original.expiresAt
200
+ ? formatShortDateOnly(info.row.original.expiresAt, interfaceLanguage.current)
201
+ : t.never
202
+ },
203
+ {
204
+ accessorKey: 'isActive',
205
+ header: t.columnStatus,
206
+ cell: (info) =>
207
+ renderComponent(StatusBadge, {
208
+ variant: 'boolean',
209
+ active: info.row.original.isActive,
210
+ activeLabel: t.activeYes,
211
+ inactiveLabel: t.activeNo
212
+ })
213
+ }
214
+ ]);
37
215
  </script>
38
216
 
39
- <div class="flex items-center justify-between gap-4 p-6">
40
- <div>
41
- <h1 class="text-2xl font-extrabold tracking-tight">Kody rabatowe</h1>
42
- <p class="text-muted-foreground text-sm">
43
- {#if query.ready}
44
- {query.current?.length ?? 0}
45
- {(query.current?.length ?? 0) === 1 ? 'kod' : 'kodów'}
46
- {:else}
47
- Ładowanie…
48
- {/if}
49
- </p>
50
- </div>
51
- <Button href="/admin/shop/coupons/new">
52
- <PlusIcon class="mr-1 size-4" />
53
- Dodaj kod
54
- </Button>
55
- </div>
217
+ <div class="p-5 pb-24 md:p-7">
218
+ <PageHeader title={t.title} count={!isLoading && !isError ? allRows.length : undefined}>
219
+ {#snippet primaryActions()}
220
+ <Button href="/admin/shop/coupons/new">
221
+ <PlusIcon class="size-4" />
222
+ {t.addCoupon}
223
+ </Button>
224
+ {/snippet}
225
+ </PageHeader>
226
+
227
+ {#if isError}
228
+ <StateDisplay kind="error" />
229
+ {:else if isLoading}
230
+ <StateDisplay kind="loading" />
231
+ {:else if allRows.length === 0}
232
+ <StateDisplay
233
+ kind="empty"
234
+ title={t.emptyTitle}
235
+ description={t.emptyDescription}
236
+ ctaLabel={t.addCoupon}
237
+ onCta={() => (window.location.href = '/admin/shop/coupons/new')}
238
+ />
239
+ {:else}
240
+ <TableToolbar
241
+ {searchQuery}
242
+ searchPlaceholder={t.searchPlaceholder}
243
+ searchLabel={t.search}
244
+ onSearchChange={(q) => {
245
+ searchQuery = q;
246
+ pagination = { ...pagination, pageIndex: 0 };
247
+ }}
248
+ hideStatusFilter
249
+ hideViewToggle
250
+ {dataFilters}
251
+ {activeDataFilters}
252
+ onDataFilterChange={(_slug, value) => {
253
+ activeFilter = value;
254
+ pagination = { ...pagination, pageIndex: 0 };
255
+ }}
256
+ />
257
+
258
+ <div class="overflow-hidden rounded-xl border bg-card shadow-sm">
259
+ <DataTable
260
+ data={filteredRows}
261
+ {columns}
262
+ enablePagination
263
+ {pagination}
264
+ onPaginationChange={(p) => (pagination = p)}
265
+ emptyTitle={t.noResults}
266
+ />
56
267
 
57
- {#if query.ready && query.current && query.current.length > 0}
58
- <div class="px-6 pb-6">
59
- <div class="border-border bg-card overflow-hidden rounded-xl border">
60
- <table class="w-full text-sm">
61
- <thead class="text-muted-foreground bg-muted/50 text-left text-xs uppercase">
62
- <tr>
63
- <th class="px-4 py-3 font-semibold">Kod</th>
64
- <th class="px-4 py-3 font-semibold">Wartość</th>
65
- <th class="px-4 py-3 font-semibold">Min. zamów.</th>
66
- <th class="px-4 py-3 font-semibold">Wykorzystano</th>
67
- <th class="px-4 py-3 font-semibold">Wygasa</th>
68
- <th class="px-4 py-3 font-semibold">Status</th>
69
- <th class="px-4 py-3"></th>
70
- </tr>
71
- </thead>
72
- <tbody>
73
- {#each query.current as c (c.id)}
74
- <tr class="border-border border-t">
75
- <td class="px-4 py-3 font-mono font-semibold">{c.code}</td>
76
- <td class="px-4 py-3">{formatValue(c.type, c.value)}</td>
77
- <td class="text-muted-foreground px-4 py-3">
78
- {c.minOrderAmount != null
79
- ? new Intl.NumberFormat('pl-PL', {
80
- style: 'currency',
81
- currency: 'PLN',
82
- minimumFractionDigits: 2
83
- }).format(c.minOrderAmount / 100)
84
- : '—'}
85
- </td>
86
- <td class="px-4 py-3">
87
- {c.usedCount}{c.maxUses != null ? ` / ${c.maxUses}` : ''}
88
- </td>
89
- <td class="text-muted-foreground px-4 py-3 text-xs">
90
- {formatDate(c.expiresAt)}
91
- </td>
92
- <td class="px-4 py-3">
93
- {#if c.isActive}
94
- <span class="rounded-full bg-green-100 px-2 py-0.5 text-xs text-green-800"
95
- >aktywny</span
96
- >
97
- {:else}
98
- <span class="rounded-full bg-gray-100 px-2 py-0.5 text-xs text-gray-800">
99
- wstrzymany
100
- </span>
101
- {/if}
102
- </td>
103
- <td class="px-4 py-3 text-right">
104
- <div class="flex justify-end gap-1">
105
- <Button
106
- href="/admin/shop/coupons/{c.id}"
107
- variant="ghost"
108
- size="sm"
109
- title="Edytuj"
110
- >
111
- <EditIcon class="size-4" />
112
- </Button>
113
- <Button
114
- onclick={() => handleDelete(c.id, c.code)}
115
- variant="ghost"
116
- size="sm"
117
- title="Usuń"
118
- >
119
- <TrashIcon class="size-4" />
120
- </Button>
121
- </div>
122
- </td>
123
- </tr>
124
- {/each}
125
- </tbody>
126
- </table>
268
+ <TablePagination
269
+ pageIndex={pagination.pageIndex}
270
+ pageSize={pagination.pageSize}
271
+ {pageCount}
272
+ {totalItems}
273
+ onPageChange={(p) => (pagination = { ...pagination, pageIndex: p })}
274
+ onPageSizeChange={(s) => (pagination = { pageIndex: 0, pageSize: s })}
275
+ />
127
276
  </div>
128
- </div>
129
- {:else if query.ready}
130
- <div class="text-muted-foreground p-6 text-sm">
131
- Brak kodów rabatowych. <a href="/admin/shop/coupons/new" class="text-primary hover:underline"
132
- >Dodaj pierwszy</a
133
- >.
134
- </div>
135
- {/if}
277
+ {/if}
278
+
279
+ </div>
@@ -1,3 +1,18 @@
1
- declare const CouponsListPage: import("svelte").Component<Record<string, never>, {}, "">;
1
+ type CouponRow = {
2
+ id: string;
3
+ code: string;
4
+ type: string;
5
+ value: string | number;
6
+ minOrderAmount: number | null;
7
+ usedCount: number;
8
+ maxUses: number | null;
9
+ expiresAt: Date | string | null;
10
+ isActive: boolean;
11
+ };
12
+ type Props = {
13
+ data?: CouponRow[];
14
+ state?: 'loading' | 'error' | 'ok';
15
+ };
16
+ declare const CouponsListPage: import("svelte").Component<Props, {}, "">;
2
17
  type CouponsListPage = ReturnType<typeof CouponsListPage>;
3
18
  export default CouponsListPage;
@@ -5,35 +5,108 @@
5
5
  import { Button } from '../../../components/ui/button/index.js';
6
6
  import TrashIcon from '@tabler/icons-svelte/icons/trash';
7
7
  import ShippingMethodForm, { type ShippingFormPayload } from './shipping-method-form.svelte';
8
+ import DetailPageShell from '../../components/layout/detail-page-shell.svelte';
9
+ import StateDisplay from '../collection/state-display.svelte';
10
+ import ConfirmationDialog from '../../components/dialogs/confirmation-dialog.svelte';
11
+ import SaveIndicator from '../entry/header/save-indicator.svelte';
12
+ import { useInterfaceLanguage } from '../../state/interface-language.svelte.js';
13
+ import { getBreadcrumbs } from '../../state/breadcrumbs.svelte.js';
14
+ import { sidebarLang } from '../../components/layout/lang.js';
15
+ import { resolveI18n } from '../../../shop/pricing.js';
16
+ import type { InterfaceLanguage } from '../../../types/languages.js';
8
17
 
9
18
  const remotes = getRemotes();
19
+ const interfaceLanguage = useInterfaceLanguage();
20
+ const breadcrumbs = getBreadcrumbs();
10
21
 
11
22
  const methodId = $derived(page.params.id ?? '');
12
23
  const methodQuery = $derived(remotes.getShippingMethodForAdmin(methodId));
13
24
  const configQuery = $derived(remotes.getShopConfig());
14
25
 
26
+ $effect(() => {
27
+ const s = sidebarLang[interfaceLanguage.current].shop;
28
+ const name = methodQuery.current?.name as Record<string, string> | undefined;
29
+ const label = name ? resolveI18n(name, interfaceLanguage.current, '') : '…';
30
+ breadcrumbs.state = [
31
+ { label: s.title },
32
+ { label: s.shipping, href: '/admin/shop/shipping-methods' },
33
+ { label: label || '…' }
34
+ ];
35
+ });
36
+
37
+ type SaveStatus = 'idle' | 'saving' | 'saved' | 'unsaved' | 'error';
38
+
15
39
  let saving = $state(false);
40
+ let saveStatus = $state<SaveStatus>('idle');
41
+ let lastSavedAt = $state<Date | null>(null);
16
42
  let deleting = $state(false);
17
43
  let errorMessage = $state<string | null>(null);
18
- let successMessage = $state<string | null>(null);
19
- let confirmingDelete = $state(false);
44
+ let confirmDeleteOpen = $state(false);
45
+
46
+ const lang: Record<
47
+ InterfaceLanguage,
48
+ {
49
+ title: string;
50
+ description: string;
51
+ deleteLabel: string;
52
+ confirmDeleteTitle: string;
53
+ confirmDeleteDescription: string;
54
+ notFoundTitle: string;
55
+ notFoundDescription: string;
56
+ backToList: string;
57
+ loading: string;
58
+ }
59
+ > = {
60
+ pl: {
61
+ title: 'Edycja metody wysyłki',
62
+ description: 'Zmień nazwę, cenę, VAT lub zasady doręczenia.',
63
+ deleteLabel: 'Usuń metodę',
64
+ confirmDeleteTitle: 'Usunąć metodę wysyłki?',
65
+ confirmDeleteDescription:
66
+ 'Aktywne zamówienia z tą metodą pozostaną nienaruszone, ale nie pojawi się więcej w koszyku. Tej akcji nie cofniesz.',
67
+ notFoundTitle: 'Nie znaleziono metody',
68
+ notFoundDescription: 'Mogła zostać usunięta lub link jest nieaktualny.',
69
+ backToList: 'Wróć do listy',
70
+ loading: 'Wczytuję…'
71
+ },
72
+ en: {
73
+ title: 'Edit shipping method',
74
+ description: 'Update the name, price, VAT or delivery rules.',
75
+ deleteLabel: 'Delete method',
76
+ confirmDeleteTitle: 'Delete shipping method?',
77
+ confirmDeleteDescription:
78
+ 'Existing orders with this method stay intact, but it will no longer appear at checkout. This cannot be undone.',
79
+ notFoundTitle: 'Method not found',
80
+ notFoundDescription: 'It may have been deleted or the link is outdated.',
81
+ backToList: 'Back to list',
82
+ loading: 'Loading…'
83
+ }
84
+ };
85
+
86
+ const t = $derived(lang[interfaceLanguage.current]);
20
87
 
21
88
  async function handleSubmit(payload: ShippingFormPayload) {
22
89
  saving = true;
90
+ saveStatus = 'saving';
23
91
  errorMessage = null;
24
- successMessage = null;
25
92
  try {
26
93
  await remotes.updateShippingMethodCmd({ id: methodId, input: payload });
27
94
  await methodQuery.refresh();
28
- successMessage = 'Zapisano zmiany.';
95
+ saveStatus = 'saved';
96
+ lastSavedAt = new Date();
29
97
  } catch (err) {
30
98
  errorMessage = err instanceof Error ? err.message : 'Nie udało się zapisać';
99
+ saveStatus = 'error';
31
100
  } finally {
32
101
  saving = false;
33
102
  }
34
103
  }
35
104
 
36
- async function handleDelete() {
105
+ function handleDelete() {
106
+ confirmDeleteOpen = true;
107
+ }
108
+
109
+ async function performDelete() {
37
110
  deleting = true;
38
111
  try {
39
112
  await remotes.deleteShippingMethodCmd(methodId);
@@ -45,59 +118,27 @@
45
118
  }
46
119
  </script>
47
120
 
48
- {#if !methodQuery.ready || !configQuery.ready}
49
- <div class="text-muted-foreground p-6">Ładowanie…</div>
50
- {:else if !methodQuery.current}
51
- <div class="p-6">
52
- <p class="mb-4">Metoda nie została znaleziona.</p>
53
- <Button href="/admin/shop/shipping-methods" variant="outline">← Wróć do listy</Button>
54
- </div>
55
- {:else if configQuery.current}
56
- <div class="space-y-6 p-6">
57
- <div class="flex items-start justify-between gap-4">
58
- <div>
59
- <h1 class="text-2xl font-extrabold tracking-tight">Edycja metody wysyłki</h1>
60
- <a href="/admin/shop/shipping-methods" class="text-muted-foreground text-sm hover:underline"
61
- >← Wróć do listy</a
62
- >
63
- </div>
64
- <div>
65
- {#if confirmingDelete}
66
- <div class="flex items-center gap-2">
67
- <span class="text-sm">Na pewno?</span>
68
- <Button
69
- type="button"
70
- variant="destructive"
71
- size="sm"
72
- onclick={handleDelete}
73
- disabled={deleting}
74
- >
75
- {deleting ? 'Usuwanie…' : 'Usuń'}
76
- </Button>
77
- <Button
78
- type="button"
79
- variant="outline"
80
- size="sm"
81
- onclick={() => (confirmingDelete = false)}>Anuluj</Button
82
- >
83
- </div>
84
- {:else}
85
- <Button
86
- type="button"
87
- variant="outline"
88
- size="sm"
89
- onclick={() => (confirmingDelete = true)}
90
- >
91
- <TrashIcon class="mr-1 size-4" /> Usuń
92
- </Button>
93
- {/if}
94
- </div>
95
- </div>
96
-
97
- {#if successMessage}
98
- <div class="rounded-lg bg-green-50 p-3 text-sm text-green-800">{successMessage}</div>
99
- {/if}
121
+ <DetailPageShell title={t.title} description={t.description}>
122
+ {#snippet secondaryActions()}
123
+ <SaveIndicator status={saveStatus} {lastSavedAt} />
124
+ {/snippet}
125
+ {#snippet primaryActions()}
126
+ <Button type="button" variant="outline" size="sm" onclick={handleDelete}>
127
+ <TrashIcon class="mr-1 size-4" /> {t.deleteLabel}
128
+ </Button>
129
+ {/snippet}
100
130
 
131
+ {#if !methodQuery.ready || !configQuery.ready}
132
+ <StateDisplay kind="loading" />
133
+ {:else if !methodQuery.current || !configQuery.current}
134
+ <StateDisplay
135
+ kind="error"
136
+ title={t.notFoundTitle}
137
+ description={t.notFoundDescription}
138
+ ctaLabel={t.backToList}
139
+ onCta={() => goto('/admin/shop/shipping-methods')}
140
+ />
141
+ {:else}
101
142
  <ShippingMethodForm
102
143
  languages={configQuery.current.languages}
103
144
  vatRates={configQuery.current.vatRates}
@@ -107,5 +148,13 @@
107
148
  {errorMessage}
108
149
  onsubmit={handleSubmit}
109
150
  />
110
- </div>
111
- {/if}
151
+ {/if}
152
+ </DetailPageShell>
153
+
154
+ <ConfirmationDialog
155
+ bind:open={confirmDeleteOpen}
156
+ title={t.confirmDeleteTitle}
157
+ description={t.confirmDeleteDescription}
158
+ loading={deleting}
159
+ onConfirm={performDelete}
160
+ />