@lodashventure/medusa-review 1.4.18 → 1.4.20

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.
@@ -1,18 +1,216 @@
1
1
  "use strict";
2
2
  const jsxRuntime = require("react/jsx-runtime");
3
+ const react = require("react");
3
4
  const adminSdk = require("@medusajs/admin-sdk");
4
- const icons = require("@medusajs/icons");
5
5
  const ui = require("@medusajs/ui");
6
+ const icons = require("@medusajs/icons");
6
7
  const axios = require("axios");
7
- const Mentions = require("rc-mentions");
8
- const react = require("react");
9
8
  const reactRouterDom = require("react-router-dom");
9
+ const Mentions = require("rc-mentions");
10
10
  const Medusa = require("@medusajs/js-sdk");
11
11
  require("@medusajs/admin-shared");
12
12
  const _interopDefault = (e) => e && e.__esModule ? e : { default: e };
13
13
  const axios__default = /* @__PURE__ */ _interopDefault(axios);
14
14
  const Mentions__default = /* @__PURE__ */ _interopDefault(Mentions);
15
15
  const Medusa__default = /* @__PURE__ */ _interopDefault(Medusa);
16
+ const ProductReviewWidget = ({ data }) => {
17
+ const [reviews, setReviews] = react.useState([]);
18
+ const [isLoading, setIsLoading] = react.useState(true);
19
+ const [error, setError] = react.useState(null);
20
+ const [stats, setStats] = react.useState({
21
+ total: 0,
22
+ average: 0,
23
+ pending: 0,
24
+ approved: 0,
25
+ rejected: 0
26
+ });
27
+ const fetchReviews = async () => {
28
+ setIsLoading(true);
29
+ setError(null);
30
+ try {
31
+ const { data: response } = await axios__default.default.get(
32
+ `/admin/reviews`,
33
+ {
34
+ params: {
35
+ product_id: data.id,
36
+ limit: 5,
37
+ offset: 0,
38
+ order: "-created_at",
39
+ fields: "id,title,content,rating,status,created_at,first_name,last_name,is_admin"
40
+ }
41
+ }
42
+ );
43
+ setReviews(response.reviews);
44
+ const total = response.count || response.reviews.length;
45
+ const average = response.reviews.length > 0 ? response.reviews.reduce((sum, r) => sum + r.rating, 0) / response.reviews.length : 0;
46
+ const pending = response.reviews.filter(
47
+ (r) => r.status === "pending"
48
+ ).length;
49
+ const approved = response.reviews.filter(
50
+ (r) => r.status === "approved"
51
+ ).length;
52
+ const rejected = response.reviews.filter(
53
+ (r) => r.status === "rejected"
54
+ ).length;
55
+ setStats({ total, average, pending, approved, rejected });
56
+ } catch (err) {
57
+ setError(
58
+ err instanceof Error ? err.message : "Failed to fetch reviews"
59
+ );
60
+ } finally {
61
+ setIsLoading(false);
62
+ }
63
+ };
64
+ react.useEffect(() => {
65
+ fetchReviews();
66
+ }, [data.id]);
67
+ const handleStatusChange = async (reviewId, status) => {
68
+ try {
69
+ await axios__default.default.post("/admin/reviews/status", {
70
+ ids: [reviewId],
71
+ status
72
+ });
73
+ ui.toast.success(`Review ${status}`, {
74
+ description: `The review has been ${status} successfully`
75
+ });
76
+ fetchReviews();
77
+ } catch (err) {
78
+ ui.toast.error("Failed to update review", {
79
+ description: err instanceof Error ? err.message : "An error occurred"
80
+ });
81
+ }
82
+ };
83
+ const getStatusColor = (status) => {
84
+ switch (status) {
85
+ case "approved":
86
+ return "green";
87
+ case "rejected":
88
+ return "red";
89
+ case "pending":
90
+ return "orange";
91
+ default:
92
+ return "grey";
93
+ }
94
+ };
95
+ const renderStars = (rating) => {
96
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center gap-0.5", children: [1, 2, 3, 4, 5].map((star) => /* @__PURE__ */ jsxRuntime.jsx(
97
+ "span",
98
+ {
99
+ className: `text-lg ${star <= rating ? "text-yellow-500" : "text-gray-300"}`,
100
+ children: "★"
101
+ },
102
+ star
103
+ )) });
104
+ };
105
+ if (error) {
106
+ return /* @__PURE__ */ jsxRuntime.jsx(ui.Container, { className: "p-6", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Alert, { variant: "error", children: error }) });
107
+ }
108
+ return /* @__PURE__ */ jsxRuntime.jsx(ui.Container, { className: "divide-y px-0 pb-0", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "px-6 py-6 space-y-6", children: [
109
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-2 md:flex-row md:items-center md:justify-between", children: [
110
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-3", children: [
111
+ /* @__PURE__ */ jsxRuntime.jsx(icons.ChatBubbleLeftRight, { className: "h-6 w-6 text-ui-fg-subtle" }),
112
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
113
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h2", children: "Product Reviews" }),
114
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "text-sm text-ui-fg-subtle", children: "Customer reviews and ratings for this product" })
115
+ ] })
116
+ ] }),
117
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-wrap gap-2", children: [
118
+ /* @__PURE__ */ jsxRuntime.jsxs(ui.Badge, { color: "blue", size: "small", children: [
119
+ stats.total,
120
+ " Total"
121
+ ] }),
122
+ stats.pending > 0 && /* @__PURE__ */ jsxRuntime.jsxs(ui.Badge, { color: "orange", size: "small", children: [
123
+ stats.pending,
124
+ " Pending"
125
+ ] })
126
+ ] })
127
+ ] }),
128
+ isLoading ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "rounded-lg border bg-ui-bg-base p-6 text-center", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "text-sm text-ui-fg-muted", children: "Loading reviews..." }) }) : reviews.length === 0 ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border border-dashed bg-ui-bg-subtle p-6 text-center", children: [
129
+ /* @__PURE__ */ jsxRuntime.jsx(icons.ChatBubbleLeftRight, { className: "h-8 w-8 mx-auto mb-2 text-ui-fg-muted" }),
130
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "text-sm text-ui-fg-muted", children: "No reviews yet for this product" }),
131
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "text-xs text-ui-fg-subtle", children: "Reviews will appear here once customers submit them" })
132
+ ] }) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
133
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "rounded-lg border bg-ui-bg-base p-4", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between mb-4", children: [
134
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
135
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "text-sm text-ui-fg-subtle mb-1", children: "Average Rating" }),
136
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
137
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-2xl font-bold", children: stats.average.toFixed(1) }),
138
+ renderStars(Math.round(stats.average))
139
+ ] })
140
+ ] }),
141
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-right", children: [
142
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "text-sm text-ui-fg-subtle mb-1", children: "Status Breakdown" }),
143
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex gap-2 justify-end", children: [
144
+ /* @__PURE__ */ jsxRuntime.jsxs(ui.Badge, { color: "green", size: "small", children: [
145
+ stats.approved,
146
+ " Approved"
147
+ ] }),
148
+ /* @__PURE__ */ jsxRuntime.jsxs(ui.Badge, { color: "red", size: "small", children: [
149
+ stats.rejected,
150
+ " Rejected"
151
+ ] })
152
+ ] })
153
+ ] })
154
+ ] }) }),
155
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-3", children: [
156
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between", children: [
157
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h3", className: "text-base", children: "Recent Reviews" }),
158
+ /* @__PURE__ */ jsxRuntime.jsx(reactRouterDom.Link, { to: "/reviews", children: /* @__PURE__ */ jsxRuntime.jsxs(ui.Button, { variant: "secondary", size: "small", children: [
159
+ /* @__PURE__ */ jsxRuntime.jsx(icons.ArrowUpRightOnBox, { className: "mr-1 h-4 w-4" }),
160
+ "View All"
161
+ ] }) })
162
+ ] }),
163
+ reviews.map((review) => /* @__PURE__ */ jsxRuntime.jsx(
164
+ "div",
165
+ {
166
+ className: "rounded-lg border bg-ui-bg-subtle p-4 space-y-3",
167
+ children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-start justify-between", children: [
168
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex-1", children: [
169
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2 mb-1", children: [
170
+ renderStars(review.rating),
171
+ /* @__PURE__ */ jsxRuntime.jsx(ui.StatusBadge, { color: getStatusColor(review.status), children: review.status.charAt(0).toUpperCase() + review.status.slice(1) })
172
+ ] }),
173
+ review.title && /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-medium mb-1", children: review.title }),
174
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "text-sm text-ui-fg-subtle line-clamp-2", children: review.content }),
175
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2 mt-2", children: [
176
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "text-xs text-ui-fg-muted", children: review.is_admin ? "Admin" : review.first_name ? `${review.first_name} ${review.last_name || ""}` : "Anonymous" }),
177
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-ui-fg-muted", children: "•" }),
178
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "text-xs text-ui-fg-muted", children: new Date(review.created_at).toLocaleDateString() })
179
+ ] })
180
+ ] }),
181
+ review.status === "pending" && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex gap-1 ml-4", children: [
182
+ /* @__PURE__ */ jsxRuntime.jsx(
183
+ ui.Button,
184
+ {
185
+ variant: "secondary",
186
+ size: "small",
187
+ onClick: () => handleStatusChange(review.id, "approved"),
188
+ title: "Approve review",
189
+ children: /* @__PURE__ */ jsxRuntime.jsx(icons.CheckCircleSolid, { className: "h-4 w-4 text-green-600" })
190
+ }
191
+ ),
192
+ /* @__PURE__ */ jsxRuntime.jsx(
193
+ ui.Button,
194
+ {
195
+ variant: "secondary",
196
+ size: "small",
197
+ onClick: () => handleStatusChange(review.id, "rejected"),
198
+ title: "Reject review",
199
+ children: /* @__PURE__ */ jsxRuntime.jsx(icons.XCircleSolid, { className: "h-4 w-4 text-red-600" })
200
+ }
201
+ )
202
+ ] })
203
+ ] })
204
+ },
205
+ review.id
206
+ ))
207
+ ] })
208
+ ] })
209
+ ] }) });
210
+ };
211
+ adminSdk.defineWidgetConfig({
212
+ zone: "product.details.after"
213
+ });
16
214
  const statusColor = (status) => status === "approved" ? "green" : status === "rejected" ? "red" : "grey";
17
215
  const mimeTypes = ["image", "video"];
18
216
  const MediaViewer = ({ media, className }) => {
@@ -459,7 +657,12 @@ const config = adminSdk.defineRouteConfig({
459
657
  label: "Reviews",
460
658
  icon: icons.ChatBubbleLeftRight
461
659
  });
462
- const widgetModule = { widgets: [] };
660
+ const widgetModule = { widgets: [
661
+ {
662
+ Component: ProductReviewWidget,
663
+ zone: ["product.details.after"]
664
+ }
665
+ ] };
463
666
  const routeModule = {
464
667
  routes: [
465
668
  {
@@ -1,13 +1,211 @@
1
- import { jsx, Fragment, jsxs } from "react/jsx-runtime";
2
- import { defineRouteConfig } from "@medusajs/admin-sdk";
3
- import { ChatBubbleLeftRight } from "@medusajs/icons";
4
- import { FocusModal, clx, ProgressAccordion, StatusBadge, Text, Button, createDataTableColumnHelper, Container, DataTable, Heading, Toaster, createDataTableCommandHelper, toast, useDataTable, Drawer } from "@medusajs/ui";
1
+ import { jsx, jsxs, Fragment } from "react/jsx-runtime";
2
+ import { useState, useEffect, useMemo } from "react";
3
+ import { defineWidgetConfig, defineRouteConfig } from "@medusajs/admin-sdk";
4
+ import { Container, Alert, Heading, Text, Badge, Button, StatusBadge, toast, FocusModal, clx, ProgressAccordion, createDataTableColumnHelper, DataTable, Toaster, createDataTableCommandHelper, useDataTable, Drawer } from "@medusajs/ui";
5
+ import { ChatBubbleLeftRight, ArrowUpRightOnBox, CheckCircleSolid, XCircleSolid } from "@medusajs/icons";
5
6
  import axios from "axios";
6
- import Mentions from "rc-mentions";
7
- import { useState, useMemo, useEffect } from "react";
8
7
  import { Link } from "react-router-dom";
8
+ import Mentions from "rc-mentions";
9
9
  import Medusa from "@medusajs/js-sdk";
10
10
  import "@medusajs/admin-shared";
11
+ const ProductReviewWidget = ({ data }) => {
12
+ const [reviews, setReviews] = useState([]);
13
+ const [isLoading, setIsLoading] = useState(true);
14
+ const [error, setError] = useState(null);
15
+ const [stats, setStats] = useState({
16
+ total: 0,
17
+ average: 0,
18
+ pending: 0,
19
+ approved: 0,
20
+ rejected: 0
21
+ });
22
+ const fetchReviews = async () => {
23
+ setIsLoading(true);
24
+ setError(null);
25
+ try {
26
+ const { data: response } = await axios.get(
27
+ `/admin/reviews`,
28
+ {
29
+ params: {
30
+ product_id: data.id,
31
+ limit: 5,
32
+ offset: 0,
33
+ order: "-created_at",
34
+ fields: "id,title,content,rating,status,created_at,first_name,last_name,is_admin"
35
+ }
36
+ }
37
+ );
38
+ setReviews(response.reviews);
39
+ const total = response.count || response.reviews.length;
40
+ const average = response.reviews.length > 0 ? response.reviews.reduce((sum, r) => sum + r.rating, 0) / response.reviews.length : 0;
41
+ const pending = response.reviews.filter(
42
+ (r) => r.status === "pending"
43
+ ).length;
44
+ const approved = response.reviews.filter(
45
+ (r) => r.status === "approved"
46
+ ).length;
47
+ const rejected = response.reviews.filter(
48
+ (r) => r.status === "rejected"
49
+ ).length;
50
+ setStats({ total, average, pending, approved, rejected });
51
+ } catch (err) {
52
+ setError(
53
+ err instanceof Error ? err.message : "Failed to fetch reviews"
54
+ );
55
+ } finally {
56
+ setIsLoading(false);
57
+ }
58
+ };
59
+ useEffect(() => {
60
+ fetchReviews();
61
+ }, [data.id]);
62
+ const handleStatusChange = async (reviewId, status) => {
63
+ try {
64
+ await axios.post("/admin/reviews/status", {
65
+ ids: [reviewId],
66
+ status
67
+ });
68
+ toast.success(`Review ${status}`, {
69
+ description: `The review has been ${status} successfully`
70
+ });
71
+ fetchReviews();
72
+ } catch (err) {
73
+ toast.error("Failed to update review", {
74
+ description: err instanceof Error ? err.message : "An error occurred"
75
+ });
76
+ }
77
+ };
78
+ const getStatusColor = (status) => {
79
+ switch (status) {
80
+ case "approved":
81
+ return "green";
82
+ case "rejected":
83
+ return "red";
84
+ case "pending":
85
+ return "orange";
86
+ default:
87
+ return "grey";
88
+ }
89
+ };
90
+ const renderStars = (rating) => {
91
+ return /* @__PURE__ */ jsx("div", { className: "flex items-center gap-0.5", children: [1, 2, 3, 4, 5].map((star) => /* @__PURE__ */ jsx(
92
+ "span",
93
+ {
94
+ className: `text-lg ${star <= rating ? "text-yellow-500" : "text-gray-300"}`,
95
+ children: "★"
96
+ },
97
+ star
98
+ )) });
99
+ };
100
+ if (error) {
101
+ return /* @__PURE__ */ jsx(Container, { className: "p-6", children: /* @__PURE__ */ jsx(Alert, { variant: "error", children: error }) });
102
+ }
103
+ return /* @__PURE__ */ jsx(Container, { className: "divide-y px-0 pb-0", children: /* @__PURE__ */ jsxs("div", { className: "px-6 py-6 space-y-6", children: [
104
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-2 md:flex-row md:items-center md:justify-between", children: [
105
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3", children: [
106
+ /* @__PURE__ */ jsx(ChatBubbleLeftRight, { className: "h-6 w-6 text-ui-fg-subtle" }),
107
+ /* @__PURE__ */ jsxs("div", { children: [
108
+ /* @__PURE__ */ jsx(Heading, { level: "h2", children: "Product Reviews" }),
109
+ /* @__PURE__ */ jsx(Text, { className: "text-sm text-ui-fg-subtle", children: "Customer reviews and ratings for this product" })
110
+ ] })
111
+ ] }),
112
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-wrap gap-2", children: [
113
+ /* @__PURE__ */ jsxs(Badge, { color: "blue", size: "small", children: [
114
+ stats.total,
115
+ " Total"
116
+ ] }),
117
+ stats.pending > 0 && /* @__PURE__ */ jsxs(Badge, { color: "orange", size: "small", children: [
118
+ stats.pending,
119
+ " Pending"
120
+ ] })
121
+ ] })
122
+ ] }),
123
+ isLoading ? /* @__PURE__ */ jsx("div", { className: "rounded-lg border bg-ui-bg-base p-6 text-center", children: /* @__PURE__ */ jsx(Text, { className: "text-sm text-ui-fg-muted", children: "Loading reviews..." }) }) : reviews.length === 0 ? /* @__PURE__ */ jsxs("div", { className: "rounded-lg border border-dashed bg-ui-bg-subtle p-6 text-center", children: [
124
+ /* @__PURE__ */ jsx(ChatBubbleLeftRight, { className: "h-8 w-8 mx-auto mb-2 text-ui-fg-muted" }),
125
+ /* @__PURE__ */ jsx(Text, { className: "text-sm text-ui-fg-muted", children: "No reviews yet for this product" }),
126
+ /* @__PURE__ */ jsx(Text, { className: "text-xs text-ui-fg-subtle", children: "Reviews will appear here once customers submit them" })
127
+ ] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
128
+ /* @__PURE__ */ jsx("div", { className: "rounded-lg border bg-ui-bg-base p-4", children: /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between mb-4", children: [
129
+ /* @__PURE__ */ jsxs("div", { children: [
130
+ /* @__PURE__ */ jsx(Text, { className: "text-sm text-ui-fg-subtle mb-1", children: "Average Rating" }),
131
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
132
+ /* @__PURE__ */ jsx("span", { className: "text-2xl font-bold", children: stats.average.toFixed(1) }),
133
+ renderStars(Math.round(stats.average))
134
+ ] })
135
+ ] }),
136
+ /* @__PURE__ */ jsxs("div", { className: "text-right", children: [
137
+ /* @__PURE__ */ jsx(Text, { className: "text-sm text-ui-fg-subtle mb-1", children: "Status Breakdown" }),
138
+ /* @__PURE__ */ jsxs("div", { className: "flex gap-2 justify-end", children: [
139
+ /* @__PURE__ */ jsxs(Badge, { color: "green", size: "small", children: [
140
+ stats.approved,
141
+ " Approved"
142
+ ] }),
143
+ /* @__PURE__ */ jsxs(Badge, { color: "red", size: "small", children: [
144
+ stats.rejected,
145
+ " Rejected"
146
+ ] })
147
+ ] })
148
+ ] })
149
+ ] }) }),
150
+ /* @__PURE__ */ jsxs("div", { className: "space-y-3", children: [
151
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between", children: [
152
+ /* @__PURE__ */ jsx(Heading, { level: "h3", className: "text-base", children: "Recent Reviews" }),
153
+ /* @__PURE__ */ jsx(Link, { to: "/reviews", children: /* @__PURE__ */ jsxs(Button, { variant: "secondary", size: "small", children: [
154
+ /* @__PURE__ */ jsx(ArrowUpRightOnBox, { className: "mr-1 h-4 w-4" }),
155
+ "View All"
156
+ ] }) })
157
+ ] }),
158
+ reviews.map((review) => /* @__PURE__ */ jsx(
159
+ "div",
160
+ {
161
+ className: "rounded-lg border bg-ui-bg-subtle p-4 space-y-3",
162
+ children: /* @__PURE__ */ jsxs("div", { className: "flex items-start justify-between", children: [
163
+ /* @__PURE__ */ jsxs("div", { className: "flex-1", children: [
164
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 mb-1", children: [
165
+ renderStars(review.rating),
166
+ /* @__PURE__ */ jsx(StatusBadge, { color: getStatusColor(review.status), children: review.status.charAt(0).toUpperCase() + review.status.slice(1) })
167
+ ] }),
168
+ review.title && /* @__PURE__ */ jsx(Text, { className: "font-medium mb-1", children: review.title }),
169
+ /* @__PURE__ */ jsx(Text, { className: "text-sm text-ui-fg-subtle line-clamp-2", children: review.content }),
170
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 mt-2", children: [
171
+ /* @__PURE__ */ jsx(Text, { className: "text-xs text-ui-fg-muted", children: review.is_admin ? "Admin" : review.first_name ? `${review.first_name} ${review.last_name || ""}` : "Anonymous" }),
172
+ /* @__PURE__ */ jsx("span", { className: "text-ui-fg-muted", children: "•" }),
173
+ /* @__PURE__ */ jsx(Text, { className: "text-xs text-ui-fg-muted", children: new Date(review.created_at).toLocaleDateString() })
174
+ ] })
175
+ ] }),
176
+ review.status === "pending" && /* @__PURE__ */ jsxs("div", { className: "flex gap-1 ml-4", children: [
177
+ /* @__PURE__ */ jsx(
178
+ Button,
179
+ {
180
+ variant: "secondary",
181
+ size: "small",
182
+ onClick: () => handleStatusChange(review.id, "approved"),
183
+ title: "Approve review",
184
+ children: /* @__PURE__ */ jsx(CheckCircleSolid, { className: "h-4 w-4 text-green-600" })
185
+ }
186
+ ),
187
+ /* @__PURE__ */ jsx(
188
+ Button,
189
+ {
190
+ variant: "secondary",
191
+ size: "small",
192
+ onClick: () => handleStatusChange(review.id, "rejected"),
193
+ title: "Reject review",
194
+ children: /* @__PURE__ */ jsx(XCircleSolid, { className: "h-4 w-4 text-red-600" })
195
+ }
196
+ )
197
+ ] })
198
+ ] })
199
+ },
200
+ review.id
201
+ ))
202
+ ] })
203
+ ] })
204
+ ] }) });
205
+ };
206
+ defineWidgetConfig({
207
+ zone: "product.details.after"
208
+ });
11
209
  const statusColor = (status) => status === "approved" ? "green" : status === "rejected" ? "red" : "grey";
12
210
  const mimeTypes = ["image", "video"];
13
211
  const MediaViewer = ({ media, className }) => {
@@ -454,7 +652,12 @@ const config = defineRouteConfig({
454
652
  label: "Reviews",
455
653
  icon: ChatBubbleLeftRight
456
654
  });
457
- const widgetModule = { widgets: [] };
655
+ const widgetModule = { widgets: [
656
+ {
657
+ Component: ProductReviewWidget,
658
+ zone: ["product.details.after"]
659
+ }
660
+ ] };
458
661
  const routeModule = {
459
662
  routes: [
460
663
  {
@@ -4,11 +4,16 @@ exports.POST = exports.GET = void 0;
4
4
  const getReviewsWorkflow_1 = require("../../../workflows/review/getReviewsWorkflow");
5
5
  const createReviewWorkflow_1 = require("../../../workflows/review/createReviewWorkflow");
6
6
  const GET = async (req, res) => {
7
+ // Extract filters from query parameters
8
+ const validatedQuery = (req.validatedQuery ?? {});
9
+ const { product_id, status } = validatedQuery;
7
10
  const { result } = await (0, getReviewsWorkflow_1.getReviewsWorkflow)().run({
8
11
  input: {
9
12
  queryConfig: req.queryConfig,
10
13
  filters: {
11
14
  parent: null,
15
+ ...(product_id && { product_id }),
16
+ ...(status && { status }),
12
17
  },
13
18
  },
14
19
  });
@@ -32,4 +37,4 @@ const POST = async (req, res) => {
32
37
  res.json(result);
33
38
  };
34
39
  exports.POST = POST;
35
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicm91dGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9zcmMvYXBpL2FkbWluL3Jldmlld3Mvcm91dGUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBS0EscUZBQWtGO0FBQ2xGLHlGQUFzRjtBQUcvRSxNQUFNLEdBQUcsR0FBRyxLQUFLLEVBQUUsR0FBa0IsRUFBRSxHQUFtQixFQUFFLEVBQUU7SUFDbkUsTUFBTSxFQUFFLE1BQU0sRUFBRSxHQUFHLE1BQU0sSUFBQSx1Q0FBa0IsR0FBRSxDQUFDLEdBQUcsQ0FBQztRQUNoRCxLQUFLLEVBQUU7WUFDTCxXQUFXLEVBQUUsR0FBRyxDQUFDLFdBQVc7WUFDNUIsT0FBTyxFQUFFO2dCQUNQLE1BQU0sRUFBRSxJQUFJO2FBQ2I7U0FDRjtLQUNGLENBQUMsQ0FBQztJQUVILEdBQUcsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUM7QUFDbkIsQ0FBQyxDQUFDO0FBWFcsUUFBQSxHQUFHLE9BV2Q7QUFFSyxNQUFNLElBQUksR0FBRyxLQUFLLEVBQ3ZCLEdBQW1ELEVBQ25ELEdBQW1CLEVBQ25CLEVBQUU7SUFDRjs7O09BR0c7SUFDSCxNQUFNLE9BQU8sR0FBRyxHQUFHLENBQUMsWUFBWSxFQUFFLFVBQVUsS0FBSyxNQUFNLENBQUM7SUFFeEQsTUFBTSxFQUFFLE1BQU0sRUFBRSxHQUFHLE1BQU0sSUFBQSwyQ0FBb0IsRUFBQyxHQUFHLENBQUMsS0FBSyxDQUFDLENBQUMsR0FBRyxDQUFDO1FBQzNELEtBQUssRUFBRTtZQUNMLEdBQUcsR0FBRyxDQUFDLGFBQWE7WUFDcEIsUUFBUSxFQUFFLE9BQU87WUFDakIsTUFBTSxFQUFFLFVBQVU7WUFDbEIsTUFBTSxFQUFFLEVBQUU7U0FDWDtLQUNGLENBQUMsQ0FBQztJQUVILEdBQUcsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUM7QUFDbkIsQ0FBQyxDQUFDO0FBcEJXLFFBQUEsSUFBSSxRQW9CZiJ9
40
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicm91dGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9zcmMvYXBpL2FkbWluL3Jldmlld3Mvcm91dGUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBS0EscUZBR3NEO0FBQ3RELHlGQUFzRjtBQUcvRSxNQUFNLEdBQUcsR0FBRyxLQUFLLEVBQ3RCLEdBQTRDLEVBQzVDLEdBQW1CLEVBQ25CLEVBQUU7SUFDRix3Q0FBd0M7SUFDeEMsTUFBTSxjQUFjLEdBQUcsQ0FBQyxHQUFHLENBQUMsY0FBYyxJQUFJLEVBQUUsQ0FBb0IsQ0FBQztJQUNyRSxNQUFNLEVBQUUsVUFBVSxFQUFFLE1BQU0sRUFBRSxHQUFHLGNBRzlCLENBQUM7SUFFRixNQUFNLEVBQUUsTUFBTSxFQUFFLEdBQUcsTUFBTSxJQUFBLHVDQUFrQixHQUFFLENBQUMsR0FBRyxDQUFDO1FBQ2hELEtBQUssRUFBRTtZQUNMLFdBQVcsRUFBRSxHQUFHLENBQUMsV0FBVztZQUM1QixPQUFPLEVBQUU7Z0JBQ1AsTUFBTSxFQUFFLElBQUk7Z0JBQ1osR0FBRyxDQUFDLFVBQVUsSUFBSSxFQUFFLFVBQVUsRUFBRSxDQUFDO2dCQUNqQyxHQUFHLENBQUMsTUFBTSxJQUFJLEVBQUUsTUFBTSxFQUFFLENBQUM7YUFDMUI7U0FDRjtLQUNGLENBQUMsQ0FBQztJQUVILEdBQUcsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUM7QUFDbkIsQ0FBQyxDQUFDO0FBdkJXLFFBQUEsR0FBRyxPQXVCZDtBQUVLLE1BQU0sSUFBSSxHQUFHLEtBQUssRUFDdkIsR0FBbUQsRUFDbkQsR0FBbUIsRUFDbkIsRUFBRTtJQUNGOzs7T0FHRztJQUNILE1BQU0sT0FBTyxHQUFHLEdBQUcsQ0FBQyxZQUFZLEVBQUUsVUFBVSxLQUFLLE1BQU0sQ0FBQztJQUV4RCxNQUFNLEVBQUUsTUFBTSxFQUFFLEdBQUcsTUFBTSxJQUFBLDJDQUFvQixFQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsQ0FBQyxHQUFHLENBQUM7UUFDM0QsS0FBSyxFQUFFO1lBQ0wsR0FBRyxHQUFHLENBQUMsYUFBYTtZQUNwQixRQUFRLEVBQUUsT0FBTztZQUNqQixNQUFNLEVBQUUsVUFBVTtZQUNsQixNQUFNLEVBQUUsRUFBRTtTQUNYO0tBQ0YsQ0FBQyxDQUFDO0lBRUgsR0FBRyxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQztBQUNuQixDQUFDLENBQUM7QUFwQlcsUUFBQSxJQUFJLFFBb0JmIn0=
@@ -2,11 +2,11 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.PostAdminUpdateReviewsStatusSchema = void 0;
4
4
  exports.POST = POST;
5
- const zod_1 = require("zod");
5
+ const z_1 = require("../../../../utils/z");
6
6
  const updateReviewWorkflow_1 = require("../../../../workflows/review/updateReviewWorkflow");
7
- exports.PostAdminUpdateReviewsStatusSchema = zod_1.z.object({
8
- ids: zod_1.z.array(zod_1.z.string()),
9
- status: zod_1.z.enum(["pending", "approved", "rejected"]),
7
+ exports.PostAdminUpdateReviewsStatusSchema = z_1.z.object({
8
+ ids: z_1.z.array(z_1.z.string()),
9
+ status: z_1.z.enum(["pending", "approved", "rejected"]),
10
10
  });
11
11
  async function POST(req, res) {
12
12
  const { ids, status } = req.validatedBody;
@@ -18,4 +18,4 @@ async function POST(req, res) {
18
18
  });
19
19
  res.json(result);
20
20
  }
21
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicm91dGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi9zcmMvYXBpL2FkbWluL3Jldmlld3Mvc3RhdHVzL3JvdXRlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQVNBLG9CQWNDO0FBdEJELDZCQUF3QjtBQUN4Qiw0RkFBeUY7QUFFNUUsUUFBQSxrQ0FBa0MsR0FBRyxPQUFDLENBQUMsTUFBTSxDQUFDO0lBQ3pELEdBQUcsRUFBRSxPQUFDLENBQUMsS0FBSyxDQUFDLE9BQUMsQ0FBQyxNQUFNLEVBQUUsQ0FBQztJQUN4QixNQUFNLEVBQUUsT0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLFNBQVMsRUFBRSxVQUFVLEVBQUUsVUFBVSxDQUFDLENBQUM7Q0FDcEQsQ0FBQyxDQUFDO0FBRUksS0FBSyxVQUFVLElBQUksQ0FDeEIsR0FBc0UsRUFDdEUsR0FBbUI7SUFFbkIsTUFBTSxFQUFFLEdBQUcsRUFBRSxNQUFNLEVBQUUsR0FBRyxHQUFHLENBQUMsYUFBYSxDQUFDO0lBRTFDLE1BQU0sRUFBRSxNQUFNLEVBQUUsR0FBRyxNQUFNLElBQUEsMkNBQW9CLEVBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQyxDQUFDLEdBQUcsQ0FBQztRQUMzRCxLQUFLLEVBQUUsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDLEVBQUUsRUFBRSxFQUFFLENBQUMsQ0FBQztZQUN0QixFQUFFO1lBQ0YsTUFBTTtTQUNQLENBQUMsQ0FBQztLQUNKLENBQUMsQ0FBQztJQUVILEdBQUcsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUM7QUFDbkIsQ0FBQyJ9
21
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicm91dGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi9zcmMvYXBpL2FkbWluL3Jldmlld3Mvc3RhdHVzL3JvdXRlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQVVBLG9CQWNDO0FBdEJELDJDQUF3QztBQUN4Qyw0RkFBeUY7QUFFNUUsUUFBQSxrQ0FBa0MsR0FBRyxLQUFDLENBQUMsTUFBTSxDQUFDO0lBQ3pELEdBQUcsRUFBRSxLQUFDLENBQUMsS0FBSyxDQUFDLEtBQUMsQ0FBQyxNQUFNLEVBQUUsQ0FBQztJQUN4QixNQUFNLEVBQUUsS0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLFNBQVMsRUFBRSxVQUFVLEVBQUUsVUFBVSxDQUFDLENBQUM7Q0FDcEQsQ0FBQyxDQUFDO0FBRUksS0FBSyxVQUFVLElBQUksQ0FDeEIsR0FBd0UsRUFDeEUsR0FBbUI7SUFFbkIsTUFBTSxFQUFFLEdBQUcsRUFBRSxNQUFNLEVBQUUsR0FBRyxHQUFHLENBQUMsYUFBYSxDQUFDO0lBRTFDLE1BQU0sRUFBRSxNQUFNLEVBQUUsR0FBRyxNQUFNLElBQUEsMkNBQW9CLEVBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQyxDQUFDLEdBQUcsQ0FBQztRQUMzRCxLQUFLLEVBQUUsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDLEVBQUUsRUFBRSxFQUFFLENBQUMsQ0FBQztZQUN0QixFQUFFO1lBQ0YsTUFBTTtTQUNQLENBQUMsQ0FBQztLQUNKLENBQUMsQ0FBQztJQUVILEdBQUcsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUM7QUFDbkIsQ0FBQyJ9
@@ -1,20 +1,20 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.POST = exports.PostStoreReviewSchema = void 0;
4
- const zod_1 = require("zod");
4
+ const z_1 = require("../../../utils/z");
5
5
  const createReviewWorkflow_1 = require("../../../workflows/review/createReviewWorkflow");
6
6
  const core_flows_1 = require("@medusajs/medusa/core-flows");
7
- exports.PostStoreReviewSchema = zod_1.z.object({
8
- parent_id: zod_1.z.string().optional(),
9
- title: zod_1.z.string().optional(),
10
- content: zod_1.z.string(),
11
- rating: zod_1.z.preprocess((val) => {
7
+ exports.PostStoreReviewSchema = z_1.z.object({
8
+ parent_id: z_1.z.string().optional(),
9
+ title: z_1.z.string().optional(),
10
+ content: z_1.z.string(),
11
+ rating: z_1.z.preprocess((val) => {
12
12
  if (val && typeof val === "string") {
13
13
  return parseInt(val);
14
14
  }
15
15
  return val;
16
- }, zod_1.z.number().min(1).max(5).optional()),
17
- product_id: zod_1.z.string(),
16
+ }, z_1.z.number().min(1).max(5).optional()),
17
+ product_id: z_1.z.string(),
18
18
  });
19
19
  const POST = async (req, res) => {
20
20
  const input = req.body;
@@ -54,4 +54,4 @@ const POST = async (req, res) => {
54
54
  }
55
55
  };
56
56
  exports.POST = POST;
57
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicm91dGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9zcmMvYXBpL3N0b3JlL3Jldmlld3Mvcm91dGUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBS0EsNkJBQXdCO0FBQ3hCLHlGQUFzRjtBQUV0Riw0REFHcUM7QUFFeEIsUUFBQSxxQkFBcUIsR0FBRyxPQUFDLENBQUMsTUFBTSxDQUFDO0lBQzVDLFNBQVMsRUFBRSxPQUFDLENBQUMsTUFBTSxFQUFFLENBQUMsUUFBUSxFQUFFO0lBQ2hDLEtBQUssRUFBRSxPQUFDLENBQUMsTUFBTSxFQUFFLENBQUMsUUFBUSxFQUFFO0lBQzVCLE9BQU8sRUFBRSxPQUFDLENBQUMsTUFBTSxFQUFFO0lBQ25CLE1BQU0sRUFBRSxPQUFDLENBQUMsVUFBVSxDQUFDLENBQUMsR0FBRyxFQUFFLEVBQUU7UUFDM0IsSUFBSSxHQUFHLElBQUksT0FBTyxHQUFHLEtBQUssUUFBUSxFQUFFLENBQUM7WUFDbkMsT0FBTyxRQUFRLENBQUMsR0FBRyxDQUFDLENBQUM7UUFDdkIsQ0FBQztRQUNELE9BQU8sR0FBRyxDQUFDO0lBQ2IsQ0FBQyxFQUFFLE9BQUMsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLFFBQVEsRUFBRSxDQUFDO0lBQ3ZDLFVBQVUsRUFBRSxPQUFDLENBQUMsTUFBTSxFQUFFO0NBQ3ZCLENBQUMsQ0FBQztBQVFJLE1BQU0sSUFBSSxHQUFHLEtBQUssRUFDdkIsR0FBa0IsRUFDbEIsR0FBbUIsRUFDbkIsRUFBRTtJQUNGLE1BQU0sS0FBSyxHQUFHLEdBQUcsQ0FBQyxJQUFJLENBQUM7SUFDdkIsTUFBTSxVQUFVLEdBQUcsR0FBRyxDQUFDLEtBQUssQ0FBQztJQUU3QixNQUFNLEVBQUUsTUFBTSxFQUFFLGFBQWEsRUFBRSxHQUFHLE1BQU0sSUFBQSxnQ0FBbUIsRUFBQyxHQUFHLENBQUMsS0FBWSxDQUFDLENBQUMsR0FBRyxDQUFDO1FBQ2hGLEtBQUssRUFBRTtZQUNMLEtBQUssRUFBRSxVQUFVLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDO2dCQUM3QixRQUFRLEVBQUUsQ0FBQyxDQUFDLFlBQVk7Z0JBQ3hCLFFBQVEsRUFBRSxDQUFDLENBQUMsUUFBUTtnQkFDcEIsT0FBTyxFQUFFLENBQUMsQ0FBQyxNQUFNLENBQUMsUUFBUSxDQUFDLFFBQVEsQ0FBQztnQkFDcEMsTUFBTSxFQUFFLFFBQVE7YUFDakIsQ0FBQyxDQUFDLElBQUksRUFBRTtTQUNWO0tBQ0YsQ0FBQyxDQUFDO0lBRUgsTUFBTSxNQUFNLEdBQUcsYUFBYSxDQUFDLEdBQUcsQ0FBQyxDQUFDLElBQUksRUFBRSxLQUFLLEVBQUUsRUFBRSxDQUFDLENBQUM7UUFDakQsTUFBTSxFQUFFLElBQUksQ0FBQyxFQUFFO1FBQ2YsT0FBTyxFQUFFLElBQUksQ0FBQyxHQUFHO1FBQ2pCLFFBQVEsRUFBRSxVQUFVLEVBQUUsRUFBRSxDQUFDLEtBQUssQ0FBQyxFQUFFLFFBQVEsSUFBSSxFQUFFO0tBQ2hELENBQUMsQ0FBQyxDQUFDO0lBRUosSUFBSSxDQUFDO1FBQ0gsTUFBTSxFQUFFLE1BQU0sRUFBRSxNQUFNLEVBQUUsR0FBRyxNQUFNLElBQUEsMkNBQW9CLEVBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQyxDQUFDLEdBQUcsQ0FBQztZQUNuRSxLQUFLLEVBQUU7Z0JBQ0wsR0FBRyxLQUFLO2dCQUNSLFdBQVcsRUFBRSxHQUFHLENBQUMsWUFBWSxFQUFFLFFBQVE7Z0JBQ3ZDLE1BQU07YUFDUDtTQUNGLENBQUMsQ0FBQztRQUVILEdBQUcsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUM7SUFDbkIsQ0FBQztJQUFDLE9BQU8sS0FBSyxFQUFFLENBQUM7UUFDZixJQUFBLGdDQUFtQixFQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsQ0FBQyxHQUFHLENBQUM7WUFDakMsS0FBSyxFQUFFO2dCQUNMLEdBQUcsRUFBRSxhQUFhLENBQUMsR0FBRyxDQUFDLENBQUMsSUFBSSxFQUFFLEVBQUUsQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDO2FBQzFDO1NBQ0YsQ0FBQyxDQUFDO1FBQ0gsTUFBTSxLQUFLLENBQUM7SUFDZCxDQUFDO0FBQ0gsQ0FBQyxDQUFDO0FBMUNXLFFBQUEsSUFBSSxRQTBDZiJ9
57
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicm91dGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9zcmMvYXBpL3N0b3JlL3Jldmlld3Mvcm91dGUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBTUEsd0NBQXFDO0FBQ3JDLHlGQUFzRjtBQUV0Riw0REFHcUM7QUFFeEIsUUFBQSxxQkFBcUIsR0FBRyxLQUFDLENBQUMsTUFBTSxDQUFDO0lBQzVDLFNBQVMsRUFBRSxLQUFDLENBQUMsTUFBTSxFQUFFLENBQUMsUUFBUSxFQUFFO0lBQ2hDLEtBQUssRUFBRSxLQUFDLENBQUMsTUFBTSxFQUFFLENBQUMsUUFBUSxFQUFFO0lBQzVCLE9BQU8sRUFBRSxLQUFDLENBQUMsTUFBTSxFQUFFO0lBQ25CLE1BQU0sRUFBRSxLQUFDLENBQUMsVUFBVSxDQUFDLENBQUMsR0FBRyxFQUFFLEVBQUU7UUFDM0IsSUFBSSxHQUFHLElBQUksT0FBTyxHQUFHLEtBQUssUUFBUSxFQUFFLENBQUM7WUFDbkMsT0FBTyxRQUFRLENBQUMsR0FBRyxDQUFDLENBQUM7UUFDdkIsQ0FBQztRQUNELE9BQU8sR0FBRyxDQUFDO0lBQ2IsQ0FBQyxFQUFFLEtBQUMsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLFFBQVEsRUFBRSxDQUFDO0lBQ3ZDLFVBQVUsRUFBRSxLQUFDLENBQUMsTUFBTSxFQUFFO0NBQ3ZCLENBQUMsQ0FBQztBQVFJLE1BQU0sSUFBSSxHQUFHLEtBQUssRUFDdkIsR0FBa0IsRUFDbEIsR0FBbUIsRUFDbkIsRUFBRTtJQUNGLE1BQU0sS0FBSyxHQUFHLEdBQUcsQ0FBQyxJQUFJLENBQUM7SUFDdkIsTUFBTSxVQUFVLEdBQUcsR0FBRyxDQUFDLEtBQUssQ0FBQztJQUU3QixNQUFNLEVBQUUsTUFBTSxFQUFFLGFBQWEsRUFBRSxHQUFHLE1BQU0sSUFBQSxnQ0FBbUIsRUFBQyxHQUFHLENBQUMsS0FBWSxDQUFDLENBQUMsR0FBRyxDQUFDO1FBQ2hGLEtBQUssRUFBRTtZQUNMLEtBQUssRUFBRSxVQUFVLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDO2dCQUM3QixRQUFRLEVBQUUsQ0FBQyxDQUFDLFlBQVk7Z0JBQ3hCLFFBQVEsRUFBRSxDQUFDLENBQUMsUUFBUTtnQkFDcEIsT0FBTyxFQUFFLENBQUMsQ0FBQyxNQUFNLENBQUMsUUFBUSxDQUFDLFFBQVEsQ0FBQztnQkFDcEMsTUFBTSxFQUFFLFFBQVE7YUFDakIsQ0FBQyxDQUFDLElBQUksRUFBRTtTQUNWO0tBQ0YsQ0FBQyxDQUFDO0lBRUgsTUFBTSxNQUFNLEdBQUcsYUFBYSxDQUFDLEdBQUcsQ0FBQyxDQUFDLElBQUksRUFBRSxLQUFLLEVBQUUsRUFBRSxDQUFDLENBQUM7UUFDakQsTUFBTSxFQUFFLElBQUksQ0FBQyxFQUFFO1FBQ2YsT0FBTyxFQUFFLElBQUksQ0FBQyxHQUFHO1FBQ2pCLFFBQVEsRUFBRSxVQUFVLEVBQUUsRUFBRSxDQUFDLEtBQUssQ0FBQyxFQUFFLFFBQVEsSUFBSSxFQUFFO0tBQ2hELENBQUMsQ0FBQyxDQUFDO0lBRUosSUFBSSxDQUFDO1FBQ0gsTUFBTSxFQUFFLE1BQU0sRUFBRSxNQUFNLEVBQUUsR0FBRyxNQUFNLElBQUEsMkNBQW9CLEVBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQyxDQUFDLEdBQUcsQ0FBQztZQUNuRSxLQUFLLEVBQUU7Z0JBQ0wsR0FBRyxLQUFLO2dCQUNSLFdBQVcsRUFBRSxHQUFHLENBQUMsWUFBWSxFQUFFLFFBQVE7Z0JBQ3ZDLE1BQU07YUFDUDtTQUNGLENBQUMsQ0FBQztRQUVILEdBQUcsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUM7SUFDbkIsQ0FBQztJQUFDLE9BQU8sS0FBSyxFQUFFLENBQUM7UUFDZixJQUFBLGdDQUFtQixFQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsQ0FBQyxHQUFHLENBQUM7WUFDakMsS0FBSyxFQUFFO2dCQUNMLEdBQUcsRUFBRSxhQUFhLENBQUMsR0FBRyxDQUFDLENBQUMsSUFBSSxFQUFFLEVBQUUsQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDO2FBQzFDO1NBQ0YsQ0FBQyxDQUFDO1FBQ0gsTUFBTSxLQUFLLENBQUM7SUFDZCxDQUFDO0FBQ0gsQ0FBQyxDQUFDO0FBMUNXLFFBQUEsSUFBSSxRQTBDZiJ9
@@ -0,0 +1,13 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.z = void 0;
4
+ const module_1 = require("module");
5
+ /**
6
+ * Ensure we always use the same Zod version that Medusa ships with (v3).
7
+ * Resolving Zod through the framework's require avoids mixing major versions.
8
+ */
9
+ const frameworkRequire = (0, module_1.createRequire)(require.resolve("@medusajs/framework"));
10
+ // eslint-disable-next-line @typescript-eslint/no-var-requires
11
+ const { z } = frameworkRequire("zod");
12
+ exports.z = z;
13
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiei5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy91dGlscy96LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUFBLG1DQUF1QztBQUd2Qzs7O0dBR0c7QUFDSCxNQUFNLGdCQUFnQixHQUFHLElBQUEsc0JBQWEsRUFBQyxPQUFPLENBQUMsT0FBTyxDQUFDLHFCQUFxQixDQUFDLENBQUMsQ0FBQztBQUUvRSw4REFBOEQ7QUFDOUQsTUFBTSxFQUFFLENBQUMsRUFBRSxHQUFHLGdCQUFnQixDQUFDLEtBQUssQ0FBZSxDQUFDO0FBRTNDLGNBQUMifQ==
@@ -4,9 +4,53 @@ exports.getReviewsWorkflow = exports.GetReviewsSchema = void 0;
4
4
  const workflows_sdk_1 = require("@medusajs/framework/workflows-sdk");
5
5
  const framework_1 = require("@medusajs/framework");
6
6
  const workflows_sdk_2 = require("@medusajs/framework/workflows-sdk");
7
- const validators_1 = require("@medusajs/medusa/api/utils/validators");
8
- exports.GetReviewsSchema = (0, validators_1.createFindParams)({
9
- order: "-created_at",
7
+ const z_1 = require("../../utils/z");
8
+ const numberParam = (schema) => z_1.z.preprocess((val) => {
9
+ if (val === undefined || val === null || val === "") {
10
+ return undefined;
11
+ }
12
+ if (typeof val === "string") {
13
+ const parsed = Number(val);
14
+ return Number.isNaN(parsed) ? undefined : parsed;
15
+ }
16
+ return val;
17
+ }, schema.optional());
18
+ const booleanParam = () => z_1.z.preprocess((val) => {
19
+ if (val === undefined || val === null || val === "") {
20
+ return undefined;
21
+ }
22
+ if (typeof val === "string") {
23
+ if (val.toLowerCase() === "true") {
24
+ return true;
25
+ }
26
+ if (val.toLowerCase() === "false") {
27
+ return false;
28
+ }
29
+ }
30
+ return val;
31
+ }, z_1.z.boolean().optional());
32
+ exports.GetReviewsSchema = z_1.z.object({
33
+ limit: numberParam(z_1.z.number().int().positive()),
34
+ offset: numberParam(z_1.z.number().int().min(0)),
35
+ order: z_1.z.string().optional(),
36
+ fields: z_1.z.string().optional(),
37
+ with_deleted: booleanParam(),
38
+ product_id: z_1.z.string().optional(),
39
+ status: z_1.z.enum(["pending", "approved", "rejected"]).optional(),
40
+ parent: z_1.z
41
+ .preprocess((val) => {
42
+ if (val === undefined) {
43
+ return undefined;
44
+ }
45
+ if (val === null) {
46
+ return null;
47
+ }
48
+ if (typeof val === "string") {
49
+ return val.toLowerCase() === "null" ? null : val;
50
+ }
51
+ return undefined;
52
+ }, z_1.z.union([z_1.z.string(), z_1.z.null()]).optional())
53
+ .optional(),
10
54
  });
11
55
  const getReviewsStep = (0, workflows_sdk_2.createStep)("get-reviews-step", async (input) => {
12
56
  const query = framework_1.container.resolve("query");
@@ -44,4 +88,4 @@ exports.getReviewsWorkflow = (0, workflows_sdk_1.createWorkflow)("get-reviews",
44
88
  const reviews = getReviewsStep(input);
45
89
  return new workflows_sdk_1.WorkflowResponse(reviews);
46
90
  });
47
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZ2V0UmV2aWV3c1dvcmtmbG93LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vc3JjL3dvcmtmbG93cy9yZXZpZXcvZ2V0UmV2aWV3c1dvcmtmbG93LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUFBLHFFQUcyQztBQUUzQyxtREFBK0Q7QUFDL0QscUVBQTZFO0FBQzdFLHNFQUF5RTtBQUU1RCxRQUFBLGdCQUFnQixHQUFHLElBQUEsNkJBQWdCLEVBQUM7SUFDL0MsS0FBSyxFQUFFLGFBQWE7Q0FDckIsQ0FBQyxDQUFDO0FBV0gsTUFBTSxjQUFjLEdBQUcsSUFBQSwwQkFBVSxFQUMvQixrQkFBa0IsRUFDbEIsS0FBSyxFQUFFLEtBQXNCLEVBQUUsRUFBRTtJQUMvQixNQUFNLEtBQUssR0FBRyxxQkFBUyxDQUFDLE9BQU8sQ0FBQyxPQUFPLENBQUMsQ0FBQztJQUV6QyxNQUFNLEVBQ0osSUFBSSxFQUFFLE9BQU8sRUFDYixRQUFRLEVBQUUsRUFBRSxLQUFLLEVBQUUsSUFBSSxFQUFFLElBQUksRUFBRSxHQUFHO1FBQ2hDLEtBQUssRUFBRSxDQUFDO1FBQ1IsSUFBSSxFQUFFLEVBQUU7UUFDUixJQUFJLEVBQUUsQ0FBQztLQUNSLEdBQ0YsR0FBRyxNQUFNLEtBQUssQ0FBQyxLQUFLLENBQUM7UUFDcEIsTUFBTSxFQUFFLFFBQVE7UUFDaEIsR0FBRyxLQUFLLENBQUMsV0FBVztRQUNwQixNQUFNLEVBQUU7WUFDTixHQUFHO1lBQ0gsZUFBZTtZQUNmLFlBQVk7WUFDWixVQUFVO1lBQ1YsWUFBWTtZQUNaLG1CQUFtQjtTQUNwQjtRQUNELE9BQU8sRUFBRSxLQUFLLENBQUMsT0FBTztLQUN2QixDQUFDLENBQUM7SUFFSCxNQUFNLHdCQUF3QixHQUFHLE9BQU8sQ0FBQyxHQUFHLENBQUMsQ0FBQyxNQUFNLEVBQUUsRUFBRTtRQUN0RCxPQUFPO1lBQ0wsR0FBRyxNQUFNO1lBQ1QsUUFBUSxFQUFFLE1BQU0sQ0FBQyxRQUFRLEVBQUUsSUFBSSxDQUM3QixDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsRUFBRSxDQUNQLElBQUksSUFBSSxDQUFDLENBQUMsQ0FBQyxVQUFVLENBQUMsQ0FBQyxPQUFPLEVBQUUsR0FBRyxJQUFJLElBQUksQ0FBQyxDQUFDLENBQUMsVUFBVSxDQUFDLENBQUMsT0FBTyxFQUFFLENBQ3RFO1NBQ0YsQ0FBQztJQUNKLENBQUMsQ0FBQyxDQUFDO0lBRUgsT0FBTyxJQUFJLDRCQUFZLENBQUM7UUFDdEIsT0FBTyxFQUFFLHdCQUF3QjtRQUNqQyxLQUFLO1FBQ0wsS0FBSyxFQUFFLElBQUk7UUFDWCxNQUFNLEVBQUUsSUFBSTtLQUNiLENBQUMsQ0FBQztBQUNMLENBQUMsQ0FDRixDQUFDO0FBRVcsUUFBQSxrQkFBa0IsR0FBRyxJQUFBLDhCQUFjLEVBQzlDLGFBQWEsRUFDYixDQUFDLEtBQXNCLEVBQUUsRUFBRTtJQUN6QixNQUFNLE9BQU8sR0FBRyxjQUFjLENBQUMsS0FBSyxDQUFDLENBQUM7SUFFdEMsT0FBTyxJQUFJLGdDQUFnQixDQUFDLE9BQU8sQ0FBQyxDQUFDO0FBQ3ZDLENBQUMsQ0FDRixDQUFDIn0=
91
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZ2V0UmV2aWV3c1dvcmtmbG93LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vc3JjL3dvcmtmbG93cy9yZXZpZXcvZ2V0UmV2aWV3c1dvcmtmbG93LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUFBLHFFQUcyQztBQUUzQyxtREFBK0Q7QUFDL0QscUVBQTZFO0FBRTdFLHFDQUFrQztBQUVsQyxNQUFNLFdBQVcsR0FBRyxDQUFDLE1BQXFCLEVBQUUsRUFBRSxDQUM1QyxLQUFDLENBQUMsVUFBVSxDQUFDLENBQUMsR0FBRyxFQUFFLEVBQUU7SUFDbkIsSUFBSSxHQUFHLEtBQUssU0FBUyxJQUFJLEdBQUcsS0FBSyxJQUFJLElBQUksR0FBRyxLQUFLLEVBQUUsRUFBRSxDQUFDO1FBQ3BELE9BQU8sU0FBUyxDQUFDO0lBQ25CLENBQUM7SUFFRCxJQUFJLE9BQU8sR0FBRyxLQUFLLFFBQVEsRUFBRSxDQUFDO1FBQzVCLE1BQU0sTUFBTSxHQUFHLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQztRQUMzQixPQUFPLE1BQU0sQ0FBQyxLQUFLLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDO0lBQ25ELENBQUM7SUFFRCxPQUFPLEdBQUcsQ0FBQztBQUNiLENBQUMsRUFBRSxNQUFNLENBQUMsUUFBUSxFQUFFLENBQUMsQ0FBQztBQUV4QixNQUFNLFlBQVksR0FBRyxHQUFHLEVBQUUsQ0FDeEIsS0FBQyxDQUFDLFVBQVUsQ0FBQyxDQUFDLEdBQUcsRUFBRSxFQUFFO0lBQ25CLElBQUksR0FBRyxLQUFLLFNBQVMsSUFBSSxHQUFHLEtBQUssSUFBSSxJQUFJLEdBQUcsS0FBSyxFQUFFLEVBQUUsQ0FBQztRQUNwRCxPQUFPLFNBQVMsQ0FBQztJQUNuQixDQUFDO0lBRUQsSUFBSSxPQUFPLEdBQUcsS0FBSyxRQUFRLEVBQUUsQ0FBQztRQUM1QixJQUFJLEdBQUcsQ0FBQyxXQUFXLEVBQUUsS0FBSyxNQUFNLEVBQUUsQ0FBQztZQUNqQyxPQUFPLElBQUksQ0FBQztRQUNkLENBQUM7UUFFRCxJQUFJLEdBQUcsQ0FBQyxXQUFXLEVBQUUsS0FBSyxPQUFPLEVBQUUsQ0FBQztZQUNsQyxPQUFPLEtBQUssQ0FBQztRQUNmLENBQUM7SUFDSCxDQUFDO0lBRUQsT0FBTyxHQUFHLENBQUM7QUFDYixDQUFDLEVBQUUsS0FBQyxDQUFDLE9BQU8sRUFBRSxDQUFDLFFBQVEsRUFBRSxDQUFDLENBQUM7QUFFaEIsUUFBQSxnQkFBZ0IsR0FBRyxLQUFDLENBQUMsTUFBTSxDQUFDO0lBQ3ZDLEtBQUssRUFBRSxXQUFXLENBQUMsS0FBQyxDQUFDLE1BQU0sRUFBRSxDQUFDLEdBQUcsRUFBRSxDQUFDLFFBQVEsRUFBRSxDQUFDO0lBQy9DLE1BQU0sRUFBRSxXQUFXLENBQUMsS0FBQyxDQUFDLE1BQU0sRUFBRSxDQUFDLEdBQUcsRUFBRSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUM1QyxLQUFLLEVBQUUsS0FBQyxDQUFDLE1BQU0sRUFBRSxDQUFDLFFBQVEsRUFBRTtJQUM1QixNQUFNLEVBQUUsS0FBQyxDQUFDLE1BQU0sRUFBRSxDQUFDLFFBQVEsRUFBRTtJQUM3QixZQUFZLEVBQUUsWUFBWSxFQUFFO0lBQzVCLFVBQVUsRUFBRSxLQUFDLENBQUMsTUFBTSxFQUFFLENBQUMsUUFBUSxFQUFFO0lBQ2pDLE1BQU0sRUFBRSxLQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsU0FBUyxFQUFFLFVBQVUsRUFBRSxVQUFVLENBQUMsQ0FBQyxDQUFDLFFBQVEsRUFBRTtJQUM5RCxNQUFNLEVBQUUsS0FBQztTQUNOLFVBQVUsQ0FBQyxDQUFDLEdBQUcsRUFBRSxFQUFFO1FBQ2xCLElBQUksR0FBRyxLQUFLLFNBQVMsRUFBRSxDQUFDO1lBQ3RCLE9BQU8sU0FBUyxDQUFDO1FBQ25CLENBQUM7UUFFRCxJQUFJLEdBQUcsS0FBSyxJQUFJLEVBQUUsQ0FBQztZQUNqQixPQUFPLElBQUksQ0FBQztRQUNkLENBQUM7UUFFRCxJQUFJLE9BQU8sR0FBRyxLQUFLLFFBQVEsRUFBRSxDQUFDO1lBQzVCLE9BQU8sR0FBRyxDQUFDLFdBQVcsRUFBRSxLQUFLLE1BQU0sQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUM7UUFDbkQsQ0FBQztRQUVELE9BQU8sU0FBUyxDQUFDO0lBQ25CLENBQUMsRUFBRSxLQUFDLENBQUMsS0FBSyxDQUFDLENBQUMsS0FBQyxDQUFDLE1BQU0sRUFBRSxFQUFFLEtBQUMsQ0FBQyxJQUFJLEVBQUUsQ0FBQyxDQUFDLENBQUMsUUFBUSxFQUFFLENBQUM7U0FDN0MsUUFBUSxFQUFFO0NBQ2QsQ0FBQyxDQUFDO0FBYUgsTUFBTSxjQUFjLEdBQUcsSUFBQSwwQkFBVSxFQUMvQixrQkFBa0IsRUFDbEIsS0FBSyxFQUFFLEtBQXNCLEVBQUUsRUFBRTtJQUMvQixNQUFNLEtBQUssR0FBRyxxQkFBUyxDQUFDLE9BQU8sQ0FBQyxPQUFPLENBQUMsQ0FBQztJQUV6QyxNQUFNLEVBQ0osSUFBSSxFQUFFLE9BQU8sRUFDYixRQUFRLEVBQUUsRUFBRSxLQUFLLEVBQUUsSUFBSSxFQUFFLElBQUksRUFBRSxHQUFHO1FBQ2hDLEtBQUssRUFBRSxDQUFDO1FBQ1IsSUFBSSxFQUFFLEVBQUU7UUFDUixJQUFJLEVBQUUsQ0FBQztLQUNSLEdBQ0YsR0FBRyxNQUFNLEtBQUssQ0FBQyxLQUFLLENBQUM7UUFDcEIsTUFBTSxFQUFFLFFBQVE7UUFDaEIsR0FBRyxLQUFLLENBQUMsV0FBVztRQUNwQixNQUFNLEVBQUU7WUFDTixHQUFHO1lBQ0gsZUFBZTtZQUNmLFlBQVk7WUFDWixVQUFVO1lBQ1YsWUFBWTtZQUNaLG1CQUFtQjtTQUNwQjtRQUNELE9BQU8sRUFBRSxLQUFLLENBQUMsT0FBTztLQUN2QixDQUFDLENBQUM7SUFFSCxNQUFNLHdCQUF3QixHQUFHLE9BQU8sQ0FBQyxHQUFHLENBQUMsQ0FBQyxNQUFNLEVBQUUsRUFBRTtRQUN0RCxPQUFPO1lBQ0wsR0FBRyxNQUFNO1lBQ1QsUUFBUSxFQUFFLE1BQU0sQ0FBQyxRQUFRLEVBQUUsSUFBSSxDQUM3QixDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsRUFBRSxDQUNQLElBQUksSUFBSSxDQUFDLENBQUMsQ0FBQyxVQUFVLENBQUMsQ0FBQyxPQUFPLEVBQUUsR0FBRyxJQUFJLElBQUksQ0FBQyxDQUFDLENBQUMsVUFBVSxDQUFDLENBQUMsT0FBTyxFQUFFLENBQ3RFO1NBQ0YsQ0FBQztJQUNKLENBQUMsQ0FBQyxDQUFDO0lBRUgsT0FBTyxJQUFJLDRCQUFZLENBQUM7UUFDdEIsT0FBTyxFQUFFLHdCQUF3QjtRQUNqQyxLQUFLO1FBQ0wsS0FBSyxFQUFFLElBQUk7UUFDWCxNQUFNLEVBQUUsSUFBSTtLQUNiLENBQUMsQ0FBQztBQUNMLENBQUMsQ0FDRixDQUFDO0FBRVcsUUFBQSxrQkFBa0IsR0FBRyxJQUFBLDhCQUFjLEVBQzlDLGFBQWEsRUFDYixDQUFDLEtBQXNCLEVBQUUsRUFBRTtJQUN6QixNQUFNLE9BQU8sR0FBRyxjQUFjLENBQUMsS0FBSyxDQUFDLENBQUM7SUFFdEMsT0FBTyxJQUFJLGdDQUFnQixDQUFDLE9BQU8sQ0FBQyxDQUFDO0FBQ3ZDLENBQUMsQ0FDRixDQUFDIn0=
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lodashventure/medusa-review",
3
- "version": "1.4.18",
3
+ "version": "1.4.20",
4
4
  "description": "A starter for Medusa plugins.",
5
5
  "author": "Medusa (https://medusajs.com)",
6
6
  "license": "MIT",