/* =============================================================
* Forge Dashboard — interactive Uganda map, member dashboard, progress
* ============================================================= */
function ForgeDashboard() {
const [groups, setGroups] = useState([]);
const [goal, setGoal] = useState({ current: 82, target: 1000 });
const [selected, setSelected] = useState(null);
const [filter, setFilter] = useState("all");
const [loaded, setLoaded] = useState(false);
useEffect(() => {
Promise.all([window.cms.getForgeGroups(), window.cms.getForgeGoal()]).then(([g, goal]) => {
setGroups(g);
setGoal(goal);
setLoaded(true);
}).catch(() => setLoaded(true));
}, []);
const filtered = filter === "all" ? groups : groups.filter((g) => g.status === filter);
const totalMembers = groups.reduce((s, g) => s + g.members, 0);
return (
{/* Stat strip */}
{[
{ label: "Active Forge groups", value: goal.current, suffix: "" },
{ label: "Men meeting weekly", value: totalMembers, suffix: "" },
{ label: "Districts engaged", value: 11, suffix: "" },
{ label: "Goal", value: goal.target, suffix: "" },
].map((s, i) => (
))}
{/* Map + side panel */}
Forge groups across Uganda
{[["all", "All"], ["active", "Active"], ["growing", "Growing"]].map(([k, l]) => (
))}
);
}
function ForgeDetail({ group, onClose }) {
// Rotate through real Forge photos by group id so each Forge feels unique
const groupPhotos = [
"uploads/Forge 1-104.jpg",
"uploads/forge meeting event section.jpg",
"uploads/FATHERS ARISE MEETING-49 (1).jpg",
"uploads/FATHERS ARISE MEETING-66.jpg",
"uploads/FATHERS ARISE MEETING-79.jpg",
"uploads/TRG_Father_sBreakfast125.jpg"
];
const photo = groupPhotos[(group.id?.charCodeAt(0) || 0) % groupPhotos.length];
return (
{group.region}
{group.name}
- Members
- {group.members} men
- Meeting
- Tue · 7pm
- Status
- {group.status}
- Curriculum
- Be a Man · wk 7
);
}
/* ----- Uganda map (placeholder polygon) ----- */
function UgandaMap({ groups, selected, onSelect, loaded }) {
// Stylised Uganda outline. Hand-drawn approximation; a real map ships from the CMS.
const ugandaPath = "M 22 18 Q 30 12 42 14 L 58 14 Q 68 18 72 22 L 80 22 L 84 28 L 82 36 L 86 44 Q 86 52 82 58 L 78 64 Q 76 70 72 74 L 64 82 Q 54 86 44 82 L 30 80 Q 22 74 18 66 L 16 56 Q 12 48 16 40 L 18 30 Q 18 22 22 18 Z";
return (
Uganda · Forge network
{groups.length} groups shown
{/* Legend */}
Active
Growing
map · placeholder geometry
);
}
/* ----- Member dashboard ----- */
function MemberDashboard() {
const [tab, setTab] = useState("login");
const [signedIn, setSignedIn] = useState(false);
return (
{!signedIn ? (
{[["login", "Sign in"], ["join", "Join a Forge"]].map(([k, l]) => (
))}
{tab === "login" ? (
) : (
setSignedIn(true)} />
)}
) : (
Welcome
Joseph K.
Forge Wakiso · Be a Man · Week 7 of 12
)}
Next meeting
Tue · 7:00pm
Forge Wakiso · Pastor Mukasa's home
- Week 8: Repentance as a daily practice
- Bring: your journal & a story
);
}
function ProgressRing({ label, value, max, color }) {
const pct = (value / max) || 0;
const r = 44, c = 2 * Math.PI * r;
const [ref, inView] = useInView();
return (
In progress
{label}
{Math.round(pct * 100)}% complete
);
}
function StepIndicator({ label, filled, total }) {
return (
{label}
{Array.from({ length: total }).map((_, i) => (
{i < filled ? "✓" : i + 1}
))}
{filled} of {total} weeks attended
);
}
function JoinForgeForm({ onComplete }) {
const [form, setForm] = useState({ name: "", phone: "", region: "", commit: false });
const [err, setErr] = useState({});
const submit = (e) => {
e.preventDefault();
const errs = {};
if (!form.name.trim()) errs.name = "Required";
if (!/^[+0-9 -]{7,}$/.test(form.phone)) errs.phone = "Enter a valid phone";
if (!form.region) errs.region = "Pick a region";
if (!form.commit) errs.commit = "Confirm the weekly commitment";
setErr(errs);
if (Object.keys(errs).length === 0) onComplete();
};
const set = (k) => (e) => setForm({ ...form, [k]: e.target.type === "checkbox" ? e.target.checked : e.target.value });
return (
);
}
window.ForgeDashboard = ForgeDashboard;