elseware-ui 2.36.8 → 2.37.0
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.
- package/dist/index.css +240 -12
- package/dist/index.css.map +1 -1
- package/dist/index.d.mts +483 -2
- package/dist/index.d.ts +483 -2
- package/dist/index.js +1596 -3
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1572 -5
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -18,7 +18,7 @@ import { DragDropContext, Droppable, Draggable } from 'react-beautiful-dnd';
|
|
|
18
18
|
import { MdUpload, MdOutlineDone, MdOutlineRemoveCircleOutline } from 'react-icons/md';
|
|
19
19
|
import '@mdxeditor/editor/style.css';
|
|
20
20
|
import { MDXEditor, headingsPlugin, linkPlugin, listsPlugin, imagePlugin, tablePlugin, linkDialogPlugin, thematicBreakPlugin, quotePlugin, toolbarPlugin, UndoRedo, Separator, BlockTypeSelect, BoldItalicUnderlineToggles, StrikeThroughSupSubToggles, ListsToggle, CreateLink, InsertImage, InsertTable, InsertThematicBreak, markdownShortcutPlugin, frontmatterPlugin, codeBlockPlugin, codeMirrorPlugin } from '@mdxeditor/editor';
|
|
21
|
-
import { BiChevronDown, BiChevronUp, BiSolidLike, BiLike, BiSolidDislike, BiDislike, BiDotsVerticalRounded, BiEdit, BiTrash, BiFlag } from 'react-icons/bi';
|
|
21
|
+
import { BiCheckCircle, BiXCircle, BiChevronDown, BiChevronUp, BiSolidLike, BiLike, BiSolidDislike, BiDislike, BiDotsVerticalRounded, BiReply, BiEdit, BiTrash, BiFlag } from 'react-icons/bi';
|
|
22
22
|
|
|
23
23
|
// node_modules/clsx/dist/clsx.mjs
|
|
24
24
|
function r(e) {
|
|
@@ -21050,12 +21050,12 @@ function AsyncStateCard({
|
|
|
21050
21050
|
className
|
|
21051
21051
|
}) {
|
|
21052
21052
|
const isError = type === "error";
|
|
21053
|
-
return /* @__PURE__ */ jsx(
|
|
21053
|
+
return /* @__PURE__ */ jsx(
|
|
21054
21054
|
Card_default,
|
|
21055
21055
|
{
|
|
21056
21056
|
ghost: true,
|
|
21057
21057
|
borderVariant: isError ? "danger" : "secondary",
|
|
21058
|
-
styles: cn("w-full
|
|
21058
|
+
styles: cn("w-full", className),
|
|
21059
21059
|
children: /* @__PURE__ */ jsx(CardContent_default, { children: /* @__PURE__ */ jsxs("div", { className: "flex flex-col items-center justify-center gap-5 px-4 py-8 text-center", children: [
|
|
21060
21060
|
/* @__PURE__ */ jsx(
|
|
21061
21061
|
"div",
|
|
@@ -21085,7 +21085,7 @@ function AsyncStateCard({
|
|
|
21085
21085
|
)
|
|
21086
21086
|
] }) })
|
|
21087
21087
|
}
|
|
21088
|
-
)
|
|
21088
|
+
);
|
|
21089
21089
|
}
|
|
21090
21090
|
var AsyncStateCard_default = React2.memo(AsyncStateCard);
|
|
21091
21091
|
|
|
@@ -22948,6 +22948,1573 @@ var TopNav = ({
|
|
|
22948
22948
|
};
|
|
22949
22949
|
return /* @__PURE__ */ jsx("div", { className: "flex items-center", children: items.map(renderNode) });
|
|
22950
22950
|
};
|
|
22951
|
+
function ReviewForm({
|
|
22952
|
+
initialValues,
|
|
22953
|
+
placeholder = "Write your review...",
|
|
22954
|
+
submitLabel = "Submit",
|
|
22955
|
+
cancelLabel = "Cancel",
|
|
22956
|
+
loading = false,
|
|
22957
|
+
disabled = false,
|
|
22958
|
+
autoFocus = false,
|
|
22959
|
+
config,
|
|
22960
|
+
onSubmit,
|
|
22961
|
+
onCancel
|
|
22962
|
+
}) {
|
|
22963
|
+
const [content, setContent] = useState(initialValues?.content ?? "");
|
|
22964
|
+
const [rating, setRating] = useState(initialValues?.rating ?? 0);
|
|
22965
|
+
const [isRecommended, setIsRecommended] = useState(
|
|
22966
|
+
initialValues?.isRecommended ?? true
|
|
22967
|
+
);
|
|
22968
|
+
const [error, setError] = useState("");
|
|
22969
|
+
const contentLength = content.trim().length;
|
|
22970
|
+
const ratingItems = useMemo(() => {
|
|
22971
|
+
return Array.from(
|
|
22972
|
+
{
|
|
22973
|
+
length: config.maxRating
|
|
22974
|
+
},
|
|
22975
|
+
(_, index) => index + 1
|
|
22976
|
+
);
|
|
22977
|
+
}, [config.maxRating]);
|
|
22978
|
+
useEffect(() => {
|
|
22979
|
+
setContent(initialValues?.content ?? "");
|
|
22980
|
+
setRating(initialValues?.rating ?? 0);
|
|
22981
|
+
setIsRecommended(initialValues?.isRecommended ?? true);
|
|
22982
|
+
setError("");
|
|
22983
|
+
}, [
|
|
22984
|
+
initialValues?.content,
|
|
22985
|
+
initialValues?.rating,
|
|
22986
|
+
initialValues?.isRecommended
|
|
22987
|
+
]);
|
|
22988
|
+
function validate() {
|
|
22989
|
+
const trimmedContent = content.trim();
|
|
22990
|
+
if (trimmedContent.length < config.minContentLength) {
|
|
22991
|
+
return `Review must be at least ${config.minContentLength} characters.`;
|
|
22992
|
+
}
|
|
22993
|
+
if (trimmedContent.length > config.maxContentLength) {
|
|
22994
|
+
return `Review cannot be more than ${config.maxContentLength} characters.`;
|
|
22995
|
+
}
|
|
22996
|
+
if (rating < config.minRating) {
|
|
22997
|
+
return "Please select a rating.";
|
|
22998
|
+
}
|
|
22999
|
+
return "";
|
|
23000
|
+
}
|
|
23001
|
+
async function handleSubmit() {
|
|
23002
|
+
const nextError = validate();
|
|
23003
|
+
if (nextError) {
|
|
23004
|
+
setError(nextError);
|
|
23005
|
+
return;
|
|
23006
|
+
}
|
|
23007
|
+
const values = {
|
|
23008
|
+
content: content.trim(),
|
|
23009
|
+
rating,
|
|
23010
|
+
isRecommended: config.allowRecommendation ? isRecommended : void 0
|
|
23011
|
+
};
|
|
23012
|
+
await onSubmit(values);
|
|
23013
|
+
}
|
|
23014
|
+
return /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-4", children: [
|
|
23015
|
+
/* @__PURE__ */ jsx(
|
|
23016
|
+
"textarea",
|
|
23017
|
+
{
|
|
23018
|
+
value: content,
|
|
23019
|
+
disabled: disabled || loading,
|
|
23020
|
+
autoFocus,
|
|
23021
|
+
placeholder,
|
|
23022
|
+
maxLength: config.maxContentLength,
|
|
23023
|
+
onChange: (event) => {
|
|
23024
|
+
setContent(event.target.value);
|
|
23025
|
+
setError("");
|
|
23026
|
+
},
|
|
23027
|
+
className: "min-h-[120px] w-full resize-none rounded-xl border border-gray-300 bg-white px-4 py-3 text-sm text-gray-900 outline-none transition-colors placeholder:text-gray-400 focus:border-blue-500 disabled:cursor-not-allowed disabled:opacity-60 dark:border-neutral-700 dark:bg-neutral-900 dark:text-gray-100 dark:placeholder:text-gray-500"
|
|
23028
|
+
}
|
|
23029
|
+
),
|
|
23030
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between gap-3 text-xs text-gray-500 dark:text-gray-400", children: [
|
|
23031
|
+
/* @__PURE__ */ jsxs("span", { children: [
|
|
23032
|
+
contentLength,
|
|
23033
|
+
"/",
|
|
23034
|
+
config.maxContentLength
|
|
23035
|
+
] }),
|
|
23036
|
+
error && /* @__PURE__ */ jsx("span", { className: "text-red-500", children: error })
|
|
23037
|
+
] }),
|
|
23038
|
+
/* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-2", children: [
|
|
23039
|
+
/* @__PURE__ */ jsx("span", { className: "text-sm font-medium text-gray-700 dark:text-gray-300", children: "Rating" }),
|
|
23040
|
+
/* @__PURE__ */ jsx("div", { className: "flex items-center gap-1", children: ratingItems.map((item) => {
|
|
23041
|
+
const active = item <= rating;
|
|
23042
|
+
return /* @__PURE__ */ jsx(
|
|
23043
|
+
"button",
|
|
23044
|
+
{
|
|
23045
|
+
type: "button",
|
|
23046
|
+
disabled: disabled || loading,
|
|
23047
|
+
onClick: () => {
|
|
23048
|
+
setRating(item);
|
|
23049
|
+
setError("");
|
|
23050
|
+
},
|
|
23051
|
+
className: `
|
|
23052
|
+
text-2xl leading-none transition-transform disabled:cursor-not-allowed disabled:opacity-60
|
|
23053
|
+
${active ? "text-yellow-400" : "text-gray-300 dark:text-neutral-700"}
|
|
23054
|
+
hover:scale-110
|
|
23055
|
+
`,
|
|
23056
|
+
"aria-label": `Rate ${item} out of ${config.maxRating}`,
|
|
23057
|
+
children: "\u2605"
|
|
23058
|
+
},
|
|
23059
|
+
item
|
|
23060
|
+
);
|
|
23061
|
+
}) })
|
|
23062
|
+
] }),
|
|
23063
|
+
config.allowRecommendation && /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-2", children: [
|
|
23064
|
+
/* @__PURE__ */ jsx("span", { className: "text-sm font-medium text-gray-700 dark:text-gray-300", children: "Do you recommend this?" }),
|
|
23065
|
+
/* @__PURE__ */ jsxs("div", { className: "flex flex-wrap gap-3", children: [
|
|
23066
|
+
/* @__PURE__ */ jsxs("label", { className: "inline-flex cursor-pointer items-center gap-2 text-sm text-gray-700 dark:text-gray-300", children: [
|
|
23067
|
+
/* @__PURE__ */ jsx(
|
|
23068
|
+
"input",
|
|
23069
|
+
{
|
|
23070
|
+
type: "radio",
|
|
23071
|
+
checked: isRecommended,
|
|
23072
|
+
disabled: disabled || loading,
|
|
23073
|
+
onChange: () => setIsRecommended(true)
|
|
23074
|
+
}
|
|
23075
|
+
),
|
|
23076
|
+
"Yes"
|
|
23077
|
+
] }),
|
|
23078
|
+
/* @__PURE__ */ jsxs("label", { className: "inline-flex cursor-pointer items-center gap-2 text-sm text-gray-700 dark:text-gray-300", children: [
|
|
23079
|
+
/* @__PURE__ */ jsx(
|
|
23080
|
+
"input",
|
|
23081
|
+
{
|
|
23082
|
+
type: "radio",
|
|
23083
|
+
checked: !isRecommended,
|
|
23084
|
+
disabled: disabled || loading,
|
|
23085
|
+
onChange: () => setIsRecommended(false)
|
|
23086
|
+
}
|
|
23087
|
+
),
|
|
23088
|
+
"No"
|
|
23089
|
+
] })
|
|
23090
|
+
] })
|
|
23091
|
+
] }),
|
|
23092
|
+
/* @__PURE__ */ jsxs("div", { className: "flex justify-end gap-2", children: [
|
|
23093
|
+
onCancel && /* @__PURE__ */ jsx(
|
|
23094
|
+
Button_default,
|
|
23095
|
+
{
|
|
23096
|
+
text: cancelLabel,
|
|
23097
|
+
variant: "secondary",
|
|
23098
|
+
appearance: "ghost",
|
|
23099
|
+
disabled: loading,
|
|
23100
|
+
onClick: onCancel
|
|
23101
|
+
}
|
|
23102
|
+
),
|
|
23103
|
+
/* @__PURE__ */ jsx(
|
|
23104
|
+
Button_default,
|
|
23105
|
+
{
|
|
23106
|
+
text: submitLabel,
|
|
23107
|
+
variant: "primary",
|
|
23108
|
+
loading,
|
|
23109
|
+
disabled: disabled || !content.trim() || rating < config.minRating,
|
|
23110
|
+
onClick: handleSubmit
|
|
23111
|
+
}
|
|
23112
|
+
)
|
|
23113
|
+
] })
|
|
23114
|
+
] });
|
|
23115
|
+
}
|
|
23116
|
+
var ReviewForm_default = ReviewForm;
|
|
23117
|
+
function ReviewComposer({
|
|
23118
|
+
currentUser,
|
|
23119
|
+
placeholder = "Write your review...",
|
|
23120
|
+
submitLabel = "Post Review",
|
|
23121
|
+
loading = false,
|
|
23122
|
+
disabled = false,
|
|
23123
|
+
config,
|
|
23124
|
+
onLoginClick,
|
|
23125
|
+
onSubmit
|
|
23126
|
+
}) {
|
|
23127
|
+
if (!currentUser) {
|
|
23128
|
+
return /* @__PURE__ */ jsx("div", { className: "rounded-xl border border-gray-200 bg-white p-4 dark:border-neutral-800 dark:bg-neutral-900", children: /* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-center justify-between gap-3", children: [
|
|
23129
|
+
/* @__PURE__ */ jsx("p", { className: "text-sm text-gray-600 dark:text-gray-400", children: "Please login to post your review." }),
|
|
23130
|
+
onLoginClick && /* @__PURE__ */ jsx(Button_default, { text: "Login", variant: "primary", onClick: onLoginClick })
|
|
23131
|
+
] }) });
|
|
23132
|
+
}
|
|
23133
|
+
return /* @__PURE__ */ jsx("div", { className: "rounded-xl border border-gray-200 bg-white p-4 dark:border-neutral-800 dark:bg-neutral-900", children: /* @__PURE__ */ jsxs("div", { className: "flex gap-4", children: [
|
|
23134
|
+
/* @__PURE__ */ jsx(Avatar, { src: currentUser.avatar, size: "md" }),
|
|
23135
|
+
/* @__PURE__ */ jsx("div", { className: "min-w-0 flex-1", children: /* @__PURE__ */ jsx(
|
|
23136
|
+
ReviewForm_default,
|
|
23137
|
+
{
|
|
23138
|
+
placeholder,
|
|
23139
|
+
submitLabel,
|
|
23140
|
+
loading,
|
|
23141
|
+
disabled,
|
|
23142
|
+
config,
|
|
23143
|
+
onSubmit
|
|
23144
|
+
}
|
|
23145
|
+
) })
|
|
23146
|
+
] }) });
|
|
23147
|
+
}
|
|
23148
|
+
var ReviewComposer_default = ReviewComposer;
|
|
23149
|
+
|
|
23150
|
+
// src/compositions/review-thread/utils/formatReviewDate.ts
|
|
23151
|
+
function formatReviewDate(date, format = "relative") {
|
|
23152
|
+
if (!date) {
|
|
23153
|
+
return "";
|
|
23154
|
+
}
|
|
23155
|
+
const target = new Date(date);
|
|
23156
|
+
if (Number.isNaN(target.getTime())) {
|
|
23157
|
+
return "";
|
|
23158
|
+
}
|
|
23159
|
+
if (format === "absolute") {
|
|
23160
|
+
return target.toLocaleString();
|
|
23161
|
+
}
|
|
23162
|
+
const now = /* @__PURE__ */ new Date();
|
|
23163
|
+
const seconds = Math.floor((now.getTime() - target.getTime()) / 1e3);
|
|
23164
|
+
if (seconds < 60) {
|
|
23165
|
+
return "Just now";
|
|
23166
|
+
}
|
|
23167
|
+
const intervals = [
|
|
23168
|
+
{
|
|
23169
|
+
label: "year",
|
|
23170
|
+
seconds: 31536e3
|
|
23171
|
+
},
|
|
23172
|
+
{
|
|
23173
|
+
label: "month",
|
|
23174
|
+
seconds: 2592e3
|
|
23175
|
+
},
|
|
23176
|
+
{
|
|
23177
|
+
label: "day",
|
|
23178
|
+
seconds: 86400
|
|
23179
|
+
},
|
|
23180
|
+
{
|
|
23181
|
+
label: "hour",
|
|
23182
|
+
seconds: 3600
|
|
23183
|
+
},
|
|
23184
|
+
{
|
|
23185
|
+
label: "minute",
|
|
23186
|
+
seconds: 60
|
|
23187
|
+
}
|
|
23188
|
+
];
|
|
23189
|
+
for (const interval of intervals) {
|
|
23190
|
+
const count = Math.floor(seconds / interval.seconds);
|
|
23191
|
+
if (count >= 1) {
|
|
23192
|
+
return `${count} ${interval.label}${count > 1 ? "s" : ""} ago`;
|
|
23193
|
+
}
|
|
23194
|
+
}
|
|
23195
|
+
return "Just now";
|
|
23196
|
+
}
|
|
23197
|
+
|
|
23198
|
+
// src/compositions/review-thread/utils/reviewState.ts
|
|
23199
|
+
function prependReview(reviews, review) {
|
|
23200
|
+
return [review, ...reviews.filter((item) => item.id !== review.id)];
|
|
23201
|
+
}
|
|
23202
|
+
function appendReview(reviews, review) {
|
|
23203
|
+
return [...reviews.filter((item) => item.id !== review.id), review];
|
|
23204
|
+
}
|
|
23205
|
+
function updateReview(reviews, reviewId, updater) {
|
|
23206
|
+
return reviews.map(
|
|
23207
|
+
(review) => review.id === reviewId ? updater(review) : review
|
|
23208
|
+
);
|
|
23209
|
+
}
|
|
23210
|
+
function replaceReview(reviews, nextReview) {
|
|
23211
|
+
return updateReview(reviews, nextReview.id, () => nextReview);
|
|
23212
|
+
}
|
|
23213
|
+
function removeReview(reviews, reviewId) {
|
|
23214
|
+
return reviews.filter((review) => review.id !== reviewId);
|
|
23215
|
+
}
|
|
23216
|
+
function findReview(reviews, reviewId) {
|
|
23217
|
+
return reviews.find((review) => review.id === reviewId);
|
|
23218
|
+
}
|
|
23219
|
+
function upsertReview(reviews, review) {
|
|
23220
|
+
const exists = reviews.some((item) => item.id === review.id);
|
|
23221
|
+
if (!exists) {
|
|
23222
|
+
return prependReview(reviews, review);
|
|
23223
|
+
}
|
|
23224
|
+
return replaceReview(reviews, review);
|
|
23225
|
+
}
|
|
23226
|
+
|
|
23227
|
+
// src/compositions/review-thread/utils/reviewReplyState.ts
|
|
23228
|
+
function addReviewReply(review, reply, maxReplies = 1) {
|
|
23229
|
+
const replies = review.replies ?? [];
|
|
23230
|
+
return {
|
|
23231
|
+
...review,
|
|
23232
|
+
replies: [reply, ...replies.filter((item) => item.id !== reply.id)].slice(
|
|
23233
|
+
0,
|
|
23234
|
+
maxReplies
|
|
23235
|
+
)
|
|
23236
|
+
};
|
|
23237
|
+
}
|
|
23238
|
+
function updateReviewReply(review, replyId, updater) {
|
|
23239
|
+
return {
|
|
23240
|
+
...review,
|
|
23241
|
+
replies: (review.replies ?? []).map(
|
|
23242
|
+
(reply) => reply.id === replyId ? updater(reply) : reply
|
|
23243
|
+
)
|
|
23244
|
+
};
|
|
23245
|
+
}
|
|
23246
|
+
function replaceReviewReply(review, nextReply) {
|
|
23247
|
+
return updateReviewReply(review, nextReply.id, () => nextReply);
|
|
23248
|
+
}
|
|
23249
|
+
function removeReviewReply(review, replyId) {
|
|
23250
|
+
return {
|
|
23251
|
+
...review,
|
|
23252
|
+
replies: (review.replies ?? []).filter((reply) => reply.id !== replyId)
|
|
23253
|
+
};
|
|
23254
|
+
}
|
|
23255
|
+
function hasReviewReply(review, replyId) {
|
|
23256
|
+
return (review.replies ?? []).some((reply) => reply.id === replyId);
|
|
23257
|
+
}
|
|
23258
|
+
|
|
23259
|
+
// src/compositions/review-thread/utils/reviewPermissions.ts
|
|
23260
|
+
function canEditReview(review) {
|
|
23261
|
+
return review.permissions?.canEdit ?? false;
|
|
23262
|
+
}
|
|
23263
|
+
function canDeleteReview(review) {
|
|
23264
|
+
return review.permissions?.canDelete ?? false;
|
|
23265
|
+
}
|
|
23266
|
+
function canReportReview(review) {
|
|
23267
|
+
return review.permissions?.canReport ?? false;
|
|
23268
|
+
}
|
|
23269
|
+
function canReplyToReview(review) {
|
|
23270
|
+
return review.permissions?.canReply ?? false;
|
|
23271
|
+
}
|
|
23272
|
+
function canEditReviewReply(reply) {
|
|
23273
|
+
return reply.permissions?.canEdit ?? false;
|
|
23274
|
+
}
|
|
23275
|
+
function canDeleteReviewReply(reply) {
|
|
23276
|
+
return reply.permissions?.canDelete ?? false;
|
|
23277
|
+
}
|
|
23278
|
+
function canReportReviewReply(reply) {
|
|
23279
|
+
return reply.permissions?.canReport ?? false;
|
|
23280
|
+
}
|
|
23281
|
+
|
|
23282
|
+
// src/compositions/review-thread/utils/normalizeReview.ts
|
|
23283
|
+
function normalizeReviewAuthor(author) {
|
|
23284
|
+
if (!author) {
|
|
23285
|
+
return null;
|
|
23286
|
+
}
|
|
23287
|
+
return {
|
|
23288
|
+
id: String(author.id ?? author._id ?? ""),
|
|
23289
|
+
username: author.username,
|
|
23290
|
+
avatar: author.avatar,
|
|
23291
|
+
firstName: author.firstName,
|
|
23292
|
+
lastName: author.lastName,
|
|
23293
|
+
role: author.role
|
|
23294
|
+
};
|
|
23295
|
+
}
|
|
23296
|
+
function normalizeReviewReply(raw, fallback) {
|
|
23297
|
+
return {
|
|
23298
|
+
id: String(raw.id ?? raw._id ?? ""),
|
|
23299
|
+
targetId: String(raw.targetId ?? fallback.targetId),
|
|
23300
|
+
reviewId: String(raw.reviewId ?? fallback.reviewId),
|
|
23301
|
+
content: String(raw.content ?? raw.replyText ?? raw.responseText ?? ""),
|
|
23302
|
+
createdAt: String(raw.createdAt ?? (/* @__PURE__ */ new Date()).toISOString()),
|
|
23303
|
+
updatedAt: raw.updatedAt,
|
|
23304
|
+
edited: raw.edited ?? false,
|
|
23305
|
+
author: normalizeReviewAuthor(raw.author ?? raw.repliedBy ?? null),
|
|
23306
|
+
authorLabel: raw.authorLabel,
|
|
23307
|
+
permissions: raw.permissions
|
|
23308
|
+
};
|
|
23309
|
+
}
|
|
23310
|
+
function normalizeReview(raw, fallbackTargetId = "") {
|
|
23311
|
+
const id = String(raw.id ?? raw._id ?? "");
|
|
23312
|
+
const targetId = String(
|
|
23313
|
+
raw.targetId ?? raw.gameSlug ?? raw.productSlug ?? raw.courseId ?? fallbackTargetId
|
|
23314
|
+
);
|
|
23315
|
+
const replies = raw.replies ? raw.replies.map(
|
|
23316
|
+
(reply) => normalizeReviewReply(reply, {
|
|
23317
|
+
targetId,
|
|
23318
|
+
reviewId: id
|
|
23319
|
+
})
|
|
23320
|
+
) : raw.ownerReply ? [
|
|
23321
|
+
normalizeReviewReply(raw.ownerReply, {
|
|
23322
|
+
targetId,
|
|
23323
|
+
reviewId: id
|
|
23324
|
+
})
|
|
23325
|
+
] : [];
|
|
23326
|
+
return {
|
|
23327
|
+
id,
|
|
23328
|
+
targetId,
|
|
23329
|
+
content: String(raw.content ?? raw.reviewText ?? ""),
|
|
23330
|
+
rating: Number(raw.rating ?? 0),
|
|
23331
|
+
isRecommended: raw.isRecommended,
|
|
23332
|
+
createdAt: String(raw.createdAt ?? (/* @__PURE__ */ new Date()).toISOString()),
|
|
23333
|
+
updatedAt: raw.updatedAt,
|
|
23334
|
+
edited: raw.edited ?? false,
|
|
23335
|
+
author: normalizeReviewAuthor(raw.author ?? raw.reviewedBy ?? null),
|
|
23336
|
+
replies,
|
|
23337
|
+
permissions: raw.permissions
|
|
23338
|
+
};
|
|
23339
|
+
}
|
|
23340
|
+
function ReviewHeader({ review, config }) {
|
|
23341
|
+
const author = review.author;
|
|
23342
|
+
const displayName = author?.firstName || author?.lastName ? `${author?.firstName ?? ""} ${author?.lastName ?? ""}`.trim() : author?.username ?? "Unknown";
|
|
23343
|
+
return /* @__PURE__ */ jsxs("div", { className: "flex min-w-0 items-center gap-3", children: [
|
|
23344
|
+
/* @__PURE__ */ jsx(Avatar, { src: author?.avatar, size: "sm" }),
|
|
23345
|
+
/* @__PURE__ */ jsxs("div", { className: "flex min-w-0 flex-col gap-0.5", children: [
|
|
23346
|
+
/* @__PURE__ */ jsxs("div", { className: "flex min-w-0 flex-wrap items-center gap-2", children: [
|
|
23347
|
+
/* @__PURE__ */ jsx("span", { className: "truncate text-sm font-semibold text-gray-900 dark:text-gray-100", children: displayName }),
|
|
23348
|
+
author?.username && /* @__PURE__ */ jsxs("span", { className: "text-sm text-gray-500 dark:text-gray-400", children: [
|
|
23349
|
+
"@",
|
|
23350
|
+
author.username
|
|
23351
|
+
] }),
|
|
23352
|
+
author?.role && /* @__PURE__ */ jsx("span", { className: "rounded-full bg-gray-100 px-2 py-0.5 text-xs font-medium text-gray-600 dark:bg-neutral-800 dark:text-gray-300", children: author.role })
|
|
23353
|
+
] }),
|
|
23354
|
+
/* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-center gap-2 text-xs text-gray-500 dark:text-gray-400", children: [
|
|
23355
|
+
/* @__PURE__ */ jsx("span", { children: formatReviewDate(review.createdAt, config.dateFormat) }),
|
|
23356
|
+
review.edited && /* @__PURE__ */ jsx("span", { children: "(edited)" })
|
|
23357
|
+
] })
|
|
23358
|
+
] })
|
|
23359
|
+
] });
|
|
23360
|
+
}
|
|
23361
|
+
var ReviewHeader_default = ReviewHeader;
|
|
23362
|
+
function ReviewContent({ review }) {
|
|
23363
|
+
return /* @__PURE__ */ jsx("div", { className: "whitespace-pre-wrap break-words text-sm leading-6 text-gray-700 dark:text-gray-300", children: review.content });
|
|
23364
|
+
}
|
|
23365
|
+
var ReviewContent_default = ReviewContent;
|
|
23366
|
+
function ReviewRating({ rating, maxRating }) {
|
|
23367
|
+
const items = Array.from(
|
|
23368
|
+
{
|
|
23369
|
+
length: maxRating
|
|
23370
|
+
},
|
|
23371
|
+
(_, index) => index + 1
|
|
23372
|
+
);
|
|
23373
|
+
return /* @__PURE__ */ jsx(
|
|
23374
|
+
"div",
|
|
23375
|
+
{
|
|
23376
|
+
className: "inline-flex items-center gap-0.5",
|
|
23377
|
+
"aria-label": `${rating} out of ${maxRating}`,
|
|
23378
|
+
children: items.map((item) => /* @__PURE__ */ jsx(
|
|
23379
|
+
"span",
|
|
23380
|
+
{
|
|
23381
|
+
className: item <= rating ? "text-sm text-yellow-400" : "text-sm text-gray-300 dark:text-neutral-700",
|
|
23382
|
+
children: "\u2605"
|
|
23383
|
+
},
|
|
23384
|
+
item
|
|
23385
|
+
))
|
|
23386
|
+
}
|
|
23387
|
+
);
|
|
23388
|
+
}
|
|
23389
|
+
var ReviewRating_default = ReviewRating;
|
|
23390
|
+
function ReviewRecommendation({ isRecommended }) {
|
|
23391
|
+
if (typeof isRecommended !== "boolean") {
|
|
23392
|
+
return null;
|
|
23393
|
+
}
|
|
23394
|
+
return /* @__PURE__ */ jsxs(
|
|
23395
|
+
"span",
|
|
23396
|
+
{
|
|
23397
|
+
className: `
|
|
23398
|
+
inline-flex items-center gap-1 rounded-full px-2.5 py-1 text-xs font-medium
|
|
23399
|
+
${isRecommended ? "bg-green-500/10 text-green-500" : "bg-red-500/10 text-red-500"}
|
|
23400
|
+
`,
|
|
23401
|
+
children: [
|
|
23402
|
+
isRecommended ? /* @__PURE__ */ jsx(BiCheckCircle, { size: 16 }) : /* @__PURE__ */ jsx(BiXCircle, { size: 16 }),
|
|
23403
|
+
isRecommended ? "Recommended" : "Not Recommended"
|
|
23404
|
+
]
|
|
23405
|
+
}
|
|
23406
|
+
);
|
|
23407
|
+
}
|
|
23408
|
+
var ReviewRecommendation_default = ReviewRecommendation;
|
|
23409
|
+
function MyReviewPanel({
|
|
23410
|
+
currentUser,
|
|
23411
|
+
myReview,
|
|
23412
|
+
loading = false,
|
|
23413
|
+
disabled = false,
|
|
23414
|
+
config,
|
|
23415
|
+
components,
|
|
23416
|
+
onLoginClick,
|
|
23417
|
+
onCreateReview,
|
|
23418
|
+
onUpdateReview,
|
|
23419
|
+
onEditReview,
|
|
23420
|
+
onDeleteReview
|
|
23421
|
+
}) {
|
|
23422
|
+
const [editing, setEditing] = useState(false);
|
|
23423
|
+
const ComposerComponent = components?.Composer ?? ReviewComposer_default;
|
|
23424
|
+
const FormComponent = components?.Form ?? ReviewForm_default;
|
|
23425
|
+
const HeaderComponent = components?.Header ?? ReviewHeader_default;
|
|
23426
|
+
const ContentComponent = components?.Content ?? ReviewContent_default;
|
|
23427
|
+
const RatingComponent = components?.Rating ?? ReviewRating_default;
|
|
23428
|
+
const RecommendationComponent = components?.Recommendation ?? ReviewRecommendation_default;
|
|
23429
|
+
async function handleCreateReview(values) {
|
|
23430
|
+
await onCreateReview(values);
|
|
23431
|
+
}
|
|
23432
|
+
async function handleUpdateReview(values) {
|
|
23433
|
+
if (!myReview) {
|
|
23434
|
+
return;
|
|
23435
|
+
}
|
|
23436
|
+
await onUpdateReview(myReview, values);
|
|
23437
|
+
setEditing(false);
|
|
23438
|
+
}
|
|
23439
|
+
function handleEdit() {
|
|
23440
|
+
if (!myReview) {
|
|
23441
|
+
return;
|
|
23442
|
+
}
|
|
23443
|
+
if (onEditReview) {
|
|
23444
|
+
onEditReview(myReview);
|
|
23445
|
+
return;
|
|
23446
|
+
}
|
|
23447
|
+
setEditing(true);
|
|
23448
|
+
}
|
|
23449
|
+
function handleDelete() {
|
|
23450
|
+
if (!myReview) {
|
|
23451
|
+
return;
|
|
23452
|
+
}
|
|
23453
|
+
onDeleteReview?.(myReview);
|
|
23454
|
+
}
|
|
23455
|
+
if (!config.showMyReviewPanel) {
|
|
23456
|
+
return null;
|
|
23457
|
+
}
|
|
23458
|
+
if (!myReview) {
|
|
23459
|
+
return /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-3", children: [
|
|
23460
|
+
/* @__PURE__ */ jsx("h3", { className: "text-base font-semibold text-gray-900 dark:text-gray-100", children: "My Review" }),
|
|
23461
|
+
/* @__PURE__ */ jsx(
|
|
23462
|
+
ComposerComponent,
|
|
23463
|
+
{
|
|
23464
|
+
currentUser,
|
|
23465
|
+
placeholder: "Write your review...",
|
|
23466
|
+
submitLabel: "Post Review",
|
|
23467
|
+
loading,
|
|
23468
|
+
disabled,
|
|
23469
|
+
config,
|
|
23470
|
+
onLoginClick,
|
|
23471
|
+
onSubmit: handleCreateReview
|
|
23472
|
+
}
|
|
23473
|
+
)
|
|
23474
|
+
] });
|
|
23475
|
+
}
|
|
23476
|
+
if (editing) {
|
|
23477
|
+
return /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-3", children: [
|
|
23478
|
+
/* @__PURE__ */ jsx("h3", { className: "text-base font-semibold text-gray-900 dark:text-gray-100", children: "Update My Review" }),
|
|
23479
|
+
/* @__PURE__ */ jsx("div", { className: "rounded-xl border border-gray-200 bg-white p-4 dark:border-neutral-800 dark:bg-neutral-900", children: /* @__PURE__ */ jsx(
|
|
23480
|
+
FormComponent,
|
|
23481
|
+
{
|
|
23482
|
+
initialValues: {
|
|
23483
|
+
content: myReview.content,
|
|
23484
|
+
rating: myReview.rating,
|
|
23485
|
+
isRecommended: myReview.isRecommended
|
|
23486
|
+
},
|
|
23487
|
+
placeholder: "Update your review...",
|
|
23488
|
+
submitLabel: "Update Review",
|
|
23489
|
+
loading,
|
|
23490
|
+
disabled,
|
|
23491
|
+
autoFocus: true,
|
|
23492
|
+
config,
|
|
23493
|
+
onSubmit: handleUpdateReview,
|
|
23494
|
+
onCancel: () => setEditing(false)
|
|
23495
|
+
}
|
|
23496
|
+
) })
|
|
23497
|
+
] });
|
|
23498
|
+
}
|
|
23499
|
+
return /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-3", children: [
|
|
23500
|
+
/* @__PURE__ */ jsx("h3", { className: "text-base font-semibold text-gray-900 dark:text-gray-100", children: "My Review" }),
|
|
23501
|
+
/* @__PURE__ */ jsx("div", { className: "rounded-xl border border-gray-200 bg-white p-4 dark:border-neutral-800 dark:bg-neutral-900", children: /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-4", children: [
|
|
23502
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-start justify-between gap-3", children: [
|
|
23503
|
+
/* @__PURE__ */ jsx(HeaderComponent, { review: myReview, config }),
|
|
23504
|
+
/* @__PURE__ */ jsxs("div", { className: "flex shrink-0 items-center gap-2", children: [
|
|
23505
|
+
/* @__PURE__ */ jsx(
|
|
23506
|
+
Button_default,
|
|
23507
|
+
{
|
|
23508
|
+
text: "Edit",
|
|
23509
|
+
variant: "secondary",
|
|
23510
|
+
appearance: "ghost",
|
|
23511
|
+
disabled: disabled || loading,
|
|
23512
|
+
onClick: handleEdit
|
|
23513
|
+
}
|
|
23514
|
+
),
|
|
23515
|
+
onDeleteReview && /* @__PURE__ */ jsx(
|
|
23516
|
+
Button_default,
|
|
23517
|
+
{
|
|
23518
|
+
text: "Delete",
|
|
23519
|
+
variant: "danger",
|
|
23520
|
+
appearance: "ghost",
|
|
23521
|
+
disabled: disabled || loading,
|
|
23522
|
+
onClick: handleDelete
|
|
23523
|
+
}
|
|
23524
|
+
)
|
|
23525
|
+
] })
|
|
23526
|
+
] }),
|
|
23527
|
+
/* @__PURE__ */ jsx(ContentComponent, { review: myReview }),
|
|
23528
|
+
/* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-center gap-3", children: [
|
|
23529
|
+
/* @__PURE__ */ jsx(
|
|
23530
|
+
RatingComponent,
|
|
23531
|
+
{
|
|
23532
|
+
rating: myReview.rating,
|
|
23533
|
+
maxRating: config.maxRating
|
|
23534
|
+
}
|
|
23535
|
+
),
|
|
23536
|
+
config.allowRecommendation && /* @__PURE__ */ jsx(
|
|
23537
|
+
RecommendationComponent,
|
|
23538
|
+
{
|
|
23539
|
+
isRecommended: myReview.isRecommended
|
|
23540
|
+
}
|
|
23541
|
+
)
|
|
23542
|
+
] })
|
|
23543
|
+
] }) })
|
|
23544
|
+
] });
|
|
23545
|
+
}
|
|
23546
|
+
var MyReviewPanel_default = MyReviewPanel;
|
|
23547
|
+
function ReviewMenuItem({
|
|
23548
|
+
icon,
|
|
23549
|
+
name,
|
|
23550
|
+
badge,
|
|
23551
|
+
to,
|
|
23552
|
+
navigate,
|
|
23553
|
+
className,
|
|
23554
|
+
onClick,
|
|
23555
|
+
style
|
|
23556
|
+
}) {
|
|
23557
|
+
return /* @__PURE__ */ jsx(
|
|
23558
|
+
MenuItem,
|
|
23559
|
+
{
|
|
23560
|
+
icon,
|
|
23561
|
+
name,
|
|
23562
|
+
badge,
|
|
23563
|
+
to,
|
|
23564
|
+
navigate,
|
|
23565
|
+
onClick,
|
|
23566
|
+
style,
|
|
23567
|
+
className
|
|
23568
|
+
}
|
|
23569
|
+
);
|
|
23570
|
+
}
|
|
23571
|
+
function ReviewMenu({
|
|
23572
|
+
open,
|
|
23573
|
+
setOpen,
|
|
23574
|
+
canEdit,
|
|
23575
|
+
canDelete,
|
|
23576
|
+
canReport,
|
|
23577
|
+
canReply,
|
|
23578
|
+
onEdit,
|
|
23579
|
+
onDelete,
|
|
23580
|
+
onReport,
|
|
23581
|
+
onReply
|
|
23582
|
+
}) {
|
|
23583
|
+
const ref = useRef(null);
|
|
23584
|
+
useClickOutside(ref, () => setOpen(false));
|
|
23585
|
+
const items = [];
|
|
23586
|
+
if (canEdit) {
|
|
23587
|
+
items.push({
|
|
23588
|
+
type: "item",
|
|
23589
|
+
icon: /* @__PURE__ */ jsx(BiEdit, {}),
|
|
23590
|
+
name: "Edit Review",
|
|
23591
|
+
component: ReviewMenuItem,
|
|
23592
|
+
onClick: () => {
|
|
23593
|
+
setOpen(false);
|
|
23594
|
+
onEdit?.();
|
|
23595
|
+
},
|
|
23596
|
+
className: "flex w-full items-center gap-2 px-4 py-3 text-sm hover:bg-gray-100 dark:hover:bg-neutral-800"
|
|
23597
|
+
});
|
|
23598
|
+
}
|
|
23599
|
+
if (canDelete) {
|
|
23600
|
+
items.push({
|
|
23601
|
+
type: "item",
|
|
23602
|
+
icon: /* @__PURE__ */ jsx(BiTrash, {}),
|
|
23603
|
+
name: "Delete Review",
|
|
23604
|
+
component: ReviewMenuItem,
|
|
23605
|
+
onClick: () => {
|
|
23606
|
+
setOpen(false);
|
|
23607
|
+
onDelete?.();
|
|
23608
|
+
},
|
|
23609
|
+
className: "flex w-full items-center gap-2 px-4 py-3 text-sm text-red-500 hover:bg-gray-100 dark:hover:bg-neutral-800"
|
|
23610
|
+
});
|
|
23611
|
+
}
|
|
23612
|
+
if (canReport) {
|
|
23613
|
+
items.push({
|
|
23614
|
+
type: "item",
|
|
23615
|
+
icon: /* @__PURE__ */ jsx(BiFlag, {}),
|
|
23616
|
+
name: "Report Review",
|
|
23617
|
+
component: ReviewMenuItem,
|
|
23618
|
+
onClick: () => {
|
|
23619
|
+
setOpen(false);
|
|
23620
|
+
onReport?.();
|
|
23621
|
+
},
|
|
23622
|
+
className: "flex w-full items-center gap-2 px-4 py-3 text-sm hover:bg-gray-100 dark:hover:bg-neutral-800"
|
|
23623
|
+
});
|
|
23624
|
+
}
|
|
23625
|
+
if (canReply) {
|
|
23626
|
+
items.push({
|
|
23627
|
+
type: "item",
|
|
23628
|
+
icon: /* @__PURE__ */ jsx(BiReply, {}),
|
|
23629
|
+
name: "Reply as Owner",
|
|
23630
|
+
component: ReviewMenuItem,
|
|
23631
|
+
onClick: () => {
|
|
23632
|
+
setOpen(false);
|
|
23633
|
+
onReply?.();
|
|
23634
|
+
},
|
|
23635
|
+
className: "flex w-full items-center gap-2 px-4 py-3 text-sm hover:bg-gray-100 dark:hover:bg-neutral-800"
|
|
23636
|
+
});
|
|
23637
|
+
}
|
|
23638
|
+
if (!items.length) {
|
|
23639
|
+
return null;
|
|
23640
|
+
}
|
|
23641
|
+
return /* @__PURE__ */ jsxs("div", { ref, className: "relative", children: [
|
|
23642
|
+
/* @__PURE__ */ jsx(
|
|
23643
|
+
"button",
|
|
23644
|
+
{
|
|
23645
|
+
type: "button",
|
|
23646
|
+
onClick: () => setOpen(!open),
|
|
23647
|
+
className: "text-gray-500 transition-colors hover:text-gray-900 dark:hover:text-gray-100",
|
|
23648
|
+
"aria-label": "Review options",
|
|
23649
|
+
children: /* @__PURE__ */ jsx(BiDotsVerticalRounded, { size: 20 })
|
|
23650
|
+
}
|
|
23651
|
+
),
|
|
23652
|
+
/* @__PURE__ */ jsx(Transition.TransitionDropdown, { visibility: open, children: /* @__PURE__ */ jsx("div", { className: "absolute right-0 top-full z-50 mt-2 min-w-[190px] overflow-hidden rounded-xl border border-gray-200 bg-white shadow-xl dark:border-neutral-800 dark:bg-neutral-900", children: /* @__PURE__ */ jsx(Menu, { items }) }) })
|
|
23653
|
+
] });
|
|
23654
|
+
}
|
|
23655
|
+
var ReviewMenu_default = ReviewMenu;
|
|
23656
|
+
function ReviewActions({ canReply, onReply }) {
|
|
23657
|
+
if (!canReply) {
|
|
23658
|
+
return null;
|
|
23659
|
+
}
|
|
23660
|
+
return /* @__PURE__ */ jsx("div", { className: "flex items-center gap-4 text-sm text-gray-500 dark:text-gray-400", children: /* @__PURE__ */ jsxs(
|
|
23661
|
+
"button",
|
|
23662
|
+
{
|
|
23663
|
+
type: "button",
|
|
23664
|
+
onClick: onReply,
|
|
23665
|
+
className: "inline-flex items-center gap-1 font-medium transition-colors hover:text-gray-900 dark:hover:text-gray-100",
|
|
23666
|
+
children: [
|
|
23667
|
+
/* @__PURE__ */ jsx(BiReply, { size: 18 }),
|
|
23668
|
+
"Reply as Owner"
|
|
23669
|
+
]
|
|
23670
|
+
}
|
|
23671
|
+
) });
|
|
23672
|
+
}
|
|
23673
|
+
var ReviewActions_default = ReviewActions;
|
|
23674
|
+
function ReviewReplyHeader({ reply, config }) {
|
|
23675
|
+
const author = reply.author;
|
|
23676
|
+
const displayName = author?.firstName || author?.lastName ? `${author?.firstName ?? ""} ${author?.lastName ?? ""}`.trim() : author?.username ?? "Unknown";
|
|
23677
|
+
return /* @__PURE__ */ jsxs("div", { className: "flex min-w-0 items-center gap-3", children: [
|
|
23678
|
+
/* @__PURE__ */ jsx(Avatar, { src: author?.avatar, size: "sm" }),
|
|
23679
|
+
/* @__PURE__ */ jsxs("div", { className: "flex min-w-0 flex-col gap-0.5", children: [
|
|
23680
|
+
/* @__PURE__ */ jsxs("div", { className: "flex min-w-0 flex-wrap items-center gap-2", children: [
|
|
23681
|
+
/* @__PURE__ */ jsx("span", { className: "truncate text-sm font-semibold text-gray-900 dark:text-gray-100", children: displayName }),
|
|
23682
|
+
(reply.authorLabel || author?.role) && /* @__PURE__ */ jsx("span", { className: "rounded-full bg-blue-500/10 px-2 py-0.5 text-xs font-medium text-blue-500", children: reply.authorLabel ?? author?.role }),
|
|
23683
|
+
author?.username && /* @__PURE__ */ jsxs("span", { className: "text-sm text-gray-500 dark:text-gray-400", children: [
|
|
23684
|
+
"@",
|
|
23685
|
+
author.username
|
|
23686
|
+
] })
|
|
23687
|
+
] }),
|
|
23688
|
+
/* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-center gap-2 text-xs text-gray-500 dark:text-gray-400", children: [
|
|
23689
|
+
/* @__PURE__ */ jsx("span", { children: formatReviewDate(reply.createdAt, config.dateFormat) }),
|
|
23690
|
+
reply.edited && /* @__PURE__ */ jsx("span", { children: "(edited)" })
|
|
23691
|
+
] })
|
|
23692
|
+
] })
|
|
23693
|
+
] });
|
|
23694
|
+
}
|
|
23695
|
+
var ReviewReplyHeader_default = ReviewReplyHeader;
|
|
23696
|
+
function ReviewReplyContent({ reply }) {
|
|
23697
|
+
return /* @__PURE__ */ jsx("div", { className: "whitespace-pre-wrap break-words text-sm leading-6 text-gray-700 dark:text-gray-300", children: reply.content });
|
|
23698
|
+
}
|
|
23699
|
+
var ReviewReplyContent_default = ReviewReplyContent;
|
|
23700
|
+
function ReviewReplyMenuItem({
|
|
23701
|
+
icon,
|
|
23702
|
+
name,
|
|
23703
|
+
badge,
|
|
23704
|
+
to,
|
|
23705
|
+
navigate,
|
|
23706
|
+
className,
|
|
23707
|
+
onClick,
|
|
23708
|
+
style
|
|
23709
|
+
}) {
|
|
23710
|
+
return /* @__PURE__ */ jsx(
|
|
23711
|
+
MenuItem,
|
|
23712
|
+
{
|
|
23713
|
+
icon,
|
|
23714
|
+
name,
|
|
23715
|
+
badge,
|
|
23716
|
+
to,
|
|
23717
|
+
navigate,
|
|
23718
|
+
onClick,
|
|
23719
|
+
style,
|
|
23720
|
+
className
|
|
23721
|
+
}
|
|
23722
|
+
);
|
|
23723
|
+
}
|
|
23724
|
+
function ReviewReplyMenu({
|
|
23725
|
+
open,
|
|
23726
|
+
setOpen,
|
|
23727
|
+
canEdit,
|
|
23728
|
+
canDelete,
|
|
23729
|
+
canReport,
|
|
23730
|
+
onEdit,
|
|
23731
|
+
onDelete,
|
|
23732
|
+
onReport
|
|
23733
|
+
}) {
|
|
23734
|
+
const ref = useRef(null);
|
|
23735
|
+
useClickOutside(ref, () => setOpen(false));
|
|
23736
|
+
const items = [];
|
|
23737
|
+
if (canEdit) {
|
|
23738
|
+
items.push({
|
|
23739
|
+
type: "item",
|
|
23740
|
+
icon: /* @__PURE__ */ jsx(BiEdit, {}),
|
|
23741
|
+
name: "Edit Reply",
|
|
23742
|
+
component: ReviewReplyMenuItem,
|
|
23743
|
+
onClick: () => {
|
|
23744
|
+
setOpen(false);
|
|
23745
|
+
onEdit?.();
|
|
23746
|
+
},
|
|
23747
|
+
className: "flex w-full items-center gap-2 px-4 py-3 text-sm hover:bg-gray-100 dark:hover:bg-neutral-800"
|
|
23748
|
+
});
|
|
23749
|
+
}
|
|
23750
|
+
if (canDelete) {
|
|
23751
|
+
items.push({
|
|
23752
|
+
type: "item",
|
|
23753
|
+
icon: /* @__PURE__ */ jsx(BiTrash, {}),
|
|
23754
|
+
name: "Delete Reply",
|
|
23755
|
+
component: ReviewReplyMenuItem,
|
|
23756
|
+
onClick: () => {
|
|
23757
|
+
setOpen(false);
|
|
23758
|
+
onDelete?.();
|
|
23759
|
+
},
|
|
23760
|
+
className: "flex w-full items-center gap-2 px-4 py-3 text-sm text-red-500 hover:bg-gray-100 dark:hover:bg-neutral-800"
|
|
23761
|
+
});
|
|
23762
|
+
}
|
|
23763
|
+
if (canReport) {
|
|
23764
|
+
items.push({
|
|
23765
|
+
type: "item",
|
|
23766
|
+
icon: /* @__PURE__ */ jsx(BiFlag, {}),
|
|
23767
|
+
name: "Report Reply",
|
|
23768
|
+
component: ReviewReplyMenuItem,
|
|
23769
|
+
onClick: () => {
|
|
23770
|
+
setOpen(false);
|
|
23771
|
+
onReport?.();
|
|
23772
|
+
},
|
|
23773
|
+
className: "flex w-full items-center gap-2 px-4 py-3 text-sm hover:bg-gray-100 dark:hover:bg-neutral-800"
|
|
23774
|
+
});
|
|
23775
|
+
}
|
|
23776
|
+
if (!items.length) {
|
|
23777
|
+
return null;
|
|
23778
|
+
}
|
|
23779
|
+
return /* @__PURE__ */ jsxs("div", { ref, className: "relative", children: [
|
|
23780
|
+
/* @__PURE__ */ jsx(
|
|
23781
|
+
"button",
|
|
23782
|
+
{
|
|
23783
|
+
type: "button",
|
|
23784
|
+
onClick: () => setOpen(!open),
|
|
23785
|
+
className: "text-gray-500 transition-colors hover:text-gray-900 dark:hover:text-gray-100",
|
|
23786
|
+
"aria-label": "Review reply options",
|
|
23787
|
+
children: /* @__PURE__ */ jsx(BiDotsVerticalRounded, { size: 18 })
|
|
23788
|
+
}
|
|
23789
|
+
),
|
|
23790
|
+
/* @__PURE__ */ jsx(Transition.TransitionDropdown, { visibility: open, children: /* @__PURE__ */ jsx("div", { className: "absolute right-0 top-full z-50 mt-2 min-w-[180px] overflow-hidden rounded-xl border border-gray-200 bg-white shadow-xl dark:border-neutral-800 dark:bg-neutral-900", children: /* @__PURE__ */ jsx(Menu, { items }) }) })
|
|
23791
|
+
] });
|
|
23792
|
+
}
|
|
23793
|
+
var ReviewReplyMenu_default = ReviewReplyMenu;
|
|
23794
|
+
function ReviewReplyItem({
|
|
23795
|
+
reply,
|
|
23796
|
+
parentReview,
|
|
23797
|
+
config,
|
|
23798
|
+
components,
|
|
23799
|
+
onEditReviewReply,
|
|
23800
|
+
onDeleteReviewReply,
|
|
23801
|
+
onReportReviewReply
|
|
23802
|
+
}) {
|
|
23803
|
+
const [menuOpen, setMenuOpen] = useState(false);
|
|
23804
|
+
const HeaderComponent = components?.ReplyHeader ?? ReviewReplyHeader_default;
|
|
23805
|
+
const ContentComponent = components?.ReplyContent ?? ReviewReplyContent_default;
|
|
23806
|
+
const MenuComponent = components?.ReplyMenu ?? ReviewReplyMenu_default;
|
|
23807
|
+
const canEdit = canEditReviewReply(reply);
|
|
23808
|
+
const canDelete = canDeleteReviewReply(reply);
|
|
23809
|
+
const canReport = canReportReviewReply(reply);
|
|
23810
|
+
return /* @__PURE__ */ jsx("div", { className: "rounded-xl border border-gray-200 bg-gray-50 p-4 dark:border-neutral-800 dark:bg-neutral-950", children: /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-3", children: [
|
|
23811
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-start justify-between gap-3", children: [
|
|
23812
|
+
/* @__PURE__ */ jsx(
|
|
23813
|
+
HeaderComponent,
|
|
23814
|
+
{
|
|
23815
|
+
reply,
|
|
23816
|
+
parentReview,
|
|
23817
|
+
config
|
|
23818
|
+
}
|
|
23819
|
+
),
|
|
23820
|
+
/* @__PURE__ */ jsx(
|
|
23821
|
+
MenuComponent,
|
|
23822
|
+
{
|
|
23823
|
+
reply,
|
|
23824
|
+
parentReview,
|
|
23825
|
+
open: menuOpen,
|
|
23826
|
+
setOpen: setMenuOpen,
|
|
23827
|
+
canEdit,
|
|
23828
|
+
canDelete,
|
|
23829
|
+
canReport,
|
|
23830
|
+
onEdit: () => onEditReviewReply?.(reply, parentReview),
|
|
23831
|
+
onDelete: () => onDeleteReviewReply?.(reply, parentReview),
|
|
23832
|
+
onReport: () => onReportReviewReply?.(reply, parentReview)
|
|
23833
|
+
}
|
|
23834
|
+
)
|
|
23835
|
+
] }),
|
|
23836
|
+
/* @__PURE__ */ jsx(ContentComponent, { reply, parentReview })
|
|
23837
|
+
] }) });
|
|
23838
|
+
}
|
|
23839
|
+
var ReviewReplyItem_default = ReviewReplyItem;
|
|
23840
|
+
function ReviewReplyList({
|
|
23841
|
+
review,
|
|
23842
|
+
replies,
|
|
23843
|
+
config,
|
|
23844
|
+
components,
|
|
23845
|
+
onEditReviewReply,
|
|
23846
|
+
onDeleteReviewReply,
|
|
23847
|
+
onReportReviewReply
|
|
23848
|
+
}) {
|
|
23849
|
+
const ReplyItemComponent = components?.ReplyItem ?? ReviewReplyItem_default;
|
|
23850
|
+
if (!config.allowReplies || !replies.length) {
|
|
23851
|
+
return null;
|
|
23852
|
+
}
|
|
23853
|
+
return /* @__PURE__ */ jsx("div", { className: "ml-6 border-l border-gray-200 pl-4 dark:border-neutral-800", children: /* @__PURE__ */ jsx("div", { className: "flex flex-col gap-3", children: replies.map((reply) => /* @__PURE__ */ jsx(
|
|
23854
|
+
ReplyItemComponent,
|
|
23855
|
+
{
|
|
23856
|
+
reply,
|
|
23857
|
+
parentReview: review,
|
|
23858
|
+
config,
|
|
23859
|
+
components,
|
|
23860
|
+
onEditReviewReply,
|
|
23861
|
+
onDeleteReviewReply,
|
|
23862
|
+
onReportReviewReply
|
|
23863
|
+
},
|
|
23864
|
+
reply.id
|
|
23865
|
+
)) }) });
|
|
23866
|
+
}
|
|
23867
|
+
var ReviewReplyList_default = ReviewReplyList;
|
|
23868
|
+
function ReviewItem({
|
|
23869
|
+
review,
|
|
23870
|
+
config,
|
|
23871
|
+
components,
|
|
23872
|
+
onEditReview,
|
|
23873
|
+
onDeleteReview,
|
|
23874
|
+
onReportReview,
|
|
23875
|
+
onReplyToReview,
|
|
23876
|
+
onEditReviewReply,
|
|
23877
|
+
onDeleteReviewReply,
|
|
23878
|
+
onReportReviewReply
|
|
23879
|
+
}) {
|
|
23880
|
+
const [menuOpen, setMenuOpen] = useState(false);
|
|
23881
|
+
const HeaderComponent = components?.Header ?? ReviewHeader_default;
|
|
23882
|
+
const ContentComponent = components?.Content ?? ReviewContent_default;
|
|
23883
|
+
const RatingComponent = components?.Rating ?? ReviewRating_default;
|
|
23884
|
+
const RecommendationComponent = components?.Recommendation ?? ReviewRecommendation_default;
|
|
23885
|
+
const MenuComponent = components?.Menu ?? ReviewMenu_default;
|
|
23886
|
+
const ActionsComponent = components?.Actions ?? ReviewActions_default;
|
|
23887
|
+
const ReplyListComponent = components?.ReplyList ?? ReviewReplyList_default;
|
|
23888
|
+
const replies = review.replies ?? [];
|
|
23889
|
+
const canEdit = canEditReview(review);
|
|
23890
|
+
const canDelete = canDeleteReview(review);
|
|
23891
|
+
const canReport = canReportReview(review);
|
|
23892
|
+
const canReply = config.allowReplies && canReplyToReview(review) && replies.length < config.maxRepliesPerReview;
|
|
23893
|
+
return /* @__PURE__ */ jsx("div", { className: "rounded-xl border border-gray-200 bg-white p-4 dark:border-neutral-800 dark:bg-neutral-900", children: /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-4", children: [
|
|
23894
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-start justify-between gap-3", children: [
|
|
23895
|
+
/* @__PURE__ */ jsx(HeaderComponent, { review, config }),
|
|
23896
|
+
/* @__PURE__ */ jsx(
|
|
23897
|
+
MenuComponent,
|
|
23898
|
+
{
|
|
23899
|
+
review,
|
|
23900
|
+
open: menuOpen,
|
|
23901
|
+
setOpen: setMenuOpen,
|
|
23902
|
+
canEdit,
|
|
23903
|
+
canDelete,
|
|
23904
|
+
canReport,
|
|
23905
|
+
canReply,
|
|
23906
|
+
onEdit: () => onEditReview?.(review),
|
|
23907
|
+
onDelete: () => onDeleteReview?.(review),
|
|
23908
|
+
onReport: () => onReportReview?.(review),
|
|
23909
|
+
onReply: () => onReplyToReview?.(review)
|
|
23910
|
+
}
|
|
23911
|
+
)
|
|
23912
|
+
] }),
|
|
23913
|
+
/* @__PURE__ */ jsx(ContentComponent, { review }),
|
|
23914
|
+
/* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-center gap-3", children: [
|
|
23915
|
+
/* @__PURE__ */ jsx(RatingComponent, { rating: review.rating, maxRating: config.maxRating }),
|
|
23916
|
+
config.allowRecommendation && /* @__PURE__ */ jsx(RecommendationComponent, { isRecommended: review.isRecommended })
|
|
23917
|
+
] }),
|
|
23918
|
+
/* @__PURE__ */ jsx(
|
|
23919
|
+
ActionsComponent,
|
|
23920
|
+
{
|
|
23921
|
+
review,
|
|
23922
|
+
canReply,
|
|
23923
|
+
onReply: () => onReplyToReview?.(review)
|
|
23924
|
+
}
|
|
23925
|
+
),
|
|
23926
|
+
/* @__PURE__ */ jsx(
|
|
23927
|
+
ReplyListComponent,
|
|
23928
|
+
{
|
|
23929
|
+
review,
|
|
23930
|
+
replies,
|
|
23931
|
+
config,
|
|
23932
|
+
components,
|
|
23933
|
+
onEditReviewReply,
|
|
23934
|
+
onDeleteReviewReply,
|
|
23935
|
+
onReportReviewReply
|
|
23936
|
+
}
|
|
23937
|
+
)
|
|
23938
|
+
] }) });
|
|
23939
|
+
}
|
|
23940
|
+
var ReviewItem_default = ReviewItem;
|
|
23941
|
+
function ReviewEmptyState({
|
|
23942
|
+
title = "No reviews yet",
|
|
23943
|
+
text = "There are no reviews to show."
|
|
23944
|
+
}) {
|
|
23945
|
+
return /* @__PURE__ */ jsxs("div", { className: "rounded-xl border border-dashed border-gray-300 bg-white p-8 text-center dark:border-neutral-800 dark:bg-neutral-900", children: [
|
|
23946
|
+
/* @__PURE__ */ jsx("div", { className: "text-sm font-semibold text-gray-900 dark:text-gray-100", children: title }),
|
|
23947
|
+
text && /* @__PURE__ */ jsx("p", { className: "mt-2 text-sm text-gray-500 dark:text-gray-400", children: text })
|
|
23948
|
+
] });
|
|
23949
|
+
}
|
|
23950
|
+
var ReviewEmptyState_default = ReviewEmptyState;
|
|
23951
|
+
function ReviewList({
|
|
23952
|
+
reviews,
|
|
23953
|
+
config,
|
|
23954
|
+
components,
|
|
23955
|
+
onEditReview,
|
|
23956
|
+
onDeleteReview,
|
|
23957
|
+
onReportReview,
|
|
23958
|
+
onReplyToReview,
|
|
23959
|
+
onEditReviewReply,
|
|
23960
|
+
onDeleteReviewReply,
|
|
23961
|
+
onReportReviewReply
|
|
23962
|
+
}) {
|
|
23963
|
+
const ItemComponent = components?.Item ?? ReviewItem_default;
|
|
23964
|
+
const EmptyStateComponent = components?.EmptyState ?? ReviewEmptyState_default;
|
|
23965
|
+
if (!reviews.length) {
|
|
23966
|
+
return /* @__PURE__ */ jsx(
|
|
23967
|
+
EmptyStateComponent,
|
|
23968
|
+
{
|
|
23969
|
+
title: config.emptyTitle,
|
|
23970
|
+
text: config.emptyText
|
|
23971
|
+
}
|
|
23972
|
+
);
|
|
23973
|
+
}
|
|
23974
|
+
return /* @__PURE__ */ jsx("div", { className: "flex flex-col gap-5", children: reviews.map((review) => /* @__PURE__ */ jsx(
|
|
23975
|
+
ItemComponent,
|
|
23976
|
+
{
|
|
23977
|
+
review,
|
|
23978
|
+
config,
|
|
23979
|
+
components,
|
|
23980
|
+
onEditReview,
|
|
23981
|
+
onDeleteReview,
|
|
23982
|
+
onReportReview,
|
|
23983
|
+
onReplyToReview,
|
|
23984
|
+
onEditReviewReply,
|
|
23985
|
+
onDeleteReviewReply,
|
|
23986
|
+
onReportReviewReply
|
|
23987
|
+
},
|
|
23988
|
+
review.id
|
|
23989
|
+
)) });
|
|
23990
|
+
}
|
|
23991
|
+
var ReviewList_default = ReviewList;
|
|
23992
|
+
|
|
23993
|
+
// src/compositions/review-thread/constants/review-thread.constants.ts
|
|
23994
|
+
var DEFAULT_REVIEW_THREAD_CONFIG = {
|
|
23995
|
+
reviewsPerPage: 10,
|
|
23996
|
+
dateFormat: "relative",
|
|
23997
|
+
minRating: 1,
|
|
23998
|
+
maxRating: 5,
|
|
23999
|
+
minContentLength: 8,
|
|
24000
|
+
maxContentLength: 2e3,
|
|
24001
|
+
allowRecommendation: true,
|
|
24002
|
+
showMyReviewPanel: true,
|
|
24003
|
+
showMyReviewInList: true,
|
|
24004
|
+
allowReplies: true,
|
|
24005
|
+
maxRepliesPerReview: 1,
|
|
24006
|
+
ownerReplyLabel: "Owner",
|
|
24007
|
+
emptyTitle: "No reviews yet",
|
|
24008
|
+
emptyText: "There are no reviews to show."
|
|
24009
|
+
};
|
|
24010
|
+
function isReviewEntity(value) {
|
|
24011
|
+
return Boolean(value && "rating" in value);
|
|
24012
|
+
}
|
|
24013
|
+
function updateReviewEverywhere(review, updater) {
|
|
24014
|
+
return updater(review);
|
|
24015
|
+
}
|
|
24016
|
+
function useReviewThreadState({
|
|
24017
|
+
targetId,
|
|
24018
|
+
dataSource,
|
|
24019
|
+
config,
|
|
24020
|
+
shouldLoadMyReview = true,
|
|
24021
|
+
loading = false,
|
|
24022
|
+
updatedReview,
|
|
24023
|
+
deletedReview,
|
|
24024
|
+
updatedReviewReply,
|
|
24025
|
+
deletedReviewReply,
|
|
24026
|
+
onReviewCreated,
|
|
24027
|
+
onReviewUpdated,
|
|
24028
|
+
onReviewDeleted
|
|
24029
|
+
}) {
|
|
24030
|
+
const [reviews, setReviews] = useState([]);
|
|
24031
|
+
const [myReview, setMyReview] = useState(null);
|
|
24032
|
+
const [isLoadingReviews, setIsLoadingReviews] = useState(true);
|
|
24033
|
+
const [isLoadingMyReview, setIsLoadingMyReview] = useState(
|
|
24034
|
+
Boolean(dataSource.getMyReview && shouldLoadMyReview)
|
|
24035
|
+
);
|
|
24036
|
+
const [isCreatingReview, setIsCreatingReview] = useState(false);
|
|
24037
|
+
const [isUpdatingReview, setIsUpdatingReview] = useState(false);
|
|
24038
|
+
const [isDeletingReview, setIsDeletingReview] = useState(false);
|
|
24039
|
+
const [isCreatingReviewReply, setIsCreatingReviewReply] = useState(false);
|
|
24040
|
+
const [isUpdatingReviewReply, setIsUpdatingReviewReply] = useState(false);
|
|
24041
|
+
const [isDeletingReviewReply, setIsDeletingReviewReply] = useState(false);
|
|
24042
|
+
const [reviewsError, setReviewsError] = useState(null);
|
|
24043
|
+
const [myReviewError, setMyReviewError] = useState(null);
|
|
24044
|
+
const error = reviewsError ?? myReviewError;
|
|
24045
|
+
const visibleReviews = useMemo(() => {
|
|
24046
|
+
if (config.showMyReviewInList || !myReview) {
|
|
24047
|
+
return reviews;
|
|
24048
|
+
}
|
|
24049
|
+
return reviews.filter((review) => review.id !== myReview.id);
|
|
24050
|
+
}, [config.showMyReviewInList, myReview, reviews]);
|
|
24051
|
+
const applyReview = useCallback((review) => {
|
|
24052
|
+
setReviews((prev) => upsertReview(prev, review));
|
|
24053
|
+
setMyReview((prev) => {
|
|
24054
|
+
if (!prev || prev.id !== review.id) {
|
|
24055
|
+
return prev;
|
|
24056
|
+
}
|
|
24057
|
+
return review;
|
|
24058
|
+
});
|
|
24059
|
+
}, []);
|
|
24060
|
+
const applyReviewUpdater = useCallback(
|
|
24061
|
+
(reviewId, updater) => {
|
|
24062
|
+
setReviews((prev) => updateReview(prev, reviewId, updater));
|
|
24063
|
+
setMyReview((prev) => {
|
|
24064
|
+
if (!prev || prev.id !== reviewId) {
|
|
24065
|
+
return prev;
|
|
24066
|
+
}
|
|
24067
|
+
return updateReviewEverywhere(prev, updater);
|
|
24068
|
+
});
|
|
24069
|
+
},
|
|
24070
|
+
[]
|
|
24071
|
+
);
|
|
24072
|
+
const removeReviewById = useCallback((reviewId) => {
|
|
24073
|
+
setReviews((prev) => removeReview(prev, reviewId));
|
|
24074
|
+
setMyReview((prev) => {
|
|
24075
|
+
if (!prev || prev.id !== reviewId) {
|
|
24076
|
+
return prev;
|
|
24077
|
+
}
|
|
24078
|
+
return null;
|
|
24079
|
+
});
|
|
24080
|
+
}, []);
|
|
24081
|
+
const loadReviews = useCallback(async () => {
|
|
24082
|
+
try {
|
|
24083
|
+
setIsLoadingReviews(true);
|
|
24084
|
+
setReviewsError(null);
|
|
24085
|
+
const result = await dataSource.getReviews({
|
|
24086
|
+
limit: config.reviewsPerPage
|
|
24087
|
+
});
|
|
24088
|
+
setReviews(result.items);
|
|
24089
|
+
} catch (error2) {
|
|
24090
|
+
setReviewsError(error2);
|
|
24091
|
+
} finally {
|
|
24092
|
+
setIsLoadingReviews(false);
|
|
24093
|
+
}
|
|
24094
|
+
}, [config.reviewsPerPage, dataSource, targetId]);
|
|
24095
|
+
const loadMyReview = useCallback(async () => {
|
|
24096
|
+
if (!dataSource.getMyReview || !shouldLoadMyReview) {
|
|
24097
|
+
setMyReview(null);
|
|
24098
|
+
setIsLoadingMyReview(false);
|
|
24099
|
+
setMyReviewError(null);
|
|
24100
|
+
return;
|
|
24101
|
+
}
|
|
24102
|
+
try {
|
|
24103
|
+
setIsLoadingMyReview(true);
|
|
24104
|
+
setMyReviewError(null);
|
|
24105
|
+
const result = await dataSource.getMyReview();
|
|
24106
|
+
setMyReview(result);
|
|
24107
|
+
} catch (error2) {
|
|
24108
|
+
setMyReview(null);
|
|
24109
|
+
setMyReviewError(error2);
|
|
24110
|
+
} finally {
|
|
24111
|
+
setIsLoadingMyReview(false);
|
|
24112
|
+
}
|
|
24113
|
+
}, [dataSource, shouldLoadMyReview, targetId]);
|
|
24114
|
+
const reload = useCallback(async () => {
|
|
24115
|
+
await Promise.all([loadReviews(), loadMyReview()]);
|
|
24116
|
+
}, [loadReviews, loadMyReview]);
|
|
24117
|
+
const createReview = useCallback(
|
|
24118
|
+
async (values) => {
|
|
24119
|
+
try {
|
|
24120
|
+
setIsCreatingReview(true);
|
|
24121
|
+
const review = await dataSource.createReview({
|
|
24122
|
+
content: values.content,
|
|
24123
|
+
rating: values.rating,
|
|
24124
|
+
isRecommended: values.isRecommended
|
|
24125
|
+
});
|
|
24126
|
+
setMyReview(review);
|
|
24127
|
+
setReviews((prev) => prependReview(prev, review));
|
|
24128
|
+
onReviewCreated?.(review);
|
|
24129
|
+
return review;
|
|
24130
|
+
} finally {
|
|
24131
|
+
setIsCreatingReview(false);
|
|
24132
|
+
}
|
|
24133
|
+
},
|
|
24134
|
+
[dataSource, onReviewCreated]
|
|
24135
|
+
);
|
|
24136
|
+
const updateReview2 = useCallback(
|
|
24137
|
+
async (review, values) => {
|
|
24138
|
+
try {
|
|
24139
|
+
setIsUpdatingReview(true);
|
|
24140
|
+
const updated = await dataSource.updateReview({
|
|
24141
|
+
id: review.id,
|
|
24142
|
+
content: values.content,
|
|
24143
|
+
rating: values.rating,
|
|
24144
|
+
isRecommended: values.isRecommended
|
|
24145
|
+
});
|
|
24146
|
+
setMyReview((prev) => {
|
|
24147
|
+
if (!prev || prev.id !== updated.id) {
|
|
24148
|
+
return prev;
|
|
24149
|
+
}
|
|
24150
|
+
return updated;
|
|
24151
|
+
});
|
|
24152
|
+
setReviews((prev) => upsertReview(prev, updated));
|
|
24153
|
+
onReviewUpdated?.(updated);
|
|
24154
|
+
return updated;
|
|
24155
|
+
} finally {
|
|
24156
|
+
setIsUpdatingReview(false);
|
|
24157
|
+
}
|
|
24158
|
+
},
|
|
24159
|
+
[dataSource, onReviewUpdated]
|
|
24160
|
+
);
|
|
24161
|
+
const deleteReview = useCallback(
|
|
24162
|
+
async (review) => {
|
|
24163
|
+
try {
|
|
24164
|
+
setIsDeletingReview(true);
|
|
24165
|
+
await dataSource.deleteReview(review.id);
|
|
24166
|
+
removeReviewById(review.id);
|
|
24167
|
+
onReviewDeleted?.(review);
|
|
24168
|
+
} finally {
|
|
24169
|
+
setIsDeletingReview(false);
|
|
24170
|
+
}
|
|
24171
|
+
},
|
|
24172
|
+
[dataSource, onReviewDeleted, removeReviewById]
|
|
24173
|
+
);
|
|
24174
|
+
const createReviewReply = useCallback(
|
|
24175
|
+
async (input) => {
|
|
24176
|
+
if (!dataSource.createReviewReply) {
|
|
24177
|
+
throw new Error("createReviewReply is not implemented by dataSource.");
|
|
24178
|
+
}
|
|
24179
|
+
try {
|
|
24180
|
+
setIsCreatingReviewReply(true);
|
|
24181
|
+
const result = await dataSource.createReviewReply(input);
|
|
24182
|
+
if (isReviewEntity(result)) {
|
|
24183
|
+
applyReview(result);
|
|
24184
|
+
} else {
|
|
24185
|
+
applyReviewUpdater(
|
|
24186
|
+
input.reviewId,
|
|
24187
|
+
(review) => addReviewReply(review, result, config.maxRepliesPerReview)
|
|
24188
|
+
);
|
|
24189
|
+
}
|
|
24190
|
+
return result;
|
|
24191
|
+
} finally {
|
|
24192
|
+
setIsCreatingReviewReply(false);
|
|
24193
|
+
}
|
|
24194
|
+
},
|
|
24195
|
+
[
|
|
24196
|
+
applyReview,
|
|
24197
|
+
applyReviewUpdater,
|
|
24198
|
+
config.maxRepliesPerReview,
|
|
24199
|
+
dataSource
|
|
24200
|
+
]
|
|
24201
|
+
);
|
|
24202
|
+
const updateReviewReply2 = useCallback(
|
|
24203
|
+
async (input) => {
|
|
24204
|
+
if (!dataSource.updateReviewReply) {
|
|
24205
|
+
throw new Error("updateReviewReply is not implemented by dataSource.");
|
|
24206
|
+
}
|
|
24207
|
+
try {
|
|
24208
|
+
setIsUpdatingReviewReply(true);
|
|
24209
|
+
const result = await dataSource.updateReviewReply(input);
|
|
24210
|
+
if (isReviewEntity(result)) {
|
|
24211
|
+
applyReview(result);
|
|
24212
|
+
} else {
|
|
24213
|
+
applyReviewUpdater(
|
|
24214
|
+
input.reviewId,
|
|
24215
|
+
(review) => replaceReviewReply(review, result)
|
|
24216
|
+
);
|
|
24217
|
+
}
|
|
24218
|
+
return result;
|
|
24219
|
+
} finally {
|
|
24220
|
+
setIsUpdatingReviewReply(false);
|
|
24221
|
+
}
|
|
24222
|
+
},
|
|
24223
|
+
[applyReview, applyReviewUpdater, dataSource]
|
|
24224
|
+
);
|
|
24225
|
+
const deleteReviewReply = useCallback(
|
|
24226
|
+
async (reviewId, replyId) => {
|
|
24227
|
+
if (!dataSource.deleteReviewReply) {
|
|
24228
|
+
throw new Error("deleteReviewReply is not implemented by dataSource.");
|
|
24229
|
+
}
|
|
24230
|
+
try {
|
|
24231
|
+
setIsDeletingReviewReply(true);
|
|
24232
|
+
const result = await dataSource.deleteReviewReply(reviewId, replyId);
|
|
24233
|
+
if (isReviewEntity(result)) {
|
|
24234
|
+
applyReview(result);
|
|
24235
|
+
} else {
|
|
24236
|
+
applyReviewUpdater(
|
|
24237
|
+
reviewId,
|
|
24238
|
+
(review) => removeReviewReply(review, replyId)
|
|
24239
|
+
);
|
|
24240
|
+
}
|
|
24241
|
+
return result;
|
|
24242
|
+
} finally {
|
|
24243
|
+
setIsDeletingReviewReply(false);
|
|
24244
|
+
}
|
|
24245
|
+
},
|
|
24246
|
+
[applyReview, applyReviewUpdater, dataSource]
|
|
24247
|
+
);
|
|
24248
|
+
useEffect(() => {
|
|
24249
|
+
let cancelled = false;
|
|
24250
|
+
async function run() {
|
|
24251
|
+
try {
|
|
24252
|
+
setIsLoadingReviews(true);
|
|
24253
|
+
setReviewsError(null);
|
|
24254
|
+
const result = await dataSource.getReviews({
|
|
24255
|
+
limit: config.reviewsPerPage
|
|
24256
|
+
});
|
|
24257
|
+
if (!cancelled) {
|
|
24258
|
+
setReviews(result.items);
|
|
24259
|
+
}
|
|
24260
|
+
} catch (error2) {
|
|
24261
|
+
if (!cancelled) {
|
|
24262
|
+
setReviewsError(error2);
|
|
24263
|
+
}
|
|
24264
|
+
} finally {
|
|
24265
|
+
if (!cancelled) {
|
|
24266
|
+
setIsLoadingReviews(false);
|
|
24267
|
+
}
|
|
24268
|
+
}
|
|
24269
|
+
}
|
|
24270
|
+
void run();
|
|
24271
|
+
return () => {
|
|
24272
|
+
cancelled = true;
|
|
24273
|
+
};
|
|
24274
|
+
}, [config.reviewsPerPage, dataSource, targetId]);
|
|
24275
|
+
useEffect(() => {
|
|
24276
|
+
let cancelled = false;
|
|
24277
|
+
async function run() {
|
|
24278
|
+
if (!dataSource.getMyReview || !shouldLoadMyReview) {
|
|
24279
|
+
setMyReview(null);
|
|
24280
|
+
setMyReviewError(null);
|
|
24281
|
+
setIsLoadingMyReview(false);
|
|
24282
|
+
return;
|
|
24283
|
+
}
|
|
24284
|
+
try {
|
|
24285
|
+
setIsLoadingMyReview(true);
|
|
24286
|
+
setMyReviewError(null);
|
|
24287
|
+
const result = await dataSource.getMyReview();
|
|
24288
|
+
if (!cancelled) {
|
|
24289
|
+
setMyReview(result);
|
|
24290
|
+
}
|
|
24291
|
+
} catch (error2) {
|
|
24292
|
+
if (!cancelled) {
|
|
24293
|
+
setMyReview(null);
|
|
24294
|
+
setMyReviewError(error2);
|
|
24295
|
+
}
|
|
24296
|
+
} finally {
|
|
24297
|
+
if (!cancelled) {
|
|
24298
|
+
setIsLoadingMyReview(false);
|
|
24299
|
+
}
|
|
24300
|
+
}
|
|
24301
|
+
}
|
|
24302
|
+
void run();
|
|
24303
|
+
return () => {
|
|
24304
|
+
cancelled = true;
|
|
24305
|
+
};
|
|
24306
|
+
}, [dataSource, shouldLoadMyReview, targetId]);
|
|
24307
|
+
useEffect(() => {
|
|
24308
|
+
if (!updatedReview) {
|
|
24309
|
+
return;
|
|
24310
|
+
}
|
|
24311
|
+
applyReview(updatedReview);
|
|
24312
|
+
}, [applyReview, updatedReview]);
|
|
24313
|
+
useEffect(() => {
|
|
24314
|
+
if (!deletedReview) {
|
|
24315
|
+
return;
|
|
24316
|
+
}
|
|
24317
|
+
removeReviewById(deletedReview.id);
|
|
24318
|
+
}, [deletedReview, removeReviewById]);
|
|
24319
|
+
useEffect(() => {
|
|
24320
|
+
if (!updatedReviewReply) {
|
|
24321
|
+
return;
|
|
24322
|
+
}
|
|
24323
|
+
if (updatedReviewReply.review) {
|
|
24324
|
+
applyReview(updatedReviewReply.review);
|
|
24325
|
+
return;
|
|
24326
|
+
}
|
|
24327
|
+
if (!updatedReviewReply.reply) {
|
|
24328
|
+
return;
|
|
24329
|
+
}
|
|
24330
|
+
applyReviewUpdater(updatedReviewReply.reviewId, (review) => {
|
|
24331
|
+
if (hasReviewReply(review, updatedReviewReply.reply.id)) {
|
|
24332
|
+
return replaceReviewReply(review, updatedReviewReply.reply);
|
|
24333
|
+
}
|
|
24334
|
+
return addReviewReply(
|
|
24335
|
+
review,
|
|
24336
|
+
updatedReviewReply.reply,
|
|
24337
|
+
config.maxRepliesPerReview
|
|
24338
|
+
);
|
|
24339
|
+
});
|
|
24340
|
+
}, [
|
|
24341
|
+
applyReview,
|
|
24342
|
+
applyReviewUpdater,
|
|
24343
|
+
config.maxRepliesPerReview,
|
|
24344
|
+
updatedReviewReply
|
|
24345
|
+
]);
|
|
24346
|
+
useEffect(() => {
|
|
24347
|
+
if (!deletedReviewReply) {
|
|
24348
|
+
return;
|
|
24349
|
+
}
|
|
24350
|
+
if (deletedReviewReply.review) {
|
|
24351
|
+
applyReview(deletedReviewReply.review);
|
|
24352
|
+
return;
|
|
24353
|
+
}
|
|
24354
|
+
applyReviewUpdater(
|
|
24355
|
+
deletedReviewReply.reviewId,
|
|
24356
|
+
(review) => removeReviewReply(review, deletedReviewReply.replyId)
|
|
24357
|
+
);
|
|
24358
|
+
}, [applyReview, applyReviewUpdater, deletedReviewReply]);
|
|
24359
|
+
return {
|
|
24360
|
+
reviews,
|
|
24361
|
+
visibleReviews,
|
|
24362
|
+
myReview,
|
|
24363
|
+
isLoadingReviews,
|
|
24364
|
+
isLoadingMyReview,
|
|
24365
|
+
isInitialLoading: loading || isLoadingReviews || isLoadingMyReview,
|
|
24366
|
+
isCreatingReview,
|
|
24367
|
+
isUpdatingReview,
|
|
24368
|
+
isDeletingReview,
|
|
24369
|
+
isCreatingReviewReply,
|
|
24370
|
+
isUpdatingReviewReply,
|
|
24371
|
+
isDeletingReviewReply,
|
|
24372
|
+
reviewsError,
|
|
24373
|
+
myReviewError,
|
|
24374
|
+
error,
|
|
24375
|
+
setReviews,
|
|
24376
|
+
setMyReview,
|
|
24377
|
+
loadReviews,
|
|
24378
|
+
loadMyReview,
|
|
24379
|
+
reload,
|
|
24380
|
+
createReview,
|
|
24381
|
+
updateReview: updateReview2,
|
|
24382
|
+
deleteReview,
|
|
24383
|
+
createReviewReply,
|
|
24384
|
+
updateReviewReply: updateReviewReply2,
|
|
24385
|
+
deleteReviewReply,
|
|
24386
|
+
applyReview,
|
|
24387
|
+
removeReviewById
|
|
24388
|
+
};
|
|
24389
|
+
}
|
|
24390
|
+
function ReviewThread({
|
|
24391
|
+
targetId,
|
|
24392
|
+
currentUser,
|
|
24393
|
+
dataSource,
|
|
24394
|
+
loading = false,
|
|
24395
|
+
disabled = false,
|
|
24396
|
+
config,
|
|
24397
|
+
components,
|
|
24398
|
+
updatedReview,
|
|
24399
|
+
deletedReview,
|
|
24400
|
+
updatedReviewReply,
|
|
24401
|
+
deletedReviewReply,
|
|
24402
|
+
onLoginClick,
|
|
24403
|
+
onEditReview,
|
|
24404
|
+
onDeleteReview,
|
|
24405
|
+
onReportReview,
|
|
24406
|
+
onReplyToReview,
|
|
24407
|
+
onEditReviewReply,
|
|
24408
|
+
onDeleteReviewReply,
|
|
24409
|
+
onReportReviewReply,
|
|
24410
|
+
onReviewCreated,
|
|
24411
|
+
onReviewUpdated,
|
|
24412
|
+
onReviewDeleted
|
|
24413
|
+
}) {
|
|
24414
|
+
const resolvedConfig = {
|
|
24415
|
+
...DEFAULT_REVIEW_THREAD_CONFIG,
|
|
24416
|
+
...config
|
|
24417
|
+
};
|
|
24418
|
+
const reviewState = useReviewThreadState({
|
|
24419
|
+
targetId,
|
|
24420
|
+
dataSource,
|
|
24421
|
+
config: resolvedConfig,
|
|
24422
|
+
shouldLoadMyReview: Boolean(currentUser),
|
|
24423
|
+
loading,
|
|
24424
|
+
updatedReview,
|
|
24425
|
+
deletedReview,
|
|
24426
|
+
updatedReviewReply,
|
|
24427
|
+
deletedReviewReply,
|
|
24428
|
+
onReviewCreated,
|
|
24429
|
+
onReviewUpdated,
|
|
24430
|
+
onReviewDeleted
|
|
24431
|
+
});
|
|
24432
|
+
function handleEditReview(review) {
|
|
24433
|
+
onEditReview?.(review);
|
|
24434
|
+
}
|
|
24435
|
+
function handleDeleteReview(review) {
|
|
24436
|
+
if (onDeleteReview) {
|
|
24437
|
+
onDeleteReview(review);
|
|
24438
|
+
return;
|
|
24439
|
+
}
|
|
24440
|
+
void reviewState.deleteReview(review);
|
|
24441
|
+
}
|
|
24442
|
+
function handleReportReview(review) {
|
|
24443
|
+
onReportReview?.(review);
|
|
24444
|
+
}
|
|
24445
|
+
function handleReplyToReview(review) {
|
|
24446
|
+
onReplyToReview?.(review);
|
|
24447
|
+
}
|
|
24448
|
+
function handleEditReviewReply(reply, parentReview) {
|
|
24449
|
+
onEditReviewReply?.(reply, parentReview);
|
|
24450
|
+
}
|
|
24451
|
+
function handleDeleteReviewReply(reply, parentReview) {
|
|
24452
|
+
onDeleteReviewReply?.(reply, parentReview);
|
|
24453
|
+
}
|
|
24454
|
+
function handleReportReviewReply(reply, parentReview) {
|
|
24455
|
+
onReportReviewReply?.(reply, parentReview);
|
|
24456
|
+
}
|
|
24457
|
+
if (reviewState.isInitialLoading) {
|
|
24458
|
+
return /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-4", children: [
|
|
24459
|
+
resolvedConfig.showMyReviewPanel && /* @__PURE__ */ jsx("div", { className: "h-40 animate-pulse rounded-xl bg-gray-100 dark:bg-neutral-900" }),
|
|
24460
|
+
/* @__PURE__ */ jsx("div", { className: "h-36 animate-pulse rounded-xl bg-gray-100 dark:bg-neutral-900" }),
|
|
24461
|
+
/* @__PURE__ */ jsx("div", { className: "h-36 animate-pulse rounded-xl bg-gray-100 dark:bg-neutral-900" })
|
|
24462
|
+
] });
|
|
24463
|
+
}
|
|
24464
|
+
if (reviewState.error && !reviewState.reviews.length) {
|
|
24465
|
+
return /* @__PURE__ */ jsx("div", { className: "rounded-xl border border-red-200 bg-red-50 p-5 dark:border-red-500/20 dark:bg-red-500/10", children: /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-3", children: [
|
|
24466
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
24467
|
+
/* @__PURE__ */ jsx("h3", { className: "text-sm font-semibold text-red-700 dark:text-red-400", children: "Failed to load reviews" }),
|
|
24468
|
+
/* @__PURE__ */ jsx("p", { className: "mt-1 text-sm text-red-600/80 dark:text-red-300/80", children: "Something went wrong while loading the review thread." })
|
|
24469
|
+
] }),
|
|
24470
|
+
/* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsx(
|
|
24471
|
+
Button_default,
|
|
24472
|
+
{
|
|
24473
|
+
text: "Retry",
|
|
24474
|
+
variant: "danger",
|
|
24475
|
+
appearance: "ghost",
|
|
24476
|
+
onClick: () => {
|
|
24477
|
+
void reviewState.reload();
|
|
24478
|
+
}
|
|
24479
|
+
}
|
|
24480
|
+
) })
|
|
24481
|
+
] }) });
|
|
24482
|
+
}
|
|
24483
|
+
return /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-8", children: [
|
|
24484
|
+
resolvedConfig.showMyReviewPanel && /* @__PURE__ */ jsx(
|
|
24485
|
+
MyReviewPanel_default,
|
|
24486
|
+
{
|
|
24487
|
+
currentUser,
|
|
24488
|
+
myReview: reviewState.myReview,
|
|
24489
|
+
loading: reviewState.isCreatingReview || reviewState.isUpdatingReview || reviewState.isDeletingReview,
|
|
24490
|
+
disabled,
|
|
24491
|
+
config: resolvedConfig,
|
|
24492
|
+
components,
|
|
24493
|
+
onLoginClick,
|
|
24494
|
+
onCreateReview: reviewState.createReview,
|
|
24495
|
+
onUpdateReview: reviewState.updateReview,
|
|
24496
|
+
onEditReview: handleEditReview,
|
|
24497
|
+
onDeleteReview: handleDeleteReview
|
|
24498
|
+
}
|
|
24499
|
+
),
|
|
24500
|
+
/* @__PURE__ */ jsx(
|
|
24501
|
+
ReviewList_default,
|
|
24502
|
+
{
|
|
24503
|
+
reviews: reviewState.visibleReviews,
|
|
24504
|
+
config: resolvedConfig,
|
|
24505
|
+
components,
|
|
24506
|
+
onEditReview: handleEditReview,
|
|
24507
|
+
onDeleteReview: handleDeleteReview,
|
|
24508
|
+
onReportReview: handleReportReview,
|
|
24509
|
+
onReplyToReview: handleReplyToReview,
|
|
24510
|
+
onEditReviewReply: handleEditReviewReply,
|
|
24511
|
+
onDeleteReviewReply: handleDeleteReviewReply,
|
|
24512
|
+
onReportReviewReply: handleReportReviewReply
|
|
24513
|
+
}
|
|
24514
|
+
)
|
|
24515
|
+
] });
|
|
24516
|
+
}
|
|
24517
|
+
var ReviewThread_default = ReviewThread;
|
|
22951
24518
|
function GenericLayout({
|
|
22952
24519
|
children,
|
|
22953
24520
|
styles,
|
|
@@ -23064,6 +24631,6 @@ function ScrollToTop({
|
|
|
23064
24631
|
}
|
|
23065
24632
|
var ScrollToTop_default = ScrollToTop;
|
|
23066
24633
|
|
|
23067
|
-
export { Accordion_default as Accordion, AreaPlot, AsyncComponentWrapper_default as AsyncComponentWrapper, Avatar, Backdrop_default as Backdrop, Badge, BarPlot, BaseChartDataSource, Block_default as Block, BlockGroup_default as BlockGroup, BoxNav_default as BoxNav, BoxNavItem_default as BoxNavItem, Brand_default as Brand, Breadcrumb, BreadcrumbItem_default as BreadcrumbItem, Button_default as Button, CHART_COLOR_PALETTE, CHART_DARK_THEME, CHART_DATA_MODES, CHART_DEFAULT_ACTIVE_DOT_RADIUS, CHART_DEFAULT_ANIMATION_DURATION, CHART_DEFAULT_BAR_RADIUS, CHART_DEFAULT_DOT_RADIUS, CHART_DEFAULT_HEIGHT, CHART_DEFAULT_MARGIN, CHART_DEFAULT_MAX_REALTIME_POINTS, CHART_DEFAULT_POLLING_INTERVAL, CHART_DEFAULT_STROKE_WIDTH, CHART_EMPTY_MESSAGE, CHART_ERROR_MESSAGE, CHART_LIGHT_THEME, CHART_LOADING_MESSAGE, CHART_STATUSES, CHART_STATUS_COLORS, CHART_VALUE_FORMATS, Caption, Card_default as Card, CardContent_default as CardContent, CardFooter_default as CardFooter, CardHeader_default as CardHeader, Chapter, Chart, ChartContainer, ChartContext, ChartEmptyState, ChartErrorState, ChartHeader, ChartLegend, ChartLoadingState, ChartPanel, ChartProvider, ChartToolbar, ChartTooltip, Checkbox_default as Checkbox, Chip, CloudinaryImage_default as CloudinaryImage, CloudinaryProvider, CloudinaryVideo_default as CloudinaryVideo, Code, CommentThread_default as CommentThread, ConfigBootstrap_default as ConfigBootstrap, Configurator, ConfiguratorError, Content, ContentArea_default as ContentArea, DEFAULT_CHART_THEME, DataView, DataViewTable_default as DataViewTable, DateSelector_default as DateSelector, DefaultLayout_default as DefaultLayout, Display, DocumentationPanel_default as DocumentationPanel, Drawer, DrawerToggler_default as DrawerToggler, EUIDevLayout_default as EUIDevLayout, EUIProvider, EnvErrorScreen_default as EnvErrorScreen, Flag, Flex, FlexCol_default as FlexCol, FlexRow_default as FlexRow, Footer, FooterNav_default as FooterNav, FooterNavGroup_default as FooterNavGroup, FooterNavItem, FooterNavItemContext, FooterNavItemTitle, Form, FormResponse_default as FormResponse, GaugePlot, GenericLayout_default as GenericLayout, GlowWrapper_default as GlowWrapper, Graph, GraphEdge, GraphNode, GraphRenderer, Grid_default as Grid, Header, HeaderNav_default as HeaderNav, HeaderNavGroup_default as HeaderNavGroup, HeaderNavItem, HeaderNavItemContext, HeaderNavItemTitle, HomeLayout_default as HomeLayout, Image2 as Image, ImageInput_default as ImageInput, InfiniteScrollTrigger_default as InfiniteScrollTrigger, Info_default as Info, Input, InputFile, InputLabel_default as InputLabel, InputList, InputListGroup, InputResponse_default as InputResponse, Label, Layout, Lead, LinePlot, Link, List_default as List, ListItem_default as ListItem, MarkdownEditor_default as MarkdownEditor, MarkdownProvider_default as MarkdownProvider, MarkdownTOC_default as MarkdownTOC, MarkdownViewer_default as MarkdownViewer, Menu, MenuGroup, MenuItem, MenuItemTitle, Modal_default as Modal, MotionSurface_default as MotionSurface, MultiImageInput_default as MultiImageInput, NumericRating_default as NumericRating, Overline, Paragraph, PiePlot, PollingChartDataSource, PriceTag, ProgressBar, ProgressBarRating_default as ProgressBarRating, Quote, Radio_default as Radio, RealtimeChartDataSource, RouteTab_default as RouteTab, RouteTabs_default as RouteTabs, ScatterPlot, ScrollToTop_default as ScrollToTop, Section, Select_default as Select, ShapeSwitch, ShowMore_default as ShowMore, Sidebar_default as Sidebar, SidebarLayout_default as SidebarLayout, SidemenuLayout_default as SidemenuLayout, Skeleton, Slider_default as Slider, Spinner_default as Spinner, StarRating_default as StarRating, StarRatingDistribution_default as StarRatingDistribution, StarRatingInput_default as StarRatingInput, StatPlot, StaticChartDataSource, Switch_default as Switch, TNDropdown, TNDropdownItem, TNDropdownTitle, TNGroup, Table_default as Table, Tag_default as Tag, Tags_default as Tags, TextArea_default as TextArea, ThemeContext, ThemeProvider, ThemeSwitch, TitleBanner, Toast, Tooltip6 as Tooltip, TopNav, Transition, TransitionAccordion_default as TransitionAccordion, TransitionBase_default as TransitionBase, TransitionDropdown_default as TransitionDropdown, TransitionFade_default as TransitionFade, TransitionFadeIn_default as TransitionFadeIn, TransitionScale_default as TransitionScale, TransitionSlide_default as TransitionSlide, Typography, UnderConstructionBanner, ValueBadge_default as ValueBadge, WorldMap, WorldMapCountryTable, YoutubeVideo_default as YoutubeVideoPlayer, addReplyToCache, applyReactionState, assertAbsoluteURL, buildURL, chartReducer, cn, createConfigurator, createForceLayout, createGridLayout, createInitialChartState, createTreeLayout, createURLResolver, decrementReplyCount, enumValues, euiToast, formatChartValue, formatCommentDate, formatConfigError, getAllowedOrigins, getBrowserHref, getBrowserOrigin, getBrowserRedirectURL, getCurrencySymbol, getLayout, getOptimisticDislikeState, getOptimisticLikeState, getSafeRedirect, incrementReplyCount, isMatch, isRenderFn, limitRealtimePoints, normalize, normalizeChartData, normalizeChartDataPoint, parseJson, parseJsonRecord, parseUrlMap, registerLayout, removeComment, removeCommentTreeFromCache, replaceRealtimePoints, resolveAppearanceStyles, resolveChartColor, resolveChartColors, resolveWithGlobal, sendToast, toConfiguratorError, updateComment, updateReplyCacheComment, useChartContext, useChartData, useChartPolling, useChartRealtime, useChartSeries, useChartTheme, useClickOutside, useCloudinaryConfig, useCurrentTheme_default as useCurrentTheme, useDrawer_default as useDrawer, useEUIConfig, useIsMobile_default as useIsMobile, useModal_default as useModal, useTheme_default as useTheme };
|
|
24634
|
+
export { Accordion_default as Accordion, AreaPlot, AsyncComponentWrapper_default as AsyncComponentWrapper, Avatar, Backdrop_default as Backdrop, Badge, BarPlot, BaseChartDataSource, Block_default as Block, BlockGroup_default as BlockGroup, BoxNav_default as BoxNav, BoxNavItem_default as BoxNavItem, Brand_default as Brand, Breadcrumb, BreadcrumbItem_default as BreadcrumbItem, Button_default as Button, CHART_COLOR_PALETTE, CHART_DARK_THEME, CHART_DATA_MODES, CHART_DEFAULT_ACTIVE_DOT_RADIUS, CHART_DEFAULT_ANIMATION_DURATION, CHART_DEFAULT_BAR_RADIUS, CHART_DEFAULT_DOT_RADIUS, CHART_DEFAULT_HEIGHT, CHART_DEFAULT_MARGIN, CHART_DEFAULT_MAX_REALTIME_POINTS, CHART_DEFAULT_POLLING_INTERVAL, CHART_DEFAULT_STROKE_WIDTH, CHART_EMPTY_MESSAGE, CHART_ERROR_MESSAGE, CHART_LIGHT_THEME, CHART_LOADING_MESSAGE, CHART_STATUSES, CHART_STATUS_COLORS, CHART_VALUE_FORMATS, Caption, Card_default as Card, CardContent_default as CardContent, CardFooter_default as CardFooter, CardHeader_default as CardHeader, Chapter, Chart, ChartContainer, ChartContext, ChartEmptyState, ChartErrorState, ChartHeader, ChartLegend, ChartLoadingState, ChartPanel, ChartProvider, ChartToolbar, ChartTooltip, Checkbox_default as Checkbox, Chip, CloudinaryImage_default as CloudinaryImage, CloudinaryProvider, CloudinaryVideo_default as CloudinaryVideo, Code, CommentThread_default as CommentThread, ConfigBootstrap_default as ConfigBootstrap, Configurator, ConfiguratorError, Content, ContentArea_default as ContentArea, DEFAULT_CHART_THEME, DEFAULT_REVIEW_THREAD_CONFIG, DataView, DataViewTable_default as DataViewTable, DateSelector_default as DateSelector, DefaultLayout_default as DefaultLayout, Display, DocumentationPanel_default as DocumentationPanel, Drawer, DrawerToggler_default as DrawerToggler, EUIDevLayout_default as EUIDevLayout, EUIProvider, EnvErrorScreen_default as EnvErrorScreen, Flag, Flex, FlexCol_default as FlexCol, FlexRow_default as FlexRow, Footer, FooterNav_default as FooterNav, FooterNavGroup_default as FooterNavGroup, FooterNavItem, FooterNavItemContext, FooterNavItemTitle, Form, FormResponse_default as FormResponse, GaugePlot, GenericLayout_default as GenericLayout, GlowWrapper_default as GlowWrapper, Graph, GraphEdge, GraphNode, GraphRenderer, Grid_default as Grid, Header, HeaderNav_default as HeaderNav, HeaderNavGroup_default as HeaderNavGroup, HeaderNavItem, HeaderNavItemContext, HeaderNavItemTitle, HomeLayout_default as HomeLayout, Image2 as Image, ImageInput_default as ImageInput, InfiniteScrollTrigger_default as InfiniteScrollTrigger, Info_default as Info, Input, InputFile, InputLabel_default as InputLabel, InputList, InputListGroup, InputResponse_default as InputResponse, Label, Layout, Lead, LinePlot, Link, List_default as List, ListItem_default as ListItem, MarkdownEditor_default as MarkdownEditor, MarkdownProvider_default as MarkdownProvider, MarkdownTOC_default as MarkdownTOC, MarkdownViewer_default as MarkdownViewer, Menu, MenuGroup, MenuItem, MenuItemTitle, Modal_default as Modal, MotionSurface_default as MotionSurface, MultiImageInput_default as MultiImageInput, NumericRating_default as NumericRating, Overline, Paragraph, PiePlot, PollingChartDataSource, PriceTag, ProgressBar, ProgressBarRating_default as ProgressBarRating, Quote, Radio_default as Radio, RealtimeChartDataSource, ReviewThread_default as ReviewThread, RouteTab_default as RouteTab, RouteTabs_default as RouteTabs, ScatterPlot, ScrollToTop_default as ScrollToTop, Section, Select_default as Select, ShapeSwitch, ShowMore_default as ShowMore, Sidebar_default as Sidebar, SidebarLayout_default as SidebarLayout, SidemenuLayout_default as SidemenuLayout, Skeleton, Slider_default as Slider, Spinner_default as Spinner, StarRating_default as StarRating, StarRatingDistribution_default as StarRatingDistribution, StarRatingInput_default as StarRatingInput, StatPlot, StaticChartDataSource, Switch_default as Switch, TNDropdown, TNDropdownItem, TNDropdownTitle, TNGroup, Table_default as Table, Tag_default as Tag, Tags_default as Tags, TextArea_default as TextArea, ThemeContext, ThemeProvider, ThemeSwitch, TitleBanner, Toast, Tooltip6 as Tooltip, TopNav, Transition, TransitionAccordion_default as TransitionAccordion, TransitionBase_default as TransitionBase, TransitionDropdown_default as TransitionDropdown, TransitionFade_default as TransitionFade, TransitionFadeIn_default as TransitionFadeIn, TransitionScale_default as TransitionScale, TransitionSlide_default as TransitionSlide, Typography, UnderConstructionBanner, ValueBadge_default as ValueBadge, WorldMap, WorldMapCountryTable, YoutubeVideo_default as YoutubeVideoPlayer, addReplyToCache, addReviewReply, appendReview, applyReactionState, assertAbsoluteURL, buildURL, canDeleteReview, canDeleteReviewReply, canEditReview, canEditReviewReply, canReplyToReview, canReportReview, canReportReviewReply, chartReducer, cn, createConfigurator, createForceLayout, createGridLayout, createInitialChartState, createTreeLayout, createURLResolver, decrementReplyCount, enumValues, euiToast, findReview, formatChartValue, formatCommentDate, formatConfigError, formatReviewDate, getAllowedOrigins, getBrowserHref, getBrowserOrigin, getBrowserRedirectURL, getCurrencySymbol, getLayout, getOptimisticDislikeState, getOptimisticLikeState, getSafeRedirect, hasReviewReply, incrementReplyCount, isMatch, isRenderFn, limitRealtimePoints, normalize, normalizeChartData, normalizeChartDataPoint, normalizeReview, normalizeReviewAuthor, normalizeReviewReply, parseJson, parseJsonRecord, parseUrlMap, prependReview, registerLayout, removeComment, removeCommentTreeFromCache, removeReview, removeReviewReply, replaceRealtimePoints, replaceReview, replaceReviewReply, resolveAppearanceStyles, resolveChartColor, resolveChartColors, resolveWithGlobal, sendToast, toConfiguratorError, updateComment, updateReplyCacheComment, updateReview, updateReviewReply, upsertReview, useChartContext, useChartData, useChartPolling, useChartRealtime, useChartSeries, useChartTheme, useClickOutside, useCloudinaryConfig, useCurrentTheme_default as useCurrentTheme, useDrawer_default as useDrawer, useEUIConfig, useIsMobile_default as useIsMobile, useModal_default as useModal, useReviewThreadState, useTheme_default as useTheme };
|
|
23068
24635
|
//# sourceMappingURL=index.mjs.map
|
|
23069
24636
|
//# sourceMappingURL=index.mjs.map
|