includio-cms 0.1.4 → 0.5.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 (296) hide show
  1. package/CHANGELOG.md +68 -0
  2. package/ROADMAP.md +18 -13
  3. package/dist/admin/api/accept-invite.js +1 -5
  4. package/dist/admin/api/invite.js +7 -16
  5. package/dist/admin/client/account/account-page.svelte +20 -50
  6. package/dist/admin/client/account/lang.d.ts +15 -23
  7. package/dist/admin/client/account/lang.js +51 -67
  8. package/dist/admin/client/account/preferences-section.svelte +26 -84
  9. package/dist/admin/client/account/profile-section.svelte +60 -40
  10. package/dist/admin/client/account/schema.d.ts +11 -3
  11. package/dist/admin/client/account/schema.js +25 -16
  12. package/dist/admin/client/account/security-section.svelte +139 -105
  13. package/dist/admin/client/account/sessions-section.svelte +35 -34
  14. package/dist/admin/client/admin/admin-after-login-layout-content.svelte +3 -5
  15. package/dist/admin/client/admin/admin-layout.svelte +3 -2
  16. package/dist/admin/client/admin/admin-preloader.svelte +36 -0
  17. package/dist/admin/client/admin/admin-preloader.svelte.d.ts +18 -0
  18. package/dist/admin/client/admin/dashboard-page.svelte +55 -41
  19. package/dist/admin/client/collection/a11y-score-cell.svelte +45 -0
  20. package/dist/admin/client/collection/a11y-score-cell.svelte.d.ts +6 -0
  21. package/dist/admin/client/collection/bulk-actions-bar.svelte +83 -0
  22. package/dist/admin/client/collection/bulk-actions-bar.svelte.d.ts +9 -0
  23. package/dist/admin/client/collection/collection-entries.svelte +255 -260
  24. package/dist/admin/client/collection/collection-view.svelte.d.ts +4 -3
  25. package/dist/admin/client/collection/collection-view.svelte.js +9 -5
  26. package/dist/admin/client/collection/collection.svelte +22 -12
  27. package/dist/admin/client/collection/data-table.svelte +50 -39
  28. package/dist/admin/client/collection/data-table.svelte.d.ts +1 -0
  29. package/dist/admin/client/collection/date-cell.svelte +7 -5
  30. package/dist/admin/client/collection/date-cell.svelte.d.ts +1 -1
  31. package/dist/admin/client/collection/empty-state.svelte +28 -0
  32. package/dist/admin/client/collection/empty-state.svelte.d.ts +9 -0
  33. package/dist/admin/client/collection/entry-link.svelte +10 -4
  34. package/dist/admin/client/collection/entry-link.svelte.d.ts +1 -0
  35. package/dist/admin/client/collection/grid-view.svelte +21 -23
  36. package/dist/admin/client/collection/grid-view.svelte.d.ts +1 -2
  37. package/dist/admin/client/collection/row-actions.svelte +60 -0
  38. package/dist/admin/client/collection/row-actions.svelte.d.ts +9 -0
  39. package/dist/admin/client/collection/status-badge.svelte +7 -8
  40. package/dist/admin/client/collection/table-pagination.svelte +122 -79
  41. package/dist/admin/client/collection/table-pagination.svelte.d.ts +1 -0
  42. package/dist/admin/client/collection/table-toolbar.svelte +108 -88
  43. package/dist/admin/client/collection/table-toolbar.svelte.d.ts +8 -9
  44. package/dist/admin/client/entry/entry-form.svelte +109 -1
  45. package/dist/admin/client/entry/entry-header.svelte +96 -37
  46. package/dist/admin/client/entry/entry-header.svelte.d.ts +5 -0
  47. package/dist/admin/client/entry/entry.svelte +171 -60
  48. package/dist/admin/client/entry/header/a11y-validator.d.ts +46 -0
  49. package/dist/admin/client/entry/header/a11y-validator.js +311 -0
  50. package/dist/admin/client/entry/header/publish-panel.svelte +373 -131
  51. package/dist/admin/client/entry/header/publish-panel.svelte.d.ts +4 -0
  52. package/dist/admin/client/entry/header/save-indicator.svelte +33 -23
  53. package/dist/admin/client/entry/header/schedule-popover.svelte +1 -1
  54. package/dist/admin/client/entry/header/status-badge.svelte +25 -118
  55. package/dist/admin/client/entry/header/version-history-sheet.svelte +314 -98
  56. package/dist/admin/client/form/form-submission/form-submission.svelte +271 -83
  57. package/dist/admin/client/form/form-submission/submission-field.svelte +12 -12
  58. package/dist/admin/client/form/form-submissions.svelte +421 -139
  59. package/dist/admin/client/form/submission-link.svelte +8 -2
  60. package/dist/admin/client/form/submission-link.svelte.d.ts +1 -0
  61. package/dist/admin/client/form/submission-status-badge.svelte +18 -4
  62. package/dist/admin/client/form/submission-status-badge.svelte.d.ts +1 -0
  63. package/dist/admin/client/login/lang.d.ts +32 -0
  64. package/dist/admin/client/login/lang.js +66 -2
  65. package/dist/admin/client/login/login-form.svelte +237 -95
  66. package/dist/admin/client/login/login-form.svelte.d.ts +2 -17
  67. package/dist/admin/client/login/login-page.svelte +34 -98
  68. package/dist/admin/client/login/reset-password-page.svelte +235 -0
  69. package/dist/admin/client/login/reset-password-page.svelte.d.ts +4 -0
  70. package/dist/admin/client/login/schema.d.ts +15 -0
  71. package/dist/admin/client/login/schema.js +21 -0
  72. package/dist/admin/client/users/accept-invite-page.svelte +166 -37
  73. package/dist/admin/client/users/create-user-dialog.svelte +15 -7
  74. package/dist/admin/client/users/delete-user-dialog.svelte +81 -16
  75. package/dist/admin/client/users/delete-user-dialog.svelte.d.ts +4 -1
  76. package/dist/admin/client/users/edit-user-dialog.svelte +3 -0
  77. package/dist/admin/client/users/invite-user-dialog.svelte +16 -3
  78. package/dist/admin/client/users/lang.d.ts +27 -0
  79. package/dist/admin/client/users/lang.js +64 -10
  80. package/dist/admin/client/users/pending-invitations.svelte +59 -23
  81. package/dist/admin/client/users/users-page.svelte +471 -72
  82. package/dist/admin/components/accessibility/accessibility-overview.svelte +2 -7
  83. package/dist/admin/components/dashboard/a11y-gauge.svelte +90 -0
  84. package/dist/admin/components/dashboard/a11y-gauge.svelte.d.ts +18 -0
  85. package/dist/admin/components/dashboard/accessibility-hub.svelte +13 -12
  86. package/dist/admin/components/dashboard/form-submissions-widget.svelte +71 -113
  87. package/dist/admin/components/dashboard/index.d.ts +4 -2
  88. package/dist/admin/components/dashboard/index.js +4 -2
  89. package/dist/admin/components/dashboard/recent-activity.svelte +53 -75
  90. package/dist/admin/components/dashboard/recent-entries.svelte +94 -0
  91. package/dist/admin/components/dashboard/recent-entries.svelte.d.ts +18 -0
  92. package/dist/admin/components/dashboard/stat-card.svelte +2 -2
  93. package/dist/admin/components/dashboard/tip-of-the-day.svelte +109 -0
  94. package/dist/admin/components/dashboard/tip-of-the-day.svelte.d.ts +3 -0
  95. package/dist/admin/components/dashboard/welcome-header.svelte +45 -0
  96. package/dist/admin/components/dashboard/welcome-header.svelte.d.ts +3 -0
  97. package/dist/admin/components/fields/{array-field.svelte → blocks-field.svelte} +4 -4
  98. package/dist/admin/components/fields/{array-field.svelte.d.ts → blocks-field.svelte.d.ts} +5 -5
  99. package/dist/admin/components/fields/content-field.svelte +27 -0
  100. package/dist/admin/components/fields/content-field.svelte.d.ts +31 -0
  101. package/dist/admin/components/fields/field-renderer.svelte +9 -7
  102. package/dist/admin/components/fields/image-field.svelte +2 -2
  103. package/dist/admin/components/fields/media-field.svelte +2 -2
  104. package/dist/admin/components/fields/seo-field.svelte +205 -25
  105. package/dist/admin/components/fields/simple-array-field.svelte +289 -0
  106. package/dist/admin/components/fields/simple-array-field.svelte.d.ts +30 -0
  107. package/dist/admin/components/fields/slug-field.svelte +3 -2
  108. package/dist/admin/components/fields/standalone-field-renderer.svelte +148 -0
  109. package/dist/admin/components/fields/standalone-field-renderer.svelte.d.ts +9 -0
  110. package/dist/admin/components/fields/text-field-wrapper.svelte +13 -1
  111. package/dist/admin/components/fields/text-field-wrapper.svelte.d.ts +2 -2
  112. package/dist/admin/components/fields/url-field.svelte +5 -4
  113. package/dist/admin/components/layout/app-sidebar.svelte +27 -24
  114. package/dist/admin/components/layout/lang.d.ts +6 -0
  115. package/dist/admin/components/layout/lang.js +13 -1
  116. package/dist/admin/components/layout/layout-renderer.svelte +352 -0
  117. package/dist/admin/components/layout/layout-renderer.svelte.d.ts +14 -0
  118. package/dist/admin/components/layout/nav-breadcrumbs.svelte +4 -4
  119. package/dist/admin/components/layout/nav-collections.svelte +65 -36
  120. package/dist/admin/components/layout/nav-footer.svelte +31 -0
  121. package/dist/admin/components/layout/nav-footer.svelte.d.ts +18 -0
  122. package/dist/admin/components/layout/nav-forms.svelte +55 -30
  123. package/dist/admin/components/layout/nav-main.svelte +14 -52
  124. package/dist/admin/components/layout/nav-search.svelte +4 -3
  125. package/dist/admin/components/layout/nav-singletons.svelte +59 -17
  126. package/dist/admin/components/layout/nav-singletons.svelte.d.ts +17 -8
  127. package/dist/admin/components/layout/site-header.svelte +74 -13
  128. package/dist/admin/components/media/alt-input.svelte +32 -22
  129. package/dist/admin/components/media/bulk-action-bar.svelte +139 -150
  130. package/dist/admin/components/media/file/file-details.svelte +299 -217
  131. package/dist/admin/components/media/file/file-miniature.svelte +54 -41
  132. package/dist/admin/components/media/file/file-miniature.svelte.d.ts +1 -0
  133. package/dist/admin/components/media/file/file-preview.svelte +1 -1
  134. package/dist/admin/components/media/file-upload.svelte +24 -26
  135. package/dist/admin/components/media/files-list.svelte +112 -40
  136. package/dist/admin/components/media/files-list.svelte.d.ts +2 -0
  137. package/dist/admin/components/media/focal-point-input.svelte +122 -26
  138. package/dist/admin/components/media/media-library.svelte +127 -70
  139. package/dist/admin/components/media/media-search.svelte +6 -6
  140. package/dist/admin/components/media/media-sort.svelte +3 -1
  141. package/dist/admin/components/media/multi-file-summary.svelte +88 -68
  142. package/dist/admin/components/media/tag-combobox.svelte +141 -66
  143. package/dist/admin/components/media/tag-combobox.svelte.d.ts +1 -0
  144. package/dist/admin/components/media/tag-sidebar.svelte +139 -121
  145. package/dist/admin/components/tiptap/FigureNodeView.svelte +144 -15
  146. package/dist/admin/components/tiptap/InlineBlockNodeView.svelte +254 -0
  147. package/dist/admin/components/tiptap/InlineBlockNodeView.svelte.d.ts +4 -0
  148. package/dist/admin/components/tiptap/SlashCommandPopup.svelte +212 -0
  149. package/dist/admin/components/tiptap/SlashCommandPopup.svelte.d.ts +8 -0
  150. package/dist/admin/components/tiptap/content-editor.svelte +280 -0
  151. package/dist/admin/components/tiptap/content-editor.svelte.d.ts +9 -0
  152. package/dist/admin/components/tiptap/editor-toolbar.svelte +230 -0
  153. package/dist/admin/components/tiptap/editor-toolbar.svelte.d.ts +16 -0
  154. package/dist/admin/components/tiptap/heading-a11y-plugin.d.ts +2 -0
  155. package/dist/admin/components/tiptap/heading-a11y-plugin.js +67 -0
  156. package/dist/admin/components/tiptap/image-dialog.svelte +172 -11
  157. package/dist/admin/components/tiptap/inline-block-node.d.ts +19 -0
  158. package/dist/admin/components/tiptap/inline-block-node.js +98 -0
  159. package/dist/admin/components/tiptap/link-dialog.svelte +9 -4
  160. package/dist/admin/components/tiptap/slash-command.d.ts +17 -0
  161. package/dist/admin/components/tiptap/slash-command.js +181 -0
  162. package/dist/admin/components/tiptap/structured-content-utils.d.ts +21 -0
  163. package/dist/admin/components/tiptap/structured-content-utils.js +150 -0
  164. package/dist/admin/components/tiptap/tiptap-editor.svelte +18 -190
  165. package/dist/admin/email/invite-template.d.ts +8 -0
  166. package/dist/admin/email/invite-template.js +99 -0
  167. package/dist/admin/email/reset-password-template.d.ts +7 -0
  168. package/dist/admin/email/reset-password-template.js +96 -0
  169. package/dist/admin/remote/ai.remote.d.ts +1 -0
  170. package/dist/admin/remote/ai.remote.js +4 -1
  171. package/dist/admin/remote/entry.remote.d.ts +8 -0
  172. package/dist/admin/remote/entry.remote.js +53 -4
  173. package/dist/admin/remote/preview.remote.js +2 -1
  174. package/dist/admin/shared/password-schema.d.ts +5 -0
  175. package/dist/admin/shared/password-schema.js +10 -0
  176. package/dist/admin/styles/admin.css +1530 -151
  177. package/dist/admin/utils/formatDate.d.ts +1 -0
  178. package/dist/admin/utils/formatDate.js +8 -0
  179. package/dist/admin/utils/roleLabel.d.ts +2 -0
  180. package/dist/admin/utils/roleLabel.js +13 -0
  181. package/dist/ai-claude/index.d.ts +2 -0
  182. package/dist/ai-claude/index.js +56 -0
  183. package/dist/cms/runtime/api.d.ts +6 -1
  184. package/dist/cms/runtime/api.js +3 -0
  185. package/dist/cms/runtime/schemas.d.ts +9 -1
  186. package/dist/cms/runtime/schemas.js +8 -0
  187. package/dist/cms/runtime/types.d.ts +82 -10
  188. package/dist/cms/runtime/types.js +4 -0
  189. package/dist/components/ui/accordion/accordion.stories.svelte +39 -0
  190. package/dist/components/ui/accordion/accordion.stories.svelte.d.ts +27 -0
  191. package/dist/components/ui/alert/alert.stories.svelte +53 -0
  192. package/dist/components/ui/alert/alert.stories.svelte.d.ts +27 -0
  193. package/dist/components/ui/alert/alert.svelte +5 -0
  194. package/dist/components/ui/alert/alert.svelte.d.ts +9 -0
  195. package/dist/components/ui/avatar/avatar.stories.svelte +16 -0
  196. package/dist/components/ui/avatar/avatar.stories.svelte.d.ts +27 -0
  197. package/dist/components/ui/badge/badge.stories.svelte +33 -0
  198. package/dist/components/ui/badge/badge.stories.svelte.d.ts +27 -0
  199. package/dist/components/ui/breadcrumb/breadcrumb.stories.svelte +33 -0
  200. package/dist/components/ui/breadcrumb/breadcrumb.stories.svelte.d.ts +27 -0
  201. package/dist/components/ui/button/button.stories.svelte +43 -0
  202. package/dist/components/ui/button/button.stories.svelte.d.ts +27 -0
  203. package/dist/components/ui/button/button.svelte +1 -2
  204. package/dist/components/ui/button/button.svelte.d.ts +0 -3
  205. package/dist/components/ui/button-group/button-group-separator.svelte.d.ts +1 -1
  206. package/dist/components/ui/card/card.stories.svelte +42 -0
  207. package/dist/components/ui/card/card.stories.svelte.d.ts +27 -0
  208. package/dist/components/ui/command/command.stories.svelte +51 -0
  209. package/dist/components/ui/command/command.stories.svelte.d.ts +27 -0
  210. package/dist/components/ui/dialog/dialog.stories.svelte +29 -0
  211. package/dist/components/ui/dialog/dialog.stories.svelte.d.ts +27 -0
  212. package/dist/components/ui/field/field-label.svelte.d.ts +1 -1
  213. package/dist/components/ui/field/field.stories.svelte +21 -0
  214. package/dist/components/ui/field/field.stories.svelte.d.ts +27 -0
  215. package/dist/components/ui/input/input.stories.svelte +40 -0
  216. package/dist/components/ui/input/input.stories.svelte.d.ts +27 -0
  217. package/dist/components/ui/input/input.svelte +2 -4
  218. package/dist/components/ui/item/item-separator.svelte.d.ts +1 -1
  219. package/dist/components/ui/label/label.stories.svelte +20 -0
  220. package/dist/components/ui/label/label.stories.svelte.d.ts +27 -0
  221. package/dist/components/ui/popover/popover.stories.svelte +29 -0
  222. package/dist/components/ui/popover/popover.stories.svelte.d.ts +27 -0
  223. package/dist/components/ui/select/select-group-heading.svelte.d.ts +1 -1
  224. package/dist/components/ui/select/select.stories.svelte +23 -0
  225. package/dist/components/ui/select/select.stories.svelte.d.ts +27 -0
  226. package/dist/components/ui/separator/separator.stories.svelte +24 -0
  227. package/dist/components/ui/separator/separator.stories.svelte.d.ts +27 -0
  228. package/dist/components/ui/sheet/sheet.stories.svelte +29 -0
  229. package/dist/components/ui/sheet/sheet.stories.svelte.d.ts +27 -0
  230. package/dist/components/ui/sidebar/sidebar-group.svelte +3 -3
  231. package/dist/components/ui/sidebar/sidebar-group.svelte.d.ts +2 -2
  232. package/dist/components/ui/sidebar/sidebar-menu-button.svelte +28 -30
  233. package/dist/components/ui/sidebar/sidebar-menu-button.svelte.d.ts +7 -7
  234. package/dist/components/ui/sidebar/sidebar-separator.svelte.d.ts +1 -1
  235. package/dist/components/ui/sidebar/sidebar-trigger.svelte +4 -4
  236. package/dist/components/ui/sonner/sonner.stories.svelte +22 -0
  237. package/dist/components/ui/sonner/sonner.stories.svelte.d.ts +26 -0
  238. package/dist/components/ui/sonner/sonner.svelte +8 -2
  239. package/dist/components/ui/sonner/toast-demo.svelte +29 -0
  240. package/dist/components/ui/sonner/toast-demo.svelte.d.ts +6 -0
  241. package/dist/components/ui/textarea/textarea.stories.svelte +22 -0
  242. package/dist/components/ui/textarea/textarea.stories.svelte.d.ts +27 -0
  243. package/dist/components/ui/textarea/textarea.svelte +0 -2
  244. package/dist/components/ui/toggle/toggle.stories.svelte +22 -0
  245. package/dist/components/ui/toggle/toggle.stories.svelte.d.ts +27 -0
  246. package/dist/components/ui/toggle-group/toggle-group.stories.svelte +17 -0
  247. package/dist/components/ui/toggle-group/toggle-group.stories.svelte.d.ts +27 -0
  248. package/dist/components/ui/tooltip/tooltip.stories.svelte +26 -0
  249. package/dist/components/ui/tooltip/tooltip.stories.svelte.d.ts +27 -0
  250. package/dist/core/fields/fieldSchemaToTs.d.ts +1 -0
  251. package/dist/core/fields/fieldSchemaToTs.js +133 -1
  252. package/dist/core/fields/layoutUtils.d.ts +17 -0
  253. package/dist/core/fields/layoutUtils.js +149 -0
  254. package/dist/core/fields/structuredToHtml.d.ts +9 -0
  255. package/dist/core/fields/structuredToHtml.js +161 -0
  256. package/dist/core/server/entries/operations/create.js +2 -1
  257. package/dist/core/server/entries/operations/get.js +8 -6
  258. package/dist/core/server/entries/operations/update.d.ts +3 -0
  259. package/dist/core/server/entries/operations/update.js +30 -2
  260. package/dist/core/server/fields/queryStructuredContent.d.ts +15 -0
  261. package/dist/core/server/fields/queryStructuredContent.js +65 -0
  262. package/dist/core/server/fields/resolveImageFields.js +51 -2
  263. package/dist/core/server/fields/resolveRelationFields.js +2 -2
  264. package/dist/core/server/fields/resolveRichtextLinks.js +80 -13
  265. package/dist/core/server/fields/resolveUrlFields.js +57 -6
  266. package/dist/core/server/fields/slugResolver.d.ts +10 -0
  267. package/dist/core/server/fields/slugResolver.js +34 -0
  268. package/dist/core/server/generator/fields.js +15 -4
  269. package/dist/core/server/generator/generator.js +3 -2
  270. package/dist/files-local/index.js +126 -64
  271. package/dist/server/auth.d.ts +5 -0
  272. package/dist/server/auth.js +12 -1
  273. package/dist/sveltekit/components/structured-content.svelte +204 -0
  274. package/dist/sveltekit/components/structured-content.svelte.d.ts +21 -0
  275. package/dist/sveltekit/config.d.ts +13 -3
  276. package/dist/sveltekit/index.d.ts +3 -0
  277. package/dist/sveltekit/index.js +3 -0
  278. package/dist/sveltekit/server/handle.js +1 -0
  279. package/dist/types/config.d.ts +3 -0
  280. package/dist/types/fields.d.ts +19 -2
  281. package/dist/types/index.d.ts +2 -0
  282. package/dist/types/index.js +2 -0
  283. package/dist/types/layout.d.ts +54 -0
  284. package/dist/types/layout.js +6 -0
  285. package/dist/types/structured-content.d.ts +63 -0
  286. package/dist/types/structured-content.js +1 -0
  287. package/dist/updates/0.1.5/index.d.ts +2 -0
  288. package/dist/updates/0.1.5/index.js +18 -0
  289. package/dist/updates/0.2.0/index.d.ts +2 -0
  290. package/dist/updates/0.2.0/index.js +11 -0
  291. package/dist/updates/0.2.2/index.d.ts +2 -0
  292. package/dist/updates/0.2.2/index.js +13 -0
  293. package/dist/updates/0.5.0/index.d.ts +2 -0
  294. package/dist/updates/0.5.0/index.js +14 -0
  295. package/dist/updates/index.js +5 -1
  296. package/package.json +16 -9
@@ -4,26 +4,23 @@
4
4
  import { sidebarLang } from './lang.js';
5
5
  import { useInterfaceLanguage } from '../../state/interface-language.svelte.js';
6
6
  import CameraIcon from '@tabler/icons-svelte/icons/camera';
7
- import DashboardIcon from '@tabler/icons-svelte/icons/dashboard';
7
+ import LayoutDashboardIcon from '@tabler/icons-svelte/icons/layout-dashboard';
8
8
  import UsersIcon from '@tabler/icons-svelte/icons/users';
9
- import SettingsIcon from '@tabler/icons-svelte/icons/settings';
10
- import { getRemotes } from '../../../sveltekit/index.js';
11
- import Skeleton from '../../../components/ui/skeleton/skeleton.svelte';
12
- import { getLocalizedLabel } from '../../utils/collectionLabel.js';
13
9
  import { page } from '$app/state';
14
10
  import { authClient } from '../../auth-client.js';
11
+ import { resolve } from '$app/paths';
12
+ import { cn } from '../../../utils.js';
15
13
 
16
14
  const interfaceLanguage = useInterfaceLanguage();
17
- const remotes = getRemotes();
18
15
  let session = authClient.useSession();
19
16
 
20
- const isAdmin = $derived(($session.data?.user as any)?.role === 'admin');
17
+ const isAdmin = $derived($session.data?.user?.role === 'admin');
21
18
 
22
19
  let items: { title: string; url: string; icon?: Icon }[] = $derived([
23
20
  {
24
21
  title: sidebarLang[interfaceLanguage.current].main.dashboard,
25
22
  url: '/admin',
26
- icon: DashboardIcon
23
+ icon: LayoutDashboardIcon
27
24
  },
28
25
  {
29
26
  title: sidebarLang[interfaceLanguage.current].main.media,
@@ -47,61 +44,26 @@
47
44
  }
48
45
  </script>
49
46
 
50
- <Sidebar.Group>
47
+ <Sidebar.Group class="px-0 py-1">
51
48
  <Sidebar.Menu>
52
49
  {#each items as item (item.title)}
53
50
  {@const active = isActive(item.url)}
54
51
  <Sidebar.MenuItem>
55
- <Sidebar.MenuButton
56
- tooltipContent={item.title}
57
- class="rounded-lg transition-colors {active
58
- ? 'bg-primary/10 text-primary font-medium'
59
- : 'hover:bg-accent'}"
60
- >
52
+ <Sidebar.MenuButton isActive={active} tooltipContent={item.title}>
61
53
  {#snippet child({ props })}
62
- <a {...props} href={item.url}>
54
+ <a class={cn(props.class)} {...props} href={item.url}>
63
55
  {#if item.icon}
64
- <item.icon class="size-4 {active ? 'text-primary' : 'text-muted-foreground'}" />
56
+ <item.icon
57
+ class="size-5! shrink-0 {active ? 'text-primary' : 'text-muted-foreground'}"
58
+ />
65
59
  {/if}
66
- <span>{item.title}</span>
60
+ <span class="{active ? 'text-primary' : 'text-muted-foreground'} flex-1 truncate"
61
+ >{item.title}</span
62
+ >
67
63
  </a>
68
64
  {/snippet}
69
65
  </Sidebar.MenuButton>
70
66
  </Sidebar.MenuItem>
71
67
  {/each}
72
- {#await remotes.getSingles()}
73
- <div class="space-y-2 px-2">
74
- <Skeleton class="h-4 w-[200px]" />
75
- <Skeleton class="h-4 w-[160px]" />
76
- </div>
77
- {:then items}
78
- {#each items as item (item)}
79
- {@const name = getLocalizedLabel(item.label, interfaceLanguage.current) ?? item.slug}
80
- {@const url = `/admin/entries/${item.slug}`}
81
- {@const active = isActive(url)}
82
- <Sidebar.MenuItem>
83
- <Sidebar.MenuButton
84
- class="rounded-lg transition-colors {active
85
- ? 'bg-primary/10 text-primary font-medium'
86
- : 'hover:bg-accent'}"
87
- >
88
- {#snippet child({ props })}
89
- <a {...props} href={url}>
90
- {#if item.sidebarIcon}
91
- <item.sidebarIcon
92
- class="size-4 {active ? 'text-primary' : 'text-muted-foreground'}"
93
- />
94
- {:else}
95
- <SettingsIcon
96
- class="size-4 {active ? 'text-primary' : 'text-muted-foreground'}"
97
- />
98
- {/if}
99
- <span>{name}</span>
100
- </a>
101
- {/snippet}
102
- </Sidebar.MenuButton>
103
- </Sidebar.MenuItem>
104
- {/each}
105
- {/await}
106
68
  </Sidebar.Menu>
107
69
  </Sidebar.Group>
@@ -45,14 +45,15 @@
45
45
  {#await getData() then { singles, collections, forms }}
46
46
  <button
47
47
  onclick={() => (open = true)}
48
- class="text-muted-foreground mx-2 flex w-[calc(100%-1rem)] items-center gap-2 rounded-md border px-2.5 py-1.5 text-sm transition-colors hover:bg-black/5 dark:border-white/10 dark:hover:bg-white/10"
48
+ class="bg-muted text-text-light hover:border-sidebar-border hover:bg-lavender-lighter hover:text-muted-foreground focus-visible:outline-primary mx-2 mt-2 mb-1 flex min-h-9 cursor-pointer items-center gap-2 rounded-[8px] border border-transparent px-2.5 py-[7px] font-sans text-[13px] transition-all group-data-[collapsible=icon]:mx-1 group-data-[collapsible=icon]:justify-center group-data-[collapsible=icon]:p-[7px] focus-visible:outline-2 focus-visible:outline-offset-2"
49
+ aria-label={sidebarLang[interfaceLanguage.current].search.placeholder}
49
50
  >
50
51
  <SearchIcon class="size-4 shrink-0" />
51
- <span class="flex-1 truncate text-left"
52
+ <span class="flex-1 truncate text-center group-data-[collapsible=icon]:hidden"
52
53
  >{sidebarLang[interfaceLanguage.current].search.placeholder}</span
53
54
  >
54
55
  <kbd
55
- class="bg-muted text-muted-foreground shrink-0 rounded px-1.5 py-0.5 text-[10px] font-medium"
56
+ class="border-sidebar-border text-text-light inline-flex shrink-0 items-center gap-0.5 rounded border bg-white px-[5px] py-0.5 font-sans text-[10px] leading-none font-semibold group-data-[collapsible=icon]:hidden"
56
57
  >⌘K</kbd
57
58
  >
58
59
  </button>
@@ -1,24 +1,66 @@
1
1
  <script lang="ts">
2
2
  import * as Sidebar from '../../../components/ui/sidebar/index.js';
3
+ import { useInterfaceLanguage } from '../../state/interface-language.svelte.js';
4
+ import { getRemotes } from '../../../sveltekit/index.js';
5
+ import { sidebarLang } from './lang.js';
6
+ import { getLocalizedLabel } from '../../utils/collectionLabel.js';
7
+ import Skeleton from '../../../components/ui/skeleton/skeleton.svelte';
8
+ import { page } from '$app/state';
9
+ import SettingsIcon from '@tabler/icons-svelte/icons/settings';
3
10
 
4
- let { items }: { items: { name: string; url: string }[] } = $props();
11
+ const interfaceLanguage = useInterfaceLanguage();
12
+ const remotes = getRemotes();
13
+
14
+ function isActive(url: string) {
15
+ return page.url.pathname.startsWith(url);
16
+ }
5
17
  </script>
6
18
 
7
- <Sidebar.Group>
8
- <Sidebar.GroupLabel>Singles</Sidebar.GroupLabel>
9
- <Sidebar.GroupContent class="flex flex-col gap-2">
19
+ {#await remotes.getSingles()}
20
+ <Sidebar.Group class="border-sidebar-border mt-1 border-t px-0 pt-2 pb-1">
21
+ <Sidebar.GroupLabel
22
+ >{sidebarLang[interfaceLanguage.current].singletons.title}</Sidebar.GroupLabel
23
+ >
10
24
  <Sidebar.Menu>
11
- {#each items as item (item.name)}
12
- <Sidebar.MenuItem>
13
- <Sidebar.MenuButton tooltipContent={item.name}>
14
- {#snippet child({ props })}
15
- <a {...props} href={item.url}>
16
- <span>{item.name}</span>
17
- </a>
18
- {/snippet}
19
- </Sidebar.MenuButton>
20
- </Sidebar.MenuItem>
21
- {/each}
25
+ <div class="space-y-2 px-2">
26
+ <Skeleton class="h-4 w-[200px]" />
27
+ <Skeleton class="h-4 w-[160px]" />
28
+ </div>
22
29
  </Sidebar.Menu>
23
- </Sidebar.GroupContent>
24
- </Sidebar.Group>
30
+ </Sidebar.Group>
31
+ {:then items}
32
+ {#if items.length > 0}
33
+ <Sidebar.Group class="border-sidebar-border mt-1 border-t px-0 pt-2 pb-1">
34
+ <Sidebar.GroupLabel class="group-data-[collapsible=icon]:hidden"
35
+ >{sidebarLang[interfaceLanguage.current].singletons.title}</Sidebar.GroupLabel
36
+ >
37
+ <Sidebar.Menu>
38
+ {#each items as item (item)}
39
+ {@const name = getLocalizedLabel(item.label, interfaceLanguage.current) ?? item.slug}
40
+ {@const url = `/admin/entries/${item.slug}`}
41
+ {@const active = isActive(url)}
42
+ <Sidebar.MenuItem>
43
+ <Sidebar.MenuButton isActive={active} tooltipContent={name}>
44
+ {#snippet child({ props })}
45
+ <a {...props} href={url}>
46
+ {#if item.sidebarIcon}
47
+ <item.sidebarIcon
48
+ class="size-5! shrink-0 {active ? 'text-primary' : 'text-muted-foreground'}"
49
+ />
50
+ {:else}
51
+ <SettingsIcon
52
+ class="size-5! shrink-0 {active ? 'text-primary' : 'text-muted-foreground'}"
53
+ />
54
+ {/if}
55
+ <span class="flex-1 truncate {active ? 'text-primary' : 'text-muted-foreground'}"
56
+ >{name}</span
57
+ >
58
+ </a>
59
+ {/snippet}
60
+ </Sidebar.MenuButton>
61
+ </Sidebar.MenuItem>
62
+ {/each}
63
+ </Sidebar.Menu>
64
+ </Sidebar.Group>
65
+ {/if}
66
+ {/await}
@@ -1,9 +1,18 @@
1
- type $$ComponentProps = {
2
- items: {
3
- name: string;
4
- url: string;
5
- }[];
6
- };
7
- declare const NavSingletons: import("svelte").Component<$$ComponentProps, {}, "">;
8
- type NavSingletons = ReturnType<typeof NavSingletons>;
1
+ interface $$__sveltets_2_IsomorphicComponent<Props extends Record<string, any> = any, Events extends Record<string, any> = any, Slots extends Record<string, any> = any, Exports = {}, Bindings = string> {
2
+ new (options: import('svelte').ComponentConstructorOptions<Props>): import('svelte').SvelteComponent<Props, Events, Slots> & {
3
+ $$bindings?: Bindings;
4
+ } & Exports;
5
+ (internal: unknown, props: {
6
+ $$events?: Events;
7
+ $$slots?: Slots;
8
+ }): Exports & {
9
+ $set?: any;
10
+ $on?: any;
11
+ };
12
+ z_$$bindings?: Bindings;
13
+ }
14
+ declare const NavSingletons: $$__sveltets_2_IsomorphicComponent<Record<string, never>, {
15
+ [evt: string]: CustomEvent<any>;
16
+ }, {}, {}, string>;
17
+ type NavSingletons = InstanceType<typeof NavSingletons>;
9
18
  export default NavSingletons;
@@ -1,37 +1,98 @@
1
1
  <script lang="ts">
2
2
  import * as Sidebar from '../../../components/ui/sidebar/index.js';
3
+ import * as Avatar from '../../../components/ui/avatar/index.js';
4
+ import * as DropdownMenu from '../../../components/ui/dropdown-menu/index.js';
3
5
  import NavBreadcrumbs from './nav-breadcrumbs.svelte';
4
- import HeaderActions from './header-actions.svelte';
5
6
  import type { InterfaceLanguage } from '../../../types/languages.js';
6
7
  import { useInterfaceLanguage } from '../../state/interface-language.svelte.js';
7
- import EyeIcon from '@tabler/icons-svelte/icons/eye';
8
+ import ExternalLinkIcon from '@tabler/icons-svelte/icons/external-link';
9
+ import LogoutIcon from '@tabler/icons-svelte/icons/logout';
10
+ import SettingsIcon from '@tabler/icons-svelte/icons/settings';
8
11
  import Button from '../../../components/ui/button/button.svelte';
12
+ import { authClient } from '../../auth-client.js';
13
+ import { toast } from 'svelte-sonner';
14
+ import { goto } from '$app/navigation';
15
+ import { toastLang } from '../../toast-lang.js';
16
+ import { sidebarLang } from './lang.js';
9
17
 
10
18
  const interfaceLanguage = useInterfaceLanguage();
19
+ let session = authClient.useSession();
11
20
 
12
- const lang: Record<InterfaceLanguage, { viewSite: string }> = {
21
+ const lang: Record<InterfaceLanguage, { openSite: string }> = {
13
22
  pl: {
14
- viewSite: 'Zobacz witrynę'
23
+ openSite: 'Otwórz stronę'
15
24
  },
16
25
  en: {
17
- viewSite: 'View Site'
26
+ openSite: 'Open site'
18
27
  }
19
28
  };
29
+
30
+ async function onLogout() {
31
+ await authClient.signOut({
32
+ fetchOptions: {
33
+ onSuccess: async () => {
34
+ toast.success(toastLang[interfaceLanguage.current].logout.success);
35
+ goto('/admin/login');
36
+ }
37
+ }
38
+ });
39
+ }
20
40
  </script>
21
41
 
22
42
  <header
23
- class="flex h-(--header-height) shrink-0 items-center gap-2 border-b border-sidebar-border bg-white/60 backdrop-blur-xl transition-[width,height] ease-linear group-has-data-[collapsible=icon]/sidebar-wrapper:h-(--header-height) dark:bg-slate-900/60"
43
+ class="flex h-(--header-height) shrink-0 items-center gap-2 border-b border-sidebar-border bg-background/60 backdrop-blur-xl transition-[width,height] ease-linear group-has-data-[collapsible=icon]/sidebar-wrapper:h-(--header-height)"
24
44
  >
25
- <div class="flex w-full items-center gap-1 px-4 lg:gap-2 lg:px-6">
26
- <Sidebar.Trigger class="-ml-1" />
27
- <NavBreadcrumbs />
45
+ <div class="flex w-full items-center px-5">
46
+ <div class="flex items-center gap-3">
47
+ <Sidebar.Trigger class="-ml-1" />
48
+ <NavBreadcrumbs />
49
+ </div>
28
50
 
29
51
  <div class="ml-auto flex items-center gap-2">
30
- <HeaderActions />
31
- <Button href="/" variant="gradient" size="sm" target="_blank" rel="noopener noreferrer">
32
- <EyeIcon class="size-4" />
33
- <span class="hidden sm:inline">{lang[interfaceLanguage.current].viewSite}</span>
52
+ <Button
53
+ href="/"
54
+ variant="outline"
55
+ size="sm"
56
+ class="text-[13px] font-medium text-primary hover:bg-[var(--lavender-lighter)] hover:border-[var(--lavender)]"
57
+ target="_blank"
58
+ rel="noopener noreferrer"
59
+ >
60
+ <ExternalLinkIcon class="size-3.5" />
61
+ <span class="hidden sm:inline">{lang[interfaceLanguage.current].openSite}</span>
34
62
  </Button>
63
+ {#if $session.data}
64
+ <DropdownMenu.Root>
65
+ <DropdownMenu.Trigger class="cursor-pointer rounded-full outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2">
66
+ <Avatar.Root class="size-[30px]">
67
+ <Avatar.Image src={$session.data.user.image} alt={$session.data.user.name} />
68
+ <Avatar.Fallback class="bg-gradient-to-br from-[var(--lavender)] to-primary text-[12px] font-bold text-white">
69
+ {$session.data.user.name
70
+ .split(' ')
71
+ .map((n) => n[0])
72
+ .join('')
73
+ .toUpperCase()
74
+ .slice(0, 2)}
75
+ </Avatar.Fallback>
76
+ </Avatar.Root>
77
+ </DropdownMenu.Trigger>
78
+ <DropdownMenu.Content align="end" class="w-56">
79
+ <DropdownMenu.Label class="flex flex-col gap-0.5">
80
+ <span class="text-sm font-medium">{$session.data.user.name}</span>
81
+ <span class="text-xs font-normal text-muted-foreground">{$session.data.user.email}</span>
82
+ </DropdownMenu.Label>
83
+ <DropdownMenu.Separator />
84
+ <DropdownMenu.Item onSelect={() => goto('/admin/account')}>
85
+ <SettingsIcon class="mr-2 size-4" />
86
+ {sidebarLang[interfaceLanguage.current].user.account}
87
+ </DropdownMenu.Item>
88
+ <DropdownMenu.Separator />
89
+ <DropdownMenu.Item onSelect={onLogout} variant="destructive">
90
+ <LogoutIcon class="mr-2 size-4" />
91
+ {sidebarLang[interfaceLanguage.current].user.logout}
92
+ </DropdownMenu.Item>
93
+ </DropdownMenu.Content>
94
+ </DropdownMenu.Root>
95
+ {/if}
35
96
  </div>
36
97
  </div>
37
98
  </header>
@@ -54,6 +54,14 @@
54
54
 
55
55
  let generating = $state(false);
56
56
 
57
+ let aiAvailable = $state(false);
58
+
59
+ $effect(() => {
60
+ remotes.isAIAvailable().then((available) => {
61
+ aiAvailable = available;
62
+ });
63
+ });
64
+
57
65
  async function generateAltText() {
58
66
  if (!input) return;
59
67
 
@@ -95,26 +103,28 @@
95
103
  disabled={generating}>{lang[interfaceLanguage.current].saveLabel}</Button
96
104
  >
97
105
 
98
- <Tooltip.Provider>
99
- <Tooltip.Root>
100
- <Tooltip.Trigger>
101
- {#snippet child({ props })}
102
- <Button
103
- {...props}
104
- variant="outline"
105
- class="shrink-0"
106
- size="icon"
107
- onclick={generateAltText}
108
- disabled={generating}
109
- aria-label={lang[interfaceLanguage.current].aiTooltip}
110
- >
111
- <Sparkles class={generating ? 'animate-bounce' : ''} />
112
- </Button>
113
- {/snippet}
114
- </Tooltip.Trigger>
115
- <Tooltip.Content>
116
- <p>{lang[interfaceLanguage.current].aiTooltip}</p>
117
- </Tooltip.Content>
118
- </Tooltip.Root>
119
- </Tooltip.Provider>
106
+ {#if aiAvailable}
107
+ <Tooltip.Provider>
108
+ <Tooltip.Root>
109
+ <Tooltip.Trigger>
110
+ {#snippet child({ props })}
111
+ <Button
112
+ {...props}
113
+ variant="outline"
114
+ class="shrink-0"
115
+ size="icon"
116
+ onclick={generateAltText}
117
+ disabled={generating}
118
+ aria-label={lang[interfaceLanguage.current].aiTooltip}
119
+ >
120
+ <Sparkles class={generating ? 'animate-bounce' : ''} />
121
+ </Button>
122
+ {/snippet}
123
+ </Tooltip.Trigger>
124
+ <Tooltip.Content>
125
+ <p>{lang[interfaceLanguage.current].aiTooltip}</p>
126
+ </Tooltip.Content>
127
+ </Tooltip.Root>
128
+ </Tooltip.Provider>
129
+ {/if}
120
130
  </div>