/* sema ikutoke Collections — Channels & Dashboard */
const { useState: useStateC, useEffect: useEffectC, useMemo: useMemoC, useRef: useRefC } = React;
/* ─── channel data ─── */
const CHANNELS = [
{
id: "wa",
name: "WhatsApp Business",
handle: "+254 712 003 421",
blurb: "The way most East African shoppers actually buy. Sync your collection to a WhatsApp catalog; buyers DM you and get a checkout link.",
status: "connected",
primary: true,
sales30: "KSh 184,200",
share: 47,
accent: "#1B8B53",
mark: "WA",
lastSync: "2 min ago",
},
{
id: "ig",
name: "Instagram Shop",
handle: "@kamau.studio",
blurb: "Tag products in posts and stories. Tap-to-buy in feed. Auto-sync from your sema ikutoke collection.",
status: "connected",
sales30: "KSh 58,800",
share: 15,
accent: "#E14118",
mark: "IG",
lastSync: "12 min ago",
},
{
id: "fb",
name: "Facebook Shop",
handle: "Kamau Studio",
blurb: "Discoverable in Facebook Shops & Marketplace. Same catalog, broader audience.",
status: "connected",
sales30: "KSh 14,400",
share: 4,
accent: "#0E2740",
mark: "FB",
lastSync: "1 hr ago",
},
{
id: "tt",
name: "TikTok Shop",
handle: "@kamau.studio",
blurb: "In-video product links. Live shopping. Beta in Kenya, Nigeria & Egypt.",
status: "needs-attention",
statusNote: "Verify business",
sales30: "—",
share: 0,
accent: "#161210",
mark: "TT",
lastSync: "Awaiting verification",
},
{
id: "jumia",
name: "Jumia",
handle: "Pending",
blurb: "Reach Jumia's marketplace shoppers. Manual approval per category (digital goods only).",
status: "available",
sales30: "—",
share: 0,
accent: "#F1582E",
mark: "JU",
lastSync: "Not connected",
},
{
id: "x",
name: "X (Twitter)",
handle: "@kamau.studio",
blurb: "Drop product cards in your replies. Buyers tap → STK push, no leaving timeline.",
status: "available",
sales30: "—",
share: 0,
accent: "#161210",
mark: "X",
lastSync: "Not connected",
},
{
id: "pin",
name: "Pinterest",
handle: "Pending",
blurb: "Rich product pins. Great for visual collections — photo books, presets, design templates.",
status: "available",
sales30: "—",
share: 0,
accent: "#C2421A",
mark: "PI",
lastSync: "Not connected",
},
{
id: "site",
name: "sema ikutoke site",
handle: "kamau.sema-ikutoke.so",
blurb: "Your home. The shell you built. Where the real catalog lives.",
status: "connected",
primary: false,
sales30: "KSh 130,400",
share: 34,
accent: "#5D2BD0",
mark: "RI",
lastSync: "Always live",
},
];
/* ═══════════════════════════════════════════════════════════════════════
CHANNELS view
═══════════════════════════════════════════════════════════════════════ */
function Channels({ goto }) {
const [focused, setFocused] = useStateC(null);
const channel = CHANNELS.find((c) => c.id === focused);
return (
§ 03 / Distribution
Sell where they already are .
sema ikutoke is your source of truth . Build your collection once — sync it to
WhatsApp, Instagram, Facebook, TikTok, anywhere your buyers spend time.
Every sale lands back in M-PESA.
{CHANNELS.map((c) => (
setFocused(c.id)} />
))}
01
One source.
Your collection in sema ikutoke. Edited once.
→
02
Many surfaces.
WhatsApp, IG, FB, TikTok, Jumia, X — automatic sync.
→
03
One inbox.
All sales settle into your M-PESA wallet. Receipts in one place.
{channel && (
setFocused(null)} goto={goto} />
)}
);
}
function ChannelCard({ channel, onOpen }) {
const c = channel;
const statusLabel = {
"connected": "● Connected",
"needs-attention": "▲ Action needed",
"available": "+ Connect",
}[c.status];
return (
{c.blurb}
{c.share > 0 && (
)}
);
}
function ChannelDrawer({ channel, onClose, goto }) {
const c = channel;
const [synced, setSynced] = useStateC(false);
const [syncing, setSyncing] = useStateC(false);
const doSync = () => {
setSyncing(true);
setTimeout(() => { setSyncing(false); setSynced(true); }, 1600);
};
return (
<>
×
{/* WhatsApp gets a chat preview */}
{c.id === "wa" && (
Hi, do you still have Field Notes Vol. 03?
Hi! Yes — here it is 👇
Field Notes Vol. 03
23 photos · 14 essays · 42 MB
KSh 1,200
Buy via M-PESA
Done — sent! 🎉
Buyers DM your business number. sema ikutoke's bot shares the catalog and sends a M-PESA STK link.
)}
▸ What gets synced
Collections
3 of 3 ▸ Field Notes, Quiet Pages, Embers
Inventory
Auto · digital · unlimited
Currency
KSh ▸ USD on request
Auto-republish
On · within 60s of edit
▸ Checkout behaviour
Payment
M-PESA · STK push (primary)
Fallback
Card · USD payouts
Delivery
Instant download · email + DM
{c.status !== "available" && (
SHARE OF SALES
{c.share}%
)}
{c.status === "available" ? (
Connect {c.name}
) : c.status === "needs-attention" ? (
Resolve · {c.statusNote}
) : (
<>
{syncing ? "Syncing…" : synced ? "✓ Synced just now" : "Sync now"}
goto("dashboard")}>View sales
>
)}
>
);
}
/* ═══════════════════════════════════════════════════════════════════════
DASHBOARD view
═══════════════════════════════════════════════════════════════════════ */
const SAMPLE_SALES = [
{ who: "Wambui K.", item: "Field Notes Vol. 03", amount: "1,200", channel: "WhatsApp", chMark: "WA", chColor: "#1B8B53", phone: "0712 *** 421" },
{ who: "Mutua O.", item: "Embers · Sample Pack", amount: "2,000", channel: "Instagram", chMark: "IG", chColor: "#E14118", phone: "0721 *** 008" },
{ who: "Achieng' P.", item: "Quiet Pages", amount: "1,200", channel: "sema ikutoke site", chMark: "RI", chColor: "#5D2BD0", phone: "0708 *** 552" },
{ who: "Otieno J.", item: "Field Notes Vol. 03", amount: "1,200", channel: "WhatsApp", chMark: "WA", chColor: "#1B8B53", phone: "0710 *** 014" },
{ who: "Naliaka B.", item: "Atelier 03", amount: "1,800", channel: "Facebook", chMark: "FB", chColor: "#0E2740", phone: "0733 *** 991" },
{ who: "Cheruiyot M.", item: "Field Notes Vol. 03", amount: "1,200", channel: "Instagram", chMark: "IG", chColor: "#E14118", phone: "0701 *** 244" },
{ who: "Wanjiku N.", item: "Embers · Sample Pack", amount: "2,000", channel: "WhatsApp", chMark: "WA", chColor: "#1B8B53", phone: "0719 *** 380" },
{ who: "Said H.", item: "Pasture & Light", amount: "2,400", channel: "sema ikutoke site", chMark: "RI", chColor: "#5D2BD0", phone: "0728 *** 117" },
];
function Dashboard({ goto }) {
const [feed, setFeed] = useStateC([SAMPLE_SALES[0], SAMPLE_SALES[1], SAMPLE_SALES[2]]);
const [revenue, setRevenue] = useStateC(46280);
const [count, setCount] = useStateC(38);
// Simulated incoming sales
useEffectC(() => {
const tick = setInterval(() => {
const next = SAMPLE_SALES[Math.floor(Math.random() * SAMPLE_SALES.length)];
const justNow = { ...next, id: Date.now(), justArrived: true };
setFeed((f) => [justNow, ...f].slice(0, 8));
setRevenue((r) => r + parseInt(next.amount.replace(/,/g, ""), 10));
setCount((c) => c + 1);
}, 4200);
return () => clearInterval(tick);
}, []);
return (
WORKSPACE
K
Kamau Studio
· kamau.sema-ikutoke.so
● 4 channels live
goto("channels")}>Manage channels
goto("builder")}>Edit collection
{/* KPI strip */}
Today
KSh {revenue.toLocaleString()}
▲ 23% vs yesterday
Sales today
{count}
{count > 30 ? "Best day this week" : "Solid pace"}
Avg. STK approval
11.2s
98.4% approval rate
In M-PESA wallet
KSh 184k
{/* Main grid */}
{/* Sales feed */}
§ Live feed
Sales as they happen.
● live
{feed.map((s, i) => (
{s.chMark}
{s.who}
{s.phone}
bought {s.item} via {s.channel}
))}
{/* Channel split */}
§ By channel
Where they're buying.
{[
{ name: "WhatsApp", pct: 47, color: "#1B8B53" },
{ name: "sema ikutoke site", pct: 34, color: "#5D2BD0" },
{ name: "Instagram", pct: 15, color: "#E14118" },
{ name: "Facebook", pct: 4, color: "#0E2740" },
].map((r) => (
))}
goto("channels")}>
Manage channels →
{/* Top collections */}
§ Top this week
Best sellers.
{[
{ name: "Field Notes Vol. 03", count: 84, rev: "100,800", g: "linear-gradient(135deg, #E14118, #14110D)" },
{ name: "Embers · Sample Pack", count: 41, rev: "82,000", g: "linear-gradient(135deg, #F1582E, #1B1410)" },
{ name: "Pasture & Light", count: 22, rev: "52,800", g: "linear-gradient(135deg, #1B8B53, #F1E8D1)" },
{ name: "Quiet Pages", count: 64, rev: "0 (free)", g: "linear-gradient(135deg, #5D2BD0, #F4DCD2)" },
].map((t, i) => (
))}
{/* Recent buyers map / list */}
§ Buyers
Who showed up this week.
Export CSV
{[
{ name: "Wambui K.", city: "Nairobi", first: true, count: 1, total: "1,200" },
{ name: "Mutua O.", city: "Mombasa", first: false, count: 3, total: "5,400" },
{ name: "Achieng' P.", city: "Kisumu", first: true, count: 1, total: "1,200" },
{ name: "Otieno J.", city: "Nairobi", first: false, count: 2, total: "2,400" },
{ name: "Naliaka B.", city: "Eldoret", first: true, count: 1, total: "1,800" },
{ name: "Cheruiyot M.", city: "Nakuru", first: true, count: 1, total: "1,200" },
{ name: "Wanjiku N.", city: "Thika", first: false, count: 4, total: "8,000" },
{ name: "Said H.", city: "Mombasa", first: true, count: 1, total: "2,400" },
].map((b, i) => (
{b.name[0]}
{b.name}
{b.city} {b.first && FIRST }
{b.count}× · KSh {b.total}
))}
);
}
Object.assign(window, { Channels, Dashboard, CHANNELS });