UNPKG

@alphabite/medusa-reviews

Version:

Alphabite's Medusa Reviews Plugin

176 lines (175 loc) 5.28 kB
"use strict"; const jsxRuntime = require("react/jsx-runtime"); const adminSdk = require("@medusajs/admin-sdk"); const icons = require("@medusajs/icons"); const ui = require("@medusajs/ui"); const reactQuery = require("@tanstack/react-query"); const react = require("react"); const Medusa = require("@medusajs/js-sdk"); const reactRouterDom = require("react-router-dom"); const _interopDefault = (e) => e && e.__esModule ? e : { default: e }; const Medusa__default = /* @__PURE__ */ _interopDefault(Medusa); const sdk = new Medusa__default.default({ baseUrl: "http://localhost:9000", debug: process.env.NODE_ENV === "development", auth: { type: "session" } }); const columnHelper = ui.createDataTableColumnHelper(); const columns = [ columnHelper.select(), columnHelper.accessor("id", { header: "ID" }), columnHelper.accessor("title", { header: "Title" }), columnHelper.accessor("rating", { header: "Rating" }), columnHelper.accessor("content", { header: "Content" }), columnHelper.accessor("status", { header: "Status", cell: ({ row }) => { const color = row.original.status === "approved" ? "green" : row.original.status === "rejected" ? "red" : "grey"; return /* @__PURE__ */ jsxRuntime.jsx(ui.StatusBadge, { color, children: row.original.status.charAt(0).toUpperCase() + row.original.status.slice(1) }); } }), columnHelper.accessor("product", { header: "Product", cell: ({ row }) => { var _a; return /* @__PURE__ */ jsxRuntime.jsx(reactRouterDom.Link, { to: `/products/${row.original.product_id}`, children: (_a = row.original.product) == null ? void 0 : _a.title }); } }) ]; const commandHelper = ui.createDataTableCommandHelper(); const useCommands = (refetch) => { return [ commandHelper.command({ label: "Approve", shortcut: "A", action: async (selection) => { const reviewsToApproveIds = Object.keys(selection); sdk.client.fetch("/admin/reviews/status", { method: "POST", body: { ids: reviewsToApproveIds, status: "approved" } }).then(() => { ui.toast.success("Reviews approved"); refetch(); }).catch(() => { ui.toast.error("Failed to approve reviews"); }); } }), commandHelper.command({ label: "Reject", shortcut: "R", action: async (selection) => { const reviewsToRejectIds = Object.keys(selection); sdk.client.fetch("/admin/reviews/status", { method: "POST", body: { ids: reviewsToRejectIds, status: "rejected" } }).then(() => { ui.toast.success("Reviews rejected"); refetch(); }).catch(() => { ui.toast.error("Failed to reject reviews"); }); } }) ]; }; const limit = 15; const ReviewsPage = () => { const [rowSelection, setRowSelection] = react.useState( {} ); const [pagination, setPagination] = react.useState({ pageSize: limit, pageIndex: 0 }); const offset = react.useMemo(() => { return pagination.pageIndex * limit; }, [pagination]); const { data, isLoading, refetch } = reactQuery.useQuery({ queryKey: ["reviews", offset, limit], queryFn: () => sdk.client.fetch("/admin/reviews", { query: { offset: pagination.pageIndex * pagination.pageSize, limit: pagination.pageSize, order: "-created_at" } }) }); const commands = useCommands(refetch); const table = ui.useDataTable({ commands, rowSelection: { state: rowSelection, onRowSelectionChange: setRowSelection }, columns, data: (data == null ? void 0 : data.reviews) || [], rowCount: (data == null ? void 0 : data.count) || 0, isLoading, pagination: { state: pagination, onPaginationChange: setPagination }, getRowId: (row) => row.id }); return /* @__PURE__ */ jsxRuntime.jsxs(ui.Container, { children: [ /* @__PURE__ */ jsxRuntime.jsxs(ui.DataTable, { instance: table, children: [ /* @__PURE__ */ jsxRuntime.jsx(ui.DataTable.CommandBar, { selectedLabel: (count) => `${count} selected` }), /* @__PURE__ */ jsxRuntime.jsx(ui.DataTable.Toolbar, { className: "flex flex-col items-start justify-between gap-2 md:flex-row md:items-center", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { children: "Reviews" }) }), /* @__PURE__ */ jsxRuntime.jsx(ui.DataTable.Table, {}), /* @__PURE__ */ jsxRuntime.jsx(ui.DataTable.Pagination, {}) ] }), /* @__PURE__ */ jsxRuntime.jsx(ui.Toaster, {}) ] }); }; const config = adminSdk.defineRouteConfig({ label: "Reviews", icon: icons.ChatBubbleLeftRight }); const widgetModule = { widgets: [] }; const routeModule = { routes: [ { Component: ReviewsPage, path: "/reviews" } ] }; const menuItemModule = { menuItems: [ { label: config.label, icon: config.icon, path: "/reviews", nested: void 0 } ] }; const formModule = { customFields: {} }; const displayModule = { displays: {} }; const plugin = { widgetModule, routeModule, menuItemModule, formModule, displayModule }; module.exports = plugin;