UNPKG

medusa-plugin-abandoned-cart

Version:
312 lines (303 loc) 12.3 kB
import { jsx, Fragment, jsxs } from 'react/jsx-runtime'; import { InformationCircleSolid, CircleStack } from '@medusajs/icons'; import { Table, Container, Toaster, Tooltip, Button, toast } from '@medusajs/ui'; import { useAdminCustomQuery, useAdminCustomPost } from 'medusa-react'; import React, { createElement } from 'react'; import { AreaChart, XAxis, YAxis, CartesianGrid, Tooltip as Tooltip$1, Area } from 'recharts'; function _extends() { _extends = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); } function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; } var _excluded = ["cdnSuffix", "cdnUrl", "countryCode", "style", "svg"]; var DEFAULT_CDN_URL = 'https://cdn.jsdelivr.net/gh/lipis/flag-icons/flags/4x3/'; var DEFAULT_CDN_SUFFIX = 'svg'; // offset between uppercase ascii and regional indicator symbols var OFFSET = 127397; var ReactCountryFlag = function ReactCountryFlag(_ref) { var _ref$cdnSuffix = _ref.cdnSuffix, cdnSuffix = _ref$cdnSuffix === void 0 ? DEFAULT_CDN_SUFFIX : _ref$cdnSuffix, _ref$cdnUrl = _ref.cdnUrl, cdnUrl = _ref$cdnUrl === void 0 ? DEFAULT_CDN_URL : _ref$cdnUrl, countryCode = _ref.countryCode, style = _ref.style, _ref$svg = _ref.svg, svg = _ref$svg === void 0 ? false : _ref$svg, props = _objectWithoutPropertiesLoose(_ref, _excluded); if (typeof countryCode !== 'string') { return null; } if (svg) { var flagUrl = "" + cdnUrl + countryCode.toLowerCase() + "." + cdnSuffix; return createElement("img", Object.assign({}, props, { src: flagUrl, style: _extends({ display: 'inline-block', width: '1em', height: '1em', verticalAlign: 'middle' }, style) })); } var emoji = countryCode.toUpperCase().replace(/./g, function (_char) { return String.fromCodePoint(_char.charCodeAt(0) + OFFSET); }); return createElement("span", Object.assign({ role: "img" }, props, { style: _extends({ display: 'inline-block', fontSize: '1em', lineHeight: '1em', verticalAlign: 'middle' }, style) }), emoji); }; const repeat = (times) => { return Array.from(Array(times).keys()); }; const LineLoading = () => { return /* @__PURE__ */ jsx(Fragment, { children: repeat(15).map((_, i) => /* @__PURE__ */ jsxs( Table.Row, { className: "animate-pulse bg-gray-100 p-4 [&_td:last-child]:w-[1%] [&_td:last-child]:whitespace-nowrap ", children: [ /* @__PURE__ */ jsx(Table.Cell, {}), /* @__PURE__ */ jsx(Table.Cell, {}), /* @__PURE__ */ jsx(Table.Cell, {}), /* @__PURE__ */ jsx(Table.Cell, {}), /* @__PURE__ */ jsx(Table.Cell, {}), /* @__PURE__ */ jsx(Table.Cell, { className: "text-right" }), /* @__PURE__ */ jsx(Table.Cell, { className: "text-ui-fg-muted" }), /* @__PURE__ */ jsx(Table.Cell, {}), /* @__PURE__ */ jsx(Table.Cell, {}), /* @__PURE__ */ jsx(Table.Cell, {}) ] }, i )) }); }; const AbandonedCarts = () => { var _a; const [pageSize] = React.useState(15); const [size, setSize] = React.useState(0); const [currentPage, setCurrentPage] = React.useState(0); const { data, isLoading, refetch } = useAdminCustomQuery("/abandoned-cart", [], { take: pageSize, skip: pageSize * currentPage, dateLimit: 50 }); React.useEffect(() => { if (data && (data == null ? void 0 : data.count) !== size && data.count !== void 0) { setSize(data == null ? void 0 : data.count); } }, [data == null ? void 0 : data.count]); const { mutate, isLoading: PostLoading } = useAdminCustomPost("/abandoned-cart", []); const canPreviousPage = currentPage > 0; const canNextPage = currentPage < Math.round(((_a = data == null ? void 0 : data.count) != null ? _a : 0) / pageSize) - 1; const previousPage = () => { setCurrentPage(currentPage - 1); }; const nextPage = () => { setCurrentPage(currentPage + 1); }; const handleAction = (id) => { mutate( { id }, { onSuccess: (data2) => { console.log(data2); toast.info("Email sent"); refetch(); }, onError: (error) => { console.log(error); console.log(error.message); toast.error("Error sending email"); } } ); }; return /* @__PURE__ */ jsxs(Container, { className: "text-ui-fg-subtle px-0 pt-0 pb-4", children: [ /* @__PURE__ */ jsx(Toaster, {}), /* @__PURE__ */ jsx("div", { className: "flex justify-between items-center p-5", children: /* @__PURE__ */ jsx("h2", { className: "text-lg font-bold", children: "Abandoned Carts" }) }), /* @__PURE__ */ jsxs("div", { className: "flex gap-1 flex-col", children: [ /* @__PURE__ */ jsxs(Table, { children: [ /* @__PURE__ */ jsx(Table.Header, { children: /* @__PURE__ */ jsxs(Table.Row, { children: [ /* @__PURE__ */ jsx(Table.HeaderCell, { children: "Name" }), /* @__PURE__ */ jsx(Table.HeaderCell, { children: "Email" }), /* @__PURE__ */ jsx(Table.HeaderCell, { children: "Qty" }), /* @__PURE__ */ jsx(Table.HeaderCell, { children: "Region" }), /* @__PURE__ */ jsx(Table.HeaderCell, { children: "Date" }), /* @__PURE__ */ jsx(Table.HeaderCell, { className: "text-right", children: "Amount" }), /* @__PURE__ */ jsx(Table.HeaderCell, {}), /* @__PURE__ */ jsx(Table.HeaderCell, { children: "Date Sent" }), /* @__PURE__ */ jsx(Table.HeaderCell, { children: "Count" }), /* @__PURE__ */ jsx(Table.HeaderCell, {}) ] }) }), /* @__PURE__ */ jsx(Table.Body, { children: !isLoading && data ? data.carts.map((cart) => { var _a2, _b; return /* @__PURE__ */ jsxs( Table.Row, { className: "[&_td:last-child]:w-[1%] [&_td:last-child]:whitespace-nowrap", children: [ /* @__PURE__ */ jsx(Table.Cell, { children: (cart == null ? void 0 : cart.first_name) + " " + (cart == null ? void 0 : cart.last_name) }), /* @__PURE__ */ jsx(Table.Cell, { children: cart == null ? void 0 : cart.email }), /* @__PURE__ */ jsx( Table.Cell, { "aria-label": (_a2 = cart == null ? void 0 : cart.items) == null ? void 0 : _a2.map((item) => { return item.title + " x" + item.quantity + " "; }).join(","), children: /* @__PURE__ */ jsx( Tooltip, { content: (_b = cart == null ? void 0 : cart.items) == null ? void 0 : _b.map((item) => { return item.title + " x" + item.quantity + " "; }).join(" | \n"), children: /* @__PURE__ */ jsxs("div", { className: "flex", children: [ cart.items.length, /* @__PURE__ */ jsx(InformationCircleSolid, {}) ] }) } ) } ), /* @__PURE__ */ jsx(Table.Cell, { children: cart == null ? void 0 : cart.region_name }), /* @__PURE__ */ jsx(Table.Cell, { children: new Date(cart.created_at).toLocaleDateString() }), /* @__PURE__ */ jsx(Table.Cell, { className: "text-right", children: (cart == null ? void 0 : cart.currency) ? new Intl.NumberFormat("en-US", { style: "currency", currency: (cart == null ? void 0 : cart.currency) || "USD" }).format((cart == null ? void 0 : cart.totalPrice) / 100) : cart == null ? void 0 : cart.totalPrice }), /* @__PURE__ */ jsx(Table.Cell, { className: "text-ui-fg-muted", children: /* @__PURE__ */ jsx( ReactCountryFlag, { countryCode: cart.country_code, style: { fontSize: "1.5em", lineHeight: "1.5em" }, title: cart == null ? void 0 : cart.country_code, "aria-label": cart == null ? void 0 : cart.country_code } ) }), /* @__PURE__ */ jsx(Table.Cell, { children: (cart == null ? void 0 : cart.abandoned_count) ? new Date( cart == null ? void 0 : cart.abandoned_lastdate ).toLocaleDateString() : "Not Sent" }), /* @__PURE__ */ jsx(Table.Cell, { children: (cart == null ? void 0 : cart.abandoned_count) ? cart == null ? void 0 : cart.abandoned_count : 0 }), /* @__PURE__ */ jsx(Table.Cell, { children: /* @__PURE__ */ jsx( Button, { disabled: PostLoading, variant: "transparent", onClick: () => { handleAction(cart == null ? void 0 : cart.id); }, children: "Send Email" } ) }) ] }, cart == null ? void 0 : cart.id ); }) : /* @__PURE__ */ jsx(LineLoading, {}) }) ] }), /* @__PURE__ */ jsx( Table.Pagination, { count: size, pageSize, pageIndex: currentPage, pageCount: Math.round(size / pageSize), canPreviousPage, canNextPage, previousPage, nextPage } ) ] }) ] }); }; const CustomPage = () => { const { data, isLoading, refetch } = useAdminCustomQuery("/abandoned-cart", [], { take: 15, skip: 15 * 1, dateLimit: 50 }); return /* @__PURE__ */ jsxs("div", { children: [ /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsxs( AreaChart, { width: 730, height: 250, data: data == null ? void 0 : data.carts, margin: { top: 10, right: 30, left: 0, bottom: 0 }, children: [ /* @__PURE__ */ jsxs("defs", { children: [ /* @__PURE__ */ jsxs("linearGradient", { id: "colorUv", x1: "0", y1: "0", x2: "0", y2: "1", children: [ /* @__PURE__ */ jsx("stop", { offset: "5%", stopColor: "#8884d8", stopOpacity: 0.8 }), /* @__PURE__ */ jsx("stop", { offset: "95%", stopColor: "#8884d8", stopOpacity: 0 }) ] }), /* @__PURE__ */ jsxs("linearGradient", { id: "colorPv", x1: "0", y1: "0", x2: "0", y2: "1", children: [ /* @__PURE__ */ jsx("stop", { offset: "5%", stopColor: "#82ca9d", stopOpacity: 0.8 }), /* @__PURE__ */ jsx("stop", { offset: "95%", stopColor: "#82ca9d", stopOpacity: 0 }) ] }) ] }), /* @__PURE__ */ jsx(XAxis, { dataKey: "created_at" }), /* @__PURE__ */ jsx(YAxis, {}), /* @__PURE__ */ jsx(CartesianGrid, { strokeDasharray: "3 3" }), /* @__PURE__ */ jsx(Tooltip$1, {}), /* @__PURE__ */ jsx( Area, { type: "monotone", dataKey: "totalPrice", stroke: "#8884d8", fillOpacity: 1, fill: "url(#colorUv)" } ) ] } ) }), /* @__PURE__ */ jsx(AbandonedCarts, {}) ] }); }; const config = { link: { label: "Abandoned Carts", icon: CircleStack } }; const entry = { identifier: "medusa-plugin-abandoned-cart", extensions: [ { Component: CustomPage, config: { path: "/abandoned-carts", type: "route", ...config } } ], }; export { entry as default };