/* Organiser dashboard + Create event flow */
const { useState } = React;
const OrganiserScreen = ({ tweaks, isMobile, nav }) => {
const currency = tweaks.currency || "INR";
const myEvents = [
{ id:"o1", title:"The Daily Standup — Saturday Special", status:"live", date:"14 Jun · 9 PM", venue:"Canvas Laugh Club", sold:182, capacity:240, revenue:91000 },
{ id:"o2", title:"Open Mic Night #47", status:"live", date:"17 Jun · 8 PM", venue:"Antisocial Khar", sold:46, capacity:80, revenue:13800 },
{ id:"o3", title:"Indie Soundcheck — June Edition", status:"draft", date:"22 Jun · 8 PM", venue:"BlueFROG", sold:0, capacity:300, revenue:0 },
{ id:"o4", title:"Standup Showcase #12", status:"past", date:"7 Jun · 9 PM", venue:"Canvas", sold:240, capacity:240, revenue:120000 },
];
const stats = [
{ v:"₹2.24L", l:"Last 30 days", trend:"+24%", up:true },
{ v:"428", l:"Tickets sold", trend:"+18%", up:true },
{ v:"4.8", l:"Avg rating", trend:"+0.2", up:true },
{ v:"73%", l:"Sell-through", trend:"-3%", up:false },
];
// Mini chart
const Spark = ({ pts, color="var(--primary)" }) => {
const max = Math.max(...pts), min = Math.min(...pts);
const w = 100, h = 30;
const path = pts.map((p,i) => `${i?"L":"M"} ${(i/(pts.length-1))*w} ${h - ((p-min)/(max-min || 1))*h}`).join(" ");
return ;
};
const StatusPill = ({ s }) => {
const cfg = { live: {c:"#10b981", l:"Live"}, draft:{c:"var(--ink-3)", l:"Draft"}, past:{c:"var(--ink-3)", l:"Past"} };
return ● {cfg[s].l} ;
};
return (
● Organiser dashboard
Eclipse Live Co.
4 events · 2 selling · Mumbai
nav("create")} className="btn btn-primary" style={{ padding:"10px 16px", fontSize:13, flexShrink:0, whiteSpace:"nowrap" }}>+ New event
{/* Stats */}
{stats.map(s => (
{s.l}
{s.v}
{s.up?"↑":"↓"} {s.trend}
Math.sin(i*0.7)*10 + i*2 + Math.random()*8)} color={s.up?"#10b981":"#ef4444"} />
))}
{/* Events table */}
Your events
{myEvents.map((e, i) => {
const pct = (e.sold / e.capacity) * 100;
return (
{e.title}
{e.date} · {e.venue}
{!isMobile && (
<>
Sold
{e.sold} / {e.capacity}
80?"#10b981":pct>50?"var(--primary)":"var(--accent)" }} />
Revenue
{fmtPrice(e.revenue, currency)}
7-day trend
Math.sin(j*0.5)*5 + j + Math.random()*3)} />
Manage
>
)}
{isMobile && (
{e.sold}/{e.capacity} · {fmtPrice(e.revenue, currency)}
Manage
)}
);
})}
{/* Insights */}
Audience
{[
{ l:"Bandra & Khar", v:34 },
{ l:"South Mumbai", v:26 },
{ l:"Andheri W", v:18 },
{ l:"Powai", v:12 },
{ l:"Other", v:10 },
].map(b => (
))}
Recent reviews
{[
{ n:"Riya K.", r:5, t:"Vibe was unreal, sound was crisp, will be back." },
{ n:"Sahil M.", r:5, t:"Best comedy night I've been to in months." },
{ n:"Tanya P.", r:4, t:"Great show, but parking was a nightmare." },
].map(r => (
{r.n}
{"★".repeat(r.r)}
"{r.t}"
))}
);
};
// ─── CREATE EVENT (multi-step) ────────────────────────────────
const CreateEventScreen = ({ tweaks, isMobile, nav }) => {
const [step, setStep] = useState(0);
const steps = ["Basics", "Venue & Date", "Tickets", "Publish"];
const [data, setData] = useState({
title: "Indie Soundcheck — June Edition",
cat: "Music",
venue: "BlueFROG, Lower Parel",
date: "22 Jun 2026",
time: "8 PM",
capacity: 300,
tiers: [{ name:"Early bird", price:799, qty:80 }, { name:"Standard", price:1199, qty:200 }],
});
const Field = ({ l, children }) => (
);
const inputCss = { width:"100%", padding:"12px 14px", background:"var(--surface)", border:"1px solid var(--line)", borderRadius:"var(--radius)", color:"var(--ink)", fontSize:14, outline:"none", fontFamily:"inherit" };
return (
nav("organiser")} style={{ fontSize:12, color:"var(--ink-3)", marginBottom:10, whiteSpace:"nowrap" }}>← Back to dashboard
Create event
{/* Steps */}
{steps.map((s, i) => {
const active = step === i, done = step > i;
return (
setStep(i)} style={{ flex: isMobile?"0 0 auto":1, padding:"10px 12px", background: active?"var(--ink)":done?"var(--surface)":"transparent", color: active?"var(--bg)":done?"var(--ink)":"var(--ink-3)", border:`1px solid ${active?"var(--ink)":done?"var(--line)":"var(--line)"}`, borderRadius:"var(--radius-sm)", display:"flex", alignItems:"center", gap:8, fontSize:12, fontWeight:600 }}>
{i+1}
{s}
{done && ✓ }
);
})}
{/* Form */}
{step === 0 && (
)}
{step === 1 && (
)}
{step === 2 && (
Pricing tiers
{data.tiers.map((t, i) => (
{const ts=[...data.tiers];ts[i].name=e.target.value;setData(d=>({...d,tiers:ts}))}} />
{const ts=[...data.tiers];ts[i].price=+e.target.value;setData(d=>({...d,tiers:ts}))}} />
{const ts=[...data.tiers];ts[i].qty=+e.target.value;setData(d=>({...d,tiers:ts}))}} />
setData(d=>({...d, tiers: d.tiers.filter((_,j)=>j!==i)}))} style={{ color:"var(--ink-3)" }}>×
))}
setData(d=>({...d, tiers:[...d.tiers, { name:"VIP", price:2499, qty:20 }]}))} className="btn btn-ghost" style={{ marginTop:6, padding:"8px 14px", fontSize:12 }}>+ Add tier
Estimated revenue at full sell-out
{fmtPrice(data.tiers.reduce((s,t)=>s+t.price*t.qty,0), tweaks.currency || "INR")}
)}
{step === 3 && (
✓ Looks good — ready to publish
{data.title}
{[
{ l:"Category", v:data.cat },
{ l:"Venue", v:data.venue },
{ l:"Date", v:`${data.date} · ${data.time}` },
{ l:"Capacity", v:`${data.capacity} (${data.tiers.reduce((s,t)=>s+t.qty,0)} sellable)` },
{ l:"Tiers", v: data.tiers.map(t=>`${t.name} ₹${t.price}`).join(" · ") },
{ l:"Status", v:"Will be live immediately" },
].map(f => (
))}
nav("organiser")} className="btn btn-primary" style={{ width:"100%", marginTop:20, padding:"12px", fontSize:14 }}>Publish event →
)}
{/* Nav buttons */}
{step < 3 && (
setStep(s=>Math.max(0,s-1))} className="btn btn-ghost" style={{ padding:"10px 16px", fontSize:13, opacity: step===0?0.4:1 }} disabled={step===0}>← Back
setStep(s=>s+1)} className="btn btn-primary" style={{ padding:"10px 18px", fontSize:13 }}>Continue →
)}
{/* Live preview */}
{!isMobile && (
Live preview
{data.cat}
{data.title}
{data.date} · {data.time}
{data.venue}
from ₹{Math.min(...data.tiers.map(t=>t.price))}
Book
)}
);
};
window.OrganiserScreen = OrganiserScreen;
window.CreateEventScreen = CreateEventScreen;