pxengine 0.1.29 → 0.1.30

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
@@ -25561,7 +25561,7 @@ var InputAtom = ({
25561
25561
  var import_class_variance_authority3 = require("class-variance-authority");
25562
25562
  var import_jsx_runtime18 = require("react/jsx-runtime");
25563
25563
  var badgeVariants = (0, import_class_variance_authority3.cva)(
25564
- "inline-flex items-center rounded-full border px-2.5 py-0.5 text-xs font-semibold transition-colors focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2",
25564
+ "inline-flex items-center rounded-full border px-2.5 py-1 text-xs font-semibold transition-colors focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2",
25565
25565
  {
25566
25566
  variants: {
25567
25567
  variant: {
@@ -34056,7 +34056,7 @@ var EditableField = import_react54.default.memo(
34056
34056
  "div",
34057
34057
  {
34058
34058
  className: cn(
34059
- "relative z-10 group flex flex-col gap-2 p-3 bg-background dark:bg-gray700 rounded-md mb-8",
34059
+ "relative z-10 group flex flex-col gap-2 p-3 bg-paperBackground rounded-md mb-8",
34060
34060
  className
34061
34061
  ),
34062
34062
  children: [
@@ -34068,13 +34068,14 @@ var EditableField = import_react54.default.memo(
34068
34068
  children: label
34069
34069
  }
34070
34070
  ),
34071
- !isEditingProp && /* @__PURE__ */ (0, import_jsx_runtime94.jsxs)("span", { className: "inline-flex items-center gap-1 text-[10px] font-medium text-green-500 dark:text-green-500", children: [
34071
+ !isEditingProp && /* @__PURE__ */ (0, import_jsx_runtime94.jsxs)("span", { className: "inline-flex items-center gap-1.5 text-[0.75rem] font-medium text-green-600 dark:text-green-500 bg-green-500/5 px-2 py-0.5 rounded-full ", children: [
34072
34072
  "Suggested by an Agent",
34073
34073
  /* @__PURE__ */ (0, import_jsx_runtime94.jsx)(
34074
- Pencil,
34074
+ "span",
34075
34075
  {
34076
- className: "h-3 w-3 hover:text-green-700 cursor-pointer",
34077
- onClick: onEdit
34076
+ className: "flex items-center gap-1 cursor-pointer text-foreground hover:text-green-700 transition-colors ml-1 pl-1.5 ",
34077
+ onClick: onEdit,
34078
+ children: /* @__PURE__ */ (0, import_jsx_runtime94.jsx)(SquarePen, { className: "h-5 w-5" })
34078
34079
  }
34079
34080
  )
34080
34081
  ] })
@@ -34087,7 +34088,7 @@ var EditableField = import_react54.default.memo(
34087
34088
  {
34088
34089
  size: "icon",
34089
34090
  variant: "outline",
34090
- className: "h-8 w-8 text-destructive border-destructive/20 hover:bg-destructive/10 rounded-lg",
34091
+ className: "h-8 w-8 text-foreground rounded-lg",
34091
34092
  onClick: onCancel,
34092
34093
  disabled: isSaving,
34093
34094
  children: /* @__PURE__ */ (0, import_jsx_runtime94.jsx)(X, { className: "h-4 w-4" })
@@ -34097,10 +34098,10 @@ var EditableField = import_react54.default.memo(
34097
34098
  Button,
34098
34099
  {
34099
34100
  size: "icon",
34100
- className: "h-8 w-8 bg-purpleLight text-purpleText2 hover:bg-purpleText1 rounded-lg border border-purpleText1 shadow-none",
34101
+ className: "h-8 w-8 text-foreground rounded-lg shadow-none",
34101
34102
  onClick: handleSave,
34102
34103
  disabled: isSaving,
34103
- children: isSaving ? /* @__PURE__ */ (0, import_jsx_runtime94.jsx)(LoaderCircle, { className: "h-4 w-4 animate-spin" }) : /* @__PURE__ */ (0, import_jsx_runtime94.jsx)(Check, { className: "h-4 w-4" })
34104
+ children: isSaving ? /* @__PURE__ */ (0, import_jsx_runtime94.jsx)(LoaderCircle, { className: "h-4 w-4 animate-spin" }) : /* @__PURE__ */ (0, import_jsx_runtime94.jsx)(Save, { className: "h-4 w-4" })
34104
34105
  }
34105
34106
  )
34106
34107
  ] })
@@ -34108,9 +34109,10 @@ var EditableField = import_react54.default.memo(
34108
34109
  "div",
34109
34110
  {
34110
34111
  className: cn(
34111
- "relative flex items-center justify-between rounded-lg px-3 py-2",
34112
- "text-[14px] text-foreground font-normal leading-relaxed"
34112
+ "relative flex items-start justify-between rounded-lg px-3 py-2",
34113
+ "text-base text-foreground/90 font-medium leading-relaxed"
34113
34114
  ),
34115
+ style: { fontFamily: "Noto Sans, sans-serif" },
34114
34116
  children: /* @__PURE__ */ (0, import_jsx_runtime94.jsx)("div", { className: "flex-1", children: formattedValue() })
34115
34117
  }
34116
34118
  )
@@ -34221,12 +34223,12 @@ var FormCard = import_react56.default.memo(
34221
34223
  title,
34222
34224
  fields,
34223
34225
  data,
34224
- editingFields = {},
34226
+ editingFields: externalEditingFields,
34225
34227
  changedFields = {},
34226
34228
  savingFields = {},
34227
- onFieldEdit,
34228
- onFieldSave,
34229
- onFieldCancel,
34229
+ onFieldEdit: externalOnFieldEdit,
34230
+ onFieldSave: externalOnFieldSave,
34231
+ onFieldCancel: externalOnFieldCancel,
34230
34232
  showTimeline = true,
34231
34233
  proceedLabel,
34232
34234
  onProceed,
@@ -34237,6 +34239,36 @@ var FormCard = import_react56.default.memo(
34237
34239
  footer
34238
34240
  }) => {
34239
34241
  const [copied, setCopied] = (0, import_react56.useState)(false);
34242
+ const [internalEditingFields, setInternalEditingFields] = (0, import_react56.useState)({});
34243
+ const [internalData, setInternalData] = (0, import_react56.useState)(data);
34244
+ import_react56.default.useEffect(() => {
34245
+ setInternalData(data);
34246
+ }, [data]);
34247
+ const isExternallyControlled = !!(externalOnFieldEdit || externalOnFieldSave || externalOnFieldCancel);
34248
+ const editingFields = isExternallyControlled ? externalEditingFields || {} : internalEditingFields;
34249
+ const activeData = isExternallyControlled ? data : internalData;
34250
+ const handleFieldEdit = (key) => {
34251
+ if (isExternallyControlled) {
34252
+ externalOnFieldEdit?.(key);
34253
+ } else {
34254
+ setInternalEditingFields((prev) => ({ ...prev, [key]: true }));
34255
+ }
34256
+ };
34257
+ const handleFieldSave = (key, newValue) => {
34258
+ if (isExternallyControlled) {
34259
+ externalOnFieldSave?.(key, newValue);
34260
+ } else {
34261
+ setInternalData((prev) => ({ ...prev, [key]: newValue }));
34262
+ setInternalEditingFields((prev) => ({ ...prev, [key]: false }));
34263
+ }
34264
+ };
34265
+ const handleFieldCancel = (key) => {
34266
+ if (isExternallyControlled) {
34267
+ externalOnFieldCancel?.(key);
34268
+ } else {
34269
+ setInternalEditingFields((prev) => ({ ...prev, [key]: false }));
34270
+ }
34271
+ };
34240
34272
  const handleCopyAll = () => {
34241
34273
  const flattenValue = (val) => {
34242
34274
  if (val === null || val === void 0) return "-";
@@ -34257,7 +34289,7 @@ var FormCard = import_react56.default.memo(
34257
34289
  title,
34258
34290
  "",
34259
34291
  ...fields.map((field) => {
34260
- const value = data[field.key];
34292
+ const value = activeData[field.key];
34261
34293
  return `${field.label}: ${flattenValue(value)}`;
34262
34294
  })
34263
34295
  ].join("\n");
@@ -34270,7 +34302,7 @@ var FormCard = import_react56.default.memo(
34270
34302
  "div",
34271
34303
  {
34272
34304
  className: cn(
34273
- "relative w-full rounded-[20px] bg-background dark:bg-gray100 border border-gray400 shadow-lg overflow-hidden mb-6 font-noto",
34305
+ "relative w-full rounded-[20px] bg-paperBackground dark:bg-gray100 border border-gray400 shadow-lg overflow-hidden mb-6 font-noto",
34274
34306
  className
34275
34307
  ),
34276
34308
  children: [
@@ -34287,7 +34319,7 @@ var FormCard = import_react56.default.memo(
34287
34319
  !hideTitle && title && /* @__PURE__ */ (0, import_jsx_runtime96.jsx)(
34288
34320
  "h3",
34289
34321
  {
34290
- className: "text-gray900 dark:text-white mb-12 font-bold",
34322
+ className: "text-gray900 dark:text-white mb-12 text-[1rem] font-bold",
34291
34323
  children: title
34292
34324
  }
34293
34325
  ),
@@ -34307,16 +34339,16 @@ var FormCard = import_react56.default.memo(
34307
34339
  EditableField,
34308
34340
  {
34309
34341
  label: field.label,
34310
- value: data[field.key],
34342
+ value: activeData[field.key],
34311
34343
  type: field.type,
34312
34344
  config: field,
34313
34345
  isEditing: editingFields[field.key],
34314
34346
  isChanged: changedFields[field.key],
34315
34347
  isSaving: savingFields[field.key],
34316
34348
  isLatestMessage,
34317
- onEdit: () => onFieldEdit?.(field.key),
34318
- onSave: (val) => onFieldSave?.(field.key, val),
34319
- onCancel: () => onFieldCancel?.(field.key),
34349
+ onEdit: () => handleFieldEdit(field.key),
34350
+ onSave: (val) => handleFieldSave(field.key, val),
34351
+ onCancel: () => handleFieldCancel(field.key),
34320
34352
  renderDisplay: field.renderDisplay,
34321
34353
  renderEdit: field.renderEdit,
34322
34354
  showIndex: showTimeline,
@@ -35177,7 +35209,7 @@ var CountrySelectDisplay = ({ value }) => {
35177
35209
  Badge2,
35178
35210
  {
35179
35211
  variant: "outline",
35180
- className: "bg-gray-50 text-gray-700 border-gray-200",
35212
+ className: "text-foreground border-gray-200 py-1",
35181
35213
  children: countryCode
35182
35214
  },
35183
35215
  countryCode
@@ -35197,7 +35229,7 @@ var KeywordBundlesEdit = ({
35197
35229
  const sortedPriorities = Object.keys(groups).map((n) => parseInt(n)).sort((a, b) => a - b);
35198
35230
  return /* @__PURE__ */ (0, import_jsx_runtime106.jsx)("div", { className: "space-y-6 pt-2", children: sortedPriorities.map((priority) => /* @__PURE__ */ (0, import_jsx_runtime106.jsxs)("div", { className: "space-y-3", children: [
35199
35231
  /* @__PURE__ */ (0, import_jsx_runtime106.jsxs)("div", { className: "flex items-center gap-2", children: [
35200
- /* @__PURE__ */ (0, import_jsx_runtime106.jsxs)(Badge2, { className: "bg-purple500 hover:bg-purple500", children: [
35232
+ /* @__PURE__ */ (0, import_jsx_runtime106.jsxs)(Badge2, { className: "bg-purple500 hover:bg-purple500 py-1", children: [
35201
35233
  "Priority ",
35202
35234
  priority
35203
35235
  ] }),
@@ -35213,7 +35245,7 @@ var KeywordBundlesEdit = ({
35213
35245
  /* @__PURE__ */ (0, import_jsx_runtime106.jsx)("div", { className: "flex flex-wrap gap-1.5", children: Array.isArray(bundle.keywords) && bundle.keywords.map((keyword, kIndex) => /* @__PURE__ */ (0, import_jsx_runtime106.jsxs)(
35214
35246
  Badge2,
35215
35247
  {
35216
- className: "bg-white border-gray-200 text-gray-700 hover:bg-red-50 hover:text-red-600 hover:border-red-100 transition-all cursor-pointer group",
35248
+ className: "bg-white py-1 border-gray-200 text-gray-700 hover:bg-red-50 hover:text-red-600 hover:border-red-100 transition-all cursor-pointer group",
35217
35249
  onClick: () => {
35218
35250
  const updatedBundles = [...bundles];
35219
35251
  updatedBundles[bundleIndex] = {
@@ -35307,7 +35339,7 @@ var KeywordBundlesDisplay = ({ value }) => {
35307
35339
  /* @__PURE__ */ (0, import_jsx_runtime106.jsx)("div", { className: "flex flex-wrap gap-2", children: deduped.map((keyword) => /* @__PURE__ */ (0, import_jsx_runtime106.jsx)(
35308
35340
  "div",
35309
35341
  {
35310
- className: "px-2 py-1 rounded bg-background bg-gray400 border border-white/10 text-gray-300 text-xs font-medium",
35342
+ className: "px-2 py-1 rounded bg-background border text-gray-300 text-sm font-medium py-1",
35311
35343
  children: keyword
35312
35344
  },
35313
35345
  keyword
@@ -35331,7 +35363,7 @@ var ObjectDisplay = ({ value }) => {
35331
35363
  var StringArrayDisplay = ({ value }) => {
35332
35364
  if (!Array.isArray(value) || value.length === 0)
35333
35365
  return /* @__PURE__ */ (0, import_jsx_runtime107.jsx)("span", { className: "text-muted-foreground italic text-sm", children: "Not specified" });
35334
- return /* @__PURE__ */ (0, import_jsx_runtime107.jsx)("div", { className: "flex flex-wrap gap-1.5 pt-1", children: value.map((item) => /* @__PURE__ */ (0, import_jsx_runtime107.jsx)(Badge2, { variant: "outline", className: "text-xs", children: item }, item)) });
35366
+ return /* @__PURE__ */ (0, import_jsx_runtime107.jsx)("div", { className: "flex flex-wrap gap-1.5 pt-1", children: value.map((item) => /* @__PURE__ */ (0, import_jsx_runtime107.jsx)(Badge2, { variant: "outline", className: "text-sm border-gray-200 py-1", children: item }, item)) });
35335
35367
  };
35336
35368
  function buildCampaignSeedFields(data) {
35337
35369
  if (!data || typeof data !== "object") return [];
@@ -35342,7 +35374,32 @@ function buildCampaignSeedFields(data) {
35342
35374
  key,
35343
35375
  label: "Keyword Bundles",
35344
35376
  type: "custom",
35345
- renderDisplay: (v) => /* @__PURE__ */ (0, import_jsx_runtime107.jsx)(KeywordBundlesDisplay, { value: v })
35377
+ renderDisplay: (v) => /* @__PURE__ */ (0, import_jsx_runtime107.jsx)(KeywordBundlesDisplay, { value: v }),
35378
+ renderEdit: (v, onChange) => /* @__PURE__ */ (0, import_jsx_runtime107.jsx)(
35379
+ Textarea,
35380
+ {
35381
+ value: Array.isArray(v) ? v.map((b) => `${(b.keywords || []).join(", ")} (Priority: ${b.priority || 1})`).join("\n") : String(v || ""),
35382
+ onChange: (e) => {
35383
+ const lines = e.target.value.split("\n").filter(Boolean);
35384
+ const bundles = lines.map((line) => {
35385
+ const match2 = line.match(/(.*?)\s*\(Priority:\s*(\d+)\)/i);
35386
+ if (match2) {
35387
+ return {
35388
+ keywords: match2[1].split(",").map((s) => s.trim()).filter(Boolean),
35389
+ priority: parseInt(match2[2]) || 1
35390
+ };
35391
+ }
35392
+ return {
35393
+ keywords: line.split(",").map((s) => s.trim()).filter(Boolean),
35394
+ priority: 1
35395
+ };
35396
+ });
35397
+ onChange(bundles);
35398
+ },
35399
+ placeholder: "Keyword 1, Keyword 2 (Priority: 1)...",
35400
+ className: "min-h-[120px] bg-background border-gray-300"
35401
+ }
35402
+ )
35346
35403
  };
35347
35404
  }
35348
35405
  if (key === "geography") {
@@ -35350,7 +35407,19 @@ function buildCampaignSeedFields(data) {
35350
35407
  key,
35351
35408
  label: "Geography",
35352
35409
  type: "custom",
35353
- renderDisplay: (v) => /* @__PURE__ */ (0, import_jsx_runtime107.jsx)(CountrySelectDisplay, { value: v })
35410
+ renderDisplay: (v) => /* @__PURE__ */ (0, import_jsx_runtime107.jsx)(CountrySelectDisplay, { value: v }),
35411
+ renderEdit: (v, onChange) => /* @__PURE__ */ (0, import_jsx_runtime107.jsx)(
35412
+ Textarea,
35413
+ {
35414
+ value: Array.isArray(v) ? v.join(", ") : String(v || ""),
35415
+ onChange: (e) => {
35416
+ const items = e.target.value.split(",").map((s) => s.trim().toUpperCase()).filter(Boolean);
35417
+ onChange(items);
35418
+ },
35419
+ placeholder: "Enter country codes (US, GB, PK) separated by commas...",
35420
+ className: "min-h-[80px] bg-background border-gray-300"
35421
+ }
35422
+ )
35354
35423
  };
35355
35424
  }
35356
35425
  if (key === "platforms" && Array.isArray(value)) {
@@ -35371,7 +35440,19 @@ function buildCampaignSeedFields(data) {
35371
35440
  },
35372
35441
  p
35373
35442
  )) });
35374
- }
35443
+ },
35444
+ renderEdit: (v, onChange) => /* @__PURE__ */ (0, import_jsx_runtime107.jsx)(
35445
+ Textarea,
35446
+ {
35447
+ value: Array.isArray(v) ? v.join(", ") : String(v || ""),
35448
+ onChange: (e) => {
35449
+ const items = e.target.value.split(",").map((s) => s.trim()).filter(Boolean);
35450
+ onChange(items);
35451
+ },
35452
+ placeholder: "Enter platforms separated by commas...",
35453
+ className: "min-h-[80px] bg-background border-gray-300"
35454
+ }
35455
+ )
35375
35456
  };
35376
35457
  }
35377
35458
  if (Array.isArray(value) && value.every((v) => typeof v === "string")) {
@@ -35403,7 +35484,26 @@ function buildCampaignSeedFields(data) {
35403
35484
  key,
35404
35485
  label,
35405
35486
  type: "custom",
35406
- renderDisplay: (v) => /* @__PURE__ */ (0, import_jsx_runtime107.jsx)(ObjectDisplay, { value: v })
35487
+ renderDisplay: (v) => /* @__PURE__ */ (0, import_jsx_runtime107.jsx)(ObjectDisplay, { value: v }),
35488
+ renderEdit: (v, onChange) => /* @__PURE__ */ (0, import_jsx_runtime107.jsx)(
35489
+ Textarea,
35490
+ {
35491
+ value: Object.entries(v || {}).map(([k, val]) => `${k.replace(/_/g, " ")}: ${val}`).join("\n"),
35492
+ onChange: (e) => {
35493
+ const lines = e.target.value.split("\n").filter(Boolean);
35494
+ const newObj = {};
35495
+ lines.forEach((line) => {
35496
+ const [k, ...rest] = line.split(":");
35497
+ if (k) {
35498
+ newObj[k.trim().replace(/\s+/g, "_").toLowerCase()] = rest.join(":").trim();
35499
+ }
35500
+ });
35501
+ onChange(newObj);
35502
+ },
35503
+ placeholder: "Enter key: value pairs (one per line)...",
35504
+ className: "min-h-[120px] bg-background border-gray-300 font-mono text-xs"
35505
+ }
35506
+ )
35407
35507
  };
35408
35508
  }
35409
35509
  const [generated] = generateFieldsFromData({ [key]: value });
@@ -35470,7 +35570,7 @@ var ObjectDisplay2 = ({ value }) => {
35470
35570
  var StringArrayDisplay2 = ({ value }) => {
35471
35571
  if (!Array.isArray(value) || value.length === 0)
35472
35572
  return /* @__PURE__ */ (0, import_jsx_runtime108.jsx)("span", { className: "text-muted-foreground italic text-sm", children: "Not specified" });
35473
- return /* @__PURE__ */ (0, import_jsx_runtime108.jsx)("div", { className: "flex flex-wrap gap-1.5 pt-1", children: value.map((item) => /* @__PURE__ */ (0, import_jsx_runtime108.jsx)(Badge2, { variant: "outline", className: "text-xs", children: item }, item)) });
35573
+ return /* @__PURE__ */ (0, import_jsx_runtime108.jsx)("div", { className: "flex flex-wrap gap-1.5 pt-1", children: value.map((item) => /* @__PURE__ */ (0, import_jsx_runtime108.jsx)(Badge2, { variant: "outline", className: "text-sm border-gray-200 py-1", children: item }, item)) });
35474
35574
  };
35475
35575
  function buildSearchSpecFields(data) {
35476
35576
  if (!data || typeof data !== "object") return [];
@@ -35494,12 +35594,25 @@ function buildSearchSpecFields(data) {
35494
35594
  renderEdit: (v, onChange) => /* @__PURE__ */ (0, import_jsx_runtime108.jsx)(CountrySelectEdit, { value: v, onChange })
35495
35595
  };
35496
35596
  }
35497
- if (key === "platforms" && Array.isArray(value)) {
35597
+ if ((key === "platforms" || key === "exclude_keywords" || key === "excludeKeywords") && Array.isArray(value)) {
35598
+ const label = key === "platforms" ? "Platforms" : "Exclude Keywords";
35498
35599
  return {
35499
35600
  key,
35500
- label: "Platforms",
35601
+ label,
35501
35602
  type: "custom",
35502
- renderDisplay: (v) => /* @__PURE__ */ (0, import_jsx_runtime108.jsx)(StringArrayDisplay2, { value: v })
35603
+ renderDisplay: (v) => /* @__PURE__ */ (0, import_jsx_runtime108.jsx)(StringArrayDisplay2, { value: v }),
35604
+ renderEdit: (v, onChange) => /* @__PURE__ */ (0, import_jsx_runtime108.jsx)(
35605
+ Textarea,
35606
+ {
35607
+ value: Array.isArray(v) ? v.join(", ") : String(v || ""),
35608
+ onChange: (e) => {
35609
+ const items = e.target.value.split(",").map((s) => s.trim()).filter(Boolean);
35610
+ onChange(items);
35611
+ },
35612
+ placeholder: `Enter ${label.toLowerCase()} separated by commas...`,
35613
+ className: "min-h-[100px] bg-background border-gray-300"
35614
+ }
35615
+ )
35503
35616
  };
35504
35617
  }
35505
35618
  if (typeof value === "object" && value !== null && !Array.isArray(value) && !("min" in value && "max" in value)) {
@@ -35508,7 +35621,26 @@ function buildSearchSpecFields(data) {
35508
35621
  key,
35509
35622
  label,
35510
35623
  type: "custom",
35511
- renderDisplay: (v) => /* @__PURE__ */ (0, import_jsx_runtime108.jsx)(ObjectDisplay2, { value: v })
35624
+ renderDisplay: (v) => /* @__PURE__ */ (0, import_jsx_runtime108.jsx)(ObjectDisplay2, { value: v }),
35625
+ renderEdit: (v, onChange) => /* @__PURE__ */ (0, import_jsx_runtime108.jsx)(
35626
+ Textarea,
35627
+ {
35628
+ value: Object.entries(v || {}).map(([k, val]) => `${k.replace(/_/g, " ")}: ${val}`).join("\n"),
35629
+ onChange: (e) => {
35630
+ const lines = e.target.value.split("\n").filter(Boolean);
35631
+ const newObj = {};
35632
+ lines.forEach((line) => {
35633
+ const [k, ...rest] = line.split(":");
35634
+ if (k) {
35635
+ newObj[k.trim().replace(/\s+/g, "_").toLowerCase()] = rest.join(":").trim();
35636
+ }
35637
+ });
35638
+ onChange(newObj);
35639
+ },
35640
+ placeholder: "Enter key: value pairs (one per line)...",
35641
+ className: "min-h-[120px] bg-background border-gray-300 font-mono text-xs"
35642
+ }
35643
+ )
35512
35644
  };
35513
35645
  }
35514
35646
  const [generated] = generateFieldsFromData({ [key]: value });
@@ -36392,7 +36524,26 @@ var CampaignConceptCard = import_react64.default.memo(
36392
36524
  ] }, k)) });
36393
36525
  }
36394
36526
  return /* @__PURE__ */ (0, import_jsx_runtime121.jsx)("span", { className: "text-muted-foreground text-sm", children: String(val) });
36395
- }
36527
+ },
36528
+ renderEdit: (v, onChange) => /* @__PURE__ */ (0, import_jsx_runtime121.jsx)(
36529
+ Textarea,
36530
+ {
36531
+ value: typeof v === "object" ? Object.entries(v || {}).map(([k, val]) => `${k.replace(/_/g, " ")}: ${val}`).join("\n") : String(v || ""),
36532
+ onChange: (e) => {
36533
+ const lines = e.target.value.split("\n").filter(Boolean);
36534
+ const newObj = {};
36535
+ lines.forEach((line) => {
36536
+ if (line.includes(":")) {
36537
+ const [k, ...rest] = line.split(":");
36538
+ newObj[k.trim().replace(/\s+/g, "_").toLowerCase()] = rest.join(":").trim().replace("%", "");
36539
+ }
36540
+ });
36541
+ onChange(newObj);
36542
+ },
36543
+ placeholder: "Tier name: percentage (one per line)...",
36544
+ className: "min-h-[120px] bg-background border-gray-300 font-mono text-xs"
36545
+ }
36546
+ )
36396
36547
  };
36397
36548
  }
36398
36549
  if (field.key === "estimatedCreators" || field.key === "estimated_creators") {
@@ -36425,14 +36576,40 @@ var CampaignConceptCard = import_react64.default.memo(
36425
36576
  )) });
36426
36577
  }
36427
36578
  return /* @__PURE__ */ (0, import_jsx_runtime121.jsx)("span", { className: "text-txtColor font-medium", children: String(val) });
36428
- }
36579
+ },
36580
+ renderEdit: (v, onChange) => /* @__PURE__ */ (0, import_jsx_runtime121.jsx)(
36581
+ Input,
36582
+ {
36583
+ value: typeof v === "object" ? `${v.min ?? 0}-${v.max ?? 0}` : String(v || ""),
36584
+ onChange: (e) => {
36585
+ const val = e.target.value;
36586
+ if (val.includes("-")) {
36587
+ const [min2, max2] = val.split("-").map((s) => parseInt(s.trim()) || 0);
36588
+ onChange({ min: min2, max: max2 });
36589
+ } else {
36590
+ onChange(val);
36591
+ }
36592
+ },
36593
+ placeholder: "Min-Max (e.g. 10-30)...",
36594
+ className: "bg-background border-gray-300"
36595
+ }
36596
+ )
36429
36597
  };
36430
36598
  }
36431
36599
  if (field.key === "primary_kpi" || field.key === "primaryKpi") {
36432
36600
  return {
36433
36601
  ...field,
36434
36602
  label: field.label || "Primary KPI",
36435
- renderDisplay: (val) => /* @__PURE__ */ (0, import_jsx_runtime121.jsx)("span", { className: "text-foreground text-sm", children: val ? String(val) : "-" })
36603
+ renderDisplay: (val) => /* @__PURE__ */ (0, import_jsx_runtime121.jsx)("span", { className: "text-foreground text-sm", children: val ? String(val) : "-" }),
36604
+ renderEdit: (v, onChange) => /* @__PURE__ */ (0, import_jsx_runtime121.jsx)(
36605
+ Input,
36606
+ {
36607
+ value: String(v || ""),
36608
+ onChange: (e) => onChange(e.target.value),
36609
+ placeholder: "Enter primary KPI...",
36610
+ className: "bg-background border-gray-300"
36611
+ }
36612
+ )
36436
36613
  };
36437
36614
  }
36438
36615
  if (field.key === "secondary_kpis" || field.key === "secondaryKpis") {
@@ -36442,7 +36619,19 @@ var CampaignConceptCard = import_react64.default.memo(
36442
36619
  renderDisplay: (val) => {
36443
36620
  const display = Array.isArray(val) ? val.map(String).join(", ") : val ? String(val) : "-";
36444
36621
  return /* @__PURE__ */ (0, import_jsx_runtime121.jsx)("span", { className: "text-foreground text-sm", children: display });
36445
- }
36622
+ },
36623
+ renderEdit: (v, onChange) => /* @__PURE__ */ (0, import_jsx_runtime121.jsx)(
36624
+ Textarea,
36625
+ {
36626
+ value: Array.isArray(v) ? v.join(", ") : String(v || ""),
36627
+ onChange: (e) => {
36628
+ const items = e.target.value.split(",").map((s) => s.trim()).filter(Boolean);
36629
+ onChange(items);
36630
+ },
36631
+ placeholder: "Enter KPIs separated by commas...",
36632
+ className: "min-h-[80px] bg-background border-gray-300"
36633
+ }
36634
+ )
36446
36635
  };
36447
36636
  }
36448
36637
  if (field.key === "platforms" || field.key === "target_platforms" || field.key === "targetPlatforms") {
@@ -36459,7 +36648,19 @@ var CampaignConceptCard = import_react64.default.memo(
36459
36648
  },
36460
36649
  p
36461
36650
  )) });
36462
- }
36651
+ },
36652
+ renderEdit: (v, onChange) => /* @__PURE__ */ (0, import_jsx_runtime121.jsx)(
36653
+ Textarea,
36654
+ {
36655
+ value: Array.isArray(v) ? v.join(", ") : String(v || ""),
36656
+ onChange: (e) => {
36657
+ const items = e.target.value.split(",").map((s) => s.trim()).filter(Boolean);
36658
+ onChange(items);
36659
+ },
36660
+ placeholder: "Enter platforms separated by commas...",
36661
+ className: "min-h-[80px] bg-background border-gray-300"
36662
+ }
36663
+ )
36463
36664
  };
36464
36665
  }
36465
36666
  return {
@@ -36505,7 +36706,7 @@ var CampaignConceptCard = import_react64.default.memo(
36505
36706
  /* @__PURE__ */ (0, import_jsx_runtime121.jsxs)("div", { className: "flex-1", children: [
36506
36707
  /* @__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) }),
36507
36708
  /* @__PURE__ */ (0, import_jsx_runtime121.jsxs)("div", { className: "flex flex-wrap gap-2", children: [
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" }) }),
36709
+ isRecommended && /* @__PURE__ */ (0, import_jsx_runtime121.jsx)("div", { className: "inline-flex text-[10px] font-bold uppercase tracking-widest", children: /* @__PURE__ */ (0, import_jsx_runtime121.jsx)("span", { className: "bg-green-600 text-white px-2 py-0.5 rounded border border-green-700", children: "Recommended" }) }),
36509
36710
  !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" }) })
36510
36711
  ] })
36511
36712
  ] }),