@emreunes/medusa-category-images 0.0.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.
@@ -0,0 +1,545 @@
1
+ "use strict";
2
+ const jsxRuntime = require("react/jsx-runtime");
3
+ const adminSdk = require("@medusajs/admin-sdk");
4
+ const ui = require("@medusajs/ui");
5
+ const reactQuery = require("@tanstack/react-query");
6
+ const Medusa = require("@medusajs/js-sdk");
7
+ const react = require("react");
8
+ const icons = require("@medusajs/icons");
9
+ require("@medusajs/admin-shared");
10
+ const _interopDefault = (e) => e && e.__esModule ? e : { default: e };
11
+ const Medusa__default = /* @__PURE__ */ _interopDefault(Medusa);
12
+ const sdk = new Medusa__default.default({
13
+ baseUrl: typeof window !== "undefined" ? window.location.origin : "http://localhost:9000",
14
+ auth: {
15
+ type: "session"
16
+ }
17
+ });
18
+ const CategoryImageItem = ({
19
+ id,
20
+ url,
21
+ alt,
22
+ isThumbnail,
23
+ isSelected,
24
+ onToggleSelect
25
+ }) => {
26
+ return /* @__PURE__ */ jsxRuntime.jsxs(
27
+ "div",
28
+ {
29
+ className: "shadow-elevation-card-rest hover:shadow-elevation-card-hover focus-visible:shadow-borders-focus bg-ui-bg-subtle-hover group relative aspect-square h-auto max-w-full overflow-hidden rounded-lg outline-none",
30
+ children: [
31
+ isThumbnail && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute left-2 top-2", children: /* @__PURE__ */ jsxRuntime.jsx(icons.ThumbnailBadge, {}) }),
32
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: ui.clx(
33
+ "transition-fg absolute right-2 top-2 opacity-0 group-focus-within:opacity-100 group-hover:opacity-100 group-focus:opacity-100",
34
+ isSelected && "opacity-100"
35
+ ), children: /* @__PURE__ */ jsxRuntime.jsx(
36
+ ui.Checkbox,
37
+ {
38
+ checked: isSelected,
39
+ onCheckedChange: onToggleSelect
40
+ }
41
+ ) }),
42
+ /* @__PURE__ */ jsxRuntime.jsx(
43
+ "img",
44
+ {
45
+ src: url,
46
+ alt,
47
+ className: "size-full object-cover object-center"
48
+ }
49
+ )
50
+ ]
51
+ },
52
+ id
53
+ );
54
+ };
55
+ const CategoryImageGallery = ({
56
+ existingImages,
57
+ uploadedFiles,
58
+ imagesToDelete,
59
+ currentThumbnailId,
60
+ selectedImageIds,
61
+ onToggleSelect
62
+ }) => {
63
+ const visibleExistingImages = existingImages.filter(
64
+ (image) => image.id && !imagesToDelete.has(image.id)
65
+ );
66
+ const hasNoImages = visibleExistingImages.length === 0 && uploadedFiles.length === 0;
67
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "bg-ui-bg-subtle size-full overflow-auto", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid h-fit auto-rows-auto grid-cols-4 gap-6 p-6", children: [
68
+ visibleExistingImages.map((image) => {
69
+ if (!image.id) return null;
70
+ const imageId = image.id;
71
+ const isThumbnail = currentThumbnailId === imageId;
72
+ return /* @__PURE__ */ jsxRuntime.jsx(
73
+ CategoryImageItem,
74
+ {
75
+ id: imageId,
76
+ url: image.url,
77
+ alt: `Category ${image.type}`,
78
+ isThumbnail,
79
+ isSelected: selectedImageIds.has(imageId),
80
+ onToggleSelect: () => onToggleSelect(imageId)
81
+ },
82
+ imageId
83
+ );
84
+ }),
85
+ uploadedFiles.map((file) => {
86
+ const uploadedId = `uploaded:${file.id}`;
87
+ const isThumbnail = currentThumbnailId === uploadedId;
88
+ return /* @__PURE__ */ jsxRuntime.jsx(
89
+ CategoryImageItem,
90
+ {
91
+ id: file.id,
92
+ url: file.url,
93
+ alt: "Uploaded",
94
+ isThumbnail,
95
+ isSelected: selectedImageIds.has(uploadedId),
96
+ onToggleSelect: () => onToggleSelect(file.id, true)
97
+ },
98
+ file.id
99
+ );
100
+ }),
101
+ hasNoImages && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "col-span-4 flex items-center justify-center p-8", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "text-ui-fg-subtle text-center", children: "No images yet. Upload images to get started." }) })
102
+ ] }) });
103
+ };
104
+ const CategoryImageUpload = ({
105
+ fileInputRef,
106
+ isUploading,
107
+ onFileSelect
108
+ }) => {
109
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "bg-ui-bg-base overflow-auto border-b px-6 py-4 lg:border-b-0 lg:border-l", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-col space-y-2", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-y-2", children: [
110
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-y-1", children: [
111
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-x-1", children: [
112
+ /* @__PURE__ */ jsxRuntime.jsx("label", { className: "font-sans txt-compact-small font-medium", children: "Media" }),
113
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "font-normal font-sans txt-compact-small text-ui-fg-muted", children: "(Optional)" })
114
+ ] }),
115
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "txt-small text-ui-fg-subtle", children: "Add media to the product to showcase it in your storefront." })
116
+ ] }),
117
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
118
+ /* @__PURE__ */ jsxRuntime.jsx(
119
+ "input",
120
+ {
121
+ ref: fileInputRef,
122
+ type: "file",
123
+ multiple: true,
124
+ accept: "image/jpeg,image/png,image/gif,image/webp,image/heic,image/svg+xml",
125
+ onChange: (e) => onFileSelect(e.target.files),
126
+ hidden: true
127
+ }
128
+ ),
129
+ /* @__PURE__ */ jsxRuntime.jsxs(
130
+ "button",
131
+ {
132
+ type: "button",
133
+ onClick: () => {
134
+ var _a;
135
+ return (_a = fileInputRef.current) == null ? void 0 : _a.click();
136
+ },
137
+ disabled: isUploading,
138
+ className: "bg-ui-bg-component border-ui-border-strong transition-fg group flex w-full flex-col items-center gap-y-2 rounded-lg border border-dashed p-8 hover:border-ui-border-interactive focus:border-ui-border-interactive focus:shadow-borders-focus outline-none focus:border-solid disabled:opacity-50 disabled:cursor-not-allowed",
139
+ onDragOver: (e) => {
140
+ e.preventDefault();
141
+ e.stopPropagation();
142
+ },
143
+ onDrop: (e) => {
144
+ e.preventDefault();
145
+ e.stopPropagation();
146
+ if (!isUploading) {
147
+ onFileSelect(e.dataTransfer.files);
148
+ }
149
+ },
150
+ children: [
151
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-ui-fg-subtle group-disabled:text-ui-fg-disabled flex items-center gap-x-2", children: [
152
+ /* @__PURE__ */ jsxRuntime.jsx(icons.ArrowDownTray, {}),
153
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "font-normal font-sans txt-medium", children: isUploading ? "Uploading..." : "Upload images" })
154
+ ] }),
155
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "font-normal font-sans txt-compact-small text-ui-fg-muted group-disabled:text-ui-fg-disabled", children: "Drag and drop images here or click to upload." })
156
+ ]
157
+ }
158
+ )
159
+ ] })
160
+ ] }) }) });
161
+ };
162
+ const useCategoryImageMutations = ({
163
+ categoryId,
164
+ onCreateSuccess,
165
+ onUpdateSuccess,
166
+ onDeleteSuccess
167
+ }) => {
168
+ const queryClient = reactQuery.useQueryClient();
169
+ const uploadFilesMutation = reactQuery.useMutation({
170
+ mutationFn: async (files) => {
171
+ const response = await sdk.admin.upload.create({ files });
172
+ return response;
173
+ },
174
+ onError: (error) => {
175
+ console.error("Failed to upload files:", error);
176
+ }
177
+ });
178
+ const createImagesMutation = reactQuery.useMutation({
179
+ mutationFn: async (images) => {
180
+ const response = await sdk.client.fetch(
181
+ `/admin/categories/${categoryId}/images`,
182
+ {
183
+ method: "POST",
184
+ headers: {
185
+ "Content-Type": "application/json"
186
+ },
187
+ body: {
188
+ images
189
+ }
190
+ }
191
+ );
192
+ return response;
193
+ },
194
+ onSuccess: () => {
195
+ queryClient.invalidateQueries({ queryKey: ["category-images", categoryId] });
196
+ onCreateSuccess == null ? void 0 : onCreateSuccess();
197
+ }
198
+ });
199
+ const updateImagesMutation = reactQuery.useMutation({
200
+ mutationFn: async (updates) => {
201
+ const response = await sdk.client.fetch(
202
+ `/admin/categories/${categoryId}/images/batch`,
203
+ {
204
+ method: "POST",
205
+ headers: {
206
+ "Content-Type": "application/json"
207
+ },
208
+ body: {
209
+ updates
210
+ }
211
+ }
212
+ );
213
+ return response;
214
+ },
215
+ onSuccess: () => {
216
+ queryClient.invalidateQueries({ queryKey: ["category-images", categoryId] });
217
+ onUpdateSuccess == null ? void 0 : onUpdateSuccess();
218
+ }
219
+ });
220
+ const deleteImagesMutation = reactQuery.useMutation({
221
+ mutationFn: async (ids) => {
222
+ const response = await sdk.client.fetch(
223
+ `/admin/categories/${categoryId}/images/batch`,
224
+ {
225
+ method: "DELETE",
226
+ headers: {
227
+ "Content-Type": "application/json"
228
+ },
229
+ body: {
230
+ ids
231
+ }
232
+ }
233
+ );
234
+ return response;
235
+ },
236
+ onSuccess: (_data, deletedIds) => {
237
+ queryClient.invalidateQueries({ queryKey: ["category-images", categoryId] });
238
+ onDeleteSuccess == null ? void 0 : onDeleteSuccess(deletedIds);
239
+ }
240
+ });
241
+ return {
242
+ uploadFilesMutation,
243
+ createImagesMutation,
244
+ updateImagesMutation,
245
+ deleteImagesMutation
246
+ };
247
+ };
248
+ const CategoryMediaModal = ({
249
+ categoryId,
250
+ existingImages
251
+ }) => {
252
+ const [open, setOpen] = react.useState(false);
253
+ const [uploadedFiles, setUploadedFiles] = react.useState([]);
254
+ const [selectedImageIds, setSelectedImageIds] = react.useState(/* @__PURE__ */ new Set());
255
+ const [currentThumbnailId, setCurrentThumbnailId] = react.useState(null);
256
+ const [imagesToDelete, setImagesToDelete] = react.useState(/* @__PURE__ */ new Set());
257
+ const fileInputRef = react.useRef(null);
258
+ const queryClient = reactQuery.useQueryClient();
259
+ const {
260
+ uploadFilesMutation,
261
+ createImagesMutation,
262
+ updateImagesMutation,
263
+ deleteImagesMutation
264
+ } = useCategoryImageMutations({
265
+ categoryId,
266
+ onCreateSuccess: () => {
267
+ setOpen(false);
268
+ resetModalState();
269
+ },
270
+ onUpdateSuccess: () => {
271
+ setSelectedImageIds(/* @__PURE__ */ new Set());
272
+ },
273
+ onDeleteSuccess: (deletedIds) => {
274
+ setSelectedImageIds(/* @__PURE__ */ new Set());
275
+ if (currentThumbnailId && deletedIds.includes(currentThumbnailId)) {
276
+ setCurrentThumbnailId(null);
277
+ }
278
+ }
279
+ });
280
+ const isSaving = createImagesMutation.isPending || updateImagesMutation.isPending || deleteImagesMutation.isPending;
281
+ const resetModalState = () => {
282
+ setUploadedFiles([]);
283
+ setSelectedImageIds(/* @__PURE__ */ new Set());
284
+ setCurrentThumbnailId(null);
285
+ setImagesToDelete(/* @__PURE__ */ new Set());
286
+ };
287
+ const initializeThumbnail = () => {
288
+ const thumbnailImage = existingImages.find((img) => img.type === "thumbnail");
289
+ if (thumbnailImage == null ? void 0 : thumbnailImage.id) {
290
+ setCurrentThumbnailId(thumbnailImage.id);
291
+ }
292
+ };
293
+ const handleOpenChange = (isOpen) => {
294
+ setOpen(isOpen);
295
+ if (isOpen) {
296
+ initializeThumbnail();
297
+ } else {
298
+ resetModalState();
299
+ }
300
+ };
301
+ const handleUploadFile = (files) => {
302
+ if (!files || files.length === 0) return;
303
+ const filesArray = Array.from(files);
304
+ uploadFilesMutation.mutate(filesArray, {
305
+ onSuccess: (data) => {
306
+ setUploadedFiles((prev) => [...prev, ...data.files]);
307
+ }
308
+ });
309
+ if (fileInputRef.current) {
310
+ fileInputRef.current.value = "";
311
+ }
312
+ };
313
+ const handleImageSelection = (id, isUploaded = false) => {
314
+ const itemId = isUploaded ? `uploaded:${id}` : id;
315
+ const newSelected = new Set(selectedImageIds);
316
+ if (newSelected.has(itemId)) {
317
+ newSelected.delete(itemId);
318
+ } else {
319
+ newSelected.add(itemId);
320
+ }
321
+ setSelectedImageIds(newSelected);
322
+ };
323
+ const handleSetAsThumbnail = () => {
324
+ if (selectedImageIds.size !== 1) return;
325
+ const selectedId = Array.from(selectedImageIds)[0];
326
+ setCurrentThumbnailId(selectedId);
327
+ if (selectedId.startsWith("uploaded:")) {
328
+ const uploadedFileId = selectedId.replace("uploaded:", "");
329
+ setUploadedFiles(
330
+ (prev) => prev.map((file) => file.id === uploadedFileId ? { ...file, type: "thumbnail" } : file)
331
+ );
332
+ }
333
+ setSelectedImageIds(/* @__PURE__ */ new Set());
334
+ };
335
+ const handleDelete = () => {
336
+ if (selectedImageIds.size === 0) return;
337
+ const uploadedFileIds = [];
338
+ const savedImageIds = [];
339
+ selectedImageIds.forEach((id) => {
340
+ if (id.startsWith("uploaded:")) {
341
+ uploadedFileIds.push(id.replace("uploaded:", ""));
342
+ } else {
343
+ savedImageIds.push(id);
344
+ }
345
+ });
346
+ if (uploadedFileIds.length > 0) {
347
+ setUploadedFiles(
348
+ (prev) => prev.filter((file) => !uploadedFileIds.includes(file.id))
349
+ );
350
+ if (currentThumbnailId == null ? void 0 : currentThumbnailId.startsWith("uploaded:")) {
351
+ const thumbnailFileId = currentThumbnailId.replace("uploaded:", "");
352
+ if (uploadedFileIds.includes(thumbnailFileId)) {
353
+ setCurrentThumbnailId(null);
354
+ }
355
+ }
356
+ }
357
+ if (savedImageIds.length > 0) {
358
+ setImagesToDelete((prev) => {
359
+ const newSet = new Set(prev);
360
+ savedImageIds.forEach((id) => newSet.add(id));
361
+ return newSet;
362
+ });
363
+ if (currentThumbnailId && savedImageIds.includes(currentThumbnailId)) {
364
+ setCurrentThumbnailId(null);
365
+ }
366
+ }
367
+ setSelectedImageIds(/* @__PURE__ */ new Set());
368
+ };
369
+ const handleSave = async () => {
370
+ const hasNewImages = uploadedFiles.length > 0;
371
+ const hasImagesToDelete = imagesToDelete.size > 0;
372
+ const initialThumbnail = existingImages.find((img) => img.type === "thumbnail");
373
+ const thumbnailChanged = currentThumbnailId && !currentThumbnailId.startsWith("uploaded:") && currentThumbnailId !== (initialThumbnail == null ? void 0 : initialThumbnail.id);
374
+ if (!hasNewImages && !hasImagesToDelete && !thumbnailChanged) {
375
+ setOpen(false);
376
+ return;
377
+ }
378
+ try {
379
+ const operations = [];
380
+ if (hasNewImages) {
381
+ const imagesToCreate = uploadedFiles.map((file) => ({
382
+ url: file.url,
383
+ file_id: file.id,
384
+ type: file.type || (currentThumbnailId === `uploaded:${file.id}` ? "thumbnail" : "image")
385
+ }));
386
+ operations.push(createImagesMutation.mutateAsync(imagesToCreate));
387
+ }
388
+ if (thumbnailChanged) {
389
+ const updates = [
390
+ {
391
+ id: currentThumbnailId,
392
+ type: "thumbnail"
393
+ }
394
+ ];
395
+ operations.push(updateImagesMutation.mutateAsync(updates));
396
+ }
397
+ if (hasImagesToDelete) {
398
+ const idsToDelete = Array.from(imagesToDelete);
399
+ operations.push(deleteImagesMutation.mutateAsync(idsToDelete));
400
+ }
401
+ await Promise.all(operations);
402
+ queryClient.invalidateQueries({ queryKey: ["category-images", categoryId] });
403
+ setOpen(false);
404
+ resetModalState();
405
+ ui.toast.success("Category media saved successfully");
406
+ } catch (error) {
407
+ ui.toast.error("Failed to save changes");
408
+ }
409
+ };
410
+ return /* @__PURE__ */ jsxRuntime.jsxs(ui.FocusModal, { open, onOpenChange: handleOpenChange, children: [
411
+ /* @__PURE__ */ jsxRuntime.jsx(ui.FocusModal.Trigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", variant: "secondary", children: "Edit" }) }),
412
+ /* @__PURE__ */ jsxRuntime.jsxs(ui.FocusModal.Content, { children: [
413
+ /* @__PURE__ */ jsxRuntime.jsx(ui.FocusModal.Header, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { children: "Edit Media" }) }),
414
+ /* @__PURE__ */ jsxRuntime.jsxs(ui.FocusModal.Body, { className: "flex h-full overflow-hidden", children: [
415
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex w-full h-full flex-col-reverse lg:grid lg:grid-cols-[1fr_560px]", children: [
416
+ /* @__PURE__ */ jsxRuntime.jsx(
417
+ CategoryImageGallery,
418
+ {
419
+ existingImages,
420
+ uploadedFiles,
421
+ imagesToDelete,
422
+ currentThumbnailId,
423
+ selectedImageIds,
424
+ onToggleSelect: handleImageSelection
425
+ }
426
+ ),
427
+ /* @__PURE__ */ jsxRuntime.jsx(
428
+ CategoryImageUpload,
429
+ {
430
+ fileInputRef,
431
+ isUploading: uploadFilesMutation.isPending,
432
+ onFileSelect: handleUploadFile
433
+ }
434
+ )
435
+ ] }),
436
+ /* @__PURE__ */ jsxRuntime.jsx(ui.CommandBar, { open: selectedImageIds.size > 0, children: /* @__PURE__ */ jsxRuntime.jsxs(ui.CommandBar.Bar, { children: [
437
+ /* @__PURE__ */ jsxRuntime.jsxs(ui.CommandBar.Value, { children: [
438
+ selectedImageIds.size,
439
+ " selected"
440
+ ] }),
441
+ /* @__PURE__ */ jsxRuntime.jsx(ui.CommandBar.Seperator, {}),
442
+ /* @__PURE__ */ jsxRuntime.jsx(
443
+ ui.CommandBar.Command,
444
+ {
445
+ action: handleSetAsThumbnail,
446
+ label: "Set as thumbnail",
447
+ shortcut: "t",
448
+ disabled: selectedImageIds.size !== 1
449
+ }
450
+ ),
451
+ /* @__PURE__ */ jsxRuntime.jsx(ui.CommandBar.Seperator, {}),
452
+ /* @__PURE__ */ jsxRuntime.jsx(
453
+ ui.CommandBar.Command,
454
+ {
455
+ action: handleDelete,
456
+ label: "Delete",
457
+ shortcut: "d"
458
+ }
459
+ )
460
+ ] }) })
461
+ ] }),
462
+ /* @__PURE__ */ jsxRuntime.jsx(ui.FocusModal.Footer, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-end gap-x-2", children: [
463
+ /* @__PURE__ */ jsxRuntime.jsx(ui.FocusModal.Close, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", variant: "secondary", children: "Cancel" }) }),
464
+ /* @__PURE__ */ jsxRuntime.jsx(
465
+ ui.Button,
466
+ {
467
+ size: "small",
468
+ onClick: handleSave,
469
+ isLoading: isSaving,
470
+ children: "Save"
471
+ }
472
+ )
473
+ ] }) })
474
+ ] })
475
+ ] });
476
+ };
477
+ const CategoryMediaWidget = ({ data }) => {
478
+ const { data: response, isLoading } = reactQuery.useQuery({
479
+ queryKey: ["category-images", data.id],
480
+ queryFn: async () => {
481
+ const result = await sdk.client.fetch(
482
+ `/admin/categories/${data.id}/images`
483
+ );
484
+ return result;
485
+ }
486
+ });
487
+ const images = (response == null ? void 0 : response.category_images) || [];
488
+ return /* @__PURE__ */ jsxRuntime.jsxs(ui.Container, { className: "divide-y p-0", children: [
489
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between px-6 py-4", children: [
490
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h2", children: "Media" }),
491
+ /* @__PURE__ */ jsxRuntime.jsx(CategoryMediaModal, { categoryId: data.id, existingImages: images })
492
+ ] }),
493
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-6 py-4", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-[repeat(auto-fill,96px)] gap-4", children: [
494
+ isLoading && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "col-span-full", children: /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-ui-fg-subtle text-sm", children: "Loading..." }) }),
495
+ !isLoading && images.length === 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "col-span-full", children: /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-ui-fg-subtle text-sm", children: "No images added yet" }) }),
496
+ images.map((image) => /* @__PURE__ */ jsxRuntime.jsxs(
497
+ "div",
498
+ {
499
+ className: "relative aspect-square overflow-hidden rounded-lg border border-ui-border-base bg-ui-bg-subtle",
500
+ children: [
501
+ /* @__PURE__ */ jsxRuntime.jsx(
502
+ "img",
503
+ {
504
+ src: image.url,
505
+ alt: `Category ${image.type}`,
506
+ className: "h-full w-full object-cover"
507
+ }
508
+ ),
509
+ image.type === "thumbnail" && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute top-2 left-2", children: /* @__PURE__ */ jsxRuntime.jsx(icons.ThumbnailBadge, {}) })
510
+ ]
511
+ },
512
+ image.id
513
+ ))
514
+ ] }) })
515
+ ] });
516
+ };
517
+ adminSdk.defineWidgetConfig({
518
+ zone: "product_category.details.after"
519
+ });
520
+ const widgetModule = { widgets: [
521
+ {
522
+ Component: CategoryMediaWidget,
523
+ zone: ["product_category.details.after"]
524
+ }
525
+ ] };
526
+ const routeModule = {
527
+ routes: []
528
+ };
529
+ const menuItemModule = {
530
+ menuItems: []
531
+ };
532
+ const formModule = { customFields: {} };
533
+ const displayModule = {
534
+ displays: {}
535
+ };
536
+ const i18nModule = { resources: {} };
537
+ const plugin = {
538
+ widgetModule,
539
+ routeModule,
540
+ menuItemModule,
541
+ formModule,
542
+ displayModule,
543
+ i18nModule
544
+ };
545
+ module.exports = plugin;