File size: 2,482 Bytes
b9cd14b
 
 
c85593f
b9cd14b
 
 
c85593f
b9cd14b
 
 
 
 
c85593f
b9cd14b
 
 
 
 
 
 
 
 
 
 
 
c85593f
b9cd14b
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
c85593f
b9cd14b
c85593f
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
b9cd14b
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
/**
 * Merge one generated sequence row (email or LinkedIn) into grouped contacts for previews.
 * When stepOrder is present (campaign wizard), dedupe by stepOrder + channel so merged timelines stay stable.
 * Always returns new references (immutable) so React re-renders when LinkedIn rows stream in after emails.
 */
export function mergeSequenceIntoContacts(prev, sequence) {
    const ch = sequence.channel || 'email';
    const matchIdx = prev.findIndex(
        (c) =>
            c.firstName === sequence.firstName &&
            c.lastName === sequence.lastName &&
            c.email === sequence.email
    );

    const stepOrder =
        sequence.stepOrder != null && sequence.stepOrder !== undefined ? sequence.stepOrder : null;
    const step = {
        emailNumber: sequence.emailNumber || 1,
        subject: sequence.subject,
        emailContent: sequence.emailContent,
        channel: ch,
        stepOrder,
    };
    const dedupeKey =
        stepOrder != null ? `ord-${stepOrder}-${ch}` : `${ch}-${step.emailNumber}`;

    if (matchIdx === -1) {
        const base = {
            id: sequence.id,
            firstName: sequence.firstName,
            lastName: sequence.lastName,
            email: sequence.email,
            company: sequence.company,
            title: sequence.title,
            product: sequence.product,
            emails: [],
            linkedin: [],
        };
        if (ch === 'linkedin') {
            base.linkedin = [step];
        } else {
            base.emails = [step];
        }
        return [...prev, base];
    }

    const existing = prev[matchIdx];
    const emails = [...(existing.emails || [])];
    const linkedin = [...(existing.linkedin || [])];

    if (ch === 'linkedin') {
        if (
            !linkedin.some((e) => {
                const k =
                    e.stepOrder != null ? `ord-${e.stepOrder}-${ch}` : `${ch}-${e.emailNumber}`;
                return k === dedupeKey;
            })
        ) {
            linkedin.push(step);
        }
    } else {
        if (
            !emails.some((e) => {
                const k =
                    e.stepOrder != null ? `ord-${e.stepOrder}-${ch}` : `${ch}-${e.emailNumber}`;
                return k === dedupeKey;
            })
        ) {
            emails.push(step);
        }
    }

    const updated = {
        ...existing,
        emails,
        linkedin,
    };
    return prev.map((c, i) => (i === matchIdx ? updated : c));
}