pxengine 0.1.27 → 0.1.29

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.cjs CHANGED
@@ -352,6 +352,10 @@ __export(atoms_exports, {
352
352
  VideoAtom: () => VideoAtom
353
353
  });
354
354
 
355
+ // src/atoms/TextAtom.tsx
356
+ var import_react_markdown = __toESM(require("react-markdown"), 1);
357
+ var import_remark_gfm = __toESM(require("remark-gfm"), 1);
358
+
355
359
  // src/lib/utils.ts
356
360
  var import_clsx = require("clsx");
357
361
  var import_tailwind_merge = require("tailwind-merge");
@@ -366,7 +370,8 @@ var TextAtom = ({
366
370
  variant = "p",
367
371
  className,
368
372
  style,
369
- backgroundColor
373
+ backgroundColor,
374
+ markdown = false
370
375
  }) => {
371
376
  const baseStyles = {
372
377
  h1: "scroll-m-20 text-4xl font-extrabold tracking-tight lg:text-5xl text-gray900",
@@ -379,14 +384,25 @@ var TextAtom = ({
379
384
  label: "text-[10px] font-bold text-gray400 uppercase tracking-widest pl-1"
380
385
  };
381
386
  const Component2 = variant === "small" || variant === "muted" || variant === "label" ? "p" : variant;
387
+ const wrapperStyles = {
388
+ ...style,
389
+ ...backgroundColor && { backgroundColor }
390
+ };
391
+ if (markdown) {
392
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
393
+ "div",
394
+ {
395
+ className: cn(baseStyles[variant], "prose prose-sm max-w-none", className),
396
+ style: wrapperStyles,
397
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_markdown.default, { remarkPlugins: [import_remark_gfm.default], children: content })
398
+ }
399
+ );
400
+ }
382
401
  return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
383
402
  Component2,
384
403
  {
385
404
  className: cn(baseStyles[variant], className),
386
- style: {
387
- ...style,
388
- ...backgroundColor && { backgroundColor }
389
- },
405
+ style: wrapperStyles,
390
406
  children: content
391
407
  }
392
408
  );
@@ -34215,16 +34231,40 @@ var FormCard = import_react56.default.memo(
34215
34231
  proceedLabel,
34216
34232
  onProceed,
34217
34233
  isLatestMessage = true,
34234
+ hideTitle = false,
34235
+ hideCopyButton = false,
34218
34236
  className,
34219
34237
  footer
34220
34238
  }) => {
34221
- const [showCopyButton, setShowCopyButton] = (0, import_react56.useState)(false);
34239
+ const [copied, setCopied] = (0, import_react56.useState)(false);
34222
34240
  const handleCopyAll = () => {
34223
- const text = fields.map((field) => {
34224
- const value = data[field.key];
34225
- return `${field.label}: ${typeof value === "object" ? JSON.stringify(value) : value}`;
34226
- }).join("\n");
34227
- navigator.clipboard.writeText(text);
34241
+ const flattenValue = (val) => {
34242
+ if (val === null || val === void 0) return "-";
34243
+ if (Array.isArray(val)) {
34244
+ return val.map((item) => {
34245
+ if (typeof item === "object" && item !== null) {
34246
+ return item.label || item.value || item.name || JSON.stringify(item);
34247
+ }
34248
+ return String(item);
34249
+ }).join(", ");
34250
+ }
34251
+ if (typeof val === "object") {
34252
+ return Object.entries(val).map(([k, v]) => `${k.replace(/_/g, " ")}: ${v}`).join(", ");
34253
+ }
34254
+ return String(val);
34255
+ };
34256
+ const text = [
34257
+ title,
34258
+ "",
34259
+ ...fields.map((field) => {
34260
+ const value = data[field.key];
34261
+ return `${field.label}: ${flattenValue(value)}`;
34262
+ })
34263
+ ].join("\n");
34264
+ navigator.clipboard.writeText(text).then(() => {
34265
+ setCopied(true);
34266
+ setTimeout(() => setCopied(false), 2e3);
34267
+ });
34228
34268
  };
34229
34269
  return /* @__PURE__ */ (0, import_jsx_runtime96.jsxs)(
34230
34270
  "div",
@@ -34233,23 +34273,21 @@ var FormCard = import_react56.default.memo(
34233
34273
  "relative w-full rounded-[20px] bg-background dark:bg-gray100 border border-gray400 shadow-lg overflow-hidden mb-6 font-noto",
34234
34274
  className
34235
34275
  ),
34236
- onMouseEnter: () => setShowCopyButton(true),
34237
- onMouseLeave: () => setShowCopyButton(false),
34238
34276
  children: [
34239
- showCopyButton && /* @__PURE__ */ (0, import_jsx_runtime96.jsx)(
34277
+ !hideCopyButton && /* @__PURE__ */ (0, import_jsx_runtime96.jsx)(
34240
34278
  "button",
34241
34279
  {
34242
34280
  onClick: handleCopyAll,
34243
34281
  title: "Copy all details",
34244
- className: "absolute top-4 right-4 p-2 rounded-lg hover:bg-gray-100 dark:hover:bg-gray200 text-gray-400 hover:text-gray-600 dark:hover:text-gray300 transition-all active:scale-95 z-10",
34245
- children: /* @__PURE__ */ (0, import_jsx_runtime96.jsx)(Copy, { className: "h-4 w-4" })
34282
+ className: "absolute top-4 right-4 p-2 rounded-lg hover:bg-gray-100 dark:hover:bg-gray-200 text-gray-400 hover:text-gray-600 dark:hover:text-gray300 transition-all active:scale-95 z-10",
34283
+ children: copied ? /* @__PURE__ */ (0, import_jsx_runtime96.jsx)(Check, { className: "h-4 w-4 text-green-500" }) : /* @__PURE__ */ (0, import_jsx_runtime96.jsx)(Copy, { className: "h-4 w-4" })
34246
34284
  }
34247
34285
  ),
34248
34286
  /* @__PURE__ */ (0, import_jsx_runtime96.jsxs)("div", { className: "p-6 relative", children: [
34249
- /* @__PURE__ */ (0, import_jsx_runtime96.jsx)(
34287
+ !hideTitle && title && /* @__PURE__ */ (0, import_jsx_runtime96.jsx)(
34250
34288
  "h3",
34251
34289
  {
34252
- className: "text-gray900 mb-12",
34290
+ className: "text-gray900 dark:text-white mb-12 font-bold",
34253
34291
  children: title
34254
34292
  }
34255
34293
  ),
@@ -35406,7 +35444,7 @@ var CampaignSeedCard = import_react60.default.memo(
35406
35444
  showTimeline: true,
35407
35445
  isLatestMessage: effectiveIsLatest,
35408
35446
  className: cn("font-noto", className),
35409
- footer: !effectiveIsLatest && (selectionStatus || hasUserResponded) ? /* @__PURE__ */ (0, import_jsx_runtime107.jsxs)("div", { className: "flex justify-end items-center gap-1.5 text-green-600 text-[10px] font-semibold py-4 pr-6", children: [
35447
+ footer: !effectiveIsLatest && selectionStatus ? /* @__PURE__ */ (0, import_jsx_runtime107.jsxs)("div", { className: "flex justify-end items-center gap-1.5 text-green-600 text-[10px] font-semibold py-4 pr-6", children: [
35410
35448
  /* @__PURE__ */ (0, import_jsx_runtime107.jsx)(CircleCheck, { className: "h-3.5 w-3.5" }),
35411
35449
  /* @__PURE__ */ (0, import_jsx_runtime107.jsx)("span", { children: selectionStatus === "agent" ? "Suggested by Agent" : "Selected by you" })
35412
35450
  ] }) : formCardProps.footer
@@ -35501,7 +35539,7 @@ var SearchSpecCard = import_react61.default.memo(
35501
35539
  });
35502
35540
  };
35503
35541
  const effectiveIsLatest = isLatestMessage && !hasUserResponded;
35504
- return /* @__PURE__ */ (0, import_jsx_runtime108.jsx)(
35542
+ return /* @__PURE__ */ (0, import_jsx_runtime108.jsx)("div", { className: "flex flex-col gap-2", children: /* @__PURE__ */ (0, import_jsx_runtime108.jsx)(
35505
35543
  FormCard,
35506
35544
  {
35507
35545
  ...formCardProps,
@@ -35512,12 +35550,12 @@ var SearchSpecCard = import_react61.default.memo(
35512
35550
  onProceed: handleProceed,
35513
35551
  isLatestMessage: effectiveIsLatest,
35514
35552
  className,
35515
- footer: !effectiveIsLatest && (selectionStatus || hasUserResponded) ? /* @__PURE__ */ (0, import_jsx_runtime108.jsxs)("div", { className: "flex justify-end items-center gap-1.5 text-green-600 text-xs font-semibold py-1", children: [
35553
+ footer: !effectiveIsLatest && selectionStatus ? /* @__PURE__ */ (0, import_jsx_runtime108.jsxs)("div", { className: "flex justify-end items-center gap-1.5 text-green-600 text-xs font-semibold py-1", children: [
35516
35554
  /* @__PURE__ */ (0, import_jsx_runtime108.jsx)(CircleCheck, { className: "h-4 w-4" }),
35517
35555
  /* @__PURE__ */ (0, import_jsx_runtime108.jsx)("span", { children: selectionStatus === "agent" ? "Selected by Agent" : "Selected by User" })
35518
35556
  ] }) : formCardProps.footer
35519
35557
  }
35520
- );
35558
+ ) });
35521
35559
  }
35522
35560
  );
35523
35561
  SearchSpecCard.displayName = "SearchSpecCard";
@@ -36241,6 +36279,7 @@ var CampaignConceptCard = import_react64.default.memo(
36241
36279
  ...formCardProps
36242
36280
  }) => {
36243
36281
  const [internalIsOpen, setInternalIsOpen] = (0, import_react64.useState)(false);
36282
+ const [copied, setCopied] = (0, import_react64.useState)(false);
36244
36283
  const isOpen = controlledIsOpen !== void 0 ? controlledIsOpen : internalIsOpen;
36245
36284
  const handleToggle = () => {
36246
36285
  if (onToggle) {
@@ -36250,55 +36289,109 @@ var CampaignConceptCard = import_react64.default.memo(
36250
36289
  }
36251
36290
  };
36252
36291
  const cardTitle = propsTitle || data.title || data.name || data.concept_name || data.conceptName || "Campaign Concept";
36292
+ const isSelected = selectionStatus != null;
36293
+ const flattenValue = (val) => {
36294
+ if (val === null || val === void 0) return "-";
36295
+ if (Array.isArray(val)) {
36296
+ return val.map((item) => {
36297
+ if (typeof item === "object" && item !== null) {
36298
+ return item.label || item.value || item.name || JSON.stringify(item);
36299
+ }
36300
+ return String(item);
36301
+ }).join(", ");
36302
+ }
36303
+ if (typeof val === "object") {
36304
+ return Object.entries(val).map(([k, v]) => `${k.replace(/_/g, " ")}: ${v}`).join(", ");
36305
+ }
36306
+ return String(val);
36307
+ };
36308
+ const handleCopyAll = (e) => {
36309
+ e.preventDefault();
36310
+ e.stopPropagation();
36311
+ const allFields = providedFields || generateFieldsFromData(data);
36312
+ const lines = [
36313
+ typeof cardTitle === "string" ? cardTitle : JSON.stringify(cardTitle),
36314
+ "",
36315
+ ...allFields.map((f) => `${f.label}: ${flattenValue(data[f.key])}`)
36316
+ ];
36317
+ navigator.clipboard.writeText(lines.join("\n")).then(() => {
36318
+ setCopied(true);
36319
+ setTimeout(() => setCopied(false), 2e3);
36320
+ });
36321
+ };
36253
36322
  const handleProceed = () => {
36254
36323
  onAction?.({
36255
36324
  type: "concept_selection",
36256
- value: typeof cardTitle === "string" ? cardTitle : JSON.stringify(cardTitle),
36325
+ value: data.title || data.name || data.concept_name || data.conceptName,
36257
36326
  data
36258
36327
  });
36259
36328
  };
36260
36329
  const effectiveIsLatest = isLatestMessage && !hasUserResponded;
36261
36330
  const fields = (0, import_react64.useMemo)(() => {
36262
36331
  const baseFields = providedFields || generateFieldsFromData(data);
36263
- return baseFields.map((field) => {
36332
+ const FIELD_ORDER = [
36333
+ "description",
36334
+ "creator_strategy",
36335
+ "primary_kpi",
36336
+ "secondary_kpis",
36337
+ "budget_allocation",
36338
+ "budgetAllocation",
36339
+ "estimated_creators",
36340
+ "estimatedCreators",
36341
+ "platforms",
36342
+ "target_platforms",
36343
+ "targetPlatforms"
36344
+ ];
36345
+ const sorted = [...baseFields].sort((a, b) => {
36346
+ const ai = FIELD_ORDER.indexOf(a.key);
36347
+ const bi = FIELD_ORDER.indexOf(b.key);
36348
+ if (ai !== -1 && bi !== -1) return ai - bi;
36349
+ if (ai !== -1) return -1;
36350
+ if (bi !== -1) return 1;
36351
+ return 0;
36352
+ });
36353
+ return sorted.map((field) => {
36264
36354
  if (field.key === "budgetAllocation" || field.key === "budget_allocation") {
36355
+ const formatKey = (k) => k.replace(/_/g, " ").replace(/([a-z])([A-Z])/g, "$1 $2").replace(/\b\w/g, (c) => c.toUpperCase());
36356
+ const formatVal = (v) => {
36357
+ const n = Number(v);
36358
+ if (!isNaN(n) && String(v).trim() !== "") return `${n}%`;
36359
+ return String(v);
36360
+ };
36265
36361
  return {
36266
36362
  ...field,
36267
36363
  label: "Budget Allocation",
36268
36364
  renderDisplay: (val) => {
36269
- if (val && typeof val === "object" && !Array.isArray(val)) {
36270
- return /* @__PURE__ */ (0, import_jsx_runtime121.jsx)("div", { className: "flex flex-wrap gap-2 pt-1", children: Object.entries(val).map(([k, v]) => /* @__PURE__ */ (0, import_jsx_runtime121.jsxs)(
36271
- "div",
36272
- {
36273
- className: "flex items-center gap-1.5 bg-background bg-gray400 border border-white/10 px-2 py-1 rounded shadow-sm",
36274
- children: [
36275
- /* @__PURE__ */ (0, import_jsx_runtime121.jsxs)("span", { className: "text-[10px] text-gray-400 font-bold uppercase tracking-tight", children: [
36276
- k.replace(/_/g, " "),
36277
- ":"
36278
- ] }),
36279
- /* @__PURE__ */ (0, import_jsx_runtime121.jsx)("span", { className: "text-xs text-white font-medium", children: String(v) })
36280
- ]
36281
- },
36282
- k
36283
- )) });
36284
- }
36365
+ if (!val) return /* @__PURE__ */ (0, import_jsx_runtime121.jsx)("span", { className: "text-muted-foreground text-sm", children: "-" });
36285
36366
  if (Array.isArray(val)) {
36286
- return /* @__PURE__ */ (0, import_jsx_runtime121.jsx)("div", { className: "flex flex-wrap gap-2 pt-1", children: val.map((item, idx) => /* @__PURE__ */ (0, import_jsx_runtime121.jsxs)(
36287
- "div",
36288
- {
36289
- className: "flex items-center gap-1.5 bg-background bg-gray400 border border-white/10 px-2 py-1 rounded shadow-sm",
36290
- children: [
36291
- item.label && /* @__PURE__ */ (0, import_jsx_runtime121.jsxs)("span", { className: "text-[10px] text-gray-400 font-bold uppercase tracking-tight", children: [
36292
- item.label,
36293
- ":"
36294
- ] }),
36295
- /* @__PURE__ */ (0, import_jsx_runtime121.jsx)("span", { className: "text-xs text-white font-medium", children: String(item.value || item) })
36296
- ]
36297
- },
36298
- idx
36299
- )) });
36367
+ return /* @__PURE__ */ (0, import_jsx_runtime121.jsx)("div", { className: "space-y-2", children: val.map((item, idx) => {
36368
+ const label = item?.label ?? item?.key ?? `Item ${idx + 1}`;
36369
+ const value = item?.value ?? item;
36370
+ return /* @__PURE__ */ (0, import_jsx_runtime121.jsxs)("div", { className: "flex items-center gap-2", children: [
36371
+ /* @__PURE__ */ (0, import_jsx_runtime121.jsxs)("span", { className: "text-muted-foreground font-medium", children: [
36372
+ idx + 1,
36373
+ "."
36374
+ ] }),
36375
+ /* @__PURE__ */ (0, import_jsx_runtime121.jsx)("span", { className: "inline-flex items-center bg-[#85888f] dark:bg-grayPill px-2 py-1 text-white dark:text-foreground text-sm font-medium rounded-md border border-[#85888f] dark:border-gray900 font-grotesk", children: String(label) }),
36376
+ /* @__PURE__ */ (0, import_jsx_runtime121.jsx)("span", { className: "text-foreground", children: "=" }),
36377
+ /* @__PURE__ */ (0, import_jsx_runtime121.jsx)("span", { className: "inline-flex items-center bg-[#85888f] dark:bg-grayPill px-2 py-1 text-white dark:text-foreground text-sm rounded-md border border-[#85888f] dark:border-gray900 font-grotesk font-medium", children: formatVal(value) })
36378
+ ] }, idx);
36379
+ }) });
36300
36380
  }
36301
- return /* @__PURE__ */ (0, import_jsx_runtime121.jsx)("span", { className: "text-gray-300 text-sm", children: val ? String(val) : "-" });
36381
+ if (typeof val === "object") {
36382
+ const entries = Object.entries(val);
36383
+ if (entries.length === 0) return /* @__PURE__ */ (0, import_jsx_runtime121.jsx)("span", { className: "text-muted-foreground text-sm", children: "-" });
36384
+ return /* @__PURE__ */ (0, import_jsx_runtime121.jsx)("div", { className: "space-y-2", children: entries.map(([k, v], idx) => /* @__PURE__ */ (0, import_jsx_runtime121.jsxs)("div", { className: "flex items-center gap-2", children: [
36385
+ /* @__PURE__ */ (0, import_jsx_runtime121.jsxs)("span", { className: "text-muted-foreground font-medium", children: [
36386
+ idx + 1,
36387
+ "."
36388
+ ] }),
36389
+ /* @__PURE__ */ (0, import_jsx_runtime121.jsx)("span", { className: "inline-flex items-center bg-[#85888f] dark:bg-grayPill px-2 py-1 text-white dark:text-foreground text-sm font-medium rounded-md border border-[#85888f] dark:border-gray900 font-grotesk", children: formatKey(k) }),
36390
+ /* @__PURE__ */ (0, import_jsx_runtime121.jsx)("span", { className: "text-foreground", children: "=" }),
36391
+ /* @__PURE__ */ (0, import_jsx_runtime121.jsx)("span", { className: "inline-flex items-center bg-[#85888f] dark:bg-grayPill px-2 py-1 text-white dark:text-foreground text-sm rounded-md border border-[#85888f] dark:border-gray900 font-grotesk font-medium", children: formatVal(v) })
36392
+ ] }, k)) });
36393
+ }
36394
+ return /* @__PURE__ */ (0, import_jsx_runtime121.jsx)("span", { className: "text-muted-foreground text-sm", children: String(val) });
36302
36395
  }
36303
36396
  };
36304
36397
  }
@@ -36307,32 +36400,64 @@ var CampaignConceptCard = import_react64.default.memo(
36307
36400
  ...field,
36308
36401
  label: "Estimated Creators",
36309
36402
  renderDisplay: (val) => {
36403
+ if (!val) return /* @__PURE__ */ (0, import_jsx_runtime121.jsx)("span", { className: "text-muted-foreground text-sm", children: "-" });
36404
+ if (typeof val === "object" && !Array.isArray(val)) {
36405
+ return /* @__PURE__ */ (0, import_jsx_runtime121.jsxs)("div", { className: "flex items-center gap-2", children: [
36406
+ /* @__PURE__ */ (0, import_jsx_runtime121.jsx)("span", { className: "inline-flex items-center px-2 py-1 bg-[#85888f] dark:bg-grayPill text-white dark:text-foreground text-sm font-medium rounded-md border font-grotesk", children: val.min ?? 0 }),
36407
+ /* @__PURE__ */ (0, import_jsx_runtime121.jsx)("span", { className: "text-foreground", children: "-" }),
36408
+ /* @__PURE__ */ (0, import_jsx_runtime121.jsx)("span", { className: "inline-flex items-center px-2 py-1 bg-[#85888f] dark:bg-grayPill text-white dark:text-foreground text-sm font-medium rounded-md border font-grotesk", children: val.max ?? 0 })
36409
+ ] });
36410
+ }
36411
+ if (typeof val === "string" && val.includes("-")) {
36412
+ return /* @__PURE__ */ (0, import_jsx_runtime121.jsx)("div", { className: "flex items-center gap-2", children: val.split("-").map((part, idx, arr) => /* @__PURE__ */ (0, import_jsx_runtime121.jsxs)(import_react64.default.Fragment, { children: [
36413
+ /* @__PURE__ */ (0, import_jsx_runtime121.jsx)("span", { className: "inline-flex items-center px-2 py-1 bg-[#85888f] dark:bg-grayPill text-white dark:text-foreground text-sm font-medium rounded-md border font-grotesk", children: part.trim() }),
36414
+ idx < arr.length - 1 && /* @__PURE__ */ (0, import_jsx_runtime121.jsx)("span", { className: "text-foreground", children: "-" })
36415
+ ] }, idx)) });
36416
+ }
36310
36417
  if (Array.isArray(val)) {
36311
- return /* @__PURE__ */ (0, import_jsx_runtime121.jsx)("div", { className: "flex gap-2 pt-1", children: val.map((v, idx) => /* @__PURE__ */ (0, import_jsx_runtime121.jsx)(
36312
- "div",
36418
+ return /* @__PURE__ */ (0, import_jsx_runtime121.jsx)("div", { className: "flex items-center gap-2", children: val.map((v, idx) => /* @__PURE__ */ (0, import_jsx_runtime121.jsx)(
36419
+ "span",
36313
36420
  {
36314
- className: "bg-background bg-purple200 border border-purple100/20 px-2 py-0.5 rounded text-white text-xs font-medium",
36421
+ className: "inline-flex items-center px-2 py-1 bg-[#85888f] dark:bg-grayPill text-white dark:text-foreground text-sm font-medium rounded-md border font-grotesk",
36315
36422
  children: String(v)
36316
36423
  },
36317
36424
  idx
36318
36425
  )) });
36319
36426
  }
36320
- return /* @__PURE__ */ (0, import_jsx_runtime121.jsx)("span", { className: "text-white font-medium", children: val ? String(val) : "-" });
36427
+ return /* @__PURE__ */ (0, import_jsx_runtime121.jsx)("span", { className: "text-txtColor font-medium", children: String(val) });
36321
36428
  }
36322
36429
  };
36323
36430
  }
36324
- if (field.key === "platforms") {
36431
+ if (field.key === "primary_kpi" || field.key === "primaryKpi") {
36325
36432
  return {
36326
36433
  ...field,
36434
+ label: field.label || "Primary KPI",
36435
+ renderDisplay: (val) => /* @__PURE__ */ (0, import_jsx_runtime121.jsx)("span", { className: "text-foreground text-sm", children: val ? String(val) : "-" })
36436
+ };
36437
+ }
36438
+ if (field.key === "secondary_kpis" || field.key === "secondaryKpis") {
36439
+ return {
36440
+ ...field,
36441
+ label: field.label || "Secondary KPIs",
36327
36442
  renderDisplay: (val) => {
36328
- const platforms = Array.isArray(val) ? val : typeof val === "string" ? val.split(/,\s*/) : [val];
36329
- return /* @__PURE__ */ (0, import_jsx_runtime121.jsx)("div", { className: "flex flex-wrap gap-1.5 pt-1", children: platforms.map((p) => /* @__PURE__ */ (0, import_jsx_runtime121.jsx)(
36330
- "div",
36443
+ const display = Array.isArray(val) ? val.map(String).join(", ") : val ? String(val) : "-";
36444
+ return /* @__PURE__ */ (0, import_jsx_runtime121.jsx)("span", { className: "text-foreground text-sm", children: display });
36445
+ }
36446
+ };
36447
+ }
36448
+ if (field.key === "platforms" || field.key === "target_platforms" || field.key === "targetPlatforms") {
36449
+ return {
36450
+ ...field,
36451
+ renderDisplay: (val) => {
36452
+ const platforms = Array.isArray(val) ? val.map(String) : typeof val === "string" ? val.split(/,\s*/).map((s) => s.trim()).filter(Boolean) : val ? [String(val)] : [];
36453
+ if (platforms.length === 0) return /* @__PURE__ */ (0, import_jsx_runtime121.jsx)("span", { className: "text-muted-foreground text-sm", children: "-" });
36454
+ return /* @__PURE__ */ (0, import_jsx_runtime121.jsx)("div", { className: "flex flex-wrap gap-2 pt-1", children: platforms.map((p) => /* @__PURE__ */ (0, import_jsx_runtime121.jsx)(
36455
+ "span",
36331
36456
  {
36332
- className: "px-2 py-0.5 rounded-full bg-blue-500/10 border border-blue-500/20 text-blue-400 text-[10px] font-bold uppercase",
36333
- children: String(p)
36457
+ className: "inline-flex items-center bg-[#85888f] dark:bg-grayPill px-2 py-1 text-white dark:text-foreground text-sm font-medium rounded-md border border-[#85888f] dark:border-gray900 font-grotesk",
36458
+ children: p
36334
36459
  },
36335
- String(p)
36460
+ p
36336
36461
  )) });
36337
36462
  }
36338
36463
  };
@@ -36340,10 +36465,24 @@ var CampaignConceptCard = import_react64.default.memo(
36340
36465
  return {
36341
36466
  ...field,
36342
36467
  renderDisplay: (val) => {
36468
+ if (Array.isArray(val)) {
36469
+ if (val.length === 0) return /* @__PURE__ */ (0, import_jsx_runtime121.jsx)("span", { className: "text-muted-foreground text-sm", children: "-" });
36470
+ return /* @__PURE__ */ (0, import_jsx_runtime121.jsx)("div", { className: "flex flex-wrap gap-1.5 pt-1", children: val.map((item, idx) => {
36471
+ const label = typeof item === "object" && item !== null ? item.label || item.value || item.name || JSON.stringify(item) : String(item);
36472
+ return /* @__PURE__ */ (0, import_jsx_runtime121.jsx)(
36473
+ "span",
36474
+ {
36475
+ className: "inline-block bg-paperBackground border border-gray400 text-txtColor text-xs px-2 py-0.5 rounded-full",
36476
+ children: label
36477
+ },
36478
+ idx
36479
+ );
36480
+ }) });
36481
+ }
36343
36482
  if (typeof val === "object" && val !== null) {
36344
- return /* @__PURE__ */ (0, import_jsx_runtime121.jsx)("div", { className: "text-gray-300 text-xs font-mono bg-black/20 p-2 rounded border border-white/5 mt-1 overflow-auto max-h-24", children: JSON.stringify(val, null, 2) });
36483
+ return /* @__PURE__ */ (0, import_jsx_runtime121.jsx)("div", { className: "text-muted-foreground text-xs font-mono bg-paperBackground p-2 rounded border border-gray400 mt-1 overflow-auto max-h-24", children: Object.entries(val).map(([k, v]) => `${k.replace(/_/g, " ")}: ${v}`).join("\n") });
36345
36484
  }
36346
- return /* @__PURE__ */ (0, import_jsx_runtime121.jsx)("span", { className: "text-gray-300 text-sm", children: String(val) });
36485
+ return /* @__PURE__ */ (0, import_jsx_runtime121.jsx)("span", { className: "text-txtColor text-sm", children: val !== void 0 && val !== null ? String(val) : "-" });
36347
36486
  }
36348
36487
  };
36349
36488
  });
@@ -36352,34 +36491,55 @@ var CampaignConceptCard = import_react64.default.memo(
36352
36491
  "div",
36353
36492
  {
36354
36493
  className: cn(
36355
- "w-full rounded-[20px] transition-all duration-300 bg-background dark:bg-gray50",
36356
- isOpen ? "border border-green-500/50 shadow-[0_0_15px_rgba(34,197,94,0.1)]" : "border border-gray400",
36494
+ "w-full rounded-xl border bg-background dark:bg-gray100 relative transition-all duration-300",
36495
+ isSelected || isRecommended ? "border-2 border-green500" : "border-gray400",
36357
36496
  className
36358
36497
  ),
36359
36498
  children: [
36360
36499
  /* @__PURE__ */ (0, import_jsx_runtime121.jsxs)(
36361
36500
  "div",
36362
36501
  {
36363
- className: "flex items-center justify-between p-6 cursor-pointer select-none",
36502
+ className: "p-6 relative flex items-start justify-between cursor-pointer select-none",
36364
36503
  onClick: handleToggle,
36365
36504
  children: [
36366
- /* @__PURE__ */ (0, import_jsx_runtime121.jsxs)("div", { className: "flex flex-col gap-2", children: [
36367
- /* @__PURE__ */ (0, import_jsx_runtime121.jsx)("h3", { className: "text-lg font-semibold text-white tracking-wide", children: typeof cardTitle === "object" ? JSON.stringify(cardTitle) : String(cardTitle) }),
36505
+ /* @__PURE__ */ (0, import_jsx_runtime121.jsxs)("div", { className: "flex-1", children: [
36506
+ /* @__PURE__ */ (0, import_jsx_runtime121.jsx)("h2", { className: "mb-1 py-1 text-txtColor font-bold", children: typeof cardTitle === "object" ? JSON.stringify(cardTitle) : String(cardTitle) }),
36368
36507
  /* @__PURE__ */ (0, import_jsx_runtime121.jsxs)("div", { className: "flex flex-wrap gap-2", children: [
36369
36508
  isRecommended && /* @__PURE__ */ (0, import_jsx_runtime121.jsx)("div", { className: "inline-flex text-[10px] font-bold uppercase tracking-widest text-[#22C55E]", children: /* @__PURE__ */ (0, import_jsx_runtime121.jsx)("span", { className: "bg-[#22C55E]/10 px-2 py-0.5 rounded border border-[#22C55E]/20", children: "Recommended" }) }),
36370
- hasUserResponded && /* @__PURE__ */ (0, import_jsx_runtime121.jsx)("div", { className: "inline-flex text-[10px] font-bold uppercase tracking-widest text-[#3B82F6]", children: /* @__PURE__ */ (0, import_jsx_runtime121.jsx)("span", { className: "bg-[#3B82F6]/10 px-2 py-0.5 rounded border border-[#3B82F6]/20", children: selectionStatus === "agent" ? "Selected by Agent" : "Selected by You" }) })
36509
+ !effectiveIsLatest && selectionStatus && /* @__PURE__ */ (0, import_jsx_runtime121.jsx)("div", { className: "inline-flex text-[10px] font-bold uppercase tracking-widest text-[#3B82F6]", children: /* @__PURE__ */ (0, import_jsx_runtime121.jsx)("span", { className: "bg-[#3B82F6]/10 px-2 py-0.5 rounded border border-[#3B82F6]/20", children: selectionStatus === "agent" ? "Selected by Agent" : "Selected by You" }) })
36371
36510
  ] })
36372
36511
  ] }),
36373
- /* @__PURE__ */ (0, import_jsx_runtime121.jsx)(
36374
- "div",
36375
- {
36376
- className: cn(
36377
- "p-2 rounded-lg bg-white/5 border border-white/10 text-gray-400 transition-transform duration-300",
36378
- isOpen && "rotate-180"
36379
- ),
36380
- children: /* @__PURE__ */ (0, import_jsx_runtime121.jsx)(ChevronDown, { className: "h-4 w-4" })
36381
- }
36382
- )
36512
+ /* @__PURE__ */ (0, import_jsx_runtime121.jsxs)("div", { className: "flex items-center gap-2 ml-3", onClick: (e) => e.stopPropagation(), children: [
36513
+ /* @__PURE__ */ (0, import_jsx_runtime121.jsx)(
36514
+ "button",
36515
+ {
36516
+ onClick: handleCopyAll,
36517
+ title: "Copy all details",
36518
+ className: "p-2 bg-background hover:bg-gray200 dark:hover:bg-gray200 text-foreground rounded-lg shadow-lg transition-all active:scale-95",
36519
+ "aria-label": "Copy all details",
36520
+ children: copied ? /* @__PURE__ */ (0, import_jsx_runtime121.jsx)(Check, { className: "h-4 w-4 text-green-500" }) : /* @__PURE__ */ (0, import_jsx_runtime121.jsx)(Copy, { className: "h-4 w-4" })
36521
+ }
36522
+ ),
36523
+ /* @__PURE__ */ (0, import_jsx_runtime121.jsx)(
36524
+ "button",
36525
+ {
36526
+ onClick: (e) => {
36527
+ e.preventDefault();
36528
+ e.stopPropagation();
36529
+ handleToggle();
36530
+ },
36531
+ className: "p-2 bg-background hover:bg-gray200 dark:hover:bg-gray200 text-foreground rounded-lg shadow-lg",
36532
+ "aria-label": isOpen ? "Collapse" : "Expand",
36533
+ title: isOpen ? "Collapse" : "Expand",
36534
+ children: /* @__PURE__ */ (0, import_jsx_runtime121.jsx)(
36535
+ ChevronDown,
36536
+ {
36537
+ className: `h-4 w-4 transition-transform ${isOpen ? "rotate-0" : "-rotate-90"}`
36538
+ }
36539
+ )
36540
+ }
36541
+ )
36542
+ ] })
36383
36543
  ]
36384
36544
  }
36385
36545
  ),
@@ -36389,27 +36549,41 @@ var CampaignConceptCard = import_react64.default.memo(
36389
36549
  initial: { height: 0, opacity: 0 },
36390
36550
  animate: { height: "auto", opacity: 1 },
36391
36551
  exit: { height: 0, opacity: 0 },
36392
- transition: { duration: 0.3, ease: "easeInOut" },
36552
+ transition: { duration: 0.2, ease: "easeIn" },
36393
36553
  className: "overflow-hidden",
36394
- children: /* @__PURE__ */ (0, import_jsx_runtime121.jsx)("div", { className: "px-6 pb-6 pt-0 border-t border-white/5", children: /* @__PURE__ */ (0, import_jsx_runtime121.jsx)(
36395
- FormCard,
36396
- {
36397
- ...formCardProps,
36398
- title: typeof cardTitle === "object" ? JSON.stringify(cardTitle) : String(cardTitle),
36399
- data,
36400
- fields,
36401
- showTimeline: true,
36402
- proceedLabel: "Continue with this concept",
36403
- onProceed: handleProceed,
36404
- isLatestMessage: effectiveIsLatest,
36405
- className: "bg-transparent border-none shadow-none mb-0 p-0",
36406
- footer: !effectiveIsLatest && (selectionStatus || hasUserResponded) ? /* @__PURE__ */ (0, import_jsx_runtime121.jsxs)("div", { className: "flex justify-end items-center gap-1.5 text-green-600 text-[10px] font-semibold py-4 pr-6", children: [
36407
- /* @__PURE__ */ (0, import_jsx_runtime121.jsx)(CircleCheck, { className: "h-3.5 w-3.5" }),
36408
- /* @__PURE__ */ (0, import_jsx_runtime121.jsx)("span", { children: selectionStatus === "agent" ? "Selected by Agent" : "Selected by You" })
36409
- ] }) : formCardProps.footer
36410
- }
36411
- ) })
36412
- }
36554
+ children: /* @__PURE__ */ (0, import_jsx_runtime121.jsxs)("div", { className: "p-6 w-full overflow-hidden relative", children: [
36555
+ /* @__PURE__ */ (0, import_jsx_runtime121.jsx)(
36556
+ "div",
36557
+ {
36558
+ className: "absolute left-[60px] top-[100px] bottom-[60px] w-[3px]",
36559
+ style: {
36560
+ background: `radial-gradient(circle closest-side, #3C3D3E 98%, transparent) 50%/2px 5px repeat-y, linear-gradient(#3C3D3E 50%, transparent 0) 50%/2px 10px repeat-y`
36561
+ }
36562
+ }
36563
+ ),
36564
+ /* @__PURE__ */ (0, import_jsx_runtime121.jsx)(
36565
+ FormCard,
36566
+ {
36567
+ ...formCardProps,
36568
+ title: typeof cardTitle === "object" ? JSON.stringify(cardTitle) : String(cardTitle),
36569
+ data,
36570
+ fields,
36571
+ showTimeline: true,
36572
+ proceedLabel: "Continue with this concept",
36573
+ onProceed: handleProceed,
36574
+ isLatestMessage: effectiveIsLatest,
36575
+ hideTitle: true,
36576
+ hideCopyButton: true,
36577
+ className: "bg-transparent border-none shadow-none mb-0 p-0",
36578
+ footer: !effectiveIsLatest && selectionStatus ? /* @__PURE__ */ (0, import_jsx_runtime121.jsxs)("div", { className: "flex justify-end items-center gap-1.5 text-green-600 text-[10px] font-semibold py-4 pr-6", children: [
36579
+ /* @__PURE__ */ (0, import_jsx_runtime121.jsx)(CircleCheck, { className: "h-3.5 w-3.5" }),
36580
+ /* @__PURE__ */ (0, import_jsx_runtime121.jsx)("span", { children: selectionStatus === "agent" ? "Selected by Agent" : "Selected by You" })
36581
+ ] }) : formCardProps.footer
36582
+ }
36583
+ )
36584
+ ] })
36585
+ },
36586
+ "expanded-content"
36413
36587
  ) })
36414
36588
  ]
36415
36589
  }