elseware-ui 2.36.9 → 2.37.1

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