import React, { useState, useEffect, useMemo } from "react"; import { BarChart, Bar, XAxis, YAxis, CartesianGrid, Tooltip, ResponsiveContainer, PieChart, Pie, Cell, LineChart, Line } from "recharts"; import { Rocket, Globe2, Radio, Package, Plus, Trash2, Orbit, ChevronDown, Check, X } from "lucide-react"; const FONT_IMPORT = `@import url('https://fonts.googleapis.com/css2?family=Fraunces:opsz,wght@9..144,400;9..144,600&family=Inter:wght@400;500;600&family=IBM+Plex+Mono:wght@400;500;600&display=swap');`; const COLORS = { navy: "#0F1329", navyDeep: "#0A0D1E", parchment: "#F6F1E4", parchmentDim: "#EDE6D3", gold: "#C9A24B", goldDim: "#8F773A", teal: "#4FA9A0", rose: "#B5654F", ink: "#1B1F33", starlight: "#EDE7D3", }; const REQUEST_TYPES = ["Curriculum Kit", "Workshop", "Summer Camp", "Chapter Partnership", "Speaking/Media"]; const STATUSES = ["New", "In Review", "Approved", "Fulfilled", "Declined"]; const STATUS_COLOR = { New: COLORS.teal, "In Review": COLORS.gold, Approved: "#6B8FB0", Fulfilled: "#7BAE7F", Declined: COLORS.rose }; const FORMATS = ["Digital", "Physical", "Book"]; const uid = () => Math.random().toString(36).slice(2, 10); const todayStr = () => new Date().toISOString().slice(0, 10); const SEED = { reach: [ { id: uid(), country: "United States", studentsReached: 208000, schoolsPartnered: 340, lastUpdated: "2026-06-01" }, { id: uid(), country: "India", studentsReached: 28000, schoolsPartnered: 41, lastUpdated: "2026-05-15" }, { id: uid(), country: "Canada", studentsReached: 9200, schoolsPartnered: 16, lastUpdated: "2026-05-20" }, { id: uid(), country: "Philippines", studentsReached: 6400, schoolsPartnered: 12, lastUpdated: "2026-04-28" }, { id: uid(), country: "South Korea", studentsReached: 4300, schoolsPartnered: 9, lastUpdated: "2026-04-10" }, { id: uid(), country: "Vietnam", studentsReached: 3100, schoolsPartnered: 7, lastUpdated: "2026-03-30" }, { id: uid(), country: "Mexico", studentsReached: 1300, schoolsPartnered: 4, lastUpdated: "2026-03-12" }, ], requests: [ { id: uid(), date: "2026-06-20", org: "Lincoln Middle School", country: "United States", type: "Curriculum Kit", students: 300, status: "Fulfilled", lowIncome: true, notes: "Requested after Kelly Clarkson Show feature." }, { id: uid(), date: "2026-06-25", org: "Delhi Public School Network", country: "India", type: "Summer Camp", students: 1200, status: "In Review", lowIncome: true, notes: "Multi-campus rollout, needs translated kits." }, { id: uid(), date: "2026-06-27", org: "Toronto STEM Collective", country: "Canada", type: "Workshop", students: 150, status: "Approved", lowIncome: false, notes: "" }, { id: uid(), date: "2026-07-01", org: "Cebu Youth Foundation", country: "Philippines", type: "Chapter Partnership", students: 500, status: "New", lowIncome: true, notes: "Wants to start a local chapter." }, { id: uid(), date: "2026-07-03", org: "Local News Network", country: "United States", type: "Speaking/Media", students: 0, status: "New", lowIncome: false, notes: "Interview request re: growth." }, ], engagement: [ { id: uid(), program: "Target Tutors", date: "2026-05-01", participants: 85, sessions: 20, satisfaction: 4.6, completionRate: 78 }, { id: uid(), program: "Math Open at West Ranch", date: "2026-04-12", participants: 140, sessions: 1, satisfaction: 4.8, completionRate: 96 }, { id: uid(), program: "Chapter Workshops (Global)", date: "2026-06-01", participants: 2100, sessions: 34, satisfaction: 4.4, completionRate: 71 }, { id: uid(), program: "Roots & Rhetoric", date: "2026-05-15", participants: 40, sessions: 8, satisfaction: 4.7, completionRate: 88 }, ], curriculum: [ { id: uid(), date: "2026-06-10", kit: "DIY Space Kit v2", format: "Physical", country: "United States", copies: 900, org: "Regional School District" }, { id: uid(), kit: "Astrophysics Explainer Series", date: "2026-06-15", format: "Digital", country: "India", copies: 5200, org: "Delhi Public School Network" }, { id: uid(), kit: "GalaxSea Starter Book", date: "2026-05-05", format: "Book", country: "Philippines", copies: 350, org: "Cebu Youth Foundation" }, { id: uid(), kit: "DIY Space Kit v2", date: "2026-06-22", format: "Physical", country: "Canada", copies: 150, org: "Toronto STEM Collective" }, ], }; function useStore(key, seed) { const [data, setData] = useState(seed); const [loaded, setLoaded] = useState(false); useEffect(() => { let cancelled = false; (async () => { try { const res = await window.storage.get(key, true); if (!cancelled && res && res.value) setData(JSON.parse(res.value)); } catch (e) { // key doesn't exist yet — seed it try { await window.storage.set(key, JSON.stringify(seed), true); } catch (_) {} } finally { if (!cancelled) setLoaded(true); } })(); return () => { cancelled = true; }; }, [key]); const persist = async (next) => { setData(next); try { await window.storage.set(key, JSON.stringify(next), true); } catch (e) { console.error("save failed", e); } }; return [data, persist, loaded]; } function Ring({ value, max, label, sub, color, icon: Icon }) { const pct = Math.max(0, Math.min(1, max ? value / max : 0)); const r = 42, c = 2 * Math.PI * r; return (
{Array.from({ length: 36 }).map((_, i) => { const a = (i / 36) * 2 * Math.PI; const x1 = 52 + (r + 4) * Math.cos(a), y1 = 52 + (r + 4) * Math.sin(a); const x2 = 52 + (r + (i % 3 === 0 ? 8 : 6)) * Math.cos(a), y2 = 52 + (r + (i % 3 === 0 ? 8 : 6)) * Math.sin(a); return ; })}
{value}
{label}
{sub}
); } function SectionCard({ children }) { return (
{children}
); } function TabButton({ active, onClick, icon: Icon, children }) { return ( ); } function Field({ label, children }) { return ( ); } const inputStyle = { padding: "7px 10px", borderRadius: 6, border: "1px solid #d9d0b8", background: "#FFFDF7", fontFamily: "'Inter', sans-serif", fontSize: 13.5, color: COLORS.ink, outline: "none", }; function Th({ children }) { return {children}; } function Td({ children, mono }) { return {children}; } function StatusPill({ status }) { const color = STATUS_COLOR[status] || "#999"; return {status}; } function DeleteButton({ onDelete, label }) { const [confirming, setConfirming] = useState(false); if (confirming) { return (
Remove?
); } return ( ); } export default function GalaxSeaTracker() { const [reach, setReach, reachLoaded] = useStore("galaxsea:reach", SEED.reach); const [requests, setRequests, reqLoaded] = useStore("galaxsea:requests", SEED.requests); const [engagement, setEngagement, engLoaded] = useStore("galaxsea:engagement", SEED.engagement); const [curriculum, setCurriculum, curLoaded] = useStore("galaxsea:curriculum", SEED.curriculum); const [tab, setTab] = useState("overview"); const allLoaded = reachLoaded && reqLoaded && engLoaded && curLoaded; const totals = useMemo(() => ({ students: reach.reduce((s, r) => s + Number(r.studentsReached || 0), 0), countries: reach.length, activeRequests: requests.filter(r => ["New", "In Review", "Approved"].includes(r.status)).length, kits: curriculum.reduce((s, c) => s + Number(c.copies || 0), 0), }), [reach, requests, curriculum]); const statusBreakdown = useMemo(() => { const map = {}; STATUSES.forEach(s => map[s] = 0); requests.forEach(r => { map[r.status] = (map[r.status] || 0) + 1; }); return STATUSES.map(s => ({ name: s, value: map[s] })).filter(d => d.value > 0); }, [requests]); const formatBreakdown = useMemo(() => { const map = {}; FORMATS.forEach(f => map[f] = 0); curriculum.forEach(c => { map[c.format] = (map[c.format] || 0) + Number(c.copies || 0); }); return FORMATS.map(f => ({ name: f, value: map[f] })); }, [curriculum]); const reachSorted = useMemo(() => [...reach].sort((a, b) => b.studentsReached - a.studentsReached), [reach]); return (
{/* Header */}
GalaxSea Explorers

Impact Tracking Log

A running record of reach, requests, engagement, and curriculum distribution — charted like a mission log.

{allLoaded ? "LOG SYNCED — SHARED WORKSPACE" : "LOADING LOG…"}
{/* KPI Rings */}
{/* Tabs */}
setTab("overview")} icon={Orbit}>Overview setTab("requests")} icon={Radio}>Outreach Requests setTab("reach")} icon={Globe2}>Reach & Demographics setTab("engagement")} icon={Rocket}>Engagement setTab("curriculum")} icon={Package}>Curriculum Distribution
{tab === "overview" && } {tab === "requests" && } {tab === "reach" && } {tab === "engagement" && } {tab === "curriculum" && }
); } function Overview({ reachSorted, statusBreakdown, formatBreakdown, engagement }) { const pieColors = [COLORS.teal, COLORS.gold, "#6B8FB0", "#7BAE7F", COLORS.rose]; return (

Reach by Country

Students reached, ranked — the star catalog of program reach.

v.toLocaleString()} />

Request Status

Where incoming outreach requests stand.

{statusBreakdown.map((_, i) => )}
{statusBreakdown.map((d, i) => (
{d.name} ({d.value})
))}

Engagement — Participants by Program

Curriculum by Format

); } function AddRow({ onAdd, children }) { const [open, setOpen] = useState(false); return (
{open &&
{children(() => setOpen(false))}
}
); } function RequestsPanel({ requests, setRequests }) { const [filterStatus, setFilterStatus] = useState("All"); const [form, setForm] = useState({ date: todayStr(), org: "", country: "", type: REQUEST_TYPES[0], students: 0, status: "New", lowIncome: false, notes: "" }); const filtered = filterStatus === "All" ? requests : requests.filter(r => r.status === filterStatus); const submit = (close) => { if (!form.org || !form.country) return; setRequests([{ ...form, id: uid(), students: Number(form.students) || 0 }, ...requests]); setForm({ date: todayStr(), org: "", country: "", type: REQUEST_TYPES[0], students: 0, status: "New", lowIncome: false, notes: "" }); close(); }; const remove = (id) => setRequests(requests.filter(r => r.id !== id)); return (

Outreach Requests

{filtered.map(r => ( ))} {filtered.length === 0 && }
DateOrganizationCountryTypeStudentsStatusLow-Income
{r.date}{r.org}{r.country}{r.type} {Number(r.students).toLocaleString()} {r.lowIncome ? "Yes" : "—"} remove(r.id)} label={r.org} />
No requests logged for this status yet.
{(close) => (
setForm({ ...form, date: e.target.value })} /> setForm({ ...form, org: e.target.value })} placeholder="School / partner name" /> setForm({ ...form, country: e.target.value })} /> setForm({ ...form, students: e.target.value })} /> setForm({ ...form, notes: e.target.value })} />
)}
); } function ReachPanel({ reach, setReach }) { const [form, setForm] = useState({ country: "", studentsReached: 0, schoolsPartnered: 0, lastUpdated: todayStr() }); const submit = (close) => { if (!form.country) return; setReach([...reach, { ...form, id: uid(), studentsReached: Number(form.studentsReached) || 0, schoolsPartnered: Number(form.schoolsPartnered) || 0 }]); setForm({ country: "", studentsReached: 0, schoolsPartnered: 0, lastUpdated: todayStr() }); close(); }; const remove = (id) => setReach(reach.filter(r => r.id !== id)); return (

Reach & Demographics

{reach.map(r => ( ))}
CountryStudents ReachedSchools PartneredLast Updated
{r.country}{Number(r.studentsReached).toLocaleString()}{r.schoolsPartnered}{r.lastUpdated} remove(r.id)} label={r.country} />
{(close) => (
setForm({ ...form, country: e.target.value })} /> setForm({ ...form, studentsReached: e.target.value })} /> setForm({ ...form, schoolsPartnered: e.target.value })} /> setForm({ ...form, lastUpdated: e.target.value })} />
)}
); } function EngagementPanel({ engagement, setEngagement }) { const [form, setForm] = useState({ program: "", date: todayStr(), participants: 0, sessions: 0, satisfaction: 4.5, completionRate: 80 }); const submit = (close) => { if (!form.program) return; setEngagement([...engagement, { ...form, id: uid(), participants: Number(form.participants) || 0, sessions: Number(form.sessions) || 0, satisfaction: Number(form.satisfaction) || 0, completionRate: Number(form.completionRate) || 0 }]); setForm({ program: "", date: todayStr(), participants: 0, sessions: 0, satisfaction: 4.5, completionRate: 80 }); close(); }; const remove = (id) => setEngagement(engagement.filter(r => r.id !== id)); return (

Engagement

{engagement.map(r => ( ))}
ProgramDateParticipantsSessionsSatisfactionCompletion %
{r.program}{r.date}{r.participants}{r.sessions} {r.satisfaction}/5{r.completionRate}% remove(r.id)} label={r.program} />
{(close) => (
setForm({ ...form, program: e.target.value })} /> setForm({ ...form, date: e.target.value })} /> setForm({ ...form, participants: e.target.value })} /> setForm({ ...form, sessions: e.target.value })} /> setForm({ ...form, satisfaction: e.target.value })} /> setForm({ ...form, completionRate: e.target.value })} />
)}
); } function CurriculumPanel({ curriculum, setCurriculum }) { const [form, setForm] = useState({ kit: "", date: todayStr(), format: FORMATS[0], country: "", copies: 0, org: "" }); const submit = (close) => { if (!form.kit || !form.country) return; setCurriculum([...curriculum, { ...form, id: uid(), copies: Number(form.copies) || 0 }]); setForm({ kit: "", date: todayStr(), format: FORMATS[0], country: "", copies: 0, org: "" }); close(); }; const remove = (id) => setCurriculum(curriculum.filter(r => r.id !== id)); return (

Curriculum Distribution

{curriculum.map(r => ( ))}
Kit / MaterialDateFormatCountryCopiesRecipient Org
{r.kit}{r.date}{r.format}{r.country} {Number(r.copies).toLocaleString()}{r.org} remove(r.id)} label={r.kit} />
{(close) => (
setForm({ ...form, kit: e.target.value })} /> setForm({ ...form, date: e.target.value })} /> setForm({ ...form, country: e.target.value })} /> setForm({ ...form, copies: e.target.value })} /> setForm({ ...form, org: e.target.value })} />
)}
); }