Live preview
Tap a stat tile to filter, type into the search bar, or click "View profile" on any card to open the detail sheet.
$segment = "all"
$query = ""
$selected = ""
$contacts = [
{id: "naomi",
name: "Naomi Rivers",
role: "VP Engineering · Looplog",
avatar: "https://i.pravatar.cc/120?img=47",
bio: "Built Looplog from 0 → 1.2M sessions/day. Owns the Q3 expansion deal.",
segment: "champions",
tags: ["champion", "enterprise"],
company: "Looplog · 240 seats",
owner: "Mei Tanaka",
arr: "$84,000",
renewal: "Q3 · Sep 14"},
{id: "marc",
name: "Marc Lee",
role: "Head of Data · Northwind",
avatar: "https://i.pravatar.cc/120?img=11",
bio: "Renewing in 14 days. Wants a custom dashboard demo before signing.",
segment: "customers",
tags: ["renewal", "data"],
company: "Northwind · 120 seats",
owner: "Naomi Rivers",
arr: "$56,000",
renewal: "Q2 · Jun 02"},
{id: "grace",
name: "Grace Hopper",
role: "Founder · Atlasworks",
avatar: "https://i.pravatar.cc/120?img=32",
bio: "Just upgraded to Scale. Asked about SSO + audit logs.",
segment: "champions",
tags: ["scale", "sso"],
company: "Atlasworks · 80 seats",
owner: "Naomi Rivers",
arr: "$42,000",
renewal: "Q1 · Mar 18"},
{id: "linus",
name: "Linus Torvalds",
role: "Staff Eng · Kernelist",
avatar: "https://i.pravatar.cc/120?img=12",
bio: "Trial expires Friday. Hands-on with the JavaScript interactions feature.",
segment: "prospects",
tags: ["trial", "perf"],
company: "Kernelist",
owner: "Sam Reyes",
arr: "$0 (trial)",
renewal: "—"},
{id: "ada",
name: "Ada Lovelace",
role: "CTO · Compute Lab",
avatar: "https://i.pravatar.cc/120?img=20",
bio: "Pilot signed. Needs onboarding for 12 engineers in two weeks.",
segment: "customers",
tags: ["onboarding", "enterprise"],
company: "Compute Lab · 12 seats",
owner: "Mei Tanaka",
arr: "$24,000",
renewal: "Q4 · Dec 08"},
{id: "mei",
name: "Mei Tanaka",
role: "Eng lead · Atlasworks",
avatar: "https://i.pravatar.cc/120?img=14",
bio: "Open question on theming for a customer-facing portal.",
segment: "champions",
tags: ["theming", "champion"],
company: "Atlasworks · 80 seats",
owner: "Naomi Rivers",
arr: "$42,000",
renewal: "Q1 · Mar 18"},
{id: "sam",
name: "Sam Reyes",
role: "Architect · Northwind",
avatar: "https://i.pravatar.cc/120?img=15",
bio: "Quiet for 30 days. Worth a check-in before the QBR.",
segment: "at-risk",
tags: ["at-risk", "qbr"],
company: "Northwind · 120 seats",
owner: "Naomi Rivers",
arr: "$56,000",
renewal: "Q2 · Jun 02"},
{id: "jordan",
name: "Jordan Patel",
role: "Founder · Looplog",
avatar: "https://i.pravatar.cc/120?img=22",
bio: "References us in their public roadmap. Great expansion candidate.",
segment: "champions",
tags: ["champion", "advocacy"],
company: "Looplog · 240 seats",
owner: "Mei Tanaka",
arr: "$84,000",
renewal: "Q3 · Sep 14"}
]
segmentRows = $segment == "all" ? $contacts : @Filter($contacts, "segment", "==", $segment)
visibleRows = $query == "" ? segmentRows : @Filter(segmentRows, "name", "contains", $query)
visibleCount = @Count(visibleRows)
totalCount = @Count($contacts)
searchBar = SearchBar("crm-q", "Search contacts by name…", $query, "/")
segments = ToggleGroup("segment", [
{value: "all", label: "All", icon: "users"},
{value: "customers", label: "Customers", icon: "handshake"},
{value: "prospects", label: "Prospects", icon: "seedling"},
{value: "champions", label: "Champions", icon: "trophy"},
{value: "at-risk", label: "At-risk", icon: "triangle-exclamation"}
], $segment)
statTiles = Grid([
Tile("Total contacts", "users", "2,481", "+128 this week", "primary", Action([@Set($segment, "all")])),
Tile("Active deals", "briefcase", "47", "$418k ARR pipeline", "info", Action([@Set($segment, "customers")])),
Tile("At-risk accounts", "triangle-exclamation", "12", "Needs follow-up this week", "warning", Action([@Set($segment, "at-risk")])),
Tile("Champions", "trophy", "63", "NPS 9 or 10 in last 30d", "success", Action([@Set($segment, "champions")]))
], 4, "m")
filterRow = Stack([
searchBar,
segments
], "column", "m")
emptyResults = EmptyState(
"No contacts match",
"Adjust the segment or clear the search to see more results.",
"magnifying-glass",
Button("Reset filters",
Action([@Set($segment, "all"), @Reset($query)]),
"secondary")
)
contactGrid = Grid(
@Each(visibleRows, "c",
ProfileCard(
c.name,
c.role,
c.avatar,
c.bio,
c.tags,
[Button("View profile",
Action([@Set($selected, c.id)]),
"secondary",
"button",
"small")]
)
),
4, "m"
)
cards = visibleCount == 0 ? emptyResults : contactGrid
selected = @First(@Filter($contacts, "id", "==", $selected))
selectedExists = @Count(@Filter($contacts, "id", "==", $selected))
detailGeneric = EmptyState("Profile not loaded",
"Pick a contact card on the left to see their details here.",
"user",
null)
detailLoaded = Stack([
PersonChip(selected.name, selected.role, selected.avatar, "lg", "online"),
DescriptionList([
DescriptionItem("Company", selected.company),
DescriptionItem("Owner", selected.owner),
DescriptionItem("ARR", selected.arr),
DescriptionItem("Renewal", selected.renewal)
]),
Note(selected.bio, "info"),
Quote("Streaming-ui-script took our recap email from 4k lines of glue to 40.",
selected.name + " · last QBR",
"primary"),
Stack(
@Each(selected.tags, "t", Tag(t, null, "sm", "info")),
"row", "s"
)
], "column", "m")
detailBody = selectedExists == 0 ? detailGeneric : detailLoaded
detailSheet = Sheet(
"Contact detail",
$selected != "",
[detailBody],
"right",
[Buttons([
Button("Close",
Action([@Set($selected, "")]),
"secondary"),
Button("Open in CRM",
Action([@ToAssistant("Open " + $selected + " in the CRM")]),
"primary")
])]
)
resultSummary = TextContent(
"Showing " + visibleCount + " of " + totalCount + " contacts" + ($query == "" ? "" : (" · matching \"" + $query + "\"")),
"small",
"muted"
)
root = Stack([
PageHeader(
"Contacts",
"2,481 contacts · 12 at-risk",
null,
[Button("New contact",
Action([@ToAssistant("Open the new-contact form")]),
"primary")],
Badge("CRM v3.1", "info")
),
statTiles,
filterRow,
resultSummary,
cards,
detailSheet
], "column", "l")