pxengine 0.1.117 → 0.1.119
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/README.md +132 -132
- package/config/tailwind-preset.js +159 -159
- package/dist/index.cjs +322 -188
- package/dist/index.cjs.map +1 -1
- package/dist/index.mjs +322 -188
- package/dist/index.mjs.map +1 -1
- package/dist/registry.json +141 -141
- package/package.json +124 -124
package/dist/index.cjs
CHANGED
|
@@ -16129,6 +16129,10 @@ var RefreshIcon = () => /* @__PURE__ */ (0, import_jsx_runtime147.jsxs)("svg", {
|
|
|
16129
16129
|
/* @__PURE__ */ (0, import_jsx_runtime147.jsx)("polyline", { points: "23 4 23 10 17 10" }),
|
|
16130
16130
|
/* @__PURE__ */ (0, import_jsx_runtime147.jsx)("path", { d: "M20.49 15a9 9 0 1 1-2.12-9.36L23 10" })
|
|
16131
16131
|
] });
|
|
16132
|
+
var EditIcon = () => /* @__PURE__ */ (0, import_jsx_runtime147.jsxs)("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.2", strokeLinecap: "round", strokeLinejoin: "round", children: [
|
|
16133
|
+
/* @__PURE__ */ (0, import_jsx_runtime147.jsx)("path", { d: "M11 4H4a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7" }),
|
|
16134
|
+
/* @__PURE__ */ (0, import_jsx_runtime147.jsx)("path", { d: "M18.5 2.5a2.121 2.121 0 0 1 3 3L12 15l-4 1 1-4 9.5-9.5z" })
|
|
16135
|
+
] });
|
|
16132
16136
|
var SlideTypeIcon = () => /* @__PURE__ */ (0, import_jsx_runtime147.jsxs)("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
|
|
16133
16137
|
/* @__PURE__ */ (0, import_jsx_runtime147.jsx)("rect", { x: "3", y: "4", width: "18", height: "14", rx: "2" }),
|
|
16134
16138
|
/* @__PURE__ */ (0, import_jsx_runtime147.jsx)("line", { x1: "3", y1: "10", x2: "21", y2: "10" })
|
|
@@ -16139,6 +16143,7 @@ function formatTemplateLabel(templateId) {
|
|
|
16139
16143
|
if (!templateId) return null;
|
|
16140
16144
|
return templateId.split("-").map((w) => w.charAt(0).toUpperCase() + w.slice(1)).join(" ");
|
|
16141
16145
|
}
|
|
16146
|
+
var Chip = ({ children }) => /* @__PURE__ */ (0, import_jsx_runtime147.jsx)("span", { className: "inline-flex items-center px-2 h-[22px] rounded-md bg-zinc-800/70 border border-zinc-700/50 text-[11px] font-medium text-zinc-400 whitespace-nowrap", children });
|
|
16142
16147
|
function deriveJobStatusUrl(newJobId, pollUrl, regenerateUrl) {
|
|
16143
16148
|
const base = pollUrl?.replace(/\/api\/jobs\/[^/]+\/status.*$/, "") ?? regenerateUrl?.replace(/\/api\/presentations\/[^/]+\/regenerate.*$/, "") ?? "";
|
|
16144
16149
|
return `${base}/api/jobs/${newJobId}/status`;
|
|
@@ -16166,7 +16171,7 @@ var FORMATS = [
|
|
|
16166
16171
|
ext: ".html",
|
|
16167
16172
|
emoji: "\u{1F310}",
|
|
16168
16173
|
desc: "Interactive web presentation \u2014 download and open in browser",
|
|
16169
|
-
accent: { text: "text-
|
|
16174
|
+
accent: { text: "text-sky-400", bg: "bg-sky-500/10 border-sky-500/20" }
|
|
16170
16175
|
}
|
|
16171
16176
|
];
|
|
16172
16177
|
var ExportModal = ({ formats, title, onClose }) => {
|
|
@@ -16283,7 +16288,7 @@ var FullscreenModal = ({ url, title, slideCount, initialSlide = 1, onClose }) =>
|
|
|
16283
16288
|
return /* @__PURE__ */ (0, import_jsx_runtime147.jsxs)("div", { className: "fixed inset-0 z-50 bg-black flex flex-col", children: [
|
|
16284
16289
|
/* @__PURE__ */ (0, import_jsx_runtime147.jsxs)("div", { className: "flex items-center justify-between gap-4 px-4 h-11 bg-zinc-950/90 border-b border-zinc-800/60 flex-shrink-0", children: [
|
|
16285
16290
|
/* @__PURE__ */ (0, import_jsx_runtime147.jsxs)("div", { className: "flex items-center gap-3 min-w-0", children: [
|
|
16286
|
-
/* @__PURE__ */ (0, import_jsx_runtime147.jsx)("span", { className: "text-
|
|
16291
|
+
/* @__PURE__ */ (0, import_jsx_runtime147.jsx)("span", { className: "text-[#DCC99B] flex-shrink-0", children: /* @__PURE__ */ (0, import_jsx_runtime147.jsx)(SlidesIcon, {}) }),
|
|
16287
16292
|
/* @__PURE__ */ (0, import_jsx_runtime147.jsx)("span", { className: "text-sm font-medium text-zinc-300 truncate", children: title }),
|
|
16288
16293
|
slideCount > 0 && /* @__PURE__ */ (0, import_jsx_runtime147.jsxs)("span", { className: "text-xs text-zinc-600 flex-shrink-0", children: [
|
|
16289
16294
|
currentSlide,
|
|
@@ -16297,7 +16302,7 @@ var FullscreenModal = ({ url, title, slideCount, initialSlide = 1, onClose }) =>
|
|
|
16297
16302
|
{
|
|
16298
16303
|
onClick: () => sendSlideCommand("prevSlide"),
|
|
16299
16304
|
disabled: !iframeReady,
|
|
16300
|
-
className: "w-7 h-7 rounded-full border border-zinc-700 bg-zinc-800 hover:border-
|
|
16305
|
+
className: "w-7 h-7 rounded-full border border-zinc-700 bg-zinc-800 hover:border-[#C0AE82] hover:text-[#DCC99B] text-zinc-400 flex items-center justify-center transition-colors disabled:opacity-30 disabled:cursor-not-allowed",
|
|
16301
16306
|
"aria-label": "Previous slide",
|
|
16302
16307
|
children: /* @__PURE__ */ (0, import_jsx_runtime147.jsx)(ChevronLeft2, {})
|
|
16303
16308
|
}
|
|
@@ -16307,7 +16312,7 @@ var FullscreenModal = ({ url, title, slideCount, initialSlide = 1, onClose }) =>
|
|
|
16307
16312
|
{
|
|
16308
16313
|
onClick: () => sendSlideCommand("nextSlide"),
|
|
16309
16314
|
disabled: !iframeReady,
|
|
16310
|
-
className: "w-7 h-7 rounded-full border border-zinc-700 bg-zinc-800 hover:border-
|
|
16315
|
+
className: "w-7 h-7 rounded-full border border-zinc-700 bg-zinc-800 hover:border-[#C0AE82] hover:text-[#DCC99B] text-zinc-400 flex items-center justify-center transition-colors disabled:opacity-30 disabled:cursor-not-allowed",
|
|
16311
16316
|
"aria-label": "Next slide",
|
|
16312
16317
|
children: /* @__PURE__ */ (0, import_jsx_runtime147.jsx)(ChevronRight2, {})
|
|
16313
16318
|
}
|
|
@@ -16883,11 +16888,11 @@ var PresentationJobCard = ({
|
|
|
16883
16888
|
/* @__PURE__ */ (0, import_jsx_runtime147.jsx)(
|
|
16884
16889
|
"div",
|
|
16885
16890
|
{
|
|
16886
|
-
className: "h-[3px]
|
|
16891
|
+
className: "h-[3px]",
|
|
16887
16892
|
style: {
|
|
16893
|
+
backgroundImage: accentGradient || "linear-gradient(90deg, #8B7D5E, #C0AE82, #DCC99B, #C0AE82, #8B7D5E)",
|
|
16888
16894
|
backgroundSize: "200% 100%",
|
|
16889
|
-
animation: "gradient-shift 2s ease-in-out infinite"
|
|
16890
|
-
...accentGradient ? { backgroundImage: accentGradient } : {}
|
|
16895
|
+
animation: "gradient-shift 2s ease-in-out infinite"
|
|
16891
16896
|
}
|
|
16892
16897
|
}
|
|
16893
16898
|
),
|
|
@@ -16896,7 +16901,7 @@ var PresentationJobCard = ({
|
|
|
16896
16901
|
/* @__PURE__ */ (0, import_jsx_runtime147.jsx)(
|
|
16897
16902
|
"div",
|
|
16898
16903
|
{
|
|
16899
|
-
className: "w-10 h-10 rounded-xl bg-
|
|
16904
|
+
className: "w-10 h-10 rounded-xl bg-[#C0AE82]/10 border border-[#C0AE82]/25 flex items-center justify-center flex-shrink-0",
|
|
16900
16905
|
style: { ...t.accentSubtle(0.1), ...t.accentBorder },
|
|
16901
16906
|
children: /* @__PURE__ */ (0, import_jsx_runtime147.jsx)("span", { className: "text-lg", children: getPhaseIcon() })
|
|
16902
16907
|
}
|
|
@@ -16914,10 +16919,11 @@ var PresentationJobCard = ({
|
|
|
16914
16919
|
/* @__PURE__ */ (0, import_jsx_runtime147.jsx)("div", { className: "h-2 bg-zinc-800 rounded-full overflow-hidden", children: /* @__PURE__ */ (0, import_jsx_runtime147.jsx)(
|
|
16915
16920
|
"div",
|
|
16916
16921
|
{
|
|
16917
|
-
className: "h-full
|
|
16922
|
+
className: "h-full rounded-full transition-all duration-500 ease-out",
|
|
16918
16923
|
style: {
|
|
16919
16924
|
width: `${Math.max(pct, 2)}%`,
|
|
16920
|
-
|
|
16925
|
+
backgroundImage: accentGradient || "linear-gradient(90deg, #8B7D5E, #C0AE82, #DCC99B)",
|
|
16926
|
+
...!accentGradient ? t.accentBg : {}
|
|
16921
16927
|
}
|
|
16922
16928
|
}
|
|
16923
16929
|
) }),
|
|
@@ -16927,7 +16933,7 @@ var PresentationJobCard = ({
|
|
|
16927
16933
|
] })
|
|
16928
16934
|
] }),
|
|
16929
16935
|
/* @__PURE__ */ (0, import_jsx_runtime147.jsxs)("div", { className: "flex items-center gap-2", children: [
|
|
16930
|
-
/* @__PURE__ */ (0, import_jsx_runtime147.jsx)("div", { className: "w-2 h-2 rounded-full bg-
|
|
16936
|
+
/* @__PURE__ */ (0, import_jsx_runtime147.jsx)("div", { className: "w-2 h-2 rounded-full bg-[#C0AE82] animate-pulse", style: t.accentBg }),
|
|
16931
16937
|
/* @__PURE__ */ (0, import_jsx_runtime147.jsx)("span", { className: "text-xs text-zinc-400", children: step })
|
|
16932
16938
|
] }),
|
|
16933
16939
|
phase === "ai_generation" && slidesTotal > 0 && /* @__PURE__ */ (0, import_jsx_runtime147.jsxs)("div", { className: "flex items-center gap-2 pt-1", children: [
|
|
@@ -16936,7 +16942,7 @@ var PresentationJobCard = ({
|
|
|
16936
16942
|
{
|
|
16937
16943
|
className: cn(
|
|
16938
16944
|
"w-6 h-1.5 rounded-full transition-all duration-300",
|
|
16939
|
-
i < slidesCompleted ? "bg-
|
|
16945
|
+
i < slidesCompleted ? "bg-[#C0AE82]" : i === slidesCompleted ? "bg-[#C0AE82]/50 animate-pulse" : "bg-zinc-700"
|
|
16940
16946
|
)
|
|
16941
16947
|
},
|
|
16942
16948
|
i
|
|
@@ -16984,7 +16990,7 @@ var PresentationJobCard = ({
|
|
|
16984
16990
|
/* @__PURE__ */ (0, import_jsx_runtime147.jsx)(
|
|
16985
16991
|
"div",
|
|
16986
16992
|
{
|
|
16987
|
-
className: "w-10 h-10 rounded-xl bg-
|
|
16993
|
+
className: "w-10 h-10 rounded-xl bg-[#C0AE82]/10 border border-[#C0AE82]/25 flex items-center justify-center flex-shrink-0 text-[#DCC99B]",
|
|
16988
16994
|
style: { ...t.accentSubtle(0.1), ...t.accentBorder, ...t.accent },
|
|
16989
16995
|
children: /* @__PURE__ */ (0, import_jsx_runtime147.jsx)(SlidesIcon, {})
|
|
16990
16996
|
}
|
|
@@ -17021,7 +17027,7 @@ var PresentationJobCard = ({
|
|
|
17021
17027
|
onChange: (e) => setSlideTemplate(i, e.target.value),
|
|
17022
17028
|
disabled: rowBusy,
|
|
17023
17029
|
title: "Design template for this slide only (default: deck's template)",
|
|
17024
|
-
className: "w-24 flex-shrink-0 bg-zinc-800/60 border border-zinc-700 rounded-lg px-1.5 h-8 text-[10px] text-zinc-300 focus:border-
|
|
17030
|
+
className: "w-24 flex-shrink-0 bg-zinc-800/60 border border-zinc-700 rounded-lg px-1.5 h-8 text-[10px] text-zinc-300 focus:border-[#C0AE82] outline-none disabled:opacity-60",
|
|
17025
17031
|
children: [
|
|
17026
17032
|
/* @__PURE__ */ (0, import_jsx_runtime147.jsx)("option", { value: "", children: "Deck default" }),
|
|
17027
17033
|
slideTemplateOptions.map((opt) => /* @__PURE__ */ (0, import_jsx_runtime147.jsx)("option", { value: opt.id, children: opt.name }, opt.id))
|
|
@@ -17034,7 +17040,7 @@ var PresentationJobCard = ({
|
|
|
17034
17040
|
value: messageEdits[i] ?? s.message ?? "",
|
|
17035
17041
|
onChange: (e) => setMessageEdits((prev) => ({ ...prev, [i]: e.target.value })),
|
|
17036
17042
|
disabled: building,
|
|
17037
|
-
className: "flex-1 min-w-0 bg-zinc-800/60 border border-zinc-700 rounded-lg px-3 h-8 text-xs text-zinc-200 focus:border-
|
|
17043
|
+
className: "flex-1 min-w-0 bg-zinc-800/60 border border-zinc-700 rounded-lg px-3 h-8 text-xs text-zinc-200 focus:border-[#C0AE82] outline-none disabled:opacity-60"
|
|
17038
17044
|
}
|
|
17039
17045
|
),
|
|
17040
17046
|
/* @__PURE__ */ (0, import_jsx_runtime147.jsx)(
|
|
@@ -17109,34 +17115,88 @@ var PresentationJobCard = ({
|
|
|
17109
17115
|
/* @__PURE__ */ (0, import_jsx_runtime147.jsx)(
|
|
17110
17116
|
"div",
|
|
17111
17117
|
{
|
|
17112
|
-
className: "w-10 h-10 rounded-xl bg-
|
|
17118
|
+
className: "w-10 h-10 rounded-xl bg-[#C0AE82]/10 border border-[#C0AE82]/25 flex items-center justify-center flex-shrink-0 text-[#DCC99B]",
|
|
17113
17119
|
style: { ...t.accentSubtle(0.1), ...t.accentBorder, ...t.accent },
|
|
17114
17120
|
children: /* @__PURE__ */ (0, import_jsx_runtime147.jsx)(SlidesIcon, {})
|
|
17115
17121
|
}
|
|
17116
17122
|
),
|
|
17117
17123
|
/* @__PURE__ */ (0, import_jsx_runtime147.jsxs)("div", { className: "flex-1 min-w-0", children: [
|
|
17118
17124
|
/* @__PURE__ */ (0, import_jsx_runtime147.jsx)("h3", { className: "text-sm font-semibold text-zinc-100 truncate leading-tight", style: t.text, children: title }),
|
|
17119
|
-
/* @__PURE__ */ (0, import_jsx_runtime147.jsxs)("
|
|
17120
|
-
slideCount ? `${slideCount} slides` : "Presentation",
|
|
17121
|
-
|
|
17122
|
-
templateLabel && ` \xB7 ${templateLabel}`
|
|
17125
|
+
/* @__PURE__ */ (0, import_jsx_runtime147.jsxs)("div", { className: "flex flex-wrap items-center gap-1.5 mt-1.5", children: [
|
|
17126
|
+
/* @__PURE__ */ (0, import_jsx_runtime147.jsx)(Chip, { children: slideCount ? `${slideCount} slides` : "Presentation" }),
|
|
17127
|
+
templateLabel && /* @__PURE__ */ (0, import_jsx_runtime147.jsx)(Chip, { children: templateLabel })
|
|
17123
17128
|
] }),
|
|
17124
|
-
generationMode === "template" &&
|
|
17129
|
+
generationMode === "template" && (isApproved || reviewStatus === "pending_review") && /* @__PURE__ */ (0, import_jsx_runtime147.jsxs)("p", { className: "flex items-center gap-1.5 text-xs mt-2", children: [
|
|
17130
|
+
/* @__PURE__ */ (0, import_jsx_runtime147.jsx)(
|
|
17131
|
+
"span",
|
|
17132
|
+
{
|
|
17133
|
+
className: cn(
|
|
17134
|
+
"w-1.5 h-1.5 rounded-full flex-shrink-0",
|
|
17135
|
+
isApproved ? "bg-emerald-400" : "bg-amber-400"
|
|
17136
|
+
)
|
|
17137
|
+
}
|
|
17138
|
+
),
|
|
17139
|
+
isApproved ? /* @__PURE__ */ (0, import_jsx_runtime147.jsx)("span", { className: "text-emerald-400/90", children: "Approved \u2014 future decks use this format" }) : /* @__PURE__ */ (0, import_jsx_runtime147.jsx)("span", { className: "text-amber-400/90", children: "Review this deck, then approve to lock the format" })
|
|
17140
|
+
] })
|
|
17125
17141
|
] }),
|
|
17126
17142
|
/* @__PURE__ */ (0, import_jsx_runtime147.jsxs)("div", { className: "flex items-center gap-1.5 flex-shrink-0 flex-wrap justify-end", children: [
|
|
17127
|
-
|
|
17128
|
-
|
|
17129
|
-
|
|
17130
|
-
|
|
17131
|
-
|
|
17132
|
-
|
|
17133
|
-
|
|
17134
|
-
|
|
17135
|
-
|
|
17136
|
-
|
|
17137
|
-
|
|
17138
|
-
|
|
17139
|
-
|
|
17143
|
+
/* @__PURE__ */ (0, import_jsx_runtime147.jsxs)("div", { className: "flex items-center rounded-lg border border-zinc-700 bg-zinc-800 overflow-hidden divide-x divide-zinc-700", children: [
|
|
17144
|
+
/* @__PURE__ */ (0, import_jsx_runtime147.jsxs)(
|
|
17145
|
+
"a",
|
|
17146
|
+
{
|
|
17147
|
+
href: hasHtml ? `/presentations/${_job_id}/edit` : void 0,
|
|
17148
|
+
"aria-disabled": !hasHtml,
|
|
17149
|
+
title: "Edit presentation content",
|
|
17150
|
+
className: cn(
|
|
17151
|
+
"flex items-center gap-1.5 px-2.5 h-7 text-xs font-medium text-zinc-300 hover:text-zinc-100 hover:bg-zinc-700/60 transition-colors",
|
|
17152
|
+
!hasHtml && "pointer-events-none opacity-40"
|
|
17153
|
+
),
|
|
17154
|
+
children: [
|
|
17155
|
+
/* @__PURE__ */ (0, import_jsx_runtime147.jsx)(EditIcon, {}),
|
|
17156
|
+
/* @__PURE__ */ (0, import_jsx_runtime147.jsx)("span", { children: "Edit" })
|
|
17157
|
+
]
|
|
17158
|
+
}
|
|
17159
|
+
),
|
|
17160
|
+
/* @__PURE__ */ (0, import_jsx_runtime147.jsxs)(
|
|
17161
|
+
"button",
|
|
17162
|
+
{
|
|
17163
|
+
onClick: () => setShowFullscreen(true),
|
|
17164
|
+
disabled: !hasHtml,
|
|
17165
|
+
title: "Open fullscreen preview",
|
|
17166
|
+
className: "flex items-center gap-1.5 px-2.5 h-7 text-xs font-medium text-zinc-300 hover:text-zinc-100 hover:bg-zinc-700/60 transition-colors disabled:opacity-40 disabled:cursor-not-allowed",
|
|
17167
|
+
children: [
|
|
17168
|
+
/* @__PURE__ */ (0, import_jsx_runtime147.jsx)(ExpandIcon, {}),
|
|
17169
|
+
/* @__PURE__ */ (0, import_jsx_runtime147.jsx)("span", { children: "Preview" })
|
|
17170
|
+
]
|
|
17171
|
+
}
|
|
17172
|
+
),
|
|
17173
|
+
canRegenerate && /* @__PURE__ */ (0, import_jsx_runtime147.jsxs)(
|
|
17174
|
+
"button",
|
|
17175
|
+
{
|
|
17176
|
+
onClick: handleRegenerate,
|
|
17177
|
+
disabled: regenerating || approving,
|
|
17178
|
+
title: "Try another design template with the same content",
|
|
17179
|
+
className: "flex items-center gap-1.5 px-2.5 h-7 text-xs font-medium text-zinc-300 hover:text-zinc-100 hover:bg-zinc-700/60 transition-colors disabled:opacity-40",
|
|
17180
|
+
children: [
|
|
17181
|
+
/* @__PURE__ */ (0, import_jsx_runtime147.jsx)(RefreshIcon, {}),
|
|
17182
|
+
/* @__PURE__ */ (0, import_jsx_runtime147.jsx)("span", { children: regenerating ? "Switching\u2026" : "Regenerate" })
|
|
17183
|
+
]
|
|
17184
|
+
}
|
|
17185
|
+
),
|
|
17186
|
+
/* @__PURE__ */ (0, import_jsx_runtime147.jsx)(
|
|
17187
|
+
"button",
|
|
17188
|
+
{
|
|
17189
|
+
onClick: handleShare,
|
|
17190
|
+
disabled: !hasHtml,
|
|
17191
|
+
title: copied ? "Copied!" : "Copy shareable link",
|
|
17192
|
+
className: cn(
|
|
17193
|
+
"flex items-center justify-center w-7 h-7 transition-colors disabled:opacity-30 disabled:cursor-not-allowed",
|
|
17194
|
+
copied ? "text-green-400" : "text-zinc-300 hover:text-zinc-100 hover:bg-zinc-700/60"
|
|
17195
|
+
),
|
|
17196
|
+
children: copied ? /* @__PURE__ */ (0, import_jsx_runtime147.jsx)(CheckIcon, {}) : /* @__PURE__ */ (0, import_jsx_runtime147.jsx)(ShareIcon, {})
|
|
17197
|
+
}
|
|
17198
|
+
)
|
|
17199
|
+
] }),
|
|
17140
17200
|
canApprove && /* @__PURE__ */ (0, import_jsx_runtime147.jsxs)(
|
|
17141
17201
|
"button",
|
|
17142
17202
|
{
|
|
@@ -17151,39 +17211,16 @@ var PresentationJobCard = ({
|
|
|
17151
17211
|
}
|
|
17152
17212
|
),
|
|
17153
17213
|
isApproved && /* @__PURE__ */ (0, import_jsx_runtime147.jsx)("span", { className: "flex items-center justify-center w-7 h-7 rounded-lg border border-emerald-500/40 bg-emerald-500/10 text-emerald-400", title: "Format saved", children: /* @__PURE__ */ (0, import_jsx_runtime147.jsx)(CheckIcon, {}) }),
|
|
17154
|
-
/* @__PURE__ */ (0, import_jsx_runtime147.jsx)(
|
|
17155
|
-
"button",
|
|
17156
|
-
{
|
|
17157
|
-
onClick: handleShare,
|
|
17158
|
-
disabled: !hasHtml,
|
|
17159
|
-
title: copied ? "Copied!" : "Copy shareable link",
|
|
17160
|
-
className: cn(
|
|
17161
|
-
"w-7 h-7 rounded-lg border flex items-center justify-center transition-all",
|
|
17162
|
-
copied ? "border-green-500/40 bg-green-500/10 text-green-400" : "border-zinc-700 bg-zinc-800 text-zinc-400 hover:border-zinc-500 hover:text-zinc-200",
|
|
17163
|
-
"disabled:opacity-30 disabled:cursor-not-allowed"
|
|
17164
|
-
),
|
|
17165
|
-
children: copied ? /* @__PURE__ */ (0, import_jsx_runtime147.jsx)(CheckIcon, {}) : /* @__PURE__ */ (0, import_jsx_runtime147.jsx)(ShareIcon, {})
|
|
17166
|
-
}
|
|
17167
|
-
),
|
|
17168
|
-
/* @__PURE__ */ (0, import_jsx_runtime147.jsxs)(
|
|
17169
|
-
"button",
|
|
17170
|
-
{
|
|
17171
|
-
onClick: () => setShowFullscreen(true),
|
|
17172
|
-
disabled: !hasHtml,
|
|
17173
|
-
title: "Open fullscreen preview",
|
|
17174
|
-
className: "flex items-center gap-1.5 px-2.5 h-7 rounded-lg border border-zinc-700 bg-zinc-800 hover:border-zinc-500 text-zinc-400 hover:text-zinc-200 text-xs font-medium transition-colors disabled:opacity-30 disabled:cursor-not-allowed",
|
|
17175
|
-
children: [
|
|
17176
|
-
/* @__PURE__ */ (0, import_jsx_runtime147.jsx)(ExpandIcon, {}),
|
|
17177
|
-
/* @__PURE__ */ (0, import_jsx_runtime147.jsx)("span", { children: "Preview" })
|
|
17178
|
-
]
|
|
17179
|
-
}
|
|
17180
|
-
),
|
|
17181
17214
|
/* @__PURE__ */ (0, import_jsx_runtime147.jsxs)(
|
|
17182
17215
|
"button",
|
|
17183
17216
|
{
|
|
17184
17217
|
onClick: () => setShowExport(true),
|
|
17185
|
-
className: "flex items-center gap-1.5 px-
|
|
17186
|
-
style: {
|
|
17218
|
+
className: "flex items-center gap-1.5 px-3 h-7 text-xs font-semibold rounded-lg transition-colors",
|
|
17219
|
+
style: {
|
|
17220
|
+
backgroundImage: accentGradient || "linear-gradient(90deg, #8B7D5E, #C0AE82, #DCC99B)",
|
|
17221
|
+
color: "#0A0A0A",
|
|
17222
|
+
...accentGradient ? t.accentText : {}
|
|
17223
|
+
},
|
|
17187
17224
|
children: [
|
|
17188
17225
|
/* @__PURE__ */ (0, import_jsx_runtime147.jsx)(DownloadIcon, {}),
|
|
17189
17226
|
/* @__PURE__ */ (0, import_jsx_runtime147.jsx)("span", { children: "Export" })
|
|
@@ -17238,7 +17275,7 @@ var PresentationJobCard = ({
|
|
|
17238
17275
|
sendSlideCommand("prevSlide");
|
|
17239
17276
|
},
|
|
17240
17277
|
disabled: !hasHtml || !iframeReady,
|
|
17241
|
-
className: "w-7 h-7 rounded-full border border-zinc-700 bg-zinc-800 hover:border-
|
|
17278
|
+
className: "w-7 h-7 rounded-full border border-zinc-700 bg-zinc-800 hover:border-[#C0AE82] hover:text-[#DCC99B] text-zinc-400 flex items-center justify-center transition-colors disabled:opacity-30 disabled:cursor-not-allowed",
|
|
17242
17279
|
"aria-label": "Previous slide",
|
|
17243
17280
|
children: /* @__PURE__ */ (0, import_jsx_runtime147.jsx)(ChevronLeft2, {})
|
|
17244
17281
|
}
|
|
@@ -17256,7 +17293,7 @@ var PresentationJobCard = ({
|
|
|
17256
17293
|
sendSlideCommand("nextSlide");
|
|
17257
17294
|
},
|
|
17258
17295
|
disabled: !hasHtml || !iframeReady,
|
|
17259
|
-
className: "w-7 h-7 rounded-full border border-zinc-700 bg-zinc-800 hover:border-
|
|
17296
|
+
className: "w-7 h-7 rounded-full border border-zinc-700 bg-zinc-800 hover:border-[#C0AE82] hover:text-[#DCC99B] text-zinc-400 flex items-center justify-center transition-colors disabled:opacity-30 disabled:cursor-not-allowed",
|
|
17260
17297
|
"aria-label": "Next slide",
|
|
17261
17298
|
children: /* @__PURE__ */ (0, import_jsx_runtime147.jsx)(ChevronRight2, {})
|
|
17262
17299
|
}
|
|
@@ -17283,10 +17320,11 @@ var PresentationJobCard = ({
|
|
|
17283
17320
|
var import_react79 = require("react");
|
|
17284
17321
|
var import_jsx_runtime148 = require("react/jsx-runtime");
|
|
17285
17322
|
var DEFAULT_THEME = {
|
|
17286
|
-
primary: "#
|
|
17287
|
-
secondary: "#
|
|
17288
|
-
accent: "#
|
|
17323
|
+
primary: "#C0AE82",
|
|
17324
|
+
secondary: "#C4AD7C",
|
|
17325
|
+
accent: "#DCC99B"
|
|
17289
17326
|
};
|
|
17327
|
+
var GOLD_GRADIENT = "linear-gradient(90deg, #8B7D5E, #C0AE82, #DCC99B)";
|
|
17290
17328
|
function readableOn(bg) {
|
|
17291
17329
|
if (!bg || typeof bg !== "string") return "#ffffff";
|
|
17292
17330
|
const hex = bg.replace("#", "");
|
|
@@ -17333,6 +17371,10 @@ var RefreshIcon2 = () => /* @__PURE__ */ (0, import_jsx_runtime148.jsxs)("svg",
|
|
|
17333
17371
|
/* @__PURE__ */ (0, import_jsx_runtime148.jsx)("polyline", { points: "23 4 23 10 17 10" }),
|
|
17334
17372
|
/* @__PURE__ */ (0, import_jsx_runtime148.jsx)("path", { d: "M20.49 15a9 9 0 1 1-2.12-9.36L23 10" })
|
|
17335
17373
|
] });
|
|
17374
|
+
var EditIcon2 = () => /* @__PURE__ */ (0, import_jsx_runtime148.jsxs)("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.2", strokeLinecap: "round", strokeLinejoin: "round", children: [
|
|
17375
|
+
/* @__PURE__ */ (0, import_jsx_runtime148.jsx)("path", { d: "M11 4H4a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7" }),
|
|
17376
|
+
/* @__PURE__ */ (0, import_jsx_runtime148.jsx)("path", { d: "M18.5 2.5a2.121 2.121 0 0 1 3 3L12 15l-4 1 1-4 9.5-9.5z" })
|
|
17377
|
+
] });
|
|
17336
17378
|
function formatTemplateLabel2(templateId) {
|
|
17337
17379
|
if (!templateId) return null;
|
|
17338
17380
|
return templateId.split("-").map((w) => w.charAt(0).toUpperCase() + w.slice(1)).join(" ");
|
|
@@ -17354,7 +17396,7 @@ var FullscreenPreviewModal = ({ url, title, onClose }) => {
|
|
|
17354
17396
|
return /* @__PURE__ */ (0, import_jsx_runtime148.jsxs)("div", { className: "fixed inset-0 z-50 bg-black flex flex-col", children: [
|
|
17355
17397
|
/* @__PURE__ */ (0, import_jsx_runtime148.jsxs)("div", { className: "flex items-center justify-between gap-4 px-4 h-11 bg-zinc-950/90 border-b border-zinc-800/60 flex-shrink-0", children: [
|
|
17356
17398
|
/* @__PURE__ */ (0, import_jsx_runtime148.jsxs)("div", { className: "flex items-center gap-3 min-w-0", children: [
|
|
17357
|
-
/* @__PURE__ */ (0, import_jsx_runtime148.jsx)("span", { className: "text-
|
|
17399
|
+
/* @__PURE__ */ (0, import_jsx_runtime148.jsx)("span", { className: "text-[#DCC99B] flex-shrink-0", children: /* @__PURE__ */ (0, import_jsx_runtime148.jsx)(DocumentIcon, {}) }),
|
|
17358
17400
|
/* @__PURE__ */ (0, import_jsx_runtime148.jsx)("span", { className: "text-sm font-medium text-zinc-300 truncate", children: title })
|
|
17359
17401
|
] }),
|
|
17360
17402
|
/* @__PURE__ */ (0, import_jsx_runtime148.jsxs)(
|
|
@@ -17380,6 +17422,102 @@ var FullscreenPreviewModal = ({ url, title, onClose }) => {
|
|
|
17380
17422
|
) })
|
|
17381
17423
|
] });
|
|
17382
17424
|
};
|
|
17425
|
+
var Chip2 = ({ children }) => /* @__PURE__ */ (0, import_jsx_runtime148.jsx)("span", { className: "inline-flex items-center px-2 h-[22px] rounded-md bg-zinc-800/70 border border-zinc-700/50 text-[11px] font-medium text-zinc-400 whitespace-nowrap capitalize", children });
|
|
17426
|
+
var REPORT_FORMATS = [
|
|
17427
|
+
{
|
|
17428
|
+
key: "pdf",
|
|
17429
|
+
label: "PDF",
|
|
17430
|
+
ext: ".pdf",
|
|
17431
|
+
emoji: "\u{1F4C4}",
|
|
17432
|
+
desc: "Print-ready, fixed layout \u2014 open in any PDF viewer",
|
|
17433
|
+
accent: { text: "text-red-400", bg: "bg-red-500/10 border-red-500/20" }
|
|
17434
|
+
},
|
|
17435
|
+
{
|
|
17436
|
+
key: "html",
|
|
17437
|
+
label: "HTML",
|
|
17438
|
+
ext: ".html",
|
|
17439
|
+
emoji: "\u{1F310}",
|
|
17440
|
+
desc: "Interactive web page \u2014 download and open in a browser",
|
|
17441
|
+
accent: { text: "text-sky-400", bg: "bg-sky-500/10 border-sky-500/20" }
|
|
17442
|
+
}
|
|
17443
|
+
];
|
|
17444
|
+
var ReportExportModal = ({ htmlUrl, pdfUrl, title, onClose }) => {
|
|
17445
|
+
const urls = { pdf: pdfUrl, html: htmlUrl };
|
|
17446
|
+
const available = REPORT_FORMATS.filter((f) => urls[f.key]);
|
|
17447
|
+
const filename = (title ?? "").replace(/[^a-z0-9]/gi, "-").toLowerCase();
|
|
17448
|
+
const [downloadingKey, setDownloadingKey] = (0, import_react79.useState)(null);
|
|
17449
|
+
(0, import_react79.useEffect)(() => {
|
|
17450
|
+
const onKey = (e) => {
|
|
17451
|
+
if (e.key === "Escape") onClose();
|
|
17452
|
+
};
|
|
17453
|
+
document.addEventListener("keydown", onKey);
|
|
17454
|
+
return () => document.removeEventListener("keydown", onKey);
|
|
17455
|
+
}, [onClose]);
|
|
17456
|
+
const handleDownload = async (key, url, ext) => {
|
|
17457
|
+
if (downloadingKey) return;
|
|
17458
|
+
const downloadName = `${filename}${ext}`;
|
|
17459
|
+
const href = `/api/download?url=${encodeURIComponent(url)}&filename=${encodeURIComponent(downloadName)}`;
|
|
17460
|
+
try {
|
|
17461
|
+
setDownloadingKey(key);
|
|
17462
|
+
const response = await fetch(href);
|
|
17463
|
+
if (!response.ok) throw new Error(`status ${response.status}`);
|
|
17464
|
+
const blob = await response.blob();
|
|
17465
|
+
const objectUrl = window.URL.createObjectURL(blob);
|
|
17466
|
+
const anchor = document.createElement("a");
|
|
17467
|
+
anchor.href = objectUrl;
|
|
17468
|
+
anchor.download = downloadName;
|
|
17469
|
+
document.body.appendChild(anchor);
|
|
17470
|
+
anchor.click();
|
|
17471
|
+
anchor.remove();
|
|
17472
|
+
window.URL.revokeObjectURL(objectUrl);
|
|
17473
|
+
} catch {
|
|
17474
|
+
window.open(url, "_blank", "noopener,noreferrer");
|
|
17475
|
+
} finally {
|
|
17476
|
+
setDownloadingKey(null);
|
|
17477
|
+
}
|
|
17478
|
+
};
|
|
17479
|
+
return /* @__PURE__ */ (0, import_jsx_runtime148.jsxs)("div", { className: "fixed inset-0 z-50 flex items-center justify-center p-4", children: [
|
|
17480
|
+
/* @__PURE__ */ (0, import_jsx_runtime148.jsx)("div", { className: "absolute inset-0 bg-black/70 backdrop-blur-sm", onClick: onClose }),
|
|
17481
|
+
/* @__PURE__ */ (0, import_jsx_runtime148.jsxs)("div", { className: "relative z-10 bg-zinc-900 border border-zinc-800 rounded-2xl w-full max-w-sm p-6 shadow-2xl", children: [
|
|
17482
|
+
/* @__PURE__ */ (0, import_jsx_runtime148.jsxs)("div", { className: "flex items-start justify-between mb-5", children: [
|
|
17483
|
+
/* @__PURE__ */ (0, import_jsx_runtime148.jsxs)("div", { className: "min-w-0 pr-3", children: [
|
|
17484
|
+
/* @__PURE__ */ (0, import_jsx_runtime148.jsx)("h3", { className: "text-sm font-semibold text-zinc-100", children: "Download report" }),
|
|
17485
|
+
/* @__PURE__ */ (0, import_jsx_runtime148.jsx)("p", { className: "text-xs text-zinc-500 mt-0.5 truncate", children: title })
|
|
17486
|
+
] }),
|
|
17487
|
+
/* @__PURE__ */ (0, import_jsx_runtime148.jsx)("button", { onClick: onClose, className: "text-zinc-500 hover:text-zinc-200 transition-colors flex-shrink-0 mt-0.5", children: /* @__PURE__ */ (0, import_jsx_runtime148.jsx)(CloseIcon2, {}) })
|
|
17488
|
+
] }),
|
|
17489
|
+
/* @__PURE__ */ (0, import_jsx_runtime148.jsxs)("div", { className: "space-y-2.5", children: [
|
|
17490
|
+
available.length === 0 && /* @__PURE__ */ (0, import_jsx_runtime148.jsx)("p", { className: "text-sm text-zinc-500 text-center py-6", children: "No formats available yet" }),
|
|
17491
|
+
available.map((fmt) => {
|
|
17492
|
+
const url = urls[fmt.key];
|
|
17493
|
+
const isDownloading = downloadingKey === fmt.key;
|
|
17494
|
+
return /* @__PURE__ */ (0, import_jsx_runtime148.jsxs)(
|
|
17495
|
+
"button",
|
|
17496
|
+
{
|
|
17497
|
+
type: "button",
|
|
17498
|
+
disabled: Boolean(downloadingKey),
|
|
17499
|
+
onClick: () => handleDownload(fmt.key, url, fmt.ext),
|
|
17500
|
+
className: cn(
|
|
17501
|
+
"flex w-full items-center gap-3.5 p-3.5 rounded-xl border transition-all text-left",
|
|
17502
|
+
"hover:brightness-110 disabled:opacity-60 disabled:cursor-not-allowed",
|
|
17503
|
+
fmt.accent.bg
|
|
17504
|
+
),
|
|
17505
|
+
children: [
|
|
17506
|
+
/* @__PURE__ */ (0, import_jsx_runtime148.jsx)("span", { className: "text-xl flex-shrink-0", children: fmt.emoji }),
|
|
17507
|
+
/* @__PURE__ */ (0, import_jsx_runtime148.jsxs)("div", { className: "flex-1 min-w-0", children: [
|
|
17508
|
+
/* @__PURE__ */ (0, import_jsx_runtime148.jsx)("p", { className: cn("text-sm font-semibold", fmt.accent.text), children: isDownloading ? `Downloading ${fmt.label}...` : fmt.label }),
|
|
17509
|
+
/* @__PURE__ */ (0, import_jsx_runtime148.jsx)("p", { className: "text-xs text-zinc-500 mt-0.5 leading-relaxed", children: isDownloading ? "Please wait while the file is being prepared." : fmt.desc })
|
|
17510
|
+
] }),
|
|
17511
|
+
/* @__PURE__ */ (0, import_jsx_runtime148.jsx)("span", { className: cn("flex-shrink-0", fmt.accent.text), children: /* @__PURE__ */ (0, import_jsx_runtime148.jsx)(DownloadIcon2, {}) })
|
|
17512
|
+
]
|
|
17513
|
+
},
|
|
17514
|
+
fmt.key
|
|
17515
|
+
);
|
|
17516
|
+
})
|
|
17517
|
+
] })
|
|
17518
|
+
] })
|
|
17519
|
+
] });
|
|
17520
|
+
};
|
|
17383
17521
|
function deriveJobStatusUrl2(newJobId, pollUrl, regenerateUrl) {
|
|
17384
17522
|
const base = pollUrl?.replace(/\/api\/jobs\/[^/]+\/status.*$/, "") ?? regenerateUrl?.replace(/\/api\/reports\/[^/]+\/regenerate.*$/, "") ?? "";
|
|
17385
17523
|
return `${base}/api/jobs/${newJobId}/status`;
|
|
@@ -17443,6 +17581,7 @@ var ResearchReportJobCard = (props) => {
|
|
|
17443
17581
|
const [error, setError] = (0, import_react79.useState)(initialError);
|
|
17444
17582
|
const [progress, setProgress] = (0, import_react79.useState)(initialProgress);
|
|
17445
17583
|
const [showPreview, setShowPreview] = (0, import_react79.useState)(false);
|
|
17584
|
+
const [showExport, setShowExport] = (0, import_react79.useState)(false);
|
|
17446
17585
|
const [previewScale, setPreviewScale] = (0, import_react79.useState)(1);
|
|
17447
17586
|
const [copied, setCopied] = (0, import_react79.useState)(false);
|
|
17448
17587
|
const [approving, setApproving] = (0, import_react79.useState)(false);
|
|
@@ -17835,8 +17974,9 @@ var ResearchReportJobCard = (props) => {
|
|
|
17835
17974
|
/* @__PURE__ */ (0, import_jsx_runtime148.jsx)(
|
|
17836
17975
|
"div",
|
|
17837
17976
|
{
|
|
17838
|
-
className: "h-[3px]
|
|
17977
|
+
className: "h-[3px]",
|
|
17839
17978
|
style: {
|
|
17979
|
+
backgroundImage: "linear-gradient(90deg, #8B7D5E, #C0AE82, #DCC99B, #C0AE82, #8B7D5E)",
|
|
17840
17980
|
backgroundSize: "200% 100%",
|
|
17841
17981
|
animation: "gradient-shift 2s ease-in-out infinite"
|
|
17842
17982
|
}
|
|
@@ -17844,7 +17984,7 @@ var ResearchReportJobCard = (props) => {
|
|
|
17844
17984
|
),
|
|
17845
17985
|
/* @__PURE__ */ (0, import_jsx_runtime148.jsxs)("div", { className: "p-5", children: [
|
|
17846
17986
|
/* @__PURE__ */ (0, import_jsx_runtime148.jsxs)("div", { className: "flex items-start gap-3", children: [
|
|
17847
|
-
/* @__PURE__ */ (0, import_jsx_runtime148.jsx)("div", { className: "w-10 h-10 rounded-xl bg-
|
|
17987
|
+
/* @__PURE__ */ (0, import_jsx_runtime148.jsx)("div", { className: "w-10 h-10 rounded-xl bg-[#C0AE82]/10 border border-[#C0AE82]/25 flex items-center justify-center flex-shrink-0", children: /* @__PURE__ */ (0, import_jsx_runtime148.jsx)("span", { className: "text-lg", children: getPhaseIcon() }) }),
|
|
17848
17988
|
/* @__PURE__ */ (0, import_jsx_runtime148.jsxs)("div", { className: "flex-1 min-w-0", children: [
|
|
17849
17989
|
/* @__PURE__ */ (0, import_jsx_runtime148.jsx)("h3", { className: "text-sm font-semibold text-zinc-100 truncate leading-tight", children: title || "Generating Research Report" }),
|
|
17850
17990
|
/* @__PURE__ */ (0, import_jsx_runtime148.jsxs)("p", { className: "text-xs text-zinc-500 mt-0.5", children: [
|
|
@@ -17859,8 +17999,8 @@ var ResearchReportJobCard = (props) => {
|
|
|
17859
17999
|
/* @__PURE__ */ (0, import_jsx_runtime148.jsx)("div", { className: "h-2 bg-zinc-800 rounded-full overflow-hidden", children: /* @__PURE__ */ (0, import_jsx_runtime148.jsx)(
|
|
17860
18000
|
"div",
|
|
17861
18001
|
{
|
|
17862
|
-
className: "h-full
|
|
17863
|
-
style: { width: `${Math.max(pct, 2)}
|
|
18002
|
+
className: "h-full rounded-full transition-all duration-500 ease-out",
|
|
18003
|
+
style: { width: `${Math.max(pct, 2)}%`, backgroundImage: GOLD_GRADIENT }
|
|
17864
18004
|
}
|
|
17865
18005
|
) }),
|
|
17866
18006
|
/* @__PURE__ */ (0, import_jsx_runtime148.jsxs)("span", { className: "absolute right-0 -top-5 text-xs text-zinc-500 font-medium tabular-nums", children: [
|
|
@@ -17869,7 +18009,7 @@ var ResearchReportJobCard = (props) => {
|
|
|
17869
18009
|
] })
|
|
17870
18010
|
] }),
|
|
17871
18011
|
/* @__PURE__ */ (0, import_jsx_runtime148.jsxs)("div", { className: "flex items-center gap-2", children: [
|
|
17872
|
-
/* @__PURE__ */ (0, import_jsx_runtime148.jsx)("div", { className: "w-2 h-2 rounded-full bg-
|
|
18012
|
+
/* @__PURE__ */ (0, import_jsx_runtime148.jsx)("div", { className: "w-2 h-2 rounded-full bg-[#C0AE82] animate-pulse" }),
|
|
17873
18013
|
/* @__PURE__ */ (0, import_jsx_runtime148.jsx)("span", { className: "text-xs text-zinc-400", children: step })
|
|
17874
18014
|
] }),
|
|
17875
18015
|
phase === "ai_generation" && searchesTotal > 0 && /* @__PURE__ */ (0, import_jsx_runtime148.jsxs)("div", { className: "pt-1", children: [
|
|
@@ -17886,7 +18026,7 @@ var ResearchReportJobCard = (props) => {
|
|
|
17886
18026
|
{
|
|
17887
18027
|
className: cn(
|
|
17888
18028
|
"flex-1 h-1 rounded-full transition-all duration-300",
|
|
17889
|
-
i < searchesCompleted ? "bg-
|
|
18029
|
+
i < searchesCompleted ? "bg-[#C0AE82]" : i === searchesCompleted ? "bg-[#C0AE82]/50 animate-pulse" : "bg-zinc-700"
|
|
17890
18030
|
)
|
|
17891
18031
|
},
|
|
17892
18032
|
i
|
|
@@ -17920,12 +18060,12 @@ var ResearchReportJobCard = (props) => {
|
|
|
17920
18060
|
"div",
|
|
17921
18061
|
{
|
|
17922
18062
|
className: "h-[3px]",
|
|
17923
|
-
style: {
|
|
18063
|
+
style: { backgroundImage: GOLD_GRADIENT }
|
|
17924
18064
|
}
|
|
17925
18065
|
),
|
|
17926
18066
|
/* @__PURE__ */ (0, import_jsx_runtime148.jsxs)("div", { className: "p-5", children: [
|
|
17927
18067
|
/* @__PURE__ */ (0, import_jsx_runtime148.jsxs)("div", { className: "flex items-start gap-3", children: [
|
|
17928
|
-
/* @__PURE__ */ (0, import_jsx_runtime148.jsx)("div", { className: "w-10 h-10 rounded-xl bg-
|
|
18068
|
+
/* @__PURE__ */ (0, import_jsx_runtime148.jsx)("div", { className: "w-10 h-10 rounded-xl bg-[#C0AE82]/10 border border-[#C0AE82]/25 flex items-center justify-center flex-shrink-0 text-[#DCC99B]", children: /* @__PURE__ */ (0, import_jsx_runtime148.jsx)(DocumentIcon, {}) }),
|
|
17929
18069
|
/* @__PURE__ */ (0, import_jsx_runtime148.jsxs)("div", { className: "flex-1 min-w-0", children: [
|
|
17930
18070
|
/* @__PURE__ */ (0, import_jsx_runtime148.jsx)("h3", { className: "text-sm font-semibold text-zinc-100 truncate leading-tight", children: title || "Report outline" }),
|
|
17931
18071
|
/* @__PURE__ */ (0, import_jsx_runtime148.jsxs)("p", { className: "text-xs text-amber-400/90 mt-0.5", children: [
|
|
@@ -17946,7 +18086,7 @@ var ResearchReportJobCard = (props) => {
|
|
|
17946
18086
|
value: headingEdits[i] ?? s.heading ?? "",
|
|
17947
18087
|
onChange: (e) => setHeadingEdits((prev) => ({ ...prev, [i]: e.target.value })),
|
|
17948
18088
|
disabled: building,
|
|
17949
|
-
className: "flex-1 min-w-0 bg-zinc-800/60 border border-zinc-700 rounded-lg px-3 h-8 text-xs text-zinc-200 focus:border-
|
|
18089
|
+
className: "flex-1 min-w-0 bg-zinc-800/60 border border-zinc-700 rounded-lg px-3 h-8 text-xs text-zinc-200 focus:border-[#C0AE82] outline-none disabled:opacity-60"
|
|
17950
18090
|
}
|
|
17951
18091
|
),
|
|
17952
18092
|
/* @__PURE__ */ (0, import_jsx_runtime148.jsx)(
|
|
@@ -18032,46 +18172,6 @@ var ResearchReportJobCard = (props) => {
|
|
|
18032
18172
|
] }) })
|
|
18033
18173
|
] }) });
|
|
18034
18174
|
}
|
|
18035
|
-
const handleDownload = async () => {
|
|
18036
|
-
if (!htmlUrl) return;
|
|
18037
|
-
const filename = `${(title ?? "").replace(/[^a-z0-9]/gi, "-").toLowerCase()}.html`;
|
|
18038
|
-
const href = `/api/download?url=${encodeURIComponent(htmlUrl)}&filename=${encodeURIComponent(filename)}`;
|
|
18039
|
-
try {
|
|
18040
|
-
const response = await fetch(href);
|
|
18041
|
-
if (!response.ok) throw new Error(`status ${response.status}`);
|
|
18042
|
-
const blob = await response.blob();
|
|
18043
|
-
const objectUrl = window.URL.createObjectURL(blob);
|
|
18044
|
-
const anchor = document.createElement("a");
|
|
18045
|
-
anchor.href = objectUrl;
|
|
18046
|
-
anchor.download = filename;
|
|
18047
|
-
document.body.appendChild(anchor);
|
|
18048
|
-
anchor.click();
|
|
18049
|
-
anchor.remove();
|
|
18050
|
-
window.URL.revokeObjectURL(objectUrl);
|
|
18051
|
-
} catch {
|
|
18052
|
-
window.open(htmlUrl, "_blank", "noopener,noreferrer");
|
|
18053
|
-
}
|
|
18054
|
-
};
|
|
18055
|
-
const handleDownloadPdf = async () => {
|
|
18056
|
-
if (!pdfUrl) return;
|
|
18057
|
-
const filename = `${(title ?? "").replace(/[^a-z0-9]/gi, "-").toLowerCase()}.pdf`;
|
|
18058
|
-
const href = `/api/download?url=${encodeURIComponent(pdfUrl)}&filename=${encodeURIComponent(filename)}`;
|
|
18059
|
-
try {
|
|
18060
|
-
const response = await fetch(href);
|
|
18061
|
-
if (!response.ok) throw new Error(`status ${response.status}`);
|
|
18062
|
-
const blob = await response.blob();
|
|
18063
|
-
const objectUrl = window.URL.createObjectURL(blob);
|
|
18064
|
-
const anchor = document.createElement("a");
|
|
18065
|
-
anchor.href = objectUrl;
|
|
18066
|
-
anchor.download = filename;
|
|
18067
|
-
document.body.appendChild(anchor);
|
|
18068
|
-
anchor.click();
|
|
18069
|
-
anchor.remove();
|
|
18070
|
-
window.URL.revokeObjectURL(objectUrl);
|
|
18071
|
-
} catch {
|
|
18072
|
-
window.open(pdfUrl, "_blank", "noopener,noreferrer");
|
|
18073
|
-
}
|
|
18074
|
-
};
|
|
18075
18175
|
const resolveShareLink = () => {
|
|
18076
18176
|
if (shareUrl) return shareUrl;
|
|
18077
18177
|
if (typeof window !== "undefined" && job_id) {
|
|
@@ -18197,30 +18297,93 @@ var ResearchReportJobCard = (props) => {
|
|
|
18197
18297
|
),
|
|
18198
18298
|
/* @__PURE__ */ (0, import_jsx_runtime148.jsxs)("div", { className: "flex-1 min-w-0", children: [
|
|
18199
18299
|
/* @__PURE__ */ (0, import_jsx_runtime148.jsx)("h3", { className: "text-sm font-semibold text-zinc-100 truncate leading-tight", children: title }),
|
|
18200
|
-
/* @__PURE__ */ (0, import_jsx_runtime148.jsxs)("
|
|
18201
|
-
depth && /* @__PURE__ */ (0, import_jsx_runtime148.jsx)(
|
|
18202
|
-
|
|
18203
|
-
|
|
18204
|
-
|
|
18205
|
-
|
|
18206
|
-
|
|
18300
|
+
(depth || sectionCount > 0 || sourceCount > 0 || wordCount > 0 || templateLabel) && /* @__PURE__ */ (0, import_jsx_runtime148.jsxs)("div", { className: "flex flex-wrap items-center gap-1.5 mt-1.5", children: [
|
|
18301
|
+
depth && /* @__PURE__ */ (0, import_jsx_runtime148.jsx)(Chip2, { children: depth }),
|
|
18302
|
+
sectionCount > 0 && /* @__PURE__ */ (0, import_jsx_runtime148.jsxs)(Chip2, { children: [
|
|
18303
|
+
sectionCount,
|
|
18304
|
+
" sections"
|
|
18305
|
+
] }),
|
|
18306
|
+
sourceCount > 0 && /* @__PURE__ */ (0, import_jsx_runtime148.jsxs)(Chip2, { children: [
|
|
18307
|
+
sourceCount,
|
|
18308
|
+
" sources"
|
|
18309
|
+
] }),
|
|
18310
|
+
wordCount > 0 && /* @__PURE__ */ (0, import_jsx_runtime148.jsxs)(Chip2, { children: [
|
|
18311
|
+
formatWordCount(wordCount),
|
|
18312
|
+
" words"
|
|
18313
|
+
] }),
|
|
18314
|
+
templateLabel && /* @__PURE__ */ (0, import_jsx_runtime148.jsx)(Chip2, { children: templateLabel })
|
|
18207
18315
|
] }),
|
|
18208
|
-
generationMode === "template" &&
|
|
18316
|
+
generationMode === "template" && (isApproved || reviewStatus === "pending_review") && /* @__PURE__ */ (0, import_jsx_runtime148.jsxs)("p", { className: "flex items-center gap-1.5 text-xs mt-2", children: [
|
|
18317
|
+
/* @__PURE__ */ (0, import_jsx_runtime148.jsx)(
|
|
18318
|
+
"span",
|
|
18319
|
+
{
|
|
18320
|
+
className: cn(
|
|
18321
|
+
"w-1.5 h-1.5 rounded-full flex-shrink-0",
|
|
18322
|
+
isApproved ? "bg-emerald-400" : "bg-amber-400"
|
|
18323
|
+
)
|
|
18324
|
+
}
|
|
18325
|
+
),
|
|
18326
|
+
isApproved ? /* @__PURE__ */ (0, import_jsx_runtime148.jsx)("span", { className: "text-emerald-400/90", children: "Approved \u2014 future reports use this format" }) : /* @__PURE__ */ (0, import_jsx_runtime148.jsx)("span", { className: "text-amber-400/90", children: "Review this report, then approve to lock the layout" })
|
|
18327
|
+
] })
|
|
18209
18328
|
] }),
|
|
18210
18329
|
/* @__PURE__ */ (0, import_jsx_runtime148.jsxs)("div", { className: "flex items-center gap-1.5 flex-shrink-0 flex-wrap justify-end", children: [
|
|
18211
|
-
|
|
18212
|
-
|
|
18213
|
-
|
|
18214
|
-
|
|
18215
|
-
|
|
18216
|
-
|
|
18217
|
-
|
|
18218
|
-
|
|
18219
|
-
|
|
18220
|
-
|
|
18221
|
-
|
|
18222
|
-
|
|
18223
|
-
|
|
18330
|
+
/* @__PURE__ */ (0, import_jsx_runtime148.jsxs)("div", { className: "flex items-center rounded-lg border border-zinc-700 bg-zinc-800 overflow-hidden divide-x divide-zinc-700", children: [
|
|
18331
|
+
/* @__PURE__ */ (0, import_jsx_runtime148.jsxs)(
|
|
18332
|
+
"a",
|
|
18333
|
+
{
|
|
18334
|
+
href: htmlUrl ? `/reports/${job_id}/edit` : void 0,
|
|
18335
|
+
"aria-disabled": !htmlUrl,
|
|
18336
|
+
title: "Edit report content",
|
|
18337
|
+
className: cn(
|
|
18338
|
+
"flex items-center gap-1.5 px-2.5 h-7 text-xs font-medium text-zinc-300 hover:text-zinc-100 hover:bg-zinc-700/60 transition-colors",
|
|
18339
|
+
!htmlUrl && "pointer-events-none opacity-40"
|
|
18340
|
+
),
|
|
18341
|
+
children: [
|
|
18342
|
+
/* @__PURE__ */ (0, import_jsx_runtime148.jsx)(EditIcon2, {}),
|
|
18343
|
+
/* @__PURE__ */ (0, import_jsx_runtime148.jsx)("span", { children: "Edit" })
|
|
18344
|
+
]
|
|
18345
|
+
}
|
|
18346
|
+
),
|
|
18347
|
+
/* @__PURE__ */ (0, import_jsx_runtime148.jsxs)(
|
|
18348
|
+
"button",
|
|
18349
|
+
{
|
|
18350
|
+
onClick: () => setShowPreview(true),
|
|
18351
|
+
disabled: !hasHTML,
|
|
18352
|
+
title: "Preview report",
|
|
18353
|
+
className: "flex items-center gap-1.5 px-2.5 h-7 text-xs font-medium text-zinc-300 hover:text-zinc-100 hover:bg-zinc-700/60 transition-colors disabled:opacity-40 disabled:cursor-not-allowed",
|
|
18354
|
+
children: [
|
|
18355
|
+
/* @__PURE__ */ (0, import_jsx_runtime148.jsx)(ExpandIcon2, {}),
|
|
18356
|
+
/* @__PURE__ */ (0, import_jsx_runtime148.jsx)("span", { children: "Preview" })
|
|
18357
|
+
]
|
|
18358
|
+
}
|
|
18359
|
+
),
|
|
18360
|
+
canRegenerate && /* @__PURE__ */ (0, import_jsx_runtime148.jsxs)(
|
|
18361
|
+
"button",
|
|
18362
|
+
{
|
|
18363
|
+
onClick: handleRegenerate,
|
|
18364
|
+
disabled: regenerating || approving,
|
|
18365
|
+
title: "Try another report template with the same data",
|
|
18366
|
+
className: "flex items-center gap-1.5 px-2.5 h-7 text-xs font-medium text-zinc-300 hover:text-zinc-100 hover:bg-zinc-700/60 transition-colors disabled:opacity-40",
|
|
18367
|
+
children: [
|
|
18368
|
+
/* @__PURE__ */ (0, import_jsx_runtime148.jsx)(RefreshIcon2, {}),
|
|
18369
|
+
/* @__PURE__ */ (0, import_jsx_runtime148.jsx)("span", { children: regenerating ? "Switching\u2026" : "Regenerate" })
|
|
18370
|
+
]
|
|
18371
|
+
}
|
|
18372
|
+
),
|
|
18373
|
+
/* @__PURE__ */ (0, import_jsx_runtime148.jsx)(
|
|
18374
|
+
"button",
|
|
18375
|
+
{
|
|
18376
|
+
onClick: handleShare,
|
|
18377
|
+
disabled: !canShare,
|
|
18378
|
+
title: !canShare && reviewStatus === "pending_review" ? "Approve the report to enable sharing" : copied ? "Copied!" : "Copy shareable link",
|
|
18379
|
+
className: cn(
|
|
18380
|
+
"flex items-center justify-center w-7 h-7 transition-colors disabled:opacity-30 disabled:cursor-not-allowed",
|
|
18381
|
+
copied ? "text-green-400" : "text-zinc-300 hover:text-zinc-100 hover:bg-zinc-700/60"
|
|
18382
|
+
),
|
|
18383
|
+
children: copied ? /* @__PURE__ */ (0, import_jsx_runtime148.jsx)(CheckIcon2, {}) : /* @__PURE__ */ (0, import_jsx_runtime148.jsx)(ShareIcon2, {})
|
|
18384
|
+
}
|
|
18385
|
+
)
|
|
18386
|
+
] }),
|
|
18224
18387
|
canApprove && /* @__PURE__ */ (0, import_jsx_runtime148.jsxs)(
|
|
18225
18388
|
"button",
|
|
18226
18389
|
{
|
|
@@ -18235,53 +18398,15 @@ var ResearchReportJobCard = (props) => {
|
|
|
18235
18398
|
}
|
|
18236
18399
|
),
|
|
18237
18400
|
isApproved && /* @__PURE__ */ (0, import_jsx_runtime148.jsx)("span", { className: "flex items-center justify-center w-7 h-7 rounded-lg border border-emerald-500/40 bg-emerald-500/10 text-emerald-400", title: "Format saved", children: /* @__PURE__ */ (0, import_jsx_runtime148.jsx)(CheckIcon2, {}) }),
|
|
18238
|
-
/* @__PURE__ */ (0, import_jsx_runtime148.jsx)(
|
|
18239
|
-
"button",
|
|
18240
|
-
{
|
|
18241
|
-
onClick: handleShare,
|
|
18242
|
-
disabled: !canShare,
|
|
18243
|
-
title: !canShare && reviewStatus === "pending_review" ? "Approve the report to enable sharing" : copied ? "Copied!" : "Copy shareable link",
|
|
18244
|
-
className: cn(
|
|
18245
|
-
"w-7 h-7 rounded-lg border flex items-center justify-center transition-all",
|
|
18246
|
-
copied ? "border-green-500/40 bg-green-500/10 text-green-400" : "border-zinc-700 bg-zinc-800 text-zinc-400 hover:border-zinc-500 hover:text-zinc-200",
|
|
18247
|
-
"disabled:opacity-30 disabled:cursor-not-allowed"
|
|
18248
|
-
),
|
|
18249
|
-
children: copied ? /* @__PURE__ */ (0, import_jsx_runtime148.jsx)(CheckIcon2, {}) : /* @__PURE__ */ (0, import_jsx_runtime148.jsx)(ShareIcon2, {})
|
|
18250
|
-
}
|
|
18251
|
-
),
|
|
18252
|
-
/* @__PURE__ */ (0, import_jsx_runtime148.jsxs)(
|
|
18253
|
-
"button",
|
|
18254
|
-
{
|
|
18255
|
-
onClick: () => setShowPreview(true),
|
|
18256
|
-
disabled: !hasHTML,
|
|
18257
|
-
title: "Preview report",
|
|
18258
|
-
className: "flex items-center gap-1.5 px-2.5 h-7 rounded-lg border border-zinc-700 bg-zinc-800 hover:border-zinc-500 text-zinc-400 hover:text-zinc-200 text-xs font-medium transition-colors disabled:opacity-30 disabled:cursor-not-allowed",
|
|
18259
|
-
children: [
|
|
18260
|
-
/* @__PURE__ */ (0, import_jsx_runtime148.jsx)(ExpandIcon2, {}),
|
|
18261
|
-
/* @__PURE__ */ (0, import_jsx_runtime148.jsx)("span", { children: "Preview" })
|
|
18262
|
-
]
|
|
18263
|
-
}
|
|
18264
|
-
),
|
|
18265
|
-
pdfUrl && /* @__PURE__ */ (0, import_jsx_runtime148.jsxs)(
|
|
18266
|
-
"button",
|
|
18267
|
-
{
|
|
18268
|
-
onClick: handleDownloadPdf,
|
|
18269
|
-
title: "Download PDF",
|
|
18270
|
-
className: "flex items-center gap-1.5 px-2.5 h-7 rounded-lg border border-zinc-700 bg-zinc-800 hover:border-zinc-500 text-zinc-400 hover:text-zinc-200 text-xs font-medium transition-colors",
|
|
18271
|
-
children: [
|
|
18272
|
-
/* @__PURE__ */ (0, import_jsx_runtime148.jsx)(DownloadIcon2, {}),
|
|
18273
|
-
/* @__PURE__ */ (0, import_jsx_runtime148.jsx)("span", { children: "PDF" })
|
|
18274
|
-
]
|
|
18275
|
-
}
|
|
18276
|
-
),
|
|
18277
18401
|
/* @__PURE__ */ (0, import_jsx_runtime148.jsxs)(
|
|
18278
18402
|
"button",
|
|
18279
18403
|
{
|
|
18280
|
-
onClick:
|
|
18281
|
-
disabled: !hasHTML,
|
|
18282
|
-
|
|
18283
|
-
|
|
18284
|
-
|
|
18404
|
+
onClick: () => setShowExport(true),
|
|
18405
|
+
disabled: !hasHTML && !pdfUrl,
|
|
18406
|
+
title: "Download this report (PDF or HTML)",
|
|
18407
|
+
className: "flex items-center gap-1.5 px-3 h-7 text-xs font-semibold rounded-lg transition-colors disabled:opacity-50 disabled:cursor-not-allowed",
|
|
18408
|
+
style: { backgroundImage: GOLD_GRADIENT, color: readableOn(primaryColor) },
|
|
18409
|
+
onMouseEnter: (e) => e.currentTarget.style.filter = "brightness(1.1)",
|
|
18285
18410
|
onMouseLeave: (e) => e.currentTarget.style.filter = "brightness(1)",
|
|
18286
18411
|
children: [
|
|
18287
18412
|
/* @__PURE__ */ (0, import_jsx_runtime148.jsx)(DownloadIcon2, {}),
|
|
@@ -18335,6 +18460,15 @@ var ResearchReportJobCard = (props) => {
|
|
|
18335
18460
|
title,
|
|
18336
18461
|
onClose: () => setShowPreview(false)
|
|
18337
18462
|
}
|
|
18463
|
+
),
|
|
18464
|
+
showExport && /* @__PURE__ */ (0, import_jsx_runtime148.jsx)(
|
|
18465
|
+
ReportExportModal,
|
|
18466
|
+
{
|
|
18467
|
+
htmlUrl,
|
|
18468
|
+
pdfUrl,
|
|
18469
|
+
title,
|
|
18470
|
+
onClose: () => setShowExport(false)
|
|
18471
|
+
}
|
|
18338
18472
|
)
|
|
18339
18473
|
] });
|
|
18340
18474
|
};
|
|
@@ -18479,7 +18613,7 @@ var WebSearchJobCard = ({
|
|
|
18479
18613
|
{
|
|
18480
18614
|
className: "h-[3px]",
|
|
18481
18615
|
style: {
|
|
18482
|
-
|
|
18616
|
+
backgroundImage: "linear-gradient(90deg, #8B7D5E, #C0AE82, #DCC99B, #C0AE82, #8B7D5E)",
|
|
18483
18617
|
backgroundSize: "200% 100%",
|
|
18484
18618
|
animation: "gradient-shift 2s ease-in-out infinite"
|
|
18485
18619
|
}
|
|
@@ -18501,7 +18635,7 @@ var WebSearchJobCard = ({
|
|
|
18501
18635
|
className: "h-full rounded-full transition-all duration-500 ease-out",
|
|
18502
18636
|
style: {
|
|
18503
18637
|
width: `${Math.max(pct, 2)}%`,
|
|
18504
|
-
|
|
18638
|
+
backgroundImage: "linear-gradient(90deg, #8B7D5E, #C0AE82, #DCC99B)"
|
|
18505
18639
|
}
|
|
18506
18640
|
}
|
|
18507
18641
|
) }),
|
|
@@ -18511,7 +18645,7 @@ var WebSearchJobCard = ({
|
|
|
18511
18645
|
] })
|
|
18512
18646
|
] }),
|
|
18513
18647
|
/* @__PURE__ */ (0, import_jsx_runtime149.jsxs)("div", { className: "flex items-center gap-2", children: [
|
|
18514
|
-
/* @__PURE__ */ (0, import_jsx_runtime149.jsx)("div", { className: "w-2 h-2 rounded-full bg-
|
|
18648
|
+
/* @__PURE__ */ (0, import_jsx_runtime149.jsx)("div", { className: "w-2 h-2 rounded-full bg-[#C0AE82] animate-pulse flex-shrink-0" }),
|
|
18515
18649
|
/* @__PURE__ */ (0, import_jsx_runtime149.jsx)("span", { className: "text-xs text-zinc-400", children: step })
|
|
18516
18650
|
] }),
|
|
18517
18651
|
searchesTotal > 0 && /* @__PURE__ */ (0, import_jsx_runtime149.jsxs)("div", { className: "pt-1", children: [
|
|
@@ -18528,7 +18662,7 @@ var WebSearchJobCard = ({
|
|
|
18528
18662
|
{
|
|
18529
18663
|
className: cn(
|
|
18530
18664
|
"flex-1 h-1 rounded-full transition-all duration-300",
|
|
18531
|
-
i < searchesCompleted ? "bg-
|
|
18665
|
+
i < searchesCompleted ? "bg-[#C0AE82]" : phase === "ai_generation" && i === searchesCompleted ? "bg-[#C0AE82]/50 animate-pulse" : "bg-zinc-700"
|
|
18532
18666
|
)
|
|
18533
18667
|
},
|
|
18534
18668
|
i
|
|
@@ -21768,7 +21902,7 @@ function PlatformMetricsBanner({
|
|
|
21768
21902
|
return /* @__PURE__ */ (0, import_jsx_runtime173.jsxs)(
|
|
21769
21903
|
"div",
|
|
21770
21904
|
{
|
|
21771
|
-
className: "\
|
|
21905
|
+
className: "\n grid grid-cols-1 gap-3 rounded-xl py-4 px-4 shadow-sm\n md:flex md:overflow-x-auto md:gap-6 md:rounded-l-xl md:py-4 md:px-4 md:items-center md:gap-0 md:px-0 md:ml-8\n ",
|
|
21772
21906
|
style: { backgroundColor: bgColor },
|
|
21773
21907
|
children: [
|
|
21774
21908
|
/* @__PURE__ */ (0, import_jsx_runtime173.jsxs)("div", { className: "flex flex-col items-center md:min-w-0", children: [
|