UNPKG

medusa-variant-images-updated

Version:
183 lines (182 loc) 9.46 kB
import { jsxs, Fragment, jsx } from "react/jsx-runtime"; import { useState, useEffect } from "react"; import { Toaster, Heading, Tooltip, Button, clx, DropdownMenu, Table, toast } from "@medusajs/ui"; import { ArrowPath, EllipsisHorizontal, PencilSquare, ThumbnailBadge } from "@medusajs/icons"; import VariantsImagesModal from "../VariantImages/VariantsImagesModal.js"; import { defineWidgetConfig } from "@medusajs/admin-sdk"; /* empty css */ import WidgetSettingsModal from "../VariantImages/WidgetSettingsModal.js"; import { fetchBackend, paginationInformation } from "../VariantImages/utils/util.js"; import { omit } from "lodash-es"; import { useTimer } from "../VariantImages/hooks/useTimer.js"; const VariantsImagesWidget = ({ data }) => { var _a; const [openedVariant, setOpenedVariant] = useState(null); const [openedDialogType, setOpenedDialogType] = useState(null); const [settings, setSettings] = useState({ baseOptionUpload: { enabled: false } }); const [options, setOptions] = useState(); const [product, setProduct] = useState(data); const [variantImagesMap, setVariantImagesMap] = useState({}); const [variantThumbnails, setVariantThumbnails] = useState({}); const updateData = async ({ variants = false, options: options2 = false, product: _product = false }) => { if (variants) { await fetchBackend(`/admin/products/${product.id}/variants?order=title&limit=500`).then((res) => { if (!res) return; setProduct((prevProd) => ({ ...prevProd, variants: res.variants })); }); } if (options2) { await fetchBackend(`/admin/products/${product.id}/options`).then((res) => { if (!res) return; setOptions(res.product_options); }); } if (_product) { await fetchBackend(`/admin/products/${product.id}?fields=-variants`).then((res) => { if (!res) return; setProduct((prevProd) => ({ ...prevProd, ...res.product })); }); } }; const { fetching, timeLeft, restart } = useTimer({ length: 6e4, onComplete: async () => await updateData({ options: true, product: true, variants: true }), recursive: true }); useEffect(() => { updateData({ options: true, variants: true }); fetchBackend(`/admin/variant-images-settings/${product.id}`).then((res) => { if (!res) return; setSettings((_current) => ({ ..._current, baseOptionUpload: { enabled: res.base_option_enabled, option: res.base_option_id || void 0 } })); }); }, []); useEffect(() => { const fetchAllVariantImages = async () => { if (!product.variants) return; const newImagesMap = {}; const newThumbnails = {}; await Promise.all( product.variants.map(async (variant) => { const res = await fetch(`/admin/variant-images?variant_id=${variant.id}`); const result = await res.json(); const images = result.data || []; newImagesMap[variant.id] = images; const thumbnail = images.find((img) => img.type === "thumbnail"); if (thumbnail) newThumbnails[variant.id] = thumbnail.url; }) ); setVariantImagesMap(newImagesMap); setVariantThumbnails(newThumbnails); }; fetchAllVariantImages(); }, [product.variants]); const handleClose = (_product) => { setOpenedVariant(null); setOpenedDialogType(null); if (_product) setProduct(_product); }; const paginationOptions = paginationInformation(product.variants); const { currentVariants } = paginationOptions; return /* @__PURE__ */ jsxs(Fragment, { children: [ /* @__PURE__ */ jsx(Toaster, {}), /* @__PURE__ */ jsxs("div", { className: "divide-y shadow-elevation-card-rest bg-ui-bg-base w-full rounded-lg divide-y p-0", children: [ /* @__PURE__ */ jsxs("div", { className: "flex flex-row justify-between items-center px-6 py-4", children: [ /* @__PURE__ */ jsx(Heading, { level: "h1", className: "flex items-center justify-between gap-x-4 ", children: /* @__PURE__ */ jsx("div", { children: "Variants Images" }) }), /* @__PURE__ */ jsxs("div", { className: "flex flex-row gap-x-4", children: [ /* @__PURE__ */ jsx(Tooltip, { content: "Refresh", children: /* @__PURE__ */ jsxs(Button, { variant: "transparent", onClick: () => restart(), className: "h-7 p-1 flex flex-row gap-x-2 text-ui-fg-subtle", children: [ /* @__PURE__ */ jsx(ArrowPath, { className: clx(fetching && "animate-spin") }), " ", /* @__PURE__ */ jsx("span", { className: "text-xs w-4", children: timeLeft }) ] }) }), /* @__PURE__ */ jsx(WidgetSettingsModal, { settings, setSettings, product, options }) ] }) ] }), /* @__PURE__ */ jsx("div", { className: "grid grid-cols-[repeat(auto-fill,minmax(225px,1fr))] gap-3 px-6 py-4", children: currentVariants == null ? void 0 : currentVariants.map((variant) => { const variantImages = variantImagesMap[variant.id] || []; const variantThumbnail = variantThumbnails[variant.id]; return /* @__PURE__ */ jsxs("div", { className: "w-full p-3 bg-[rgba(45,45,49,1)] rounded-md flex flex-col", children: [ /* @__PURE__ */ jsxs("div", { className: "flex items-center mb-3 bg-ui-bg-base rounded-full text-center relative py-[1.5px]", children: [ /* @__PURE__ */ jsx("div", { className: "inter-base-semibold flex-1", children: variant.title }), /* @__PURE__ */ jsxs(DropdownMenu, { children: [ /* @__PURE__ */ jsx(DropdownMenu.Trigger, { asChild: true, children: /* @__PURE__ */ jsx(Button, { variant: "transparent", className: "rounded-full absolute right-0 top-0", children: /* @__PURE__ */ jsx(EllipsisHorizontal, {}) }) }), /* @__PURE__ */ jsxs(DropdownMenu.Content, { children: [ /* @__PURE__ */ jsxs( DropdownMenu.Item, { onClick: () => { setOpenedVariant(variant); setOpenedDialogType("thumbnail"); }, className: "gap-x-2", children: [ /* @__PURE__ */ jsx(PencilSquare, { className: "text-ui-fg-subtle" }), "Edit Thumbnail" ] } ), /* @__PURE__ */ jsxs( DropdownMenu.Item, { onClick: () => { setOpenedVariant(variant); setOpenedDialogType("media"); }, className: "gap-x-2", children: [ /* @__PURE__ */ jsx(PencilSquare, { className: "text-ui-fg-subtle" }), "Edit Media" ] } ) ] }) ] }) ] }), /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 grid-rows-2 items-center gap-3 h-full w-full", children: [ variantThumbnail ? /* @__PURE__ */ jsxs("div", { className: "relative w-full h-full", children: [ /* @__PURE__ */ jsx("img", { src: variantThumbnail, alt: "Thumbnail", className: "object-cover bg-clip-border w-full h-full rounded-md aspect-square" }), /* @__PURE__ */ jsx(Tooltip, { content: "Thumbnail", children: /* @__PURE__ */ jsx(ThumbnailBadge, { className: "absolute top-2 left-2" }) }) ] }) : /* @__PURE__ */ jsx("div", { className: "w-full h-full aspect-square break-words text-ui-fg-muted text-[14px] text-center border rounded-md border-ui-border-strong border-dashed p-[15%] flex justify-center items-center", children: "No thumbnail" }), (variantImages == null ? void 0 : variantImages.length) ? variantImages.filter((img) => img.type === "media").slice(0, 3).map((image, i) => /* @__PURE__ */ jsx("div", { className: "w-full h-full relative", children: /* @__PURE__ */ jsx("img", { src: image.url, alt: "Uploaded image", className: "object-cover aspect-square w-full h-full bg-clip-border rounded-md" }) }, i)) : Array.from({ length: 3 }).map((_, i) => /* @__PURE__ */ jsx( "div", { className: "w-full h-full aspect-square break-words text-ui-fg-muted text-[14px] text-center border rounded-md border-ui-border-strong border-dashed p-[20%] flex justify-center items-center", children: "No images" }, i )) ] }) ] }, variant.id); }) }), /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsx(Table.Pagination, { count: ((_a = product.variants) == null ? void 0 : _a.length) || 0, ...omit(paginationOptions, "currentVariants") }) }) ] }), openedDialogType && /* @__PURE__ */ jsx( VariantsImagesModal, { product, variant: openedVariant, open: !!openedVariant, onClose: handleClose, type: openedDialogType, settings, notify: toast } ) ] }); }; const Image = ({ image }) => /* @__PURE__ */ jsx("img", { src: image.url, alt: "Uploaded image", className: "object-cover aspect-square w-full h-full bg-clip-border rounded-md" }); const config = defineWidgetConfig({ zone: "product.details.after" }); export { Image, config, VariantsImagesWidget as default };