diff --git a/web/src/components/app/campaigns/sequences/CampaignFlow.tsx b/web/src/components/app/campaigns/sequences/CampaignFlow.tsx
index 4616a669..ac248499 100644
--- a/web/src/components/app/campaigns/sequences/CampaignFlow.tsx
+++ b/web/src/components/app/campaigns/sequences/CampaignFlow.tsx
@@ -216,6 +216,7 @@ type StepNodeData = {
endsHere: boolean;
orphan: boolean;
onDelete: () => void;
+ onAddReply: () => void;
};
function StepNode({ data, selected }: NodeProps) {
@@ -266,6 +267,22 @@ function StepNode({ data, selected }: NodeProps) {
Ends here
) : null}
+ {/* Explicit, discoverable way to build a reply-triggered step (the
+ reply branch is otherwise only reachable via a connection's
+ condition dropdown). Creates an action step that fires instantly
+ on reply. */}
+
{/* Right dot = start an "if" branch; bottom dot = plain "go there". */}
@@ -273,14 +290,23 @@ function StepNode({ data, selected }: NodeProps) {
);
}
-type IfNodeData = { label: string; onDelete: () => void };
+type IfNodeData = { label: string; instant: boolean; onDelete: () => void };
function IfNode({ data, selected }: NodeProps) {
const d = data as IfNodeData;
+ // Reply-class branches fire the moment the contact replies, not at the next
+ // scheduled step. A violet "instant" badge distinguishes them from the
+ // engagement (opened / clicked / within-N-days) branches that are checked at
+ // the next step boundary. The whole node carries a tooltip explaining it.
return (