includio-cms 0.1.4 → 0.5.1
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/CHANGELOG.md +83 -0
- package/ROADMAP.md +26 -13
- package/dist/admin/api/accept-invite.js +1 -5
- package/dist/admin/api/invite.js +7 -16
- package/dist/admin/client/account/account-page.svelte +20 -50
- package/dist/admin/client/account/lang.d.ts +15 -23
- package/dist/admin/client/account/lang.js +51 -67
- package/dist/admin/client/account/preferences-section.svelte +26 -84
- package/dist/admin/client/account/profile-section.svelte +60 -40
- package/dist/admin/client/account/schema.d.ts +11 -3
- package/dist/admin/client/account/schema.js +25 -16
- package/dist/admin/client/account/security-section.svelte +139 -105
- package/dist/admin/client/account/sessions-section.svelte +35 -34
- package/dist/admin/client/admin/admin-after-login-layout-content.svelte +3 -5
- package/dist/admin/client/admin/admin-layout.svelte +3 -2
- package/dist/admin/client/admin/admin-preloader.svelte +36 -0
- package/dist/admin/client/admin/admin-preloader.svelte.d.ts +18 -0
- package/dist/admin/client/admin/dashboard-page.svelte +35 -67
- package/dist/admin/client/collection/a11y-score-cell.svelte +45 -0
- package/dist/admin/client/collection/a11y-score-cell.svelte.d.ts +6 -0
- package/dist/admin/client/collection/bulk-actions-bar.svelte +100 -0
- package/dist/admin/client/collection/bulk-actions-bar.svelte.d.ts +10 -0
- package/dist/admin/client/collection/collection-entries.svelte +277 -258
- package/dist/admin/client/collection/collection-view.svelte.d.ts +4 -3
- package/dist/admin/client/collection/collection-view.svelte.js +9 -5
- package/dist/admin/client/collection/collection.svelte +22 -12
- package/dist/admin/client/collection/data-table.svelte +50 -39
- package/dist/admin/client/collection/data-table.svelte.d.ts +1 -0
- package/dist/admin/client/collection/date-cell.svelte +7 -5
- package/dist/admin/client/collection/date-cell.svelte.d.ts +1 -1
- package/dist/admin/client/collection/empty-state.svelte +28 -0
- package/dist/admin/client/collection/empty-state.svelte.d.ts +9 -0
- package/dist/admin/client/collection/entry-link.svelte +10 -4
- package/dist/admin/client/collection/entry-link.svelte.d.ts +1 -0
- package/dist/admin/client/collection/grid-view.svelte +21 -23
- package/dist/admin/client/collection/grid-view.svelte.d.ts +1 -2
- package/dist/admin/client/collection/row-actions.svelte +69 -0
- package/dist/admin/client/collection/row-actions.svelte.d.ts +10 -0
- package/dist/admin/client/collection/status-badge.svelte +7 -8
- package/dist/admin/client/collection/table-pagination.svelte +122 -79
- package/dist/admin/client/collection/table-pagination.svelte.d.ts +1 -0
- package/dist/admin/client/collection/table-toolbar.svelte +108 -88
- package/dist/admin/client/collection/table-toolbar.svelte.d.ts +8 -9
- package/dist/admin/client/entry/entry-form.svelte +109 -1
- package/dist/admin/client/entry/entry-header.svelte +143 -37
- package/dist/admin/client/entry/entry-header.svelte.d.ts +8 -0
- package/dist/admin/client/entry/entry.svelte +272 -61
- package/dist/admin/client/entry/header/a11y-validator.d.ts +47 -0
- package/dist/admin/client/entry/header/a11y-validator.js +352 -0
- package/dist/admin/client/entry/header/publish-panel.svelte +531 -129
- package/dist/admin/client/entry/header/publish-panel.svelte.d.ts +4 -0
- package/dist/admin/client/entry/header/save-indicator.svelte +33 -23
- package/dist/admin/client/entry/header/schedule-popover.svelte +1 -1
- package/dist/admin/client/entry/header/status-badge.svelte +25 -118
- package/dist/admin/client/entry/header/version-history-sheet.svelte +322 -98
- package/dist/admin/client/form/form-submission/form-submission.svelte +271 -83
- package/dist/admin/client/form/form-submission/submission-field.svelte +12 -12
- package/dist/admin/client/form/form-submissions.svelte +421 -139
- package/dist/admin/client/form/submission-link.svelte +8 -2
- package/dist/admin/client/form/submission-link.svelte.d.ts +1 -0
- package/dist/admin/client/form/submission-status-badge.svelte +18 -4
- package/dist/admin/client/form/submission-status-badge.svelte.d.ts +1 -0
- package/dist/admin/client/login/lang.d.ts +32 -0
- package/dist/admin/client/login/lang.js +66 -2
- package/dist/admin/client/login/login-form.svelte +237 -95
- package/dist/admin/client/login/login-form.svelte.d.ts +2 -17
- package/dist/admin/client/login/login-page.svelte +34 -98
- package/dist/admin/client/login/reset-password-page.svelte +235 -0
- package/dist/admin/client/login/reset-password-page.svelte.d.ts +4 -0
- package/dist/admin/client/login/schema.d.ts +15 -0
- package/dist/admin/client/login/schema.js +21 -0
- package/dist/admin/client/users/accept-invite-page.svelte +166 -37
- package/dist/admin/client/users/create-user-dialog.svelte +15 -7
- package/dist/admin/client/users/delete-user-dialog.svelte +81 -16
- package/dist/admin/client/users/delete-user-dialog.svelte.d.ts +4 -1
- package/dist/admin/client/users/edit-user-dialog.svelte +3 -0
- package/dist/admin/client/users/invite-user-dialog.svelte +16 -3
- package/dist/admin/client/users/lang.d.ts +27 -0
- package/dist/admin/client/users/lang.js +64 -10
- package/dist/admin/client/users/pending-invitations.svelte +59 -23
- package/dist/admin/client/users/users-page.svelte +471 -72
- package/dist/admin/components/accessibility/accessibility-overview.svelte +2 -7
- package/dist/admin/components/dashboard/a11y-gauge.svelte +90 -0
- package/dist/admin/components/dashboard/a11y-gauge.svelte.d.ts +18 -0
- package/dist/admin/components/dashboard/accessibility-hub.svelte +13 -12
- package/dist/admin/components/dashboard/changelog-dialog.svelte +157 -0
- package/dist/admin/components/dashboard/changelog-dialog.svelte.d.ts +6 -0
- package/dist/admin/components/dashboard/form-submissions-widget.svelte +71 -113
- package/dist/admin/components/dashboard/index.d.ts +4 -2
- package/dist/admin/components/dashboard/index.js +4 -2
- package/dist/admin/components/dashboard/orphaned-entries-notice.svelte +240 -0
- package/dist/admin/components/dashboard/orphaned-entries-notice.svelte.d.ts +13 -0
- package/dist/admin/components/dashboard/recent-activity.svelte +53 -75
- package/dist/admin/components/dashboard/recent-entries.svelte +94 -0
- package/dist/admin/components/dashboard/recent-entries.svelte.d.ts +18 -0
- package/dist/admin/components/dashboard/stat-card.svelte +2 -2
- package/dist/admin/components/dashboard/tip-of-the-day.svelte +109 -0
- package/dist/admin/components/dashboard/tip-of-the-day.svelte.d.ts +3 -0
- package/dist/admin/components/dashboard/welcome-header.svelte +45 -0
- package/dist/admin/components/dashboard/welcome-header.svelte.d.ts +3 -0
- package/dist/admin/components/fields/{array-field.svelte → blocks-field.svelte} +4 -4
- package/dist/admin/components/fields/{array-field.svelte.d.ts → blocks-field.svelte.d.ts} +5 -5
- package/dist/admin/components/fields/content-field.svelte +27 -0
- package/dist/admin/components/fields/content-field.svelte.d.ts +31 -0
- package/dist/admin/components/fields/field-renderer.svelte +9 -7
- package/dist/admin/components/fields/image-field.svelte +2 -2
- package/dist/admin/components/fields/media-field.svelte +2 -2
- package/dist/admin/components/fields/seo-field.svelte +205 -25
- package/dist/admin/components/fields/simple-array-field.svelte +289 -0
- package/dist/admin/components/fields/simple-array-field.svelte.d.ts +30 -0
- package/dist/admin/components/fields/slug-field.svelte +3 -2
- package/dist/admin/components/fields/standalone-field-renderer.svelte +148 -0
- package/dist/admin/components/fields/standalone-field-renderer.svelte.d.ts +9 -0
- package/dist/admin/components/fields/text-field-wrapper.svelte +147 -3
- package/dist/admin/components/fields/text-field-wrapper.svelte.d.ts +2 -2
- package/dist/admin/components/fields/url-field.svelte +5 -4
- package/dist/admin/components/layout/app-sidebar.svelte +27 -24
- package/dist/admin/components/layout/lang.d.ts +6 -0
- package/dist/admin/components/layout/lang.js +13 -1
- package/dist/admin/components/layout/layout-renderer.svelte +352 -0
- package/dist/admin/components/layout/layout-renderer.svelte.d.ts +14 -0
- package/dist/admin/components/layout/nav-breadcrumbs.svelte +4 -4
- package/dist/admin/components/layout/nav-collections.svelte +65 -36
- package/dist/admin/components/layout/nav-footer.svelte +38 -0
- package/dist/admin/components/layout/nav-footer.svelte.d.ts +3 -0
- package/dist/admin/components/layout/nav-forms.svelte +55 -30
- package/dist/admin/components/layout/nav-main.svelte +14 -52
- package/dist/admin/components/layout/nav-search.svelte +4 -3
- package/dist/admin/components/layout/nav-singletons.svelte +59 -17
- package/dist/admin/components/layout/nav-singletons.svelte.d.ts +17 -8
- package/dist/admin/components/layout/site-header.svelte +74 -13
- package/dist/admin/components/media/alt-input.svelte +32 -22
- package/dist/admin/components/media/bulk-action-bar.svelte +139 -150
- package/dist/admin/components/media/file/file-details.svelte +299 -217
- package/dist/admin/components/media/file/file-miniature.svelte +54 -41
- package/dist/admin/components/media/file/file-miniature.svelte.d.ts +1 -0
- package/dist/admin/components/media/file/file-preview.svelte +1 -1
- package/dist/admin/components/media/file-upload.svelte +24 -26
- package/dist/admin/components/media/files-list.svelte +112 -40
- package/dist/admin/components/media/files-list.svelte.d.ts +2 -0
- package/dist/admin/components/media/focal-point-input.svelte +122 -26
- package/dist/admin/components/media/media-library.svelte +127 -70
- package/dist/admin/components/media/media-search.svelte +6 -6
- package/dist/admin/components/media/media-sort.svelte +3 -1
- package/dist/admin/components/media/multi-file-summary.svelte +88 -68
- package/dist/admin/components/media/tag-combobox.svelte +141 -66
- package/dist/admin/components/media/tag-combobox.svelte.d.ts +1 -0
- package/dist/admin/components/media/tag-sidebar.svelte +139 -121
- package/dist/admin/components/tiptap/FigureNodeView.svelte +144 -15
- package/dist/admin/components/tiptap/InlineBlockNodeView.svelte +254 -0
- package/dist/admin/components/tiptap/InlineBlockNodeView.svelte.d.ts +4 -0
- package/dist/admin/components/tiptap/SlashCommandPopup.svelte +212 -0
- package/dist/admin/components/tiptap/SlashCommandPopup.svelte.d.ts +8 -0
- package/dist/admin/components/tiptap/content-editor.svelte +280 -0
- package/dist/admin/components/tiptap/content-editor.svelte.d.ts +9 -0
- package/dist/admin/components/tiptap/editor-toolbar.svelte +230 -0
- package/dist/admin/components/tiptap/editor-toolbar.svelte.d.ts +16 -0
- package/dist/admin/components/tiptap/heading-a11y-plugin.d.ts +2 -0
- package/dist/admin/components/tiptap/heading-a11y-plugin.js +67 -0
- package/dist/admin/components/tiptap/image-dialog.svelte +172 -11
- package/dist/admin/components/tiptap/inline-block-node.d.ts +19 -0
- package/dist/admin/components/tiptap/inline-block-node.js +98 -0
- package/dist/admin/components/tiptap/link-dialog.svelte +9 -4
- package/dist/admin/components/tiptap/slash-command.d.ts +17 -0
- package/dist/admin/components/tiptap/slash-command.js +181 -0
- package/dist/admin/components/tiptap/structured-content-utils.d.ts +21 -0
- package/dist/admin/components/tiptap/structured-content-utils.js +150 -0
- package/dist/admin/components/tiptap/tiptap-editor.svelte +18 -190
- package/dist/admin/email/invite-template.d.ts +8 -0
- package/dist/admin/email/invite-template.js +99 -0
- package/dist/admin/email/reset-password-template.d.ts +7 -0
- package/dist/admin/email/reset-password-template.js +96 -0
- package/dist/admin/remote/ai.remote.d.ts +1 -0
- package/dist/admin/remote/ai.remote.js +4 -1
- package/dist/admin/remote/entry.remote.d.ts +9 -0
- package/dist/admin/remote/entry.remote.js +58 -8
- package/dist/admin/remote/preview.remote.js +2 -1
- package/dist/admin/shared/password-schema.d.ts +5 -0
- package/dist/admin/shared/password-schema.js +10 -0
- package/dist/admin/state/content-language.svelte.d.ts +3 -0
- package/dist/admin/state/content-language.svelte.js +8 -0
- package/dist/admin/styles/admin.css +1530 -151
- package/dist/admin/utils/formatDate.d.ts +1 -0
- package/dist/admin/utils/formatDate.js +8 -0
- package/dist/admin/utils/roleLabel.d.ts +2 -0
- package/dist/admin/utils/roleLabel.js +13 -0
- package/dist/admin/utils/translationStatus.d.ts +17 -0
- package/dist/admin/utils/translationStatus.js +134 -0
- package/dist/ai-claude/index.d.ts +2 -0
- package/dist/ai-claude/index.js +56 -0
- package/dist/cms/runtime/api.d.ts +6 -1
- package/dist/cms/runtime/api.js +3 -0
- package/dist/cms/runtime/schemas.d.ts +9 -1
- package/dist/cms/runtime/schemas.js +8 -0
- package/dist/cms/runtime/types.d.ts +82 -10
- package/dist/cms/runtime/types.js +4 -0
- package/dist/components/ui/accordion/accordion.stories.svelte +39 -0
- package/dist/components/ui/accordion/accordion.stories.svelte.d.ts +27 -0
- package/dist/components/ui/alert/alert.stories.svelte +53 -0
- package/dist/components/ui/alert/alert.stories.svelte.d.ts +27 -0
- package/dist/components/ui/alert/alert.svelte +5 -0
- package/dist/components/ui/alert/alert.svelte.d.ts +9 -0
- package/dist/components/ui/avatar/avatar.stories.svelte +16 -0
- package/dist/components/ui/avatar/avatar.stories.svelte.d.ts +27 -0
- package/dist/components/ui/badge/badge.stories.svelte +33 -0
- package/dist/components/ui/badge/badge.stories.svelte.d.ts +27 -0
- package/dist/components/ui/breadcrumb/breadcrumb.stories.svelte +33 -0
- package/dist/components/ui/breadcrumb/breadcrumb.stories.svelte.d.ts +27 -0
- package/dist/components/ui/button/button.stories.svelte +43 -0
- package/dist/components/ui/button/button.stories.svelte.d.ts +27 -0
- package/dist/components/ui/button/button.svelte +1 -2
- package/dist/components/ui/button/button.svelte.d.ts +0 -3
- package/dist/components/ui/button-group/button-group-separator.svelte.d.ts +1 -1
- package/dist/components/ui/card/card.stories.svelte +42 -0
- package/dist/components/ui/card/card.stories.svelte.d.ts +27 -0
- package/dist/components/ui/command/command.stories.svelte +51 -0
- package/dist/components/ui/command/command.stories.svelte.d.ts +27 -0
- package/dist/components/ui/dialog/dialog.stories.svelte +29 -0
- package/dist/components/ui/dialog/dialog.stories.svelte.d.ts +27 -0
- package/dist/components/ui/field/field-label.svelte.d.ts +1 -1
- package/dist/components/ui/field/field.stories.svelte +21 -0
- package/dist/components/ui/field/field.stories.svelte.d.ts +27 -0
- package/dist/components/ui/input/input.stories.svelte +40 -0
- package/dist/components/ui/input/input.stories.svelte.d.ts +27 -0
- package/dist/components/ui/input/input.svelte +2 -4
- package/dist/components/ui/item/item-separator.svelte.d.ts +1 -1
- package/dist/components/ui/label/label.stories.svelte +20 -0
- package/dist/components/ui/label/label.stories.svelte.d.ts +27 -0
- package/dist/components/ui/popover/popover.stories.svelte +29 -0
- package/dist/components/ui/popover/popover.stories.svelte.d.ts +27 -0
- package/dist/components/ui/select/select-group-heading.svelte.d.ts +1 -1
- package/dist/components/ui/select/select.stories.svelte +23 -0
- package/dist/components/ui/select/select.stories.svelte.d.ts +27 -0
- package/dist/components/ui/separator/separator.stories.svelte +24 -0
- package/dist/components/ui/separator/separator.stories.svelte.d.ts +27 -0
- package/dist/components/ui/sheet/sheet.stories.svelte +29 -0
- package/dist/components/ui/sheet/sheet.stories.svelte.d.ts +27 -0
- package/dist/components/ui/sidebar/sidebar-group.svelte +3 -3
- package/dist/components/ui/sidebar/sidebar-group.svelte.d.ts +2 -2
- package/dist/components/ui/sidebar/sidebar-menu-button.svelte +28 -30
- package/dist/components/ui/sidebar/sidebar-menu-button.svelte.d.ts +7 -7
- package/dist/components/ui/sidebar/sidebar-separator.svelte.d.ts +1 -1
- package/dist/components/ui/sidebar/sidebar-trigger.svelte +4 -4
- package/dist/components/ui/sonner/sonner.stories.svelte +22 -0
- package/dist/components/ui/sonner/sonner.stories.svelte.d.ts +26 -0
- package/dist/components/ui/sonner/sonner.svelte +8 -2
- package/dist/components/ui/sonner/toast-demo.svelte +29 -0
- package/dist/components/ui/sonner/toast-demo.svelte.d.ts +6 -0
- package/dist/components/ui/textarea/textarea.stories.svelte +22 -0
- package/dist/components/ui/textarea/textarea.stories.svelte.d.ts +27 -0
- package/dist/components/ui/textarea/textarea.svelte +0 -2
- package/dist/components/ui/toggle/toggle.stories.svelte +22 -0
- package/dist/components/ui/toggle/toggle.stories.svelte.d.ts +27 -0
- package/dist/components/ui/toggle-group/toggle-group.stories.svelte +17 -0
- package/dist/components/ui/toggle-group/toggle-group.stories.svelte.d.ts +27 -0
- package/dist/components/ui/tooltip/tooltip.stories.svelte +26 -0
- package/dist/components/ui/tooltip/tooltip.stories.svelte.d.ts +27 -0
- package/dist/core/fields/fieldSchemaToTs.d.ts +1 -0
- package/dist/core/fields/fieldSchemaToTs.js +133 -1
- package/dist/core/fields/layoutUtils.d.ts +17 -0
- package/dist/core/fields/layoutUtils.js +149 -0
- package/dist/core/fields/structuredToHtml.d.ts +9 -0
- package/dist/core/fields/structuredToHtml.js +161 -0
- package/dist/core/server/entries/operations/create.js +2 -1
- package/dist/core/server/entries/operations/get.js +10 -7
- package/dist/core/server/entries/operations/update.d.ts +3 -0
- package/dist/core/server/entries/operations/update.js +30 -2
- package/dist/core/server/fields/queryStructuredContent.d.ts +15 -0
- package/dist/core/server/fields/queryStructuredContent.js +65 -0
- package/dist/core/server/fields/resolveImageFields.js +51 -2
- package/dist/core/server/fields/resolveRelationFields.js +2 -2
- package/dist/core/server/fields/resolveRichtextLinks.js +80 -13
- package/dist/core/server/fields/resolveUrlFields.js +57 -6
- package/dist/core/server/fields/slugResolver.d.ts +10 -0
- package/dist/core/server/fields/slugResolver.js +34 -0
- package/dist/core/server/generator/fields.js +15 -4
- package/dist/core/server/generator/generator.js +3 -2
- package/dist/db-postgres/index.js +10 -6
- package/dist/files-local/index.js +126 -64
- package/dist/server/auth.d.ts +5 -0
- package/dist/server/auth.js +12 -1
- package/dist/sveltekit/components/structured-content.svelte +204 -0
- package/dist/sveltekit/components/structured-content.svelte.d.ts +21 -0
- package/dist/sveltekit/config.d.ts +13 -3
- package/dist/sveltekit/index.d.ts +3 -0
- package/dist/sveltekit/index.js +3 -0
- package/dist/sveltekit/server/handle.js +1 -0
- package/dist/types/config.d.ts +3 -0
- package/dist/types/entries.d.ts +3 -0
- package/dist/types/fields.d.ts +19 -2
- package/dist/types/index.d.ts +2 -0
- package/dist/types/index.js +2 -0
- package/dist/types/layout.d.ts +54 -0
- package/dist/types/layout.js +6 -0
- package/dist/types/structured-content.d.ts +63 -0
- package/dist/types/structured-content.js +1 -0
- package/dist/updates/0.1.5/index.d.ts +2 -0
- package/dist/updates/0.1.5/index.js +18 -0
- package/dist/updates/0.2.0/index.d.ts +2 -0
- package/dist/updates/0.2.0/index.js +11 -0
- package/dist/updates/0.2.2/index.d.ts +2 -0
- package/dist/updates/0.2.2/index.js +13 -0
- package/dist/updates/0.5.0/index.d.ts +2 -0
- package/dist/updates/0.5.0/index.js +14 -0
- package/dist/updates/0.5.1/index.d.ts +2 -0
- package/dist/updates/0.5.1/index.js +17 -0
- package/dist/updates/index.js +6 -1
- package/package.json +16 -9
- package/dist/admin/components/dashboard/updates-banner.svelte +0 -170
- package/dist/admin/components/dashboard/updates-banner.svelte.d.ts +0 -3
|
@@ -0,0 +1,240 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { useInterfaceLanguage } from '../../state/interface-language.svelte.js';
|
|
3
|
+
import type { InterfaceLanguage } from '../../../types/languages.js';
|
|
4
|
+
|
|
5
|
+
type OrphanedEntry = { id: string; slug: string; createdAt: string };
|
|
6
|
+
|
|
7
|
+
type Props = {
|
|
8
|
+
entries: OrphanedEntry[];
|
|
9
|
+
deleting: boolean;
|
|
10
|
+
ondelete: () => void;
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
let { entries, deleting, ondelete }: Props = $props();
|
|
14
|
+
|
|
15
|
+
const interfaceLanguage = useInterfaceLanguage();
|
|
16
|
+
|
|
17
|
+
const lang: Record<
|
|
18
|
+
InterfaceLanguage,
|
|
19
|
+
{
|
|
20
|
+
title: string;
|
|
21
|
+
description: (n: number) => string;
|
|
22
|
+
details: string;
|
|
23
|
+
deleteBtn: string;
|
|
24
|
+
deletingBtn: string;
|
|
25
|
+
}
|
|
26
|
+
> = {
|
|
27
|
+
pl: {
|
|
28
|
+
title: 'Wpisy do uporządkowania',
|
|
29
|
+
description: (n) =>
|
|
30
|
+
n === 1
|
|
31
|
+
? 'Masz 1 wpis, którego typ został usunięty z konfiguracji. Możesz go bezpiecznie usunąć.'
|
|
32
|
+
: `Masz ${n} wpisów, których typ został usunięty z konfiguracji. Możesz je bezpiecznie usunąć.`,
|
|
33
|
+
details: 'Pokaż szczegóły',
|
|
34
|
+
deleteBtn: 'Usuń niepotrzebne wpisy',
|
|
35
|
+
deletingBtn: 'Usuwanie…'
|
|
36
|
+
},
|
|
37
|
+
en: {
|
|
38
|
+
title: 'Entries to clean up',
|
|
39
|
+
description: (n) =>
|
|
40
|
+
n === 1
|
|
41
|
+
? 'You have 1 entry whose content type was removed. You can safely delete it.'
|
|
42
|
+
: `You have ${n} entries whose content type was removed. You can safely delete them.`,
|
|
43
|
+
details: 'Show details',
|
|
44
|
+
deleteBtn: 'Delete unused entries',
|
|
45
|
+
deletingBtn: 'Deleting…'
|
|
46
|
+
}
|
|
47
|
+
};
|
|
48
|
+
</script>
|
|
49
|
+
|
|
50
|
+
{#if entries.length > 0}
|
|
51
|
+
{@const t = lang[interfaceLanguage.current]}
|
|
52
|
+
<div class="orphaned-notice" role="status">
|
|
53
|
+
<div class="orphaned-notice-header">
|
|
54
|
+
<div class="orphaned-notice-icon" aria-hidden="true">
|
|
55
|
+
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M21 4H8l-7 8 7 8h13a2 2 0 0 0 2-2V6a2 2 0 0 0-2-2"/><line x1="18" x2="12" y1="9" y2="15"/><line x1="12" x2="18" y1="9" y2="15"/></svg>
|
|
56
|
+
</div>
|
|
57
|
+
<div class="orphaned-notice-content">
|
|
58
|
+
<h3 class="orphaned-notice-title">{t.title}</h3>
|
|
59
|
+
<p class="orphaned-notice-desc">{t.description(entries.length)}</p>
|
|
60
|
+
</div>
|
|
61
|
+
</div>
|
|
62
|
+
|
|
63
|
+
<details class="orphaned-notice-details">
|
|
64
|
+
<summary class="orphaned-notice-summary">{t.details}</summary>
|
|
65
|
+
<ul class="orphaned-notice-slugs">
|
|
66
|
+
{#each entries as entry}
|
|
67
|
+
<li><code>{entry.slug}</code></li>
|
|
68
|
+
{/each}
|
|
69
|
+
</ul>
|
|
70
|
+
</details>
|
|
71
|
+
|
|
72
|
+
<div class="orphaned-notice-actions">
|
|
73
|
+
<button
|
|
74
|
+
type="button"
|
|
75
|
+
class="orphaned-notice-btn"
|
|
76
|
+
onclick={ondelete}
|
|
77
|
+
disabled={deleting}
|
|
78
|
+
>
|
|
79
|
+
{#if deleting}
|
|
80
|
+
<svg class="orphaned-notice-spinner" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5"><path d="M21 12a9 9 0 1 1-6.219-8.56"/></svg>
|
|
81
|
+
{t.deletingBtn}
|
|
82
|
+
{:else}
|
|
83
|
+
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M3 6h18"/><path d="M19 6v14c0 1-1 2-2 2H7c-1 0-2-1-2-2V6"/><path d="M8 6V4c0-1 1-2 2-2h4c1 0 2 1 2 2v2"/></svg>
|
|
84
|
+
{t.deleteBtn}
|
|
85
|
+
{/if}
|
|
86
|
+
</button>
|
|
87
|
+
</div>
|
|
88
|
+
</div>
|
|
89
|
+
{/if}
|
|
90
|
+
|
|
91
|
+
<style>
|
|
92
|
+
.orphaned-notice {
|
|
93
|
+
background: var(--warning-bg);
|
|
94
|
+
border: 1px solid color-mix(in oklch, var(--warning) 20%, transparent);
|
|
95
|
+
border-radius: var(--radius-lg);
|
|
96
|
+
box-shadow: var(--shadow-sm);
|
|
97
|
+
margin-bottom: 20px;
|
|
98
|
+
animation: dash-fade-up 0.3s ease both;
|
|
99
|
+
animation-delay: 0.06s;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
.orphaned-notice-header {
|
|
103
|
+
display: flex;
|
|
104
|
+
gap: 12px;
|
|
105
|
+
padding: 18px 20px 0;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
.orphaned-notice-icon {
|
|
109
|
+
display: flex;
|
|
110
|
+
align-items: center;
|
|
111
|
+
justify-content: center;
|
|
112
|
+
width: 32px;
|
|
113
|
+
height: 32px;
|
|
114
|
+
border-radius: var(--radius);
|
|
115
|
+
background: color-mix(in oklch, var(--warning) 14%, transparent);
|
|
116
|
+
color: var(--warning);
|
|
117
|
+
flex-shrink: 0;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
.orphaned-notice-content {
|
|
121
|
+
flex: 1;
|
|
122
|
+
min-width: 0;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
.orphaned-notice-title {
|
|
126
|
+
font-size: 14px;
|
|
127
|
+
font-weight: 600;
|
|
128
|
+
color: var(--foreground);
|
|
129
|
+
margin: 0 0 4px;
|
|
130
|
+
line-height: 1.4;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
.orphaned-notice-desc {
|
|
134
|
+
font-size: 13px;
|
|
135
|
+
font-weight: 400;
|
|
136
|
+
color: var(--muted-foreground);
|
|
137
|
+
line-height: 1.5;
|
|
138
|
+
margin: 0;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
.orphaned-notice-details {
|
|
142
|
+
padding: 0 20px;
|
|
143
|
+
margin-top: 12px;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
.orphaned-notice-summary {
|
|
147
|
+
font-size: 12px;
|
|
148
|
+
font-weight: 600;
|
|
149
|
+
color: var(--warning);
|
|
150
|
+
cursor: pointer;
|
|
151
|
+
user-select: none;
|
|
152
|
+
list-style: none;
|
|
153
|
+
display: inline-flex;
|
|
154
|
+
align-items: center;
|
|
155
|
+
gap: 4px;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
.orphaned-notice-summary::-webkit-details-marker {
|
|
159
|
+
display: none;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
.orphaned-notice-summary::before {
|
|
163
|
+
content: '›';
|
|
164
|
+
display: inline-block;
|
|
165
|
+
font-size: 14px;
|
|
166
|
+
line-height: 1;
|
|
167
|
+
transition: transform 0.15s ease;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
details[open] > .orphaned-notice-summary::before {
|
|
171
|
+
transform: rotate(90deg);
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
.orphaned-notice-summary:focus-visible {
|
|
175
|
+
outline: 2px solid var(--primary);
|
|
176
|
+
outline-offset: 2px;
|
|
177
|
+
border-radius: 2px;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
.orphaned-notice-slugs {
|
|
181
|
+
list-style: none;
|
|
182
|
+
padding: 0;
|
|
183
|
+
margin: 8px 0 0;
|
|
184
|
+
display: flex;
|
|
185
|
+
flex-wrap: wrap;
|
|
186
|
+
gap: 6px;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
.orphaned-notice-slugs code {
|
|
190
|
+
font-size: 11px;
|
|
191
|
+
font-family: ui-monospace, 'SF Mono', 'Cascadia Code', monospace;
|
|
192
|
+
background: color-mix(in oklch, var(--warning) 10%, var(--card));
|
|
193
|
+
border: 1px solid color-mix(in oklch, var(--warning) 14%, transparent);
|
|
194
|
+
color: var(--foreground);
|
|
195
|
+
padding: 2px 8px;
|
|
196
|
+
border-radius: 4px;
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
.orphaned-notice-actions {
|
|
200
|
+
padding: 14px 20px 16px;
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
.orphaned-notice-btn {
|
|
204
|
+
display: inline-flex;
|
|
205
|
+
align-items: center;
|
|
206
|
+
gap: 6px;
|
|
207
|
+
padding: 7px 14px;
|
|
208
|
+
border: 1px solid color-mix(in oklch, var(--warning) 30%, transparent);
|
|
209
|
+
border-radius: var(--radius);
|
|
210
|
+
background: var(--card);
|
|
211
|
+
font-size: 13px;
|
|
212
|
+
font-weight: 600;
|
|
213
|
+
color: var(--warning);
|
|
214
|
+
cursor: pointer;
|
|
215
|
+
transition: 0.15s ease;
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
.orphaned-notice-btn:hover:not(:disabled) {
|
|
219
|
+
background: color-mix(in oklch, var(--warning) 8%, var(--card));
|
|
220
|
+
border-color: color-mix(in oklch, var(--warning) 40%, transparent);
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
.orphaned-notice-btn:focus-visible {
|
|
224
|
+
outline: 2px solid var(--primary);
|
|
225
|
+
outline-offset: 2px;
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
.orphaned-notice-btn:disabled {
|
|
229
|
+
opacity: 0.6;
|
|
230
|
+
cursor: not-allowed;
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
@keyframes notice-spin {
|
|
234
|
+
to { transform: rotate(360deg); }
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
.orphaned-notice-spinner {
|
|
238
|
+
animation: notice-spin 0.8s linear infinite;
|
|
239
|
+
}
|
|
240
|
+
</style>
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
type OrphanedEntry = {
|
|
2
|
+
id: string;
|
|
3
|
+
slug: string;
|
|
4
|
+
createdAt: string;
|
|
5
|
+
};
|
|
6
|
+
type Props = {
|
|
7
|
+
entries: OrphanedEntry[];
|
|
8
|
+
deleting: boolean;
|
|
9
|
+
ondelete: () => void;
|
|
10
|
+
};
|
|
11
|
+
declare const OrphanedEntriesNotice: import("svelte").Component<Props, {}, "">;
|
|
12
|
+
type OrphanedEntriesNotice = ReturnType<typeof OrphanedEntriesNotice>;
|
|
13
|
+
export default OrphanedEntriesNotice;
|
|
@@ -1,34 +1,25 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
import { useInterfaceLanguage } from '../../state/interface-language.svelte.js';
|
|
3
3
|
import { formatRelativeDate as formatRelativeDateUtil } from '../../utils/formatDate.js';
|
|
4
|
-
import * as Card from '../../../components/ui/card/index.js';
|
|
5
4
|
import Skeleton from '../../../components/ui/skeleton/skeleton.svelte';
|
|
6
5
|
import { getRemotes } from '../../../sveltekit/index.js';
|
|
7
6
|
import type { InterfaceLanguage } from '../../../types/languages.js';
|
|
8
|
-
import HistoryIcon from '@tabler/icons-svelte/icons/history';
|
|
9
|
-
import EditIcon from '@tabler/icons-svelte/icons/edit';
|
|
10
7
|
|
|
11
8
|
const interfaceLanguage = useInterfaceLanguage();
|
|
12
9
|
const remotes = getRemotes();
|
|
13
10
|
|
|
14
|
-
const lang: Record<
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
noActivity: string;
|
|
20
|
-
edited: string;
|
|
21
|
-
}
|
|
22
|
-
> = {
|
|
11
|
+
const lang: Record<InterfaceLanguage, {
|
|
12
|
+
title: string;
|
|
13
|
+
noActivity: string;
|
|
14
|
+
edited: string;
|
|
15
|
+
}> = {
|
|
23
16
|
pl: {
|
|
24
|
-
title: '
|
|
25
|
-
description: 'Najnowsze zmiany',
|
|
17
|
+
title: 'Aktywność',
|
|
26
18
|
noActivity: 'Brak aktywności',
|
|
27
19
|
edited: 'Edytowano'
|
|
28
20
|
},
|
|
29
21
|
en: {
|
|
30
|
-
title: '
|
|
31
|
-
description: 'Latest changes',
|
|
22
|
+
title: 'Activity',
|
|
32
23
|
noActivity: 'No activity',
|
|
33
24
|
edited: 'Edited'
|
|
34
25
|
}
|
|
@@ -39,64 +30,51 @@
|
|
|
39
30
|
}
|
|
40
31
|
</script>
|
|
41
32
|
|
|
42
|
-
<
|
|
43
|
-
<
|
|
44
|
-
<
|
|
45
|
-
|
|
46
|
-
<HistoryIcon class="size-5 text-violet-600 dark:text-violet-400" />
|
|
47
|
-
</div>
|
|
48
|
-
<div>
|
|
49
|
-
<Card.Title>{lang[interfaceLanguage.current].title}</Card.Title>
|
|
50
|
-
<Card.Description>{lang[interfaceLanguage.current].description}</Card.Description>
|
|
51
|
-
</div>
|
|
52
|
-
</div>
|
|
53
|
-
</Card.Header>
|
|
54
|
-
<Card.Content>
|
|
55
|
-
{#await remotes.getRecentActivity(10)}
|
|
56
|
-
<div class="space-y-3">
|
|
57
|
-
{#each Array(5) as _}
|
|
58
|
-
<div class="flex items-center gap-3">
|
|
59
|
-
<Skeleton class="size-8 rounded-full" />
|
|
60
|
-
<div class="flex-1 space-y-1">
|
|
61
|
-
<Skeleton class="h-4 w-40" />
|
|
62
|
-
<Skeleton class="h-3 w-24" />
|
|
63
|
-
</div>
|
|
64
|
-
</div>
|
|
65
|
-
{/each}
|
|
66
|
-
</div>
|
|
67
|
-
{:then activity}
|
|
68
|
-
{#if activity.length === 0}
|
|
69
|
-
<p class="text-muted-foreground py-4 text-center text-sm">
|
|
70
|
-
{lang[interfaceLanguage.current].noActivity}
|
|
71
|
-
</p>
|
|
72
|
-
{:else}
|
|
73
|
-
<div class="relative">
|
|
74
|
-
<div class="absolute bottom-0 left-4 top-0 w-px bg-slate-200 dark:bg-slate-700"></div>
|
|
33
|
+
<section class="dash-card dash-card--activity" aria-labelledby="activity-heading">
|
|
34
|
+
<div class="dash-card-header">
|
|
35
|
+
<h2 class="dash-card-title" id="activity-heading">{lang[interfaceLanguage.current].title}</h2>
|
|
36
|
+
</div>
|
|
75
37
|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
<div class="relative z-10 rounded-full border-2 border-white bg-slate-100 p-1.5 dark:border-slate-900 dark:bg-slate-800">
|
|
83
|
-
<EditIcon class="size-3 text-slate-600 dark:text-slate-400" />
|
|
84
|
-
</div>
|
|
85
|
-
<div class="flex-1 min-w-0">
|
|
86
|
-
<p class="truncate text-sm font-medium group-hover:text-primary">
|
|
87
|
-
{item.label || item.slug}
|
|
88
|
-
</p>
|
|
89
|
-
<p class="text-muted-foreground text-xs">
|
|
90
|
-
{lang[interfaceLanguage.current].edited} · {formatRelativeDate(
|
|
91
|
-
new Date(item.updatedAt)
|
|
92
|
-
)}
|
|
93
|
-
</p>
|
|
94
|
-
</div>
|
|
95
|
-
</a>
|
|
96
|
-
{/each}
|
|
38
|
+
{#await remotes.getRecentActivity(10)}
|
|
39
|
+
<ul class="activity-list">
|
|
40
|
+
{#each Array(4) as _}
|
|
41
|
+
<li class="activity-item">
|
|
42
|
+
<div class="activity-dot-col">
|
|
43
|
+
<Skeleton class="rounded-full" style="width:10px;height:10px" />
|
|
97
44
|
</div>
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
</
|
|
45
|
+
<div class="activity-body">
|
|
46
|
+
<Skeleton class="h-4 w-40" />
|
|
47
|
+
<Skeleton class="h-3 w-24 mt-1" />
|
|
48
|
+
</div>
|
|
49
|
+
</li>
|
|
50
|
+
{/each}
|
|
51
|
+
</ul>
|
|
52
|
+
{:then activity}
|
|
53
|
+
{#if activity.length === 0}
|
|
54
|
+
<p class="text-center text-sm py-6" style="color:var(--text-light)">
|
|
55
|
+
{lang[interfaceLanguage.current].noActivity}
|
|
56
|
+
</p>
|
|
57
|
+
{:else}
|
|
58
|
+
<ul class="activity-list" aria-label={lang[interfaceLanguage.current].title}>
|
|
59
|
+
{#each activity as item, i}
|
|
60
|
+
<li class="activity-item">
|
|
61
|
+
<div class="activity-dot-col">
|
|
62
|
+
<div class="activity-dot activity-dot--edit" aria-hidden="true"></div>
|
|
63
|
+
{#if i < activity.length - 1}
|
|
64
|
+
<div class="activity-line" aria-hidden="true"></div>
|
|
65
|
+
{/if}
|
|
66
|
+
</div>
|
|
67
|
+
<a href="/admin/entries/{item.entryId}" class="activity-body" style="text-decoration:none">
|
|
68
|
+
<p class="activity-text">
|
|
69
|
+
{lang[interfaceLanguage.current].edited} „{item.label || item.slug}"
|
|
70
|
+
</p>
|
|
71
|
+
<p class="activity-meta">
|
|
72
|
+
{formatRelativeDate(new Date(item.updatedAt))}
|
|
73
|
+
</p>
|
|
74
|
+
</a>
|
|
75
|
+
</li>
|
|
76
|
+
{/each}
|
|
77
|
+
</ul>
|
|
78
|
+
{/if}
|
|
79
|
+
{/await}
|
|
80
|
+
</section>
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { useInterfaceLanguage } from '../../state/interface-language.svelte.js';
|
|
3
|
+
import { formatRelativeDate as formatRelativeDateUtil } from '../../utils/formatDate.js';
|
|
4
|
+
import { getLocalizedLabel } from '../../utils/collectionLabel.js';
|
|
5
|
+
import Skeleton from '../../../components/ui/skeleton/skeleton.svelte';
|
|
6
|
+
import { getRemotes } from '../../../sveltekit/index.js';
|
|
7
|
+
import type { InterfaceLanguage, Localized } from '../../../types/languages.js';
|
|
8
|
+
|
|
9
|
+
const interfaceLanguage = useInterfaceLanguage();
|
|
10
|
+
const remotes = getRemotes();
|
|
11
|
+
|
|
12
|
+
const lang: Record<InterfaceLanguage, {
|
|
13
|
+
title: string;
|
|
14
|
+
viewAll: string;
|
|
15
|
+
noEntries: string;
|
|
16
|
+
published: string;
|
|
17
|
+
draft: string;
|
|
18
|
+
scheduled: string;
|
|
19
|
+
}> = {
|
|
20
|
+
pl: {
|
|
21
|
+
title: 'Ostatnie wpisy',
|
|
22
|
+
viewAll: 'Wszystkie →',
|
|
23
|
+
noEntries: 'Brak wpisów',
|
|
24
|
+
published: 'Opubl.',
|
|
25
|
+
draft: 'Szkic',
|
|
26
|
+
scheduled: 'Zaplan.'
|
|
27
|
+
},
|
|
28
|
+
en: {
|
|
29
|
+
title: 'Recent entries',
|
|
30
|
+
viewAll: 'View all →',
|
|
31
|
+
noEntries: 'No entries',
|
|
32
|
+
published: 'Published',
|
|
33
|
+
draft: 'Draft',
|
|
34
|
+
scheduled: 'Scheduled'
|
|
35
|
+
}
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
function formatRelativeDate(date: Date): string {
|
|
39
|
+
return formatRelativeDateUtil(date, interfaceLanguage.current);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
const statusIcon: Record<string, string> = {
|
|
43
|
+
published: '●',
|
|
44
|
+
draft: '○',
|
|
45
|
+
scheduled: '◐'
|
|
46
|
+
};
|
|
47
|
+
</script>
|
|
48
|
+
|
|
49
|
+
<section class="dash-card dash-card--entries" aria-labelledby="entries-heading">
|
|
50
|
+
<div class="dash-card-header">
|
|
51
|
+
<h2 class="dash-card-title" id="entries-heading">{lang[interfaceLanguage.current].title}</h2>
|
|
52
|
+
<a href="/admin/entries" class="dash-card-link">{lang[interfaceLanguage.current].viewAll}</a>
|
|
53
|
+
</div>
|
|
54
|
+
|
|
55
|
+
{#await remotes.getRecentEntries(6)}
|
|
56
|
+
<ul class="entries-list">
|
|
57
|
+
{#each Array(4) as _}
|
|
58
|
+
<li class="entry-item">
|
|
59
|
+
<div class="entry-item-link" style="pointer-events:none">
|
|
60
|
+
<div class="entry-item-main">
|
|
61
|
+
<Skeleton class="h-4 w-36" />
|
|
62
|
+
<Skeleton class="h-3 w-20 mt-1" />
|
|
63
|
+
</div>
|
|
64
|
+
</div>
|
|
65
|
+
</li>
|
|
66
|
+
{/each}
|
|
67
|
+
</ul>
|
|
68
|
+
{:then entries}
|
|
69
|
+
{#if entries.length === 0}
|
|
70
|
+
<p class="text-center text-sm py-6" style="color:var(--text-light)">
|
|
71
|
+
{lang[interfaceLanguage.current].noEntries}
|
|
72
|
+
</p>
|
|
73
|
+
{:else}
|
|
74
|
+
<ul class="entries-list" aria-label={lang[interfaceLanguage.current].title}>
|
|
75
|
+
{#each entries as entry}
|
|
76
|
+
<li class="entry-item">
|
|
77
|
+
<a href="/admin/entries/{entry.entryId}" class="entry-item-link">
|
|
78
|
+
<div class="entry-item-main">
|
|
79
|
+
<span class="entry-item-title">{entry.label || entry.slug}</span>
|
|
80
|
+
<span class="entry-item-meta">
|
|
81
|
+
{getLocalizedLabel(entry.collectionLabel as Localized, interfaceLanguage.current)} · {formatRelativeDate(new Date(entry.updatedAt))}
|
|
82
|
+
</span>
|
|
83
|
+
</div>
|
|
84
|
+
<span class="dash-status-badge dash-status-{entry.status}">
|
|
85
|
+
<span aria-hidden="true">{statusIcon[entry.status] ?? ''}</span>
|
|
86
|
+
{lang[interfaceLanguage.current][entry.status as keyof typeof lang['pl']] ?? entry.status}
|
|
87
|
+
</span>
|
|
88
|
+
</a>
|
|
89
|
+
</li>
|
|
90
|
+
{/each}
|
|
91
|
+
</ul>
|
|
92
|
+
{/if}
|
|
93
|
+
{/await}
|
|
94
|
+
</section>
|
|
@@ -0,0 +1,18 @@
|
|
|
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 RecentEntries: $$__sveltets_2_IsomorphicComponent<Record<string, never>, {
|
|
15
|
+
[evt: string]: CustomEvent<any>;
|
|
16
|
+
}, {}, {}, string>;
|
|
17
|
+
type RecentEntries = InstanceType<typeof RecentEntries>;
|
|
18
|
+
export default RecentEntries;
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
let { label, value, trend, icon, variant = 'default' }: Props = $props();
|
|
13
13
|
|
|
14
14
|
const variantClasses = {
|
|
15
|
-
default: 'text-
|
|
15
|
+
default: 'text-foreground',
|
|
16
16
|
success: 'text-emerald-600 dark:text-emerald-400',
|
|
17
17
|
warning: 'text-amber-600 dark:text-amber-400',
|
|
18
18
|
danger: 'text-rose-600 dark:text-rose-400'
|
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
|
|
22
22
|
<div class="flex items-center gap-3">
|
|
23
23
|
{#if icon}
|
|
24
|
-
<div class="rounded-lg bg-
|
|
24
|
+
<div class="rounded-lg bg-muted p-2">
|
|
25
25
|
{@render icon()}
|
|
26
26
|
</div>
|
|
27
27
|
{/if}
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { useInterfaceLanguage } from '../../state/interface-language.svelte.js';
|
|
3
|
+
import type { InterfaceLanguage } from '../../../types/languages.js';
|
|
4
|
+
|
|
5
|
+
const interfaceLanguage = useInterfaceLanguage();
|
|
6
|
+
|
|
7
|
+
interface Tip {
|
|
8
|
+
text: Record<InterfaceLanguage, string>;
|
|
9
|
+
link?: string;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
const tips: Tip[] = [
|
|
13
|
+
{
|
|
14
|
+
text: {
|
|
15
|
+
pl: 'Dodaj opis do każdego zdjęcia — osoby niewidome używają czytników ekranu, które odczytują ten tekst zamiast obrazu.',
|
|
16
|
+
en: 'Add a description to every image — blind users rely on screen readers that read this text instead of the image.'
|
|
17
|
+
},
|
|
18
|
+
link: 'https://www.w3.org/WAI/tutorials/images/'
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
text: {
|
|
22
|
+
pl: 'Używaj nagłówków w kolejności (H1 → H2 → H3). Pomijanie poziomów dezorientuje użytkowników czytników ekranu.',
|
|
23
|
+
en: 'Use headings in order (H1 → H2 → H3). Skipping levels confuses screen reader users.'
|
|
24
|
+
},
|
|
25
|
+
link: 'https://www.w3.org/WAI/tutorials/page-structure/headings/'
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
text: {
|
|
29
|
+
pl: 'Linki powinny opisywać cel — „Czytaj artykuł" jest lepsze niż „Kliknij tutaj".',
|
|
30
|
+
en: 'Links should describe their destination — "Read the article" is better than "Click here".'
|
|
31
|
+
},
|
|
32
|
+
link: 'https://www.w3.org/WAI/tips/writing/#provide-informative-unique-page-titles'
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
text: {
|
|
36
|
+
pl: 'Kontrast tekstu powinien wynosić min. 4.5:1 (WCAG AA). Używaj jasnego tła z ciemnym tekstem lub odwrotnie.',
|
|
37
|
+
en: 'Text contrast should be at least 4.5:1 (WCAG AA). Use light backgrounds with dark text or vice versa.'
|
|
38
|
+
}
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
text: {
|
|
42
|
+
pl: 'Tabele danych potrzebują nagłówków (<th>) — bez nich czytnik ekranu nie powie, co oznacza dana komórka.',
|
|
43
|
+
en: 'Data tables need headers (<th>) — without them, screen readers can\'t tell what each cell means.'
|
|
44
|
+
}
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
text: {
|
|
48
|
+
pl: 'Formularze powinny mieć etykiety (<label>) powiązane z polami. Placeholder nie zastępuje etykiety.',
|
|
49
|
+
en: 'Form fields should have associated labels. Placeholder text is not a replacement for labels.'
|
|
50
|
+
}
|
|
51
|
+
},
|
|
52
|
+
{
|
|
53
|
+
text: {
|
|
54
|
+
pl: 'Treść powinna być zrozumiała dla jak najszerszego grona odbiorców. Unikaj żargonu i skomplikowanych zdań.',
|
|
55
|
+
en: 'Content should be understandable by the widest audience possible. Avoid jargon and complex sentences.'
|
|
56
|
+
}
|
|
57
|
+
},
|
|
58
|
+
{
|
|
59
|
+
text: {
|
|
60
|
+
pl: 'Nie przekazuj informacji wyłącznie kolorem — osoby z daltonizmem mogą ich nie rozróżnić. Dodaj ikonę lub tekst.',
|
|
61
|
+
en: 'Don\'t convey information through color alone — people with color blindness may not distinguish them. Add an icon or text.'
|
|
62
|
+
}
|
|
63
|
+
},
|
|
64
|
+
{
|
|
65
|
+
text: {
|
|
66
|
+
pl: 'Wideo powinno mieć napisy — pomagają osobom niesłyszącym i tym, którzy oglądają bez dźwięku.',
|
|
67
|
+
en: 'Videos should have captions — they help deaf users and those watching without sound.'
|
|
68
|
+
}
|
|
69
|
+
},
|
|
70
|
+
{
|
|
71
|
+
text: {
|
|
72
|
+
pl: 'Język strony powinien być ustawiony w atrybucie lang. Pomaga to czytnikom ekranu poprawnie wymawiać treść.',
|
|
73
|
+
en: 'The page language should be set in the lang attribute. This helps screen readers pronounce content correctly.'
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
];
|
|
77
|
+
|
|
78
|
+
function getDayOfYear(): number {
|
|
79
|
+
const now = new Date();
|
|
80
|
+
const start = new Date(now.getFullYear(), 0, 0);
|
|
81
|
+
const diff = now.getTime() - start.getTime();
|
|
82
|
+
return Math.floor(diff / (1000 * 60 * 60 * 24));
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
const tip = $derived(tips[getDayOfYear() % tips.length]);
|
|
86
|
+
|
|
87
|
+
const labelText: Record<InterfaceLanguage, string> = {
|
|
88
|
+
pl: 'Wskazówka dnia',
|
|
89
|
+
en: 'Tip of the day'
|
|
90
|
+
};
|
|
91
|
+
|
|
92
|
+
const learnMore: Record<InterfaceLanguage, string> = {
|
|
93
|
+
pl: 'Dowiedz się więcej →',
|
|
94
|
+
en: 'Learn more →'
|
|
95
|
+
};
|
|
96
|
+
</script>
|
|
97
|
+
|
|
98
|
+
<div class="dash-card dash-card--tip tip-card">
|
|
99
|
+
<div class="tip-card-label">
|
|
100
|
+
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" aria-hidden="true"><path d="M9 18h6"/><path d="M10 22h4"/><path d="M12 2a7 7 0 0 0-4 12.7V17h8v-2.3A7 7 0 0 0 12 2z"/></svg>
|
|
101
|
+
{labelText[interfaceLanguage.current]}
|
|
102
|
+
</div>
|
|
103
|
+
<p class="tip-card-text">{tip.text[interfaceLanguage.current]}</p>
|
|
104
|
+
{#if tip.link}
|
|
105
|
+
<a href={tip.link} class="tip-card-link" target="_blank" rel="noopener noreferrer">
|
|
106
|
+
{learnMore[interfaceLanguage.current]}
|
|
107
|
+
</a>
|
|
108
|
+
{/if}
|
|
109
|
+
</div>
|