includio-cms 0.14.6 → 0.15.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 (127) hide show
  1. package/CHANGELOG.md +25 -0
  2. package/DOCS.md +45 -1
  3. package/ROADMAP.md +23 -2
  4. package/dist/admin/auth-client.d.ts +42 -42
  5. package/dist/admin/client/entry/entry.svelte +1 -0
  6. package/dist/admin/client/index.d.ts +6 -0
  7. package/dist/admin/client/index.js +6 -0
  8. package/dist/admin/client/shop/shipping-method-edit-page.svelte +113 -0
  9. package/dist/admin/client/shop/shipping-method-edit-page.svelte.d.ts +3 -0
  10. package/dist/admin/client/shop/shipping-method-form.svelte +244 -0
  11. package/dist/admin/client/shop/shipping-method-form.svelte.d.ts +37 -0
  12. package/dist/admin/client/shop/shipping-method-new-page.svelte +47 -0
  13. package/dist/admin/client/shop/shipping-method-new-page.svelte.d.ts +3 -0
  14. package/dist/admin/client/shop/shipping-methods-list-page.svelte +172 -0
  15. package/dist/admin/client/shop/shipping-methods-list-page.svelte.d.ts +3 -0
  16. package/dist/admin/client/shop/shop-order-detail-page.svelte +332 -0
  17. package/dist/admin/client/shop/shop-order-detail-page.svelte.d.ts +3 -0
  18. package/dist/admin/client/shop/shop-orders-list-page.svelte +150 -0
  19. package/dist/admin/client/shop/shop-orders-list-page.svelte.d.ts +3 -0
  20. package/dist/admin/client/shop/shop-products-list-page.svelte +157 -0
  21. package/dist/admin/client/shop/shop-products-list-page.svelte.d.ts +3 -0
  22. package/dist/admin/components/fields/field-renderer.svelte +4 -2
  23. package/dist/admin/components/fields/shop-field.svelte +298 -0
  24. package/dist/admin/components/fields/shop-field.svelte.d.ts +7 -0
  25. package/dist/admin/components/layout/app-sidebar.svelte +2 -0
  26. package/dist/admin/components/layout/lang.d.ts +6 -0
  27. package/dist/admin/components/layout/lang.js +12 -0
  28. package/dist/admin/components/layout/nav-shop.svelte +55 -0
  29. package/dist/admin/components/layout/nav-shop.svelte.d.ts +3 -0
  30. package/dist/admin/remote/index.d.ts +1 -0
  31. package/dist/admin/remote/index.js +1 -0
  32. package/dist/admin/remote/shop.remote.d.ts +244 -0
  33. package/dist/admin/remote/shop.remote.js +153 -0
  34. package/dist/cli/scaffold/admin.js +84 -0
  35. package/dist/core/cms.d.ts +2 -0
  36. package/dist/core/cms.js +2 -0
  37. package/dist/core/fields/fieldSchemaToTs.js +5 -0
  38. package/dist/core/server/entries/operations/get.js +3 -3
  39. package/dist/core/server/fields/populateEntry.d.ts +1 -1
  40. package/dist/core/server/fields/populateEntry.js +3 -1
  41. package/dist/core/server/generator/fields.js +14 -0
  42. package/dist/core/server/generator/generator.js +13 -0
  43. package/dist/db-postgres/schema/index.d.ts +1 -0
  44. package/dist/db-postgres/schema/index.js +1 -0
  45. package/dist/db-postgres/schema/shop/index.d.ts +8 -0
  46. package/dist/db-postgres/schema/shop/index.js +8 -0
  47. package/dist/db-postgres/schema/shop/order.d.ts +396 -0
  48. package/dist/db-postgres/schema/shop/order.js +28 -0
  49. package/dist/db-postgres/schema/shop/orderItem.d.ts +179 -0
  50. package/dist/db-postgres/schema/shop/orderItem.js +20 -0
  51. package/dist/db-postgres/schema/shop/orderStatusHistory.d.ts +112 -0
  52. package/dist/db-postgres/schema/shop/orderStatusHistory.js +12 -0
  53. package/dist/db-postgres/schema/shop/payment.d.ts +180 -0
  54. package/dist/db-postgres/schema/shop/payment.js +16 -0
  55. package/dist/db-postgres/schema/shop/product.d.ts +143 -0
  56. package/dist/db-postgres/schema/shop/product.js +15 -0
  57. package/dist/db-postgres/schema/shop/productVariant.d.ts +164 -0
  58. package/dist/db-postgres/schema/shop/productVariant.js +15 -0
  59. package/dist/db-postgres/schema/shop/shippingMethod.d.ts +190 -0
  60. package/dist/db-postgres/schema/shop/shippingMethod.js +13 -0
  61. package/dist/db-postgres/schema/shop/stockReservation.d.ts +109 -0
  62. package/dist/db-postgres/schema/shop/stockReservation.js +13 -0
  63. package/dist/db-postgres/schema-core.d.ts +9 -0
  64. package/dist/db-postgres/schema-core.js +9 -0
  65. package/dist/db-postgres/schema-shop.d.ts +1 -0
  66. package/dist/db-postgres/schema-shop.js +1 -0
  67. package/dist/email-nodemailer/index.d.ts +2 -9
  68. package/dist/shop/adapters/manual/index.d.ts +10 -0
  69. package/dist/shop/adapters/manual/index.js +16 -0
  70. package/dist/shop/cart/cookie.d.ts +8 -0
  71. package/dist/shop/cart/cookie.js +84 -0
  72. package/dist/shop/cart/types.d.ts +42 -0
  73. package/dist/shop/cart/types.js +1 -0
  74. package/dist/shop/client/index.d.ts +59 -0
  75. package/dist/shop/client/index.js +40 -0
  76. package/dist/shop/http/cart-handler.d.ts +7 -0
  77. package/dist/shop/http/cart-handler.js +88 -0
  78. package/dist/shop/http/checkout-handler.d.ts +4 -0
  79. package/dist/shop/http/checkout-handler.js +100 -0
  80. package/dist/shop/http/index.d.ts +3 -0
  81. package/dist/shop/http/index.js +3 -0
  82. package/dist/shop/http/shipping-handler.d.ts +4 -0
  83. package/dist/shop/http/shipping-handler.js +31 -0
  84. package/dist/shop/index.d.ts +4 -0
  85. package/dist/shop/index.js +17 -0
  86. package/dist/shop/pricing.d.ts +15 -0
  87. package/dist/shop/pricing.js +31 -0
  88. package/dist/shop/rate-limit.d.ts +9 -0
  89. package/dist/shop/rate-limit.js +28 -0
  90. package/dist/shop/server/cart-hydrate.d.ts +4 -0
  91. package/dist/shop/server/cart-hydrate.js +172 -0
  92. package/dist/shop/server/db.d.ts +4 -0
  93. package/dist/shop/server/db.js +16 -0
  94. package/dist/shop/server/email.d.ts +2 -0
  95. package/dist/shop/server/email.js +138 -0
  96. package/dist/shop/server/order-number.d.ts +5 -0
  97. package/dist/shop/server/order-number.js +15 -0
  98. package/dist/shop/server/orders.d.ts +45 -0
  99. package/dist/shop/server/orders.js +293 -0
  100. package/dist/shop/server/populate.d.ts +15 -0
  101. package/dist/shop/server/populate.js +39 -0
  102. package/dist/shop/server/shipping.d.ts +37 -0
  103. package/dist/shop/server/shipping.js +111 -0
  104. package/dist/shop/server/shop-data.d.ts +51 -0
  105. package/dist/shop/server/shop-data.js +186 -0
  106. package/dist/shop/services/cart.service.d.ts +38 -0
  107. package/dist/shop/services/cart.service.js +1 -0
  108. package/dist/shop/services/email.service.d.ts +6 -0
  109. package/dist/shop/services/email.service.js +1 -0
  110. package/dist/shop/services/index.d.ts +6 -0
  111. package/dist/shop/services/index.js +1 -0
  112. package/dist/shop/services/orders.service.d.ts +34 -0
  113. package/dist/shop/services/orders.service.js +1 -0
  114. package/dist/shop/services/payment.service.d.ts +7 -0
  115. package/dist/shop/services/payment.service.js +1 -0
  116. package/dist/shop/services/products.service.d.ts +31 -0
  117. package/dist/shop/services/products.service.js +1 -0
  118. package/dist/shop/services/shipping.service.d.ts +23 -0
  119. package/dist/shop/services/shipping.service.js +1 -0
  120. package/dist/shop/types.d.ts +72 -0
  121. package/dist/shop/types.js +1 -0
  122. package/dist/types/cms.d.ts +3 -0
  123. package/dist/types/fields.d.ts +18 -2
  124. package/dist/updates/0.15.0/index.d.ts +2 -0
  125. package/dist/updates/0.15.0/index.js +25 -0
  126. package/dist/updates/index.js +2 -1
  127. package/package.json +27 -1
@@ -0,0 +1,298 @@
1
+ <script lang="ts">
2
+ import { getContext } from 'svelte';
3
+ import { Button } from '../../../components/ui/button/index.js';
4
+ import { Switch } from '../../../components/ui/switch/index.js';
5
+ import TrashIcon from '@tabler/icons-svelte/icons/trash';
6
+ import PlusIcon from '@tabler/icons-svelte/icons/plus';
7
+ import BuildingStoreIcon from '@tabler/icons-svelte/icons/building-store';
8
+ import { getRemotes } from '../../../sveltekit/index.js';
9
+ import type { ShopField } from '../../../types/fields.js';
10
+
11
+ type Props = { field: ShopField };
12
+ const { field }: Props = $props();
13
+
14
+ const entryId = getContext<string>('cms-entry-id');
15
+ const remotes = getRemotes();
16
+ const dataQuery = $derived(remotes.getShopDataForEntry(entryId));
17
+ const configQuery = $derived(remotes.getShopConfig());
18
+
19
+ type InputMode = 'net' | 'gross';
20
+ let inputMode = $state<InputMode>('gross');
21
+ let inputPrice = $state('0.00');
22
+ let vatRate = $state<number | string>(23);
23
+ let isActive = $state(true);
24
+ let variants = $state<
25
+ Array<{
26
+ id?: string;
27
+ sku: string;
28
+ name: string;
29
+ priceDelta: string;
30
+ stock: string;
31
+ }>
32
+ >([]);
33
+
34
+ let loaded = $state(false);
35
+ let saving = $state(false);
36
+ let errorMessage = $state<string | null>(null);
37
+ let successMessage = $state<string | null>(null);
38
+
39
+ const inputPriceCents = $derived(Math.round(parseFloat(inputPrice || '0') * 100));
40
+ const vat = $derived(Number(vatRate) || 0);
41
+ const netCents = $derived(
42
+ inputMode === 'net' ? inputPriceCents : Math.round(inputPriceCents / (1 + vat / 100))
43
+ );
44
+ const grossCents = $derived(
45
+ inputMode === 'gross' ? inputPriceCents : Math.round(inputPriceCents * (1 + vat / 100))
46
+ );
47
+ const vatCents = $derived(grossCents - netCents);
48
+
49
+ function formatCents(cents: number) {
50
+ return (cents / 100).toFixed(2);
51
+ }
52
+
53
+ function switchMode(newMode: InputMode) {
54
+ if (newMode === inputMode) return;
55
+ // Preserve economic value — if user typed gross, switch shows net (computed) in the input, and vice versa.
56
+ const preservedCents = newMode === 'net' ? netCents : grossCents;
57
+ inputMode = newMode;
58
+ inputPrice = formatCents(preservedCents);
59
+ }
60
+
61
+ $effect(() => {
62
+ if (!loaded && dataQuery.ready && configQuery.ready) {
63
+ const shop = dataQuery.current;
64
+ if (shop) {
65
+ // Shop storage is always net — default UI to net when hydrating existing data.
66
+ inputMode = 'net';
67
+ inputPrice = (shop.basePrice / 100).toFixed(2);
68
+ vatRate = shop.vatRate;
69
+ isActive = shop.isActive;
70
+ variants = shop.variants.map((v) => ({
71
+ id: v.id,
72
+ sku: v.sku ?? '',
73
+ name:
74
+ typeof v.name === 'object' && v.name !== null
75
+ ? String(
76
+ Object.values(v.name as Record<string, string>)[0] ?? ''
77
+ )
78
+ : '',
79
+ priceDelta: (v.priceDelta / 100).toFixed(2),
80
+ stock: v.stock == null ? '' : String(v.stock)
81
+ }));
82
+ } else {
83
+ const defaultVat = configQuery.current?.vatRates[0] ?? 23;
84
+ vatRate = defaultVat;
85
+ }
86
+ loaded = true;
87
+ }
88
+ });
89
+
90
+ function addVariant() {
91
+ variants.push({
92
+ id: undefined,
93
+ sku: '',
94
+ name: '',
95
+ priceDelta: '0.00',
96
+ stock: ''
97
+ });
98
+ }
99
+
100
+ function removeVariant(i: number) {
101
+ variants.splice(i, 1);
102
+ }
103
+
104
+ async function save() {
105
+ if (!entryId) {
106
+ errorMessage = 'Brak ID wpisu — zapisz najpierw wpis, potem dane sklepu.';
107
+ return;
108
+ }
109
+ saving = true;
110
+ errorMessage = null;
111
+ successMessage = null;
112
+ try {
113
+ const stockEnabled = configQuery.current?.features.stock ?? false;
114
+ const variantsEnabled = configQuery.current?.features.variants ?? false;
115
+ await remotes.upsertShopDataForEntry({
116
+ entryId,
117
+ data: {
118
+ basePrice: netCents,
119
+ vatRate: Number(vatRate),
120
+ isActive
121
+ },
122
+ variants: variantsEnabled
123
+ ? variants.map((v) => ({
124
+ id: v.id,
125
+ sku: v.sku || null,
126
+ name: v.name ? { pl: v.name } : null,
127
+ priceDelta: Math.round(parseFloat(v.priceDelta || '0') * 100),
128
+ stock: stockEnabled && v.stock !== '' ? parseInt(v.stock, 10) : null,
129
+ attributes: null
130
+ }))
131
+ : []
132
+ });
133
+ await dataQuery.refresh();
134
+ successMessage = 'Zapisano dane sklepu.';
135
+ } catch (err) {
136
+ errorMessage = err instanceof Error ? err.message : 'Nie udało się zapisać';
137
+ } finally {
138
+ saving = false;
139
+ }
140
+ }
141
+ </script>
142
+
143
+ <section class="border-border bg-card space-y-4 rounded-xl border p-5">
144
+ <header class="flex items-center justify-between">
145
+ <div class="flex items-center gap-2">
146
+ <BuildingStoreIcon class="text-primary size-5" />
147
+ <h3 class="text-base font-bold">Sklep</h3>
148
+ </div>
149
+ <label class="flex items-center gap-2 text-sm">
150
+ <Switch bind:checked={isActive} />
151
+ <span>Aktywny</span>
152
+ </label>
153
+ </header>
154
+
155
+ {#if !configQuery.ready || !dataQuery.ready}
156
+ <p class="text-muted-foreground text-sm">Ładowanie…</p>
157
+ {:else if !configQuery.current}
158
+ <p class="text-muted-foreground text-sm">Sklep nie jest skonfigurowany.</p>
159
+ {:else}
160
+ {@const config = configQuery.current}
161
+
162
+ <div class="space-y-3">
163
+ <div class="grid grid-cols-[1fr_auto] gap-3">
164
+ <label class="block">
165
+ <div class="mb-1 flex items-center justify-between">
166
+ <span class="text-muted-foreground text-xs font-semibold">
167
+ Cena bazowa ({inputMode === 'net' ? 'netto' : 'brutto'}, PLN)
168
+ </span>
169
+ <div class="bg-muted inline-flex rounded-md p-0.5 text-xs">
170
+ <button
171
+ type="button"
172
+ class="rounded px-2 py-0.5 {inputMode === 'net'
173
+ ? 'bg-background text-primary font-semibold shadow-sm'
174
+ : 'text-muted-foreground'}"
175
+ onclick={() => switchMode('net')}
176
+ >
177
+ Netto
178
+ </button>
179
+ <button
180
+ type="button"
181
+ class="rounded px-2 py-0.5 {inputMode === 'gross'
182
+ ? 'bg-background text-primary font-semibold shadow-sm'
183
+ : 'text-muted-foreground'}"
184
+ onclick={() => switchMode('gross')}
185
+ >
186
+ Brutto
187
+ </button>
188
+ </div>
189
+ </div>
190
+ <input
191
+ type="number"
192
+ step="0.01"
193
+ min="0"
194
+ bind:value={inputPrice}
195
+ class="border-border w-full rounded-lg border px-3 py-2"
196
+ />
197
+ </label>
198
+ <label class="block">
199
+ <span class="text-muted-foreground mb-1 block text-xs font-semibold">VAT</span>
200
+ <select
201
+ bind:value={vatRate}
202
+ class="border-border w-full rounded-lg border px-3 py-2"
203
+ >
204
+ {#each config.vatRates as r (r)}
205
+ <option value={r}>{r}%</option>
206
+ {/each}
207
+ </select>
208
+ </label>
209
+ </div>
210
+ <div class="bg-muted/40 border-border grid grid-cols-3 gap-2 rounded-lg border p-2.5 text-center text-xs">
211
+ <div>
212
+ <div class="text-muted-foreground font-semibold uppercase tracking-wide">Netto</div>
213
+ <div class="text-sm font-bold tabular-nums">{formatCents(netCents)} zł</div>
214
+ </div>
215
+ <div class="border-border border-x">
216
+ <div class="text-muted-foreground font-semibold uppercase tracking-wide">VAT</div>
217
+ <div class="text-sm font-bold tabular-nums">{formatCents(vatCents)} zł</div>
218
+ </div>
219
+ <div>
220
+ <div class="text-muted-foreground font-semibold uppercase tracking-wide">Brutto</div>
221
+ <div class="text-primary text-sm font-bold tabular-nums">{formatCents(grossCents)} zł</div>
222
+ </div>
223
+ </div>
224
+ </div>
225
+
226
+ {#if config.features.variants}
227
+ <div class="border-border space-y-3 rounded-lg border-t pt-4">
228
+ <div class="flex items-center justify-between">
229
+ <h4 class="text-sm font-bold">Warianty</h4>
230
+ <Button type="button" variant="outline" size="sm" onclick={addVariant}>
231
+ <PlusIcon class="mr-1 size-4" /> Dodaj wariant
232
+ </Button>
233
+ </div>
234
+ {#if variants.length === 0}
235
+ <p class="text-muted-foreground text-xs">Brak wariantów — zostanie użyta cena bazowa.</p>
236
+ {/if}
237
+ {#each variants as v, i (i)}
238
+ <div class="border-border grid grid-cols-2 gap-2 rounded-lg border p-3">
239
+ <label class="block">
240
+ <span class="text-muted-foreground mb-0.5 block text-xs">Nazwa</span>
241
+ <input
242
+ type="text"
243
+ bind:value={v.name}
244
+ class="border-border w-full rounded border px-2 py-1 text-sm"
245
+ />
246
+ </label>
247
+ <label class="block">
248
+ <span class="text-muted-foreground mb-0.5 block text-xs">SKU</span>
249
+ <input
250
+ type="text"
251
+ bind:value={v.sku}
252
+ class="border-border w-full rounded border px-2 py-1 font-mono text-sm"
253
+ />
254
+ </label>
255
+ <label class="block">
256
+ <span class="text-muted-foreground mb-0.5 block text-xs">Zmiana ceny (PLN)</span>
257
+ <input
258
+ type="number"
259
+ step="0.01"
260
+ bind:value={v.priceDelta}
261
+ class="border-border w-full rounded border px-2 py-1 text-sm"
262
+ />
263
+ </label>
264
+ {#if config.features.stock}
265
+ <label class="block">
266
+ <span class="text-muted-foreground mb-0.5 block text-xs">Stock (puste = ∞)</span>
267
+ <input
268
+ type="number"
269
+ min="0"
270
+ bind:value={v.stock}
271
+ class="border-border w-full rounded border px-2 py-1 text-sm"
272
+ />
273
+ </label>
274
+ {/if}
275
+ <div class="col-span-2 flex justify-end">
276
+ <Button type="button" variant="ghost" size="sm" onclick={() => removeVariant(i)}>
277
+ <TrashIcon class="size-4" />
278
+ </Button>
279
+ </div>
280
+ </div>
281
+ {/each}
282
+ </div>
283
+ {/if}
284
+
285
+ {#if errorMessage}
286
+ <div class="rounded-lg bg-red-50 p-2.5 text-xs text-red-800">{errorMessage}</div>
287
+ {/if}
288
+ {#if successMessage}
289
+ <div class="rounded-lg bg-green-50 p-2.5 text-xs text-green-800">{successMessage}</div>
290
+ {/if}
291
+
292
+ <div class="flex justify-end">
293
+ <Button type="button" onclick={save} disabled={saving}>
294
+ {saving ? 'Zapisywanie…' : 'Zapisz dane sklepu'}
295
+ </Button>
296
+ </div>
297
+ {/if}
298
+ </section>
@@ -0,0 +1,7 @@
1
+ import type { ShopField } from '../../../types/fields.js';
2
+ type Props = {
3
+ field: ShopField;
4
+ };
5
+ declare const ShopField: import("svelte").Component<Props, {}, "">;
6
+ type ShopField = ReturnType<typeof ShopField>;
7
+ export default ShopField;
@@ -6,6 +6,7 @@
6
6
  import NavCollections from './nav-collections.svelte';
7
7
  import NavFooter from './nav-footer.svelte';
8
8
  import NavForms from './nav-forms.svelte';
9
+ import NavShop from './nav-shop.svelte';
9
10
  import NavSearch from './nav-search.svelte';
10
11
  import { resolve } from '$app/paths';
11
12
  let { ...restProps }: ComponentProps<typeof Sidebar.Root> = $props();
@@ -34,6 +35,7 @@
34
35
  <NavSingletons />
35
36
  <NavCollections />
36
37
  <NavForms />
38
+ <NavShop />
37
39
  </div>
38
40
  </Sidebar.Content>
39
41
  <Sidebar.Footer class="p-0">
@@ -19,6 +19,12 @@ export declare const sidebarLang: Record<string, {
19
19
  forms: {
20
20
  title: string;
21
21
  };
22
+ shop: {
23
+ title: string;
24
+ products: string;
25
+ orders: string;
26
+ shipping: string;
27
+ };
22
28
  footer: {
23
29
  help: string;
24
30
  };
@@ -20,6 +20,12 @@ export const sidebarLang = {
20
20
  forms: {
21
21
  title: 'Formularze'
22
22
  },
23
+ shop: {
24
+ title: 'Sklep',
25
+ products: 'Produkty',
26
+ orders: 'Zamówienia',
27
+ shipping: 'Metody wysyłki'
28
+ },
23
29
  footer: {
24
30
  help: 'Pomoc'
25
31
  },
@@ -53,6 +59,12 @@ export const sidebarLang = {
53
59
  forms: {
54
60
  title: 'Forms'
55
61
  },
62
+ shop: {
63
+ title: 'Shop',
64
+ products: 'Products',
65
+ orders: 'Orders',
66
+ shipping: 'Shipping methods'
67
+ },
56
68
  footer: {
57
69
  help: 'Help'
58
70
  },
@@ -0,0 +1,55 @@
1
+ <script lang="ts">
2
+ import { useInterfaceLanguage } from '../../state/interface-language.svelte.js';
3
+ import * as Sidebar from '../../../components/ui/sidebar/index.js';
4
+ import { sidebarLang } from './lang.js';
5
+ import { getRemotes } from '../../../sveltekit/index.js';
6
+ import PackageIcon from '@tabler/icons-svelte/icons/package';
7
+ import ShoppingCartIcon from '@tabler/icons-svelte/icons/shopping-cart';
8
+ import TruckIcon from '@tabler/icons-svelte/icons/truck';
9
+ import BuildingStoreIcon from '@tabler/icons-svelte/icons/building-store';
10
+ import { page } from '$app/state';
11
+
12
+ const interfaceLanguage = useInterfaceLanguage();
13
+ const lang = $derived(sidebarLang[interfaceLanguage.current].shop);
14
+ const remotes = getRemotes();
15
+ const enabledQuery = $derived(remotes.getShopEnabled());
16
+
17
+ function isActive(url: string) {
18
+ const pathname = page.url.pathname;
19
+ return pathname === url || pathname.startsWith(url + '/');
20
+ }
21
+
22
+ const items = $derived([
23
+ { title: lang.products, url: '/admin/shop/products', icon: PackageIcon },
24
+ { title: lang.orders, url: '/admin/shop/orders', icon: ShoppingCartIcon },
25
+ { title: lang.shipping, url: '/admin/shop/shipping-methods', icon: TruckIcon }
26
+ ]);
27
+ </script>
28
+
29
+ {#if enabledQuery.ready && enabledQuery.current}
30
+ <Sidebar.Group class="border-sidebar-border mt-1 border-t px-0 pt-2 pb-1">
31
+ <Sidebar.GroupLabel class="group-data-[collapsible=icon]:hidden">
32
+ <BuildingStoreIcon class="mr-1 size-3.5" />
33
+ {lang.title}
34
+ </Sidebar.GroupLabel>
35
+ <Sidebar.Menu>
36
+ {#each items as item (item.url)}
37
+ {@const active = isActive(item.url)}
38
+ <Sidebar.MenuItem>
39
+ <Sidebar.MenuButton isActive={active} tooltipContent={item.title}>
40
+ {#snippet child({ props })}
41
+ <a {...props} href={item.url}>
42
+ <item.icon
43
+ class="size-5! shrink-0 {active ? 'text-primary' : 'text-muted-foreground'}"
44
+ />
45
+ <span class="flex-1 truncate {active ? 'text-primary' : 'text-muted-foreground'}">
46
+ {item.title}
47
+ </span>
48
+ </a>
49
+ {/snippet}
50
+ </Sidebar.MenuButton>
51
+ </Sidebar.MenuItem>
52
+ {/each}
53
+ </Sidebar.Menu>
54
+ </Sidebar.Group>
55
+ {/if}
@@ -0,0 +1,3 @@
1
+ declare const NavShop: import("svelte").Component<Record<string, never>, {}, "">;
2
+ type NavShop = ReturnType<typeof NavShop>;
3
+ export default NavShop;
@@ -8,3 +8,4 @@ export * from './form.remote.js';
8
8
  export * from './ai.remote.js';
9
9
  export * from './preview.remote.js';
10
10
  export * from './email.remote.js';
11
+ export * from './shop.remote.js';
@@ -8,3 +8,4 @@ export * from './form.remote.js';
8
8
  export * from './ai.remote.js';
9
9
  export * from './preview.remote.js';
10
10
  export * from './email.remote.js';
11
+ export * from './shop.remote.js';
@@ -0,0 +1,244 @@
1
+ export declare const getShopEnabled: import("@sveltejs/kit").RemoteQueryFunction<void, boolean>;
2
+ export declare const getShopConfig: import("@sveltejs/kit").RemoteQueryFunction<void, {
3
+ currency: "PLN";
4
+ vatRates: number[];
5
+ features: Required<import("../../shop/types.js").ShopFeatures>;
6
+ languages: import("../../types/languages.js").Language[];
7
+ } | null>;
8
+ export declare const listShopProductEntries: import("@sveltejs/kit").RemoteQueryFunction<void, import("../../shop/server/shop-data.js").ShopEntryListItem[]>;
9
+ export declare const getShopDataForEntry: import("@sveltejs/kit").RemoteQueryFunction<string, import("../../shop/server/shop-data.js").ShopDataWithVariants | null>;
10
+ export declare const upsertShopDataForEntry: import("@sveltejs/kit").RemoteCommand<{
11
+ entryId: string;
12
+ data: {
13
+ basePrice: number;
14
+ vatRate: number;
15
+ isActive?: boolean | undefined;
16
+ sortOrder?: number | null | undefined;
17
+ };
18
+ variants?: {
19
+ id?: string | undefined;
20
+ sku?: string | null | undefined;
21
+ name?: Record<string, string> | null | undefined;
22
+ priceDelta?: number | undefined;
23
+ stock?: number | null | undefined;
24
+ attributes?: Record<string, string> | null | undefined;
25
+ }[] | undefined;
26
+ }, Promise<import("../../shop/server/shop-data.js").ShopDataWithVariants>>;
27
+ export declare const deleteShopDataForEntry: import("@sveltejs/kit").RemoteCommand<string, Promise<{
28
+ success: boolean;
29
+ }>>;
30
+ export declare const listShippingMethodsAdmin: import("@sveltejs/kit").RemoteQueryFunction<void, {
31
+ id: string;
32
+ name: Record<string, string>;
33
+ createdAt: Date;
34
+ sortOrder: number | null;
35
+ description: Record<string, string> | null;
36
+ vatRate: number;
37
+ isActive: boolean;
38
+ price: number;
39
+ carrierType: string;
40
+ conditions: {
41
+ freeAbove?: number;
42
+ } | null;
43
+ }[]>;
44
+ export declare const getShippingMethodForAdmin: import("@sveltejs/kit").RemoteQueryFunction<string, {
45
+ id: string;
46
+ name: Record<string, string>;
47
+ createdAt: Date;
48
+ sortOrder: number | null;
49
+ description: Record<string, string> | null;
50
+ vatRate: number;
51
+ isActive: boolean;
52
+ price: number;
53
+ carrierType: string;
54
+ conditions: {
55
+ freeAbove?: number;
56
+ } | null;
57
+ } | null>;
58
+ export declare const createShippingMethodCmd: import("@sveltejs/kit").RemoteCommand<{
59
+ name: Record<string, string>;
60
+ price: number;
61
+ vatRate: number;
62
+ description?: Record<string, string> | null | undefined;
63
+ carrierType?: string | undefined;
64
+ conditions?: {
65
+ freeAbove?: number | undefined;
66
+ } | null | undefined;
67
+ isActive?: boolean | undefined;
68
+ sortOrder?: number | null | undefined;
69
+ }, Promise<{
70
+ id: string;
71
+ name: Record<string, string>;
72
+ createdAt: Date;
73
+ sortOrder: number | null;
74
+ description: Record<string, string> | null;
75
+ vatRate: number;
76
+ isActive: boolean;
77
+ price: number;
78
+ carrierType: string;
79
+ conditions: {
80
+ freeAbove?: number;
81
+ } | null;
82
+ }>>;
83
+ export declare const updateShippingMethodCmd: import("@sveltejs/kit").RemoteCommand<{
84
+ id: string;
85
+ input: {
86
+ name?: Record<string, string> | undefined;
87
+ description?: Record<string, string> | null | undefined;
88
+ price?: number | undefined;
89
+ vatRate?: number | undefined;
90
+ carrierType?: string | undefined;
91
+ conditions?: {
92
+ freeAbove?: number | undefined;
93
+ } | null | undefined;
94
+ isActive?: boolean | undefined;
95
+ sortOrder?: number | null | undefined;
96
+ };
97
+ }, Promise<{
98
+ id: string;
99
+ name: Record<string, string>;
100
+ createdAt: Date;
101
+ sortOrder: number | null;
102
+ description: Record<string, string> | null;
103
+ vatRate: number;
104
+ isActive: boolean;
105
+ price: number;
106
+ carrierType: string;
107
+ conditions: {
108
+ freeAbove?: number;
109
+ } | null;
110
+ }>>;
111
+ export declare const deleteShippingMethodCmd: import("@sveltejs/kit").RemoteCommand<string, Promise<{
112
+ success: boolean;
113
+ }>>;
114
+ export declare const reorderShippingMethodsCmd: import("@sveltejs/kit").RemoteCommand<string[], Promise<{
115
+ success: boolean;
116
+ }>>;
117
+ export declare const listOrdersAdmin: import("@sveltejs/kit").RemoteQueryFunction<{
118
+ status?: "done" | "new" | "awaitingPayment" | "paid" | "preparing" | "sent" | "cancelled" | "paymentRejected" | undefined;
119
+ email?: string | undefined;
120
+ limit?: number | undefined;
121
+ offset?: number | undefined;
122
+ } | undefined, {
123
+ number: string;
124
+ id: string;
125
+ status: import("../../shop/types.js").OrderStatus;
126
+ createdAt: Date;
127
+ updatedAt: Date;
128
+ language: string | null;
129
+ consents: {
130
+ id: string;
131
+ accepted: boolean;
132
+ label: string;
133
+ }[] | null;
134
+ carrierType: string | null;
135
+ currency: string;
136
+ customerEmail: string;
137
+ customerName: string | null;
138
+ customerPhone: string | null;
139
+ shippingAddress: Record<string, string> | null;
140
+ totalNet: number;
141
+ totalGross: number;
142
+ vatAmount: number;
143
+ shippingNet: number;
144
+ shippingGross: number;
145
+ shippingMethodId: string | null;
146
+ carrierRef: string | null;
147
+ paymentMethod: string | null;
148
+ notes: string | null;
149
+ }[]>;
150
+ export declare const getOrderForAdmin: import("@sveltejs/kit").RemoteQueryFunction<string, {
151
+ order: {
152
+ number: string;
153
+ id: string;
154
+ status: import("../../shop/types.js").OrderStatus;
155
+ createdAt: Date;
156
+ updatedAt: Date;
157
+ language: string | null;
158
+ consents: {
159
+ id: string;
160
+ accepted: boolean;
161
+ label: string;
162
+ }[] | null;
163
+ carrierType: string | null;
164
+ currency: string;
165
+ customerEmail: string;
166
+ customerName: string | null;
167
+ customerPhone: string | null;
168
+ shippingAddress: Record<string, string> | null;
169
+ totalNet: number;
170
+ totalGross: number;
171
+ vatAmount: number;
172
+ shippingNet: number;
173
+ shippingGross: number;
174
+ shippingMethodId: string | null;
175
+ carrierRef: string | null;
176
+ paymentMethod: string | null;
177
+ notes: string | null;
178
+ };
179
+ items: {
180
+ id: string;
181
+ vatRate: number;
182
+ productId: string | null;
183
+ orderId: string;
184
+ variantId: string | null;
185
+ nameSnapshot: Record<string, string>;
186
+ skuSnapshot: string | null;
187
+ priceNetSnapshot: number;
188
+ priceGrossSnapshot: number;
189
+ qty: number;
190
+ }[];
191
+ history: {
192
+ id: string;
193
+ note: string | null;
194
+ status: import("../../shop/types.js").OrderStatus;
195
+ orderId: string;
196
+ changedBy: string | null;
197
+ changedAt: Date;
198
+ }[];
199
+ } | null>;
200
+ export declare const updateOrderStatusCmd: import("@sveltejs/kit").RemoteCommand<{
201
+ orderId: string;
202
+ status: "done" | "new" | "awaitingPayment" | "paid" | "preparing" | "sent" | "cancelled" | "paymentRejected";
203
+ note?: string | undefined;
204
+ }, Promise<{
205
+ number: string;
206
+ id: string;
207
+ status: import("../../shop/types.js").OrderStatus;
208
+ createdAt: Date;
209
+ updatedAt: Date;
210
+ language: string | null;
211
+ consents: {
212
+ id: string;
213
+ accepted: boolean;
214
+ label: string;
215
+ }[] | null;
216
+ carrierType: string | null;
217
+ currency: string;
218
+ customerEmail: string;
219
+ customerName: string | null;
220
+ customerPhone: string | null;
221
+ shippingAddress: Record<string, string> | null;
222
+ totalNet: number;
223
+ totalGross: number;
224
+ vatAmount: number;
225
+ shippingNet: number;
226
+ shippingGross: number;
227
+ shippingMethodId: string | null;
228
+ carrierRef: string | null;
229
+ paymentMethod: string | null;
230
+ notes: string | null;
231
+ }>>;
232
+ export declare const resendOrderEmailCmd: import("@sveltejs/kit").RemoteCommand<{
233
+ orderId: string;
234
+ status: "done" | "new" | "awaitingPayment" | "paid" | "preparing" | "sent" | "cancelled" | "paymentRejected";
235
+ }, Promise<{
236
+ success: boolean;
237
+ }>>;
238
+ export declare const listShopableCollections: import("@sveltejs/kit").RemoteQueryFunction<void, {
239
+ slug: string;
240
+ labels: {
241
+ singular?: import("../../types/languages.js").Localized;
242
+ plural?: import("../../types/languages.js").Localized;
243
+ } | undefined;
244
+ }[]>;