feat: build dashboard lead funnel
This commit is contained in:
@@ -4,7 +4,10 @@ import test from "node:test";
|
||||
import {
|
||||
dashboardKpis,
|
||||
dashboardNavigation,
|
||||
groupLeadFunnelCards,
|
||||
leadFunnelStages,
|
||||
pipelineStages,
|
||||
toLeadFunnelCard,
|
||||
reviewQueue,
|
||||
} from "../lib/dashboard-model";
|
||||
|
||||
@@ -16,14 +19,14 @@ test("dashboardNavigation contains the expected sidebar routes in order", () =>
|
||||
assert.deepEqual(
|
||||
dashboardNavigation.map((item: NavigationItem) => [item.label, item.href]),
|
||||
[
|
||||
["Dashboard", "/dashboard"],
|
||||
["Campaigns", "/dashboard/campaigns"],
|
||||
["Übersicht", "/dashboard"],
|
||||
["Kampagnen", "/dashboard/campaigns"],
|
||||
["Leads", "/dashboard/leads"],
|
||||
["Audits", "/dashboard/audits"],
|
||||
["Outreach", "/dashboard/outreach"],
|
||||
["Review", "/dashboard/outreach"],
|
||||
["Analytics", "/dashboard/analytics"],
|
||||
["Blacklist", "/dashboard/blacklist"],
|
||||
["Settings", "/dashboard/settings"],
|
||||
["Sperrliste", "/dashboard/blacklist"],
|
||||
["Einstellungen", "/dashboard/settings"],
|
||||
],
|
||||
);
|
||||
});
|
||||
@@ -39,6 +42,102 @@ test("pipelineStages keep the first-screen workflow focused on pipeline overview
|
||||
);
|
||||
});
|
||||
|
||||
test("leadFunnelStages expose the agreed German funnel columns", () => {
|
||||
assert.deepEqual(
|
||||
leadFunnelStages.map((stage) => stage.title),
|
||||
[
|
||||
"Kontakt fehlt",
|
||||
"Audit bereit",
|
||||
"Freigabe offen",
|
||||
"Kontaktiert",
|
||||
"Follow-up",
|
||||
"Zurückgestellt",
|
||||
],
|
||||
);
|
||||
});
|
||||
|
||||
test("toLeadFunnelCard exposes scan data and derives missing contact next action", () => {
|
||||
const card = toLeadFunnelCard({
|
||||
id: "lead-1",
|
||||
companyName: "Malerbetrieb Klein",
|
||||
niche: "Maler",
|
||||
city: "Freiburg",
|
||||
postalCode: "79098",
|
||||
priority: "high",
|
||||
contactStatus: "missing_contact",
|
||||
blacklistStatus: "clear",
|
||||
});
|
||||
|
||||
assert.equal(card.stageId, "missing_contact");
|
||||
assert.equal(card.company, "Malerbetrieb Klein");
|
||||
assert.equal(card.niche, "Maler");
|
||||
assert.equal(card.location, "79098 Freiburg");
|
||||
assert.equal(card.priorityLabel, "Hoch");
|
||||
assert.equal(card.contactStatusLabel, "Kontakt fehlt");
|
||||
assert.equal(card.nextAction, "Kontaktquelle recherchieren");
|
||||
});
|
||||
|
||||
test("groupLeadFunnelCards derives review, follow-up, and deferred columns without schema migration", () => {
|
||||
const groups = groupLeadFunnelCards([
|
||||
{
|
||||
id: "lead-review",
|
||||
companyName: "Physio am Park",
|
||||
city: "Freiburg",
|
||||
priority: "medium",
|
||||
contactStatus: "outreach_ready",
|
||||
blacklistStatus: "clear",
|
||||
outreach: {
|
||||
approvalStatus: "draft",
|
||||
sendStatus: "not_sent",
|
||||
responseStatus: "none",
|
||||
salesStatus: "follow_up_planned",
|
||||
},
|
||||
},
|
||||
{
|
||||
id: "lead-follow-up",
|
||||
companyName: "Tischlerei Weber",
|
||||
city: "Emmendingen",
|
||||
priority: "medium",
|
||||
contactStatus: "contacted",
|
||||
blacklistStatus: "clear",
|
||||
outreach: {
|
||||
approvalStatus: "approved",
|
||||
sendStatus: "sent",
|
||||
responseStatus: "follow_up_needed",
|
||||
salesStatus: "follow_up_planned",
|
||||
},
|
||||
},
|
||||
{
|
||||
id: "lead-replied",
|
||||
companyName: "Salon Licht",
|
||||
city: "Freiburg",
|
||||
priority: "low",
|
||||
contactStatus: "replied",
|
||||
blacklistStatus: "clear",
|
||||
},
|
||||
{
|
||||
id: "lead-defer",
|
||||
companyName: "Cafe Morgen",
|
||||
city: "Basel",
|
||||
priority: "defer",
|
||||
contactStatus: "new",
|
||||
blacklistStatus: "clear",
|
||||
},
|
||||
]);
|
||||
|
||||
assert.deepEqual(
|
||||
groups.map((group) => [group.stage.id, group.cards.map((card) => card.id)]),
|
||||
[
|
||||
["missing_contact", []],
|
||||
["audit_ready", []],
|
||||
["review_open", ["lead-review"]],
|
||||
["contacted", ["lead-replied"]],
|
||||
["follow_up", ["lead-follow-up"]],
|
||||
["deferred", ["lead-defer"]],
|
||||
],
|
||||
);
|
||||
});
|
||||
|
||||
test("dashboardKpis and reviewQueue expose the above-the-fold dashboard summary", () => {
|
||||
assert.equal(dashboardKpis.length, 4);
|
||||
assert.equal(reviewQueue.length, 3);
|
||||
|
||||
Reference in New Issue
Block a user