Wayan Satria
WS
, wayan.satria@gmail.com
Stage, Consideration Warm Magnet, Panduan Landing Page
Generate jadwal follow up
Lead ini belum punya jadwal follow up, pilih Followup Template Group untuk mengenerate roadmap otomatis.
Setelah tergenerate, semua item akan berstatus pending, kamu tinggal jalankan follow up sesuai jadwal.
Awareness Total, 0, selesai, 0, pending, 0
No Konten Jadwal Status WA
Belum ada item roadmap untuk stage ini.
Kalau masih ada token seperti {{freebie_link}}, berarti belum ada datanya, tinggal isi manual.
Consideration Total, 0, selesai, 0, pending, 0
No Konten Jadwal Status WA
Belum ada item roadmap untuk stage ini.
Kalau masih ada token seperti {{freebie_link}}, berarti belum ada datanya, tinggal isi manual.

Identitas Halaman

  • Nama file, page-detail-followup-lead.php
  • URL, https://web.putuadi.id/marketing/detail-lead/detail-followup-lead/?idl=LD2602151537481362
  • Modul, CRM, Marketing
  • Fungsi utama, menampilkan dan mengelola roadmap follow up (jadwal konten follow up) untuk 1 lead, berdasarkan template yang sudah dibuat di master Followup Templates dan Followup Template Groups.
  • Prompt : https://chatgpt.com/share/6995fe9a-d5e4-8006-87dd-548202c2fb23

1) Konsep Besar, Apa yang Dikerjakan Halaman Ini

Halaman ini adalah “monitoring dan eksekusi” roadmap follow up untuk satu lead.

Yang terjadi di halaman ini secara sederhana:

  1. Sistem membaca data lead dari tb_leads.
  2. Sistem membaca daftar item roadmap dari tb_lead_roadmap_items, dan join ke tb_followup_templates untuk mengambil judul konten dan teks template follow up.
  3. Sistem menampilkan item-item roadmap, dikelompokkan per stage Customer Journey (Awareness, Consideration, Purchase, Retention, Advocacy).
  4. User bisa melakukan aksi:
    • Generate roadmap awal dari sebuah Followup Template Group (khusus lead yang belum punya item roadmap sama sekali).
    • Generate stage berikutnya (Retention atau Advocacy) jika stage sebelumnya sudah selesai.
    • Menandai item sebagai terkirim atau skip.
    • Membuka modal “Lihat teks” untuk melihat isi pesan follow up, lalu copy.
    • Klik tombol WhatsApp untuk mengirim pesan yang sudah dirender (template diisi variabel lead) via wa.me.

Output akhirnya, lead punya jadwal follow up yang rapi, bisa dieksekusi manual oleh tim, dan status tiap follow up bisa dipantau.


2) Parameter URL

Parameter wajib

  • idl, ID lead
    • Contoh, ?idl=LD2602151537481362
    • Disanitasi, hanya alfanumerik (A-Za-z0-9), karakter lain dibuang.

Jika idl kosong atau tidak valid, halaman menampilkan pesan warning.

Parameter opsional

  • debug=1
    • Menampilkan panel debug berisi SQL loader items dan total rows yang didapat.
    • Tujuan, melacak masalah data kosong, join tidak match, filter salah, dan sebagainya.

3) Dependensi File Include

Halaman ini mengandalkan beberapa include internal:

  1. include_crm_helpers.php
    • Helper umum, misalnya:
      • wb_get_current_user_login_safe()
      • wb_wa_digits() untuk normalisasi nomor WhatsApp
      • wb_tpl_render() untuk render template text dengan variabel lead
      • wb_format_datetime_id() untuk format datetime tampilan
  2. include_crm_db.php
    • Menyediakan koneksi DB, variabel mysqli $koneksi
    • Bisa juga menyediakan $dbError jika koneksi bermasalah
  3. include_crm_definitions.php
    • Definisi stage, label, dan mapping yang dipakai UI dan normalisasi
    • Umumnya menyediakan array $stages seperti:
      • awareness, consideration, purchase, retention, advocacy
      • masing-masing punya label
  4. include_crm_roadmap.php
    • Helper roadmap tambahan
    • Yang dipakai di halaman ini:
      • wb_roadmap_mark_item(...) untuk update status item
  5. Layout:
    • header.php, sidebar.php, topbar.php, footer.php
    • include_tentang_halaman.php

4) Tabel Database yang Dipakai

Halaman ini memakai 4 tabel utama (dan 1 tabel opsional).

A. tb_leads

Dipakai untuk:

  • Ambil data lead yang sedang dibuka
  • Ambil stage lead untuk menentukan stage mana yang tampil dan aturan generate
  • Simpan template_group pada lead saat generate roadmap awal

Kolom yang biasa dipakai (minimal):

  • id_lead
  • full_name
  • company_name
  • email
  • phone
  • lead_magnet
  • stage
  • template_group (opsional tapi dipakai bila ada)
  • updated_at

B. tb_lead_roadmap_items

Ini tabel inti, berisi item roadmap per lead.

Kolom minimal yang diasumsikan ada:

  • id_item (ID item roadmap)
  • id_roadmap (relasi ke roadmap header)
  • id_lead
  • id_template
  • stage
  • step_no
  • day_number
  • scheduled_at
  • status (pending, sent, skipped)
  • created_at
  • updated_at

C. tb_followup_templates

Master isi konten follow up.

Kolom minimal yang dipakai di halaman ini:

  • id_template
  • stage
  • step_no
  • day_number
  • title
  • message_text
  • channel
  • template_group (dipakai untuk filter berdasarkan group)
  • is_active (opsional, jika ada, hanya yang aktif yang diambil)

D. tb_followup_template_groups

Master group drip sequence.

Kolom yang dipakai:

  • id_group
  • group_key
  • group_name
  • default_send_time (HH:MM:SS)
  • timezone_name (opsional)
  • is_active

E. tb_lead_roadmaps (opsional)

Dipakai sebagai “header roadmap”.

Jika tabel ini ada, halaman akan:

  • Cek apakah lead sudah punya roadmap header
  • Jika belum ada, buat baru id_roadmap
  • Simpan metadata group bila kolom tersedia (template_group, group_key, group_name, id_group, created_by, updated_by)

Kalau tabel ini tidak ada, halaman tetap bisa jalan, karena id_roadmap bisa dibuat secara internal untuk item.


5) Struktur Data dan Relasi yang Dipakai

Konsep relasi ideal:

  • 1 Lead (tb_leads)
    • punya 1 Roadmap header (tb_lead_roadmaps) opsional
      • punya banyak Roadmap items (tb_lead_roadmap_items)
        • setiap item merujuk ke 1 Template (tb_followup_templates)

Di UI, item-item roadmap akan ditampilkan per stage.


6) Komponen UI yang Ditampilkan

6.1 Header halaman

  • Pretitle, “CRM”
  • Title, “Roadmap Follow up Lead”
  • Subtitle, “Peta jadwal konten follow up untuk 1 lead”
  • Tombol kembali, kembali ke halaman detail lead, /marketing/detail-lead/?idl=...

6.2 Lead summary card

Menampilkan informasi lead:

  • Nama lengkap
  • Avatar
    • jika ada URL foto di kolom tertentu, dipakai sebagai background image avatar
    • kalau tidak ada, pakai inisial nama
  • Company, email
  • Badge:
    • Stage label
    • Traffic Temperature
    • Lead magnet (jika ada)

Tombol:

  • Detail Lead
  • WhatsApp, jika nomor valid

6.3 Panel “Generate jadwal follow up” (hanya kondisi tertentu)

Panel ini hanya muncul kalau:

  • lead valid, dan
  • jumlah roadmap items untuk lead ini = 0, dan
  • tabel group ada dan group list tersedia

Isi panel:

  • dropdown Followup Template Group
  • tombol Generate (submit form)

6.4 Card per stage

Halaman menampilkan beberapa stage sesuai aturan visibleStages (dibahas di bagian aturan).

Tiap card stage berisi:

  • Badge nama stage
  • Ringkasan progress, total, selesai, pending
  • Progress bar
  • Tabel daftar item roadmap stage tersebut

Tabel item roadmap kolom:

  • No
  • Konten (judul template, hari ke berapa)
  • Jadwal (scheduled_at)
  • Status (Pending, Terkirim, Skip)
  • Tombol WhatsApp (langsung ke wa.me + text)
  • Dropdown aksi:
    • Lihat teks (modal)
    • Tandai terkirim
    • Skip

6.5 Modal “Teks Follow up”

Modal menampilkan:

  • Title (judul konten)
  • Textarea isi pesan yang sudah dirender
  • Tombol Copy
  • Tombol Tutup

Ada fallback jika Bootstrap modal tidak tersedia, modal tetap bisa tampil dengan JS manual.

6.6 Toast notifikasi

Jika ada query ?flash=...&msg=..., halaman memunculkan toast.
Setelah toast muncul, URL dibersihkan (flash dan msg dihapus dari query string) supaya tidak muncul lagi saat refresh.


7) Aturan Stage, Traffic Temperature, dan Stage yang Ditampilkan

7.1 Mapping Traffic Temperature (untuk badge)

  • Awareness, Cold
  • Consideration, Warm
  • Purchase, Retention, Advocacy, Hot

7.2 Stage yang ditampilkan (visibleStages)

Aturannya:

  1. Jika lead stage = awareness atau consideration
    • tampilkan, awareness dan consideration
    • ini untuk memastikan nurture awal tetap terlihat dua stage pertama
  2. Jika lead stage = purchase
    • tampilkan purchase
    • jika sudah ada item retention, tampilkan retention juga
  3. Jika lead stage = retention
    • tampilkan retention
    • jika sudah ada item advocacy, tampilkan advocacy juga
  4. Jika lead stage = advocacy
    • tampilkan advocacy saja
  5. Jika stage lead tidak dikenal
    • fallback, tampil awareness dan consideration

8) Aksi dan Form POST yang Didukung

Halaman mengenali POST berdasarkan wb_action.

8.1 Mark item, terkirim atau skip

  • wb_action = mark_item_sent
  • wb_action = mark_item_skipped

Input:

  • id_item
  • note (opsional)

Proses:

  • Panggil wb_roadmap_mark_item($koneksi, $idItem, $status, $userLogin, $note, $err)
  • Redirect balik ke halaman ini dengan flash message

Status yang dipakai:

  • sent
  • skipped
  • default, pending

8.2 Generate roadmap awal dari group

  • wb_action = generate_from_group

Kondisi:

  • Lead harus ada
  • Lead belum punya item roadmap sama sekali
  • Group harus valid dan aktif

Input:

  • group_id (id_group dari tb_followup_template_groups)

Proses besar:

  1. Ambil lead
  2. Cek ada item roadmap atau tidak, kalau sudah ada, generate diblok
  3. Ambil data group, termasuk default_send_time dan timezone
  4. Tentukan stage yang akan digenerate:
    • Jika lead stage awareness atau consideration, generate dua stage, awareness dan consideration
    • Jika lead stage masuk hot (purchase, retention, advocacy), generate hanya stage lead saat ini
    • Jika tidak jelas, fallback awareness dan consideration
  5. Ambil template dari tb_followup_templates:
    • stage termasuk stage yang ditentukan
    • template_group harus match salah satu kandidat group:
      • id_group, group_key, group_name
    • jika ada kolom is_active, hanya ambil yang is_active=1
    • urutan item:
      • berdasarkan stage urutan fixed
      • lalu day_number, lalu step_no, lalu id_template
  6. Buat roadmap header di tb_lead_roadmaps jika tabelnya ada dan lead belum punya
  7. Simpan template_group ke lead jika kolomnya ada
  8. Insert ke tb_lead_roadmap_items untuk setiap template yang lolos
    • mencegah dobel, jika sudah ada item untuk id_template tersebut, skip
    • hitung scheduled_at per template, berdasarkan aturan scheduling
  9. Redirect dengan flash success, menyebut total item yang berhasil dibuat

8.3 Generate stage berikutnya

  • wb_action = generate_next_stage

Input:

  • stage_to, hanya boleh retention atau advocacy

Aturan boleh generate:

  • stage_to = retention, hanya jika lead stage sekarang = purchase, dan semua item purchase sudah selesai, dan retention belum ada item
  • stage_to = advocacy, hanya jika lead stage sekarang = retention, dan semua item retention sudah selesai, dan advocacy belum ada item

Proses:

  1. Validasi stage_to
  2. Ambil lead, normalisasi stage
  3. Validasi aturan di atas
  4. Ambil id_roadmap yang sudah ada:
    • prioritas dari tb_lead_roadmap_items
    • fallback ke tb_lead_roadmaps jika ada
  5. Ambil template stage_to
    • jika lead punya template_group dan group bisa diresolve, filter template_group sesuai kandidat group
    • jika ada is_active, ambil yang aktif
  6. Insert item roadmap seperti proses awal, hitung scheduled_at mulai dari hari ini
  7. Update tb_leads.stage menjadi stage_to
  8. Redirect dengan flash message

9) Algoritma Perhitungan Jadwal scheduled_at

Fungsi:

  • wb_calc_scheduled_at($baseDate, $baseTime, $dayNum, $stepNo, $tzObj)

Aturan penting yang diterapkan:

  1. Tanggal mulai selalu hari ini
    • $baseDate = date('Y-m-d')
  2. Day number dipetakan ke offset hari seperti ini:
    • day_number = 0, offset hari 0, tetap hari ini
    • day_number = 1, offset hari 0, tetap hari ini
    • day_number = 2, offset hari 1, besok
    • day_number = 3, offset hari 2, lusa
    • rumus, jika day_number >= 2, offsetDays = day_number – 1
  3. Time default
    • Diambil dari tb_followup_template_groups.default_send_time
    • Jika tidak valid, fallback 09:00:00
  4. Offset menit berdasarkan step number
    • step_no dipakai untuk menggeser menit, supaya dalam 1 hari tidak semua pesan punya jam yang sama
    • rumus, (step_no - 1) * 10 menit
    • contoh:
      • step 1, +0 menit
      • step 2, +10 menit
      • step 3, +20 menit
  5. Timezone
    • Jika group memiliki timezone_name, dipakai untuk membentuk DateTime
    • Jika invalid, sistem fallback ke timezone default server PHP

Contoh konkret:

  • baseDate hari ini, 2026-02-19
  • baseTime, 09:00:00

Template A, day_number 1, step_no 1

  • offset hari 0, jam 09:00
  • scheduled_at = 2026-02-19 09:00:00

Template B, day_number 1, step_no 3

  • offset hari 0, jam 09:20
  • scheduled_at = 2026-02-19 09:20:00

Template C, day_number 2, step_no 1

  • offset hari 1, jam 09:00
  • scheduled_at = 2026-02-20 09:00:00

10) Render Template Pesan dan Variabel yang Dipakai

Template pesan berasal dari tb_followup_templates.message_text.

Sebelum dikirim ke WhatsApp atau ditampilkan di modal, pesan dirender dengan variabel lead:

Variabel yang disiapkan di halaman:

$varsLead = [
  'full_name'     => $leadName,
  'company_name'  => $leadComp,
  'email'         => $leadEmail,
  'phone'         => $leadPhone,
  'lead_magnet'   => $leadMagnet,
  'freebie_link'  => '',
];

Render dilakukan oleh helper:

  • wb_tpl_render($message_text, $varsLead)

Catatan:

  • Kalau masih ada token seperti {{freebie_link}}, artinya datanya belum diisi, karena di halaman ini freebie_link masih string kosong.
  • Ini sengaja, karena ada konteks bahwa beberapa data bisa diisi belakangan, atau punya sumber lain.

11) Integrasi WhatsApp (Manual Execution)

Di setiap item, tombol WhatsApp membuat URL seperti:

  • https://wa.me/<digits>?text=<encoded_message>

Nomor WhatsApp:

  • Diproses oleh helper wb_wa_digits($leadPhone)
  • Jika tidak bisa dinormalisasi menjadi digits valid, tombol WhatsApp tidak muncul (diganti tanda “-”).

Pesan:

  • Pesan sudah dalam kondisi final (template sudah dirender)
  • Ditambahkan ke query text=... melalui rawurlencode

Tujuannya:

  • Tim bisa follow up manual satu per satu, tetapi tetap konsisten dari sisi pesan dan urutan jadwal.

12) Status Item dan Progress Stage

12.1 Status yang digunakan

  • pending, default saat item dibuat
  • sent, saat follow up sudah dikirim
  • skipped, saat item dilewati

Badge status:

  • pending, warning
  • sent, success
  • skipped, secondary

12.2 Perhitungan progress per stage

Fungsi:

  • wb_stage_progress($items) menghasilkan:
    • total
    • done, sent + skipped
    • pending

Progress bar:

  • done / total * 100

12.3 Definisi “stage selesai”

Fungsi:

  • wb_stage_completed($items)
  • stage dianggap selesai jika semua item statusnya sent atau skipped

Aturan ini dipakai untuk mengaktifkan tombol:

  • Generate Stage Retention
  • Generate Stage Advocacy

13) Proteksi, Validasi, dan Pencegahan Duplikasi

Halaman ini punya beberapa proteksi penting:

  1. Validasi lead harus ada
  2. Validasi tabel wajib harus ada
  3. Generate roadmap awal diblok jika lead sudah punya item roadmap
  4. Insert item dicek satu per satu, tidak boleh ada item ganda:
    • cek SELECT 1 FROM tb_lead_roadmap_items WHERE id_lead=? AND id_template=? LIMIT 1
  5. Generate stage berikutnya diblok jika:
    • stage sekarang tidak sesuai aturan
    • stage sebelumnya belum selesai
    • stage target sudah punya item

14) Error Handling dan Debugging

14.1 Gaya error di halaman

  • Error kritis koneksi atau struktur tabel disimpan ke $dbError, lalu ditampilkan sebagai alert warning.
  • Error operasi generate dan insert biasanya diarahkan ke redirect + flash message, sehingga user tetap di halaman yang sama, tidak “white screen”.

14.2 Debug mode sederhana

  • Tambahkan &debug=1
  • Halaman menampilkan:
    • SQL loader items
    • total data items hasil query

Ini sangat membantu untuk:

  • memastikan query benar
  • memastikan join template match
  • memastikan data memang ada di DB

14.3 Debug WordPress yang direkomendasikan

Kalau butuh pelacakan lebih dalam (misalnya issue production yang intermittent), aktifkan log WP:

Di wp-config.php:

define('WP_DEBUG', true);
define('WP_DEBUG_LOG', true);
define('WP_DEBUG_DISPLAY', false);

Lalu cek file:

  • wp-content/debug.log

Praktik yang bagus:

  • saat error terjadi, ambil 30 sampai 80 baris terakhir dari debug.log
  • cocokkan timestamp, lalu telusuri query atau fungsi mana yang memicu error

15) Catatan Implementasi Teknis Penting di File Ini

Beberapa helper DB dibuat di dalam halaman supaya halaman tetap kuat walau environment berbeda:

  • wb_db_one(), ambil 1 row
  • wb_db_all(), ambil banyak row
  • wb_db_exec(), eksekusi query prepared statement
  • wb_stmt_bind_safe(), binding param aman, mencegah fatal error mismatch jumlah tipe dan variabel
  • wb_tbl_exists(), wb_col_exists(), deteksi tabel dan kolom dinamis, supaya backward compatible saat tabel berubah

Tujuan desain ini:

  • mengurangi kemungkinan “critical error”
  • lebih toleran terhadap variasi struktur kolom antar environment

16) Checklist Pengujian, QA Manual

Gunakan checklist ini setelah ada perubahan apapun.

A. Read-only

  1. Buka halaman dengan lead valid yang sudah punya roadmap
  2. Pastikan items muncul dan terbagi per stage yang sesuai
  3. Pastikan join template menampilkan title dan message

B. Generate roadmap awal

  1. Buat lead baru tanpa item roadmap
  2. Pastikan panel generate muncul
  3. Pilih group, klik Generate
  4. Pastikan redirect sukses dan jumlah item sesuai template
  5. Pastikan tidak bisa generate ulang (harus muncul warning)

C. Lihat teks dan Copy

  1. Klik dropdown item, pilih “Lihat teks”
  2. Modal muncul, teks terisi
  3. Tombol Copy berfungsi
  4. Pastikan tetap jalan walau Bootstrap modal gagal (fallback)

D. WhatsApp

  1. Pastikan tombol WhatsApp muncul jika nomor valid
  2. Pastikan link wa.me terbuka dan teks sudah berisi nama lead (token terisi)

E. Mark sent / skip

  1. Tandai terkirim, status berubah sent
  2. Skip, status berubah skipped
  3. Progress bar berubah sesuai

F. Generate next stage

  1. Selesaikan semua item purchase, status sent atau skipped
  2. Tombol generate retention muncul
  3. Klik generate retention, item retention tercipta, stage lead berubah retention
  4. Lakukan hal sama untuk advocacy

17) Ekstensi yang Disarankan (Jika Mau Naik Level)

Kalau nanti kamu mau membuat sistem ini makin “siap operasional tim”, pengembangan yang paling masuk akal:

  1. Simpan freebie_link ke data lead atau ke lead magnet, lalu render token itu otomatis
  2. Tambahkan “note per item” yang bisa diisi di UI sebelum mark sent, untuk mencatat respon lead
  3. Tambahkan filter, hari ini, minggu ini, overdue, untuk operasional follow up harian
  4. Tambahkan audit log, siapa yang mark sent, kapan, dari user mana
  5. Tambahkan “reschedule”, ubah scheduled_at per item tanpa mengubah template
  6. Tambahkan tombol “copy to clipboard + open WA” otomatis untuk mempercepat eksekusi

18) Ringkasan untuk Pembaca Baru

Jika kamu baru pertama kali melihat sistem ini, ingat 3 hal:

  1. Template follow up disiapkan dulu di Master, lalu dikelompokkan dengan Followup Template Group.
  2. Halaman ini mengubah template menjadi item roadmap nyata untuk lead tertentu, lengkap dengan jadwal dan status.
  3. Operasionalnya manual, tetapi terstruktur, tinggal klik lihat teks, copy, kirim WA, lalu tandai terkirim.