import { useState, useRef } from "react"; // ─── CONSTANTS ──────────────────────────────────────────────────────────────── const USERS = [ { id: 0, name: "Manager", role: "manager", avatar: "MG", pin: "0000", color: "#111827" }, { id: 1, name: "Asha Mensah", role: "employee", avatar: "AM", pin: "1111", color: "#6366f1", trustBattery: 87, handle: "@brand_asha" }, { id: 2, name: "Jordan Blake", role: "employee", avatar: "JB", pin: "2222", color: "#0891b2", trustBattery: 62, handle: "@brand_jordan" }, { id: 3, name: "Priya Nair", role: "employee", avatar: "PN", pin: "3333", color: "#059669", trustBattery: 95, handle: "@brand_priya" }, ]; const TASKS = [ { label: "Content Creation", icon: "✏️", points: 5 }, { label: "Content Scheduling", icon: "📅", points: 2 }, { label: "Community Engagement", icon: "💬", points: 3 }, { label: "Reporting & Analytics", icon: "📊", points: 2 }, { label: "Inbox Management", icon: "📥", points: 1 }, { label: "Ad Campaign Management", icon: "📣", points: 4 }, { label: "Strategy", icon: "🧠", points: 5 }, { label: "Research", icon: "🔍", points: 4 }, { label: "Brand Development", icon: "🎨", points: 5 }, { label: "Competitor Analysis", icon: "🔭", points: 4 }, ]; const SAMPLE_HISTORY = { 1: [ { date: "Mon", points: 8, status: "verified", trustDelta: 5 }, { date: "Tue", points: 10, status: "verified", trustDelta: 6 }, { date: "Wed", points: 6, status: "flagged", trustDelta: -3 }, { date: "Thu", points: 9, status: "verified", trustDelta: 5 }, { date: "Fri", points: 0, status: "pending", trustDelta: 0 }, ], 2: [ { date: "Mon", points: 6, status: "verified", trustDelta: 3 }, { date: "Tue", points: 4, status: "flagged", trustDelta: -5 }, { date: "Wed", points: 7, status: "verified", trustDelta: 4 }, { date: "Thu", points: 5, status: "flagged", trustDelta: -4 }, { date: "Fri", points: 0, status: "pending", trustDelta: 0 }, ], 3: [ { date: "Mon", points: 10, status: "verified", trustDelta: 6 }, { date: "Tue", points: 12, status: "verified", trustDelta: 7 }, { date: "Wed", points: 9, status: "verified", trustDelta: 5 }, { date: "Thu", points: 11, status: "verified", trustDelta: 6 }, { date: "Fri", points: 0, status: "pending", trustDelta: 0 }, ], }; // ─── UTILS ──────────────────────────────────────────────────────────────────── const batteryColor = v => v >= 80 ? "#059669" : v >= 55 ? "#d97706" : "#dc2626"; const batteryLabel = v => v >= 80 ? "Elite" : v >= 55 ? "Solid" : "At risk"; const getHour = () => new Date().getHours(); const isPlanOpen = () => getHour() < 16; // 4 PM cutoff (test mode) const isFriday = () => new Date().getDay() === 5; async function callGemini(apiKey, prompt) { const res = await fetch( `https://generativelanguage.googleapis.com/v1beta/models/gemini-1.5-flash:generateContent?key=${apiKey}`, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ contents: [{ parts: [{ text: prompt }] }], generationConfig: { temperature: 0.7, maxOutputTokens: 500 }, }), } ); if (!res.ok) throw new Error("API error " + res.status); const d = await res.json(); return d.candidates?.[0]?.content?.parts?.[0]?.text || ""; } // ─── SHARED UI ──────────────────────────────────────────────────────────────── function Avatar({ initials, size = 40, color = "#6366f1" }) { return (
{initials}
); } function Pill({ children, color = "#6366f1", bg }) { return {children}; } function Card({ children, style, onClick }) { return (
{ if (onClick) e.currentTarget.style.boxShadow = "0 4px 16px rgba(0,0,0,0.1)"; }} onMouseLeave={e => { if (onClick) e.currentTarget.style.boxShadow = "0 1px 4px rgba(0,0,0,0.06)"; }} >{children}
); } function Spinner() { return (
Analysing with Gemini...
); } function TrustBar({ value }) { const color = batteryColor(value); return (
Trust Battery {batteryLabel(value)}
{value}%
); } // ─── SETUP ──────────────────────────────────────────────────────────────────── function SetupScreen({ onDone }) { const [key, setKey] = useState(""); const [testing, setTesting] = useState(false); const [result, setResult] = useState(null); async function test() { setTesting(true); setResult(null); try { await callGemini(key, "Reply with just: OK"); setResult("ok"); } catch { setResult("fail"); } setTesting(false); } return (

TYHID

Track Your Hours, I Dare You

Gemini API Key
setKey(e.target.value)} placeholder="AIza..." style={{ width: "100%", padding: "11px 14px", borderRadius: 10, border: "1.5px solid #e5e7eb", fontSize: 14, outline: "none", marginBottom: 10, boxSizing: "border-box" }} /> {result && (
{result === "ok" ? "✓ Connected! Ready to go." : "✗ Invalid key — check and try again."}
)}

🧪 Test mode: plan submission open until 4 PM

); } // ─── LOGIN ──────────────────────────────────────────────────────────────────── function LoginScreen({ onLogin }) { const [selected, setSelected] = useState(null); const [pin, setPin] = useState(""); const [error, setError] = useState(""); const [shaking, setShaking] = useState(false); function handleDigit(d) { if (pin.length >= 4) return; const next = pin + d; setPin(next); setError(""); if (next.length === 4) { setTimeout(() => { if (selected?.pin === next) { onLogin(selected); } else { setShaking(true); setError("Wrong PIN"); setTimeout(() => { setPin(""); setShaking(false); }, 600); } }, 100); } } return (

TYHID

Who are you?

{!selected ? (
{USERS.map(u => ( setSelected(u)} style={{ textAlign: "center", padding: "1.25rem 1rem" }}>
{u.name}
{u.role}
))}
) : (
{selected.name}
Enter your PIN
{[0,1,2,3].map(i => (
))}
{error &&
{error}
}
{[1,2,3,4,5,6,7,8,9,"",0,"⌫"].map((d, i) => ( ))}

Demo PINs: 0000 / 1111 / 2222 / 3333

)}
); } // ─── CLOCK-IN (PLAN) ────────────────────────────────────────────────────────── function ClockIn({ user, apiKey, onPlanLocked }) { const open = isPlanOpen(); const [goals, setGoals] = useState([{ id: 1, taskText: "", hours: "", notes: "", points: 0, aiResult: null, aiLoading: false }]); const [submitting, setSubmitting] = useState(false); const totalPoints = goals.reduce((s, g) => s + (Number(g.points) || 0), 0); function addGoal() { setGoals(p => [...p, { id: Date.now(), taskText: "", hours: "", notes: "", points: 0, aiResult: null, aiLoading: false }]); } function update(id, patch) { setGoals(p => p.map(g => g.id === id ? { ...g, ...patch } : g)); } function removeGoal(id) { setGoals(p => p.filter(g => g.id !== id)); } function pickTemplate(goalId, t) { update(goalId, { taskText: t.label, points: t.points, hours: "", aiResult: null }); } async function getAIFeedback(goal) { if (!goal.taskText) return; update(goal.id, { aiLoading: true, aiResult: null }); try { const prompt = `You are an AI Strategic Coach for a marketing team. Evaluate this task: Task: ${goal.taskText} Planned hours: ${goal.hours || "not given"} Details: ${goal.notes || "none"} Reply ONLY in this format: SCORE: [1-10] POINTS: [1, 2, 3, 5, 8, or 13] ROI: [HIGH, MEDIUM, or LOW] FEEDBACK: [2 direct, specific coaching sentences]`; const r = await callGemini(apiKey, prompt); const score = parseInt(r.match(/SCORE:\s*(\d+)/)?.[1] || "7"); const pts = parseInt(r.match(/POINTS:\s*(\d+)/)?.[1] || "3"); const roi = r.match(/ROI:\s*(HIGH|MEDIUM|LOW)/)?.[1] || "MEDIUM"; const feedback = r.match(/FEEDBACK:\s*(.+)/s)?.[1]?.trim() || r; update(goal.id, { aiLoading: false, aiResult: { score, pts, roi, feedback }, points: pts }); } catch (e) { update(goal.id, { aiLoading: false, aiResult: { error: e.message } }); } } async function handleSubmit() { setSubmitting(true); await new Promise(r => setTimeout(r, 900)); onPlanLocked(goals); } return (

🕘 Clock In — Today's Plan

Min 8 story points · Locks at 4:00 PM

{open ? "OPEN" : "LOCKED"}
{!open && (
🔒 Submission closed at 4:00 PM. Contact your manager for an override.
)} {goals.map((goal, idx) => (
Goal {idx + 1}
{goal.points > 0 && {goal.points} pts} {goals.length > 1 && }
What are you working on?
update(goal.id, { taskText: e.target.value, points: 0, aiResult: null })} placeholder="Type your task, or pick a suggestion below..." disabled={!open} style={{ width: "100%", padding: "10px 13px", borderRadius: 9, border: "1.5px solid #e5e7eb", fontSize: 14, outline: "none", boxSizing: "border-box" }} onFocus={e => e.target.style.borderColor = user.color} onBlur={e => e.target.style.borderColor = "#e5e7eb"} />
{TASKS.map(t => { const active = goal.taskText === t.label; return ( ); })}
Hours planned
update(goal.id, { hours: e.target.value })} placeholder="e.g. 2.5" min="0.5" max="8" step="0.5" disabled={!open} style={{ width: "100%", padding: "9px 12px", borderRadius: 9, border: "1.5px solid #e5e7eb", fontSize: 14, outline: "none", boxSizing: "border-box" }} />
Story points
{goal.points || "via template or AI"}