includio-cms 0.28.0 → 0.34.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.
- package/API.md +39 -13
- package/CHANGELOG.md +19 -0
- package/DOCS.md +1 -1
- package/ROADMAP.md +1 -0
- package/dist/admin/api/handler.js +4 -0
- package/dist/admin/api/integrations.d.ts +13 -0
- package/dist/admin/api/integrations.js +61 -0
- package/dist/admin/api/test-email.d.ts +9 -0
- package/dist/admin/api/test-email.js +39 -0
- package/dist/admin/auth-client.d.ts +2209 -2209
- package/dist/admin/client/index.d.ts +10 -0
- package/dist/admin/client/index.js +12 -0
- package/dist/admin/client/maintenance/maintenance-page.svelte +210 -0
- package/dist/admin/client/shop/coupon-schema.d.ts +1 -1
- package/dist/admin/client/shop/restore-order-cell.svelte +29 -0
- package/dist/admin/client/shop/restore-order-cell.svelte.d.ts +8 -0
- package/dist/admin/client/shop/shop-order-detail-page.svelte +71 -1
- package/dist/admin/client/shop/shop-orders-list-page.svelte +113 -53
- package/dist/admin/components/layout/app-sidebar.svelte +2 -0
- package/dist/admin/components/layout/nav-custom.svelte +26 -0
- package/dist/admin/components/layout/nav-custom.svelte.d.ts +3 -0
- package/dist/admin/components/layout/page-header.svelte +13 -3
- package/dist/admin/components/layout/page-header.svelte.d.ts +13 -3
- package/dist/admin/remote/admin.remote.d.ts +7 -0
- package/dist/admin/remote/admin.remote.js +10 -0
- package/dist/admin/remote/entry.remote.d.ts +4 -4
- package/dist/admin/remote/index.d.ts +1 -0
- package/dist/admin/remote/index.js +1 -0
- package/dist/admin/remote/invite.d.ts +2 -2
- package/dist/admin/remote/shop.remote.d.ts +75 -48
- package/dist/admin/remote/shop.remote.js +41 -10
- package/dist/admin/types.d.ts +15 -0
- package/dist/admin/utils/csv-export.d.ts +45 -0
- package/dist/admin/utils/csv-export.js +61 -0
- package/dist/cli/scaffold/admin.js +1 -1
- package/dist/components/ui/button-group/button-group-separator.svelte.d.ts +1 -1
- package/dist/components/ui/command/command.svelte.d.ts +1 -1
- package/dist/components/ui/field/field-label.svelte.d.ts +1 -1
- package/dist/components/ui/input/input.svelte.d.ts +1 -1
- package/dist/components/ui/input-group/input-group-input.svelte.d.ts +1 -1
- package/dist/components/ui/item/item-separator.svelte.d.ts +1 -1
- package/dist/components/ui/select/select-group-heading.svelte.d.ts +1 -1
- package/dist/components/ui/sidebar/sidebar-input.svelte.d.ts +1 -1
- package/dist/components/ui/sidebar/sidebar-separator.svelte.d.ts +1 -1
- package/dist/core/cms.d.ts +44 -2
- package/dist/core/cms.js +64 -0
- package/dist/core/index.d.ts +1 -4
- package/dist/core/index.js +4 -4
- package/dist/core/server/index.d.ts +4 -1
- package/dist/core/server/index.js +4 -1
- package/dist/db-postgres/schema/shop/order.d.ts +34 -0
- package/dist/db-postgres/schema/shop/order.js +4 -0
- package/dist/paraglide/messages/_index.d.ts +3 -36
- package/dist/paraglide/messages/_index.js +3 -71
- package/dist/paraglide/messages/hello_world.d.ts +5 -0
- package/dist/paraglide/messages/hello_world.js +33 -0
- package/dist/paraglide/messages/login_hello.d.ts +16 -0
- package/dist/paraglide/messages/login_hello.js +34 -0
- package/dist/paraglide/messages/login_please_login.d.ts +16 -0
- package/dist/paraglide/messages/login_please_login.js +34 -0
- package/dist/shop/adapters/fakturownia/client.d.ts +5 -0
- package/dist/shop/adapters/fakturownia/client.js +20 -0
- package/dist/shop/adapters/fakturownia/index.js +11 -0
- package/dist/shop/adapters/payu/index.js +11 -0
- package/dist/shop/index.d.ts +1 -1
- package/dist/shop/server/coupons.d.ts +10 -0
- package/dist/shop/server/coupons.js +19 -0
- package/dist/shop/server/email.d.ts +7 -3
- package/dist/shop/server/email.js +86 -112
- package/dist/shop/server/emailTemplateRegistry.d.ts +47 -0
- package/dist/shop/server/emailTemplateRegistry.js +288 -0
- package/dist/shop/server/orders.d.ts +60 -1
- package/dist/shop/server/orders.js +145 -16
- package/dist/shop/templates/_partials/footer.en.html +4 -0
- package/dist/shop/templates/_partials/footer.pl.html +4 -0
- package/dist/shop/templates/_partials/header.en.html +4 -0
- package/dist/shop/templates/_partials/header.pl.html +4 -0
- package/dist/shop/templates/_partials/items.en.html +14 -0
- package/dist/shop/templates/_partials/items.pl.html +14 -0
- package/dist/shop/templates/_partials/tracking.en.html +7 -0
- package/dist/shop/templates/_partials/tracking.pl.html +7 -0
- package/dist/shop/templates/awaiting-payment.en.html +6 -0
- package/dist/shop/templates/awaiting-payment.pl.html +6 -0
- package/dist/shop/templates/cancelled.en.html +6 -0
- package/dist/shop/templates/cancelled.pl.html +6 -0
- package/dist/shop/templates/low-stock.en.html +14 -0
- package/dist/shop/templates/low-stock.pl.html +14 -0
- package/dist/shop/templates/order-completed.en.html +6 -0
- package/dist/shop/templates/order-completed.pl.html +6 -0
- package/dist/shop/templates/order-received.en.html +7 -0
- package/dist/shop/templates/order-received.pl.html +7 -0
- package/dist/shop/templates/payment-received.en.html +7 -0
- package/dist/shop/templates/payment-received.pl.html +7 -0
- package/dist/shop/templates/payment-rejected.en.html +6 -0
- package/dist/shop/templates/payment-rejected.pl.html +6 -0
- package/dist/shop/templates/preparing.en.html +7 -0
- package/dist/shop/templates/preparing.pl.html +7 -0
- package/dist/shop/templates/refunded.en.html +6 -0
- package/dist/shop/templates/refunded.pl.html +6 -0
- package/dist/shop/templates/shipped.en.html +7 -0
- package/dist/shop/templates/shipped.pl.html +7 -0
- package/dist/shop/types.d.ts +63 -0
- package/dist/sveltekit/index.d.ts +0 -1
- package/dist/sveltekit/index.js +0 -1
- package/dist/sveltekit/server/index.d.ts +2 -0
- package/dist/sveltekit/server/index.js +4 -0
- package/dist/types/adapters/email.d.ts +13 -0
- package/dist/types/cms.d.ts +30 -0
- package/dist/types/index.d.ts +1 -1
- package/dist/updates/0.34.0/index.d.ts +2 -0
- package/dist/updates/0.34.0/index.js +17 -0
- package/dist/updates/index.js +3 -1
- package/package.json +7 -2
- package/dist/paraglide/messages/en.d.ts +0 -5
- package/dist/paraglide/messages/en.js +0 -14
- package/dist/paraglide/messages/pl.d.ts +0 -5
- package/dist/paraglide/messages/pl.js +0 -14
|
@@ -1,10 +1,14 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
import { getRemotes } from '../../../sveltekit/index.js';
|
|
3
|
+
import { authClient } from '../../auth-client.js';
|
|
3
4
|
import { useInterfaceLanguage } from '../../state/interface-language.svelte.js';
|
|
4
5
|
import { getBreadcrumbs } from '../../state/breadcrumbs.svelte.js';
|
|
5
6
|
import { sidebarLang } from '../../components/layout/lang.js';
|
|
6
7
|
import { Button } from '../../../components/ui/button/index.js';
|
|
7
8
|
import DownloadIcon from '@tabler/icons-svelte/icons/download';
|
|
9
|
+
import TrashIcon from '@tabler/icons-svelte/icons/trash';
|
|
10
|
+
import ArrowBackIcon from '@tabler/icons-svelte/icons/arrow-back-up';
|
|
11
|
+
import RestoreOrderCell from './restore-order-cell.svelte';
|
|
8
12
|
import { formatCentsPrice, formatDateTime } from '../../utils/formatters.js';
|
|
9
13
|
import PageHeader from '../../components/layout/page-header.svelte';
|
|
10
14
|
import DataTable from '../collection/data-table.svelte';
|
|
@@ -13,6 +17,7 @@
|
|
|
13
17
|
import StateDisplay from '../collection/state-display.svelte';
|
|
14
18
|
import StatusBadge from '../collection/status-badge.svelte';
|
|
15
19
|
import EntryLink from '../collection/entry-link.svelte';
|
|
20
|
+
import { downloadCsv } from '../../utils/csv-export.js';
|
|
16
21
|
import { renderComponent } from '../../../components/ui/data-table/render-helpers.js';
|
|
17
22
|
import type { ColumnDef, PaginationState } from '@tanstack/table-core';
|
|
18
23
|
import type { InterfaceLanguage } from '../../../types/languages.js';
|
|
@@ -43,6 +48,9 @@
|
|
|
43
48
|
const interfaceLanguage = useInterfaceLanguage();
|
|
44
49
|
const breadcrumbs = getBreadcrumbs();
|
|
45
50
|
|
|
51
|
+
const session = authClient.useSession();
|
|
52
|
+
const isAdmin = $derived($session.data?.user?.role === 'admin');
|
|
53
|
+
|
|
46
54
|
$effect(() => {
|
|
47
55
|
const s = sidebarLang[interfaceLanguage.current].shop;
|
|
48
56
|
breadcrumbs.state = [{ label: s.title }, { label: s.orders }];
|
|
@@ -50,22 +58,30 @@
|
|
|
50
58
|
|
|
51
59
|
let statusFilter = $state<string | null>(null);
|
|
52
60
|
let searchQuery = $state('');
|
|
53
|
-
let
|
|
61
|
+
let appliedSearch = $state('');
|
|
54
62
|
let pagination = $state<PaginationState>({ pageIndex: 0, pageSize: 50 });
|
|
55
63
|
let exporting = $state(false);
|
|
56
|
-
let
|
|
64
|
+
let trashMode = $state(false);
|
|
65
|
+
let searchDebounceTimer: ReturnType<typeof setTimeout> | null = null;
|
|
57
66
|
|
|
58
67
|
const ordersQuery = $derived(
|
|
59
68
|
useInjectedData
|
|
60
69
|
? null
|
|
61
70
|
: remotes.listOrdersAdmin({
|
|
62
71
|
status: (statusFilter as OrderStatus | null) ?? undefined,
|
|
63
|
-
|
|
72
|
+
search: appliedSearch || undefined,
|
|
73
|
+
deleted: trashMode ? 'only' : 'exclude',
|
|
64
74
|
limit: pagination.pageSize,
|
|
65
75
|
offset: pagination.pageIndex * pagination.pageSize
|
|
66
76
|
})
|
|
67
77
|
);
|
|
68
78
|
|
|
79
|
+
function toggleTrash() {
|
|
80
|
+
trashMode = !trashMode;
|
|
81
|
+
statusFilter = null;
|
|
82
|
+
pagination = { ...pagination, pageIndex: 0 };
|
|
83
|
+
}
|
|
84
|
+
|
|
69
85
|
const items = $derived<OrderRow[]>(
|
|
70
86
|
useInjectedData
|
|
71
87
|
? (injectedData ?? [])
|
|
@@ -114,12 +130,18 @@
|
|
|
114
130
|
statusCancelled: string;
|
|
115
131
|
statusPaymentRejected: string;
|
|
116
132
|
statusRefunded: string;
|
|
133
|
+
trash: string;
|
|
134
|
+
exitTrash: string;
|
|
135
|
+
trashTitle: string;
|
|
136
|
+
restore: string;
|
|
137
|
+
columnRestore: string;
|
|
138
|
+
trashEmpty: string;
|
|
117
139
|
}
|
|
118
140
|
> = {
|
|
119
141
|
en: {
|
|
120
142
|
title: 'Orders',
|
|
121
143
|
search: 'Search',
|
|
122
|
-
searchPlaceholder: '
|
|
144
|
+
searchPlaceholder: 'Search by number, email or name…',
|
|
123
145
|
filterStatus: 'Status',
|
|
124
146
|
columnNumber: 'Number',
|
|
125
147
|
columnDate: 'Date',
|
|
@@ -142,12 +164,18 @@
|
|
|
142
164
|
statusDone: 'Done',
|
|
143
165
|
statusCancelled: 'Cancelled',
|
|
144
166
|
statusPaymentRejected: 'Payment rejected',
|
|
145
|
-
statusRefunded: 'Refunded'
|
|
167
|
+
statusRefunded: 'Refunded',
|
|
168
|
+
trash: 'Trash',
|
|
169
|
+
exitTrash: 'Back to orders',
|
|
170
|
+
trashTitle: 'Trash',
|
|
171
|
+
restore: 'Restore',
|
|
172
|
+
columnRestore: '',
|
|
173
|
+
trashEmpty: 'Trash is empty.'
|
|
146
174
|
},
|
|
147
175
|
pl: {
|
|
148
176
|
title: 'Zamówienia',
|
|
149
177
|
search: 'Szukaj',
|
|
150
|
-
searchPlaceholder: '
|
|
178
|
+
searchPlaceholder: 'Szukaj po numerze, e-mailu lub nazwie…',
|
|
151
179
|
filterStatus: 'Status',
|
|
152
180
|
columnNumber: 'Numer',
|
|
153
181
|
columnDate: 'Data',
|
|
@@ -170,7 +198,13 @@
|
|
|
170
198
|
statusDone: 'Zrealizowane',
|
|
171
199
|
statusCancelled: 'Anulowane',
|
|
172
200
|
statusPaymentRejected: 'Płatność odrzucona',
|
|
173
|
-
statusRefunded: 'Zwrócone'
|
|
201
|
+
statusRefunded: 'Zwrócone',
|
|
202
|
+
trash: 'Kosz',
|
|
203
|
+
exitTrash: 'Wróć do zamówień',
|
|
204
|
+
trashTitle: 'Kosz',
|
|
205
|
+
restore: 'Przywróć',
|
|
206
|
+
columnRestore: '',
|
|
207
|
+
trashEmpty: 'Kosz jest pusty.'
|
|
174
208
|
}
|
|
175
209
|
};
|
|
176
210
|
const t = $derived(lang[interfaceLanguage.current]);
|
|
@@ -194,10 +228,10 @@
|
|
|
194
228
|
]);
|
|
195
229
|
const activeDataFilters = $derived({ status: statusFilter });
|
|
196
230
|
|
|
197
|
-
function
|
|
198
|
-
if (
|
|
199
|
-
|
|
200
|
-
|
|
231
|
+
function scheduleSearchUpdate(value: string) {
|
|
232
|
+
if (searchDebounceTimer) clearTimeout(searchDebounceTimer);
|
|
233
|
+
searchDebounceTimer = setTimeout(() => {
|
|
234
|
+
appliedSearch = value.trim();
|
|
201
235
|
pagination = { ...pagination, pageIndex: 0 };
|
|
202
236
|
}, 350);
|
|
203
237
|
}
|
|
@@ -205,22 +239,14 @@
|
|
|
205
239
|
async function handleExportCsv() {
|
|
206
240
|
exporting = true;
|
|
207
241
|
try {
|
|
208
|
-
const opts: { status?: OrderStatus;
|
|
242
|
+
const opts: { status?: OrderStatus; search?: string } = {};
|
|
209
243
|
if (statusFilter) opts.status = statusFilter as OrderStatus;
|
|
210
|
-
if (
|
|
244
|
+
if (appliedSearch) opts.search = appliedSearch;
|
|
211
245
|
const result = await remotes.exportOrdersCsv(
|
|
212
246
|
Object.keys(opts).length > 0 ? opts : undefined
|
|
213
247
|
);
|
|
214
|
-
const blob = new Blob(['' + result.csv], { type: 'text/csv;charset=utf-8' });
|
|
215
|
-
const url = URL.createObjectURL(blob);
|
|
216
|
-
const a = document.createElement('a');
|
|
217
248
|
const ts = new Date().toISOString().slice(0, 10);
|
|
218
|
-
|
|
219
|
-
a.download = `orders-${ts}.csv`;
|
|
220
|
-
document.body.appendChild(a);
|
|
221
|
-
a.click();
|
|
222
|
-
a.remove();
|
|
223
|
-
URL.revokeObjectURL(url);
|
|
249
|
+
downloadCsv({ filename: `orders-${ts}.csv`, csv: result.csv });
|
|
224
250
|
} catch (err) {
|
|
225
251
|
alert(err instanceof Error ? err.message : t.exportError);
|
|
226
252
|
} finally {
|
|
@@ -273,25 +299,53 @@
|
|
|
273
299
|
variant: 'order',
|
|
274
300
|
status: info.row.original.status
|
|
275
301
|
})
|
|
276
|
-
}
|
|
302
|
+
},
|
|
303
|
+
...(trashMode && isAdmin
|
|
304
|
+
? [
|
|
305
|
+
{
|
|
306
|
+
id: 'restore',
|
|
307
|
+
header: t.columnRestore,
|
|
308
|
+
cell: (info) =>
|
|
309
|
+
renderComponent(RestoreOrderCell, {
|
|
310
|
+
orderId: info.row.original.id,
|
|
311
|
+
label: t.restore,
|
|
312
|
+
onRestored: () => ordersQuery?.refresh()
|
|
313
|
+
})
|
|
314
|
+
} satisfies ColumnDef<OrderRow>
|
|
315
|
+
]
|
|
316
|
+
: [])
|
|
277
317
|
]);
|
|
278
318
|
</script>
|
|
279
319
|
|
|
280
320
|
<div class="p-5 pb-24 md:p-7">
|
|
281
|
-
<PageHeader
|
|
321
|
+
<PageHeader
|
|
322
|
+
title={trashMode ? t.trashTitle : t.title}
|
|
323
|
+
count={!isLoading && !isError ? total : undefined}
|
|
324
|
+
>
|
|
282
325
|
{#snippet secondaryActions()}
|
|
283
|
-
|
|
284
|
-
<
|
|
285
|
-
|
|
286
|
-
|
|
326
|
+
{#if isAdmin && !useInjectedData}
|
|
327
|
+
<Button variant={trashMode ? 'default' : 'outline'} size="sm" onclick={toggleTrash}>
|
|
328
|
+
{#if trashMode}
|
|
329
|
+
<ArrowBackIcon class="size-4" />
|
|
330
|
+
{t.exitTrash}
|
|
331
|
+
{:else}
|
|
332
|
+
<TrashIcon class="size-4" />
|
|
333
|
+
{t.trash}
|
|
334
|
+
{/if}
|
|
335
|
+
</Button>
|
|
336
|
+
{/if}
|
|
337
|
+
{#if !trashMode}
|
|
338
|
+
<Button variant="outline" size="sm" onclick={handleExportCsv} disabled={exporting}>
|
|
339
|
+
<DownloadIcon class="size-4" />
|
|
340
|
+
{exporting ? t.exporting : t.exportCsv}
|
|
341
|
+
</Button>
|
|
342
|
+
{/if}
|
|
287
343
|
{/snippet}
|
|
288
344
|
</PageHeader>
|
|
289
345
|
|
|
290
|
-
{#if isError}
|
|
291
|
-
<StateDisplay kind="
|
|
292
|
-
{:else if isLoading && total === 0}
|
|
293
|
-
<StateDisplay kind="loading" />
|
|
294
|
-
{:else if total === 0 && !statusFilter && !appliedEmail}
|
|
346
|
+
{#if !isLoading && !isError && total === 0 && trashMode}
|
|
347
|
+
<StateDisplay kind="empty" title={t.trashEmpty} />
|
|
348
|
+
{:else if !isLoading && !isError && total === 0 && !statusFilter && !appliedSearch}
|
|
295
349
|
<StateDisplay kind="empty" title={t.emptyTitle} description={t.emptyDescription} />
|
|
296
350
|
{:else}
|
|
297
351
|
<TableToolbar
|
|
@@ -300,7 +354,7 @@
|
|
|
300
354
|
searchLabel={t.search}
|
|
301
355
|
onSearchChange={(q) => {
|
|
302
356
|
searchQuery = q;
|
|
303
|
-
|
|
357
|
+
scheduleSearchUpdate(q);
|
|
304
358
|
}}
|
|
305
359
|
hideStatusFilter
|
|
306
360
|
hideViewToggle
|
|
@@ -313,26 +367,32 @@
|
|
|
313
367
|
/>
|
|
314
368
|
|
|
315
369
|
<div class="overflow-hidden rounded-xl border bg-card shadow-sm">
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
370
|
+
{#if isError}
|
|
371
|
+
<StateDisplay kind="error" />
|
|
372
|
+
{:else if isLoading && items.length === 0}
|
|
373
|
+
<StateDisplay kind="loading" />
|
|
374
|
+
{:else}
|
|
375
|
+
<DataTable
|
|
376
|
+
data={items}
|
|
377
|
+
{columns}
|
|
378
|
+
enablePagination
|
|
379
|
+
manualPagination
|
|
380
|
+
{pageCount}
|
|
381
|
+
rowCount={total}
|
|
382
|
+
{pagination}
|
|
383
|
+
onPaginationChange={(p) => (pagination = p)}
|
|
384
|
+
emptyTitle={t.noResults}
|
|
385
|
+
/>
|
|
327
386
|
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
387
|
+
<TablePagination
|
|
388
|
+
pageIndex={pagination.pageIndex}
|
|
389
|
+
pageSize={pagination.pageSize}
|
|
390
|
+
{pageCount}
|
|
391
|
+
totalItems={total}
|
|
392
|
+
onPageChange={(p) => (pagination = { ...pagination, pageIndex: p })}
|
|
393
|
+
onPageSizeChange={(s) => (pagination = { pageIndex: 0, pageSize: s })}
|
|
394
|
+
/>
|
|
395
|
+
{/if}
|
|
336
396
|
</div>
|
|
337
397
|
{/if}
|
|
338
398
|
</div>
|
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
import NavFooter from './nav-footer.svelte';
|
|
8
8
|
import NavForms from './nav-forms.svelte';
|
|
9
9
|
import NavShop from './nav-shop.svelte';
|
|
10
|
+
import NavCustom from './nav-custom.svelte';
|
|
10
11
|
import NavSearch from './nav-search.svelte';
|
|
11
12
|
import { resolve } from '$app/paths';
|
|
12
13
|
import { useInterfaceLanguage } from '../../state/interface-language.svelte.js';
|
|
@@ -41,6 +42,7 @@
|
|
|
41
42
|
<NavCollections />
|
|
42
43
|
<NavForms />
|
|
43
44
|
<NavShop />
|
|
45
|
+
<NavCustom />
|
|
44
46
|
</nav>
|
|
45
47
|
</Sidebar.Content>
|
|
46
48
|
<Sidebar.Footer class="p-0">
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
/**
|
|
3
|
+
* Renders sidebar entries from `CMSConfig.admin.extraNavItems`.
|
|
4
|
+
* Sits below the built-in Shop section (or wherever the consumer mounts
|
|
5
|
+
* `<NavCustom />` in their sidebar). Hidden when no items are configured.
|
|
6
|
+
* @internal — consumed by `app-sidebar.svelte`, not user-facing.
|
|
7
|
+
*/
|
|
8
|
+
import { getRemotes } from '../../../sveltekit/index.js';
|
|
9
|
+
import { page } from '$app/state';
|
|
10
|
+
import NavSection, { type NavSectionItem } from './nav-section.svelte';
|
|
11
|
+
|
|
12
|
+
const remotes = getRemotes();
|
|
13
|
+
const itemsQuery = $derived(remotes.getAdminExtraNavItems());
|
|
14
|
+
const items = $derived<NavSectionItem[]>(
|
|
15
|
+
(itemsQuery.current ?? []).map((i) => ({ title: i.title, url: i.url }))
|
|
16
|
+
);
|
|
17
|
+
|
|
18
|
+
function isActive(url: string) {
|
|
19
|
+
const pathname = page.url.pathname;
|
|
20
|
+
return pathname === url || pathname.startsWith(url + '/');
|
|
21
|
+
}
|
|
22
|
+
</script>
|
|
23
|
+
|
|
24
|
+
{#if items.length}
|
|
25
|
+
<NavSection {items} {isActive} withTopBorder />
|
|
26
|
+
{/if}
|
|
@@ -1,8 +1,18 @@
|
|
|
1
1
|
<script lang="ts" module>
|
|
2
2
|
/**
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
3
|
+
* Page header pattern for admin list/detail pages — title + optional
|
|
4
|
+
* description, count badge, and primary/secondary action slots. Use this
|
|
5
|
+
* in custom admin routes to keep visual parity with the built-in
|
|
6
|
+
* `CollectionPage`, `ShopOrdersListPage` etc.
|
|
7
|
+
*
|
|
8
|
+
* Props:
|
|
9
|
+
* - `title` (string, required) — main heading.
|
|
10
|
+
* - `description?` (string) — small grey caption under the title.
|
|
11
|
+
* - `count?` (number) — small pill badge next to the title (e.g. result count).
|
|
12
|
+
* - `primaryActions?` (Snippet) — right-side primary CTA(s).
|
|
13
|
+
* - `secondaryActions?` (Snippet) — left-of-primary actions (e.g. export buttons).
|
|
14
|
+
*
|
|
15
|
+
* @public
|
|
6
16
|
*/
|
|
7
17
|
import type { Snippet } from 'svelte';
|
|
8
18
|
</script>
|
|
@@ -1,7 +1,17 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
4
|
-
*
|
|
2
|
+
* Page header pattern for admin list/detail pages — title + optional
|
|
3
|
+
* description, count badge, and primary/secondary action slots. Use this
|
|
4
|
+
* in custom admin routes to keep visual parity with the built-in
|
|
5
|
+
* `CollectionPage`, `ShopOrdersListPage` etc.
|
|
6
|
+
*
|
|
7
|
+
* Props:
|
|
8
|
+
* - `title` (string, required) — main heading.
|
|
9
|
+
* - `description?` (string) — small grey caption under the title.
|
|
10
|
+
* - `count?` (number) — small pill badge next to the title (e.g. result count).
|
|
11
|
+
* - `primaryActions?` (Snippet) — right-side primary CTA(s).
|
|
12
|
+
* - `secondaryActions?` (Snippet) — left-of-primary actions (e.g. export buttons).
|
|
13
|
+
*
|
|
14
|
+
* @public
|
|
5
15
|
*/
|
|
6
16
|
import type { Snippet } from 'svelte';
|
|
7
17
|
type $$ComponentProps = {
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { AdminNavItem } from '../types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Returns the consumer-configured extra sidebar items
|
|
4
|
+
* (`CMSConfig.admin.extraNavItems`). Empty array when not set.
|
|
5
|
+
* @public
|
|
6
|
+
*/
|
|
7
|
+
export declare const getAdminExtraNavItems: import("@sveltejs/kit").RemoteQueryFunction<void, AdminNavItem[]>;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { query } from '$app/server';
|
|
2
|
+
import { getCMS } from '../../core/cms.js';
|
|
3
|
+
/**
|
|
4
|
+
* Returns the consumer-configured extra sidebar items
|
|
5
|
+
* (`CMSConfig.admin.extraNavItems`). Empty array when not set.
|
|
6
|
+
* @public
|
|
7
|
+
*/
|
|
8
|
+
export const getAdminExtraNavItems = query(async () => {
|
|
9
|
+
return getCMS().adminConfig?.extraNavItems ?? [];
|
|
10
|
+
});
|
|
@@ -7,7 +7,7 @@ export declare const getRawEntries: import("@sveltejs/kit").RemoteQueryFunction<
|
|
|
7
7
|
limit?: number | undefined;
|
|
8
8
|
offset?: number | undefined;
|
|
9
9
|
orderBy?: {
|
|
10
|
-
column: "
|
|
10
|
+
column: "sortOrder" | "createdAt" | "updatedAt";
|
|
11
11
|
direction: "asc" | "desc";
|
|
12
12
|
} | undefined;
|
|
13
13
|
}, {
|
|
@@ -22,7 +22,7 @@ export declare const getEntries: import("@sveltejs/kit").RemoteQueryFunction<{
|
|
|
22
22
|
status?: "draft" | "published" | "scheduled" | "archived" | undefined;
|
|
23
23
|
slug?: string | undefined;
|
|
24
24
|
orderBy?: {
|
|
25
|
-
column: "
|
|
25
|
+
column: "sortOrder" | "createdAt" | "updatedAt";
|
|
26
26
|
direction: "asc" | "desc";
|
|
27
27
|
} | undefined;
|
|
28
28
|
}, import("../../types/entries.js").Entry[]>;
|
|
@@ -48,7 +48,7 @@ export declare const getEntryLabels: import("@sveltejs/kit").RemoteQueryFunction
|
|
|
48
48
|
ids?: string[] | undefined;
|
|
49
49
|
search?: string | undefined;
|
|
50
50
|
limit?: number | undefined;
|
|
51
|
-
status?: "
|
|
51
|
+
status?: "all" | "draft" | "published" | undefined;
|
|
52
52
|
language?: string | undefined;
|
|
53
53
|
}, {
|
|
54
54
|
id: string;
|
|
@@ -110,7 +110,7 @@ export declare const getRecentEntries: import("@sveltejs/kit").RemoteQueryFuncti
|
|
|
110
110
|
}, {
|
|
111
111
|
entryId: string;
|
|
112
112
|
slug: string;
|
|
113
|
-
kind: "
|
|
113
|
+
kind: "single" | "collection";
|
|
114
114
|
containerLabel: Localized;
|
|
115
115
|
label: string | null;
|
|
116
116
|
labelLanguage: string | null;
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import type { UserRole } from '../../types/roles.js';
|
|
2
2
|
export declare function createInvitation(email: string, role: UserRole, createdBy: string): Promise<{
|
|
3
3
|
id: string;
|
|
4
|
-
role: string;
|
|
5
4
|
createdAt: Date;
|
|
6
5
|
email: string;
|
|
7
6
|
expiresAt: Date;
|
|
8
|
-
createdBy: string;
|
|
9
7
|
token: string;
|
|
8
|
+
role: string;
|
|
9
|
+
createdBy: string;
|
|
10
10
|
usedAt: Date | null;
|
|
11
11
|
}>;
|
|
12
12
|
export declare function getInvitationByToken(token: string): Promise<{
|