Seth commited on
Commit ·
8f69e9d
1
Parent(s): 7394679
update
Browse files
frontend/src/components/campaigns/CampaignsDashboardTab.jsx
CHANGED
|
@@ -183,7 +183,7 @@ export default function CampaignsDashboardTab() {
|
|
| 183 |
useEffect(() => {
|
| 184 |
const tick = async () => {
|
| 185 |
const list = campaignsRef.current.filter(
|
| 186 |
-
(c) => c.fileId && !c.generationComplete
|
| 187 |
);
|
| 188 |
if (!list.length) return;
|
| 189 |
const updates = await Promise.all(
|
|
@@ -192,6 +192,13 @@ export default function CampaignsDashboardTab() {
|
|
| 192 |
const res = await apiFetch(
|
| 193 |
`/api/generation-status?file_id=${encodeURIComponent(c.fileId)}`
|
| 194 |
);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 195 |
if (!res.ok) return { id: c.id, skip: true };
|
| 196 |
const status = await res.json();
|
| 197 |
return {
|
|
@@ -208,7 +215,11 @@ export default function CampaignsDashboardTab() {
|
|
| 208 |
setCampaigns((prev) =>
|
| 209 |
prev.map((c) => {
|
| 210 |
const u = updates.find((x) => x.id === c.id);
|
| 211 |
-
if (!u
|
|
|
|
|
|
|
|
|
|
|
|
|
| 212 |
return {
|
| 213 |
...c,
|
| 214 |
generationComplete: u.generationComplete,
|
|
|
|
| 183 |
useEffect(() => {
|
| 184 |
const tick = async () => {
|
| 185 |
const list = campaignsRef.current.filter(
|
| 186 |
+
(c) => c.fileId && !c.generationComplete && !c.generationStatusUnavailable
|
| 187 |
);
|
| 188 |
if (!list.length) return;
|
| 189 |
const updates = await Promise.all(
|
|
|
|
| 192 |
const res = await apiFetch(
|
| 193 |
`/api/generation-status?file_id=${encodeURIComponent(c.fileId)}`
|
| 194 |
);
|
| 195 |
+
if (res.status === 404) {
|
| 196 |
+
return {
|
| 197 |
+
id: c.id,
|
| 198 |
+
skip: false,
|
| 199 |
+
generationStatusUnavailable: true,
|
| 200 |
+
};
|
| 201 |
+
}
|
| 202 |
if (!res.ok) return { id: c.id, skip: true };
|
| 203 |
const status = await res.json();
|
| 204 |
return {
|
|
|
|
| 215 |
setCampaigns((prev) =>
|
| 216 |
prev.map((c) => {
|
| 217 |
const u = updates.find((x) => x.id === c.id);
|
| 218 |
+
if (!u) return c;
|
| 219 |
+
if (u.skip) return c;
|
| 220 |
+
if (u.generationStatusUnavailable) {
|
| 221 |
+
return { ...c, generationStatusUnavailable: true };
|
| 222 |
+
}
|
| 223 |
return {
|
| 224 |
...c,
|
| 225 |
generationComplete: u.generationComplete,
|
frontend/src/components/campaigns/CreateCampaignWizard.jsx
CHANGED
|
@@ -325,6 +325,8 @@ export default function CreateCampaignWizard({
|
|
| 325 |
const promptEditorRef = useRef(null);
|
| 326 |
const prevGenRunIdRef = useRef(null);
|
| 327 |
const hydratedCampaignIdRef = useRef(null);
|
|
|
|
|
|
|
| 328 |
|
| 329 |
const sequenceHasLinkedin = useMemo(
|
| 330 |
() =>
|
|
@@ -361,13 +363,33 @@ export default function CreateCampaignWizard({
|
|
| 361 |
}, []);
|
| 362 |
|
| 363 |
useEffect(() => {
|
| 364 |
-
if (!open)
|
| 365 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 366 |
|
| 367 |
useEffect(() => {
|
| 368 |
if (!open || !initialCampaign?.id) return;
|
| 369 |
if (hydratedCampaignIdRef.current === initialCampaign.id) return;
|
| 370 |
hydratedCampaignIdRef.current = initialCampaign.id;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 371 |
setGenSequences([]);
|
| 372 |
setGenContacts([]);
|
| 373 |
setGenRunId(0);
|
|
@@ -412,7 +434,7 @@ export default function CreateCampaignWizard({
|
|
| 412 |
? { ...initialCampaign.wizardLinkedinPrompts }
|
| 413 |
: {}
|
| 414 |
);
|
| 415 |
-
}, [open, initialCampaign?.id]);
|
| 416 |
|
| 417 |
useEffect(() => {
|
| 418 |
if (!open || !wizardUpload?.fileId || !initialCampaign?.id) return;
|
|
@@ -605,12 +627,18 @@ export default function CreateCampaignWizard({
|
|
| 605 |
setGenComplete(true);
|
| 606 |
es.close();
|
| 607 |
if (eventSourceRef.current === es) eventSourceRef.current = null;
|
|
|
|
|
|
|
|
|
|
| 608 |
} else if (data.type === 'error') {
|
| 609 |
console.error(data.error);
|
| 610 |
alert(`Generation error: ${data.error}`);
|
| 611 |
setGenRunning(false);
|
| 612 |
es.close();
|
| 613 |
if (eventSourceRef.current === es) eventSourceRef.current = null;
|
|
|
|
|
|
|
|
|
|
| 614 |
}
|
| 615 |
} catch (e) {
|
| 616 |
console.error(e);
|
|
@@ -762,7 +790,6 @@ export default function CreateCampaignWizard({
|
|
| 762 |
generationProgressPercent: Math.min(100, Math.round(genProgress || 0)),
|
| 763 |
});
|
| 764 |
onOpenChange(false);
|
| 765 |
-
reset();
|
| 766 |
};
|
| 767 |
|
| 768 |
useEffect(() => {
|
|
|
|
| 325 |
const promptEditorRef = useRef(null);
|
| 326 |
const prevGenRunIdRef = useRef(null);
|
| 327 |
const hydratedCampaignIdRef = useRef(null);
|
| 328 |
+
const openRef = useRef(open);
|
| 329 |
+
openRef.current = open;
|
| 330 |
|
| 331 |
const sequenceHasLinkedin = useMemo(
|
| 332 |
() =>
|
|
|
|
| 363 |
}, []);
|
| 364 |
|
| 365 |
useEffect(() => {
|
| 366 |
+
if (!open) {
|
| 367 |
+
if (genRunning) return;
|
| 368 |
+
reset();
|
| 369 |
+
}
|
| 370 |
+
}, [open, genRunning, reset]);
|
| 371 |
+
|
| 372 |
+
/** Fresh "Create" session — clear any in-component state (including orphan streams). */
|
| 373 |
+
useEffect(() => {
|
| 374 |
+
if (open && !initialCampaign?.id) {
|
| 375 |
+
reset();
|
| 376 |
+
}
|
| 377 |
+
}, [open, initialCampaign?.id, reset]);
|
| 378 |
|
| 379 |
useEffect(() => {
|
| 380 |
if (!open || !initialCampaign?.id) return;
|
| 381 |
if (hydratedCampaignIdRef.current === initialCampaign.id) return;
|
| 382 |
hydratedCampaignIdRef.current = initialCampaign.id;
|
| 383 |
+
const incomingFile = initialCampaign.fileId || null;
|
| 384 |
+
const currentFile = wizardUpload?.fileId ?? null;
|
| 385 |
+
if (eventSourceRef.current) {
|
| 386 |
+
const keepStream =
|
| 387 |
+
!!incomingFile && !!currentFile && incomingFile === currentFile;
|
| 388 |
+
if (!keepStream) {
|
| 389 |
+
eventSourceRef.current.close();
|
| 390 |
+
eventSourceRef.current = null;
|
| 391 |
+
}
|
| 392 |
+
}
|
| 393 |
setGenSequences([]);
|
| 394 |
setGenContacts([]);
|
| 395 |
setGenRunId(0);
|
|
|
|
| 434 |
? { ...initialCampaign.wizardLinkedinPrompts }
|
| 435 |
: {}
|
| 436 |
);
|
| 437 |
+
}, [open, initialCampaign?.id, wizardUpload?.fileId]);
|
| 438 |
|
| 439 |
useEffect(() => {
|
| 440 |
if (!open || !wizardUpload?.fileId || !initialCampaign?.id) return;
|
|
|
|
| 627 |
setGenComplete(true);
|
| 628 |
es.close();
|
| 629 |
if (eventSourceRef.current === es) eventSourceRef.current = null;
|
| 630 |
+
if (!openRef.current) {
|
| 631 |
+
reset();
|
| 632 |
+
}
|
| 633 |
} else if (data.type === 'error') {
|
| 634 |
console.error(data.error);
|
| 635 |
alert(`Generation error: ${data.error}`);
|
| 636 |
setGenRunning(false);
|
| 637 |
es.close();
|
| 638 |
if (eventSourceRef.current === es) eventSourceRef.current = null;
|
| 639 |
+
if (!openRef.current) {
|
| 640 |
+
reset();
|
| 641 |
+
}
|
| 642 |
}
|
| 643 |
} catch (e) {
|
| 644 |
console.error(e);
|
|
|
|
| 790 |
generationProgressPercent: Math.min(100, Math.round(genProgress || 0)),
|
| 791 |
});
|
| 792 |
onOpenChange(false);
|
|
|
|
| 793 |
};
|
| 794 |
|
| 795 |
useEffect(() => {
|