import React, { useState, useEffect, useMemo, useRef } from 'react'; import { Layout, Calendar, CheckSquare, Target, User, LogOut, Plus, Trash2, GripVertical, AlertCircle, Sun, Moon, ChevronRight, CheckCircle2, Circle, Brain, Dumbbell, PenTool, Smile, Menu, X, Save } from 'lucide-react'; import { initializeApp } from 'firebase/app'; import { getAuth, signInWithCustomToken, signInAnonymously, onAuthStateChanged, signOut, updateProfile } from 'firebase/auth'; import { getFirestore, collection, doc, setDoc, onSnapshot, query, deleteDoc, updateDoc, serverTimestamp } from 'firebase/firestore'; // --- Firebase Configuration & Setup --- const getFirebaseConfig = () => { try { // In the real environment, this is injected. // Fallback for local testing or if undefined. if (typeof __firebase_config !== 'undefined') { return JSON.parse(__firebase_config); } return null; } catch (e) { console.error("Firebase config parsing error:", e); return null; } }; const firebaseConfig = getFirebaseConfig(); const app = firebaseConfig ? initializeApp(firebaseConfig) : null; const auth = app ? getAuth(app) : null; const db = app ? getFirestore(app) : null; const appId = typeof __app_id !== 'undefined' ? __app_id : 'plannerdada-default'; // --- Constants & Data Models --- const QUADRANTS = { DO: { id: 'do', title: 'Do', subtitle: 'Urgent & Important', color: 'bg-red-50', border: 'border-red-200', text: 'text-red-700', icon: AlertCircle, limit: 3 }, DECIDE: { id: 'decide', title: 'Decide', subtitle: 'Not Urgent & Important', color: 'bg-blue-50', border: 'border-blue-200', text: 'text-blue-700', icon: Calendar, limit: null }, DELEGATE: { id: 'delegate', title: 'Delegate', subtitle: 'Urgent & Not Important', color: 'bg-yellow-50', border: 'border-yellow-200', text: 'text-yellow-700', icon: User, limit: null }, DELETE: { id: 'delete', title: 'Delete', subtitle: 'Not Urgent & Not Important', color: 'bg-gray-50', border: 'border-gray-200', text: 'text-gray-700', icon: Trash2, limit: null }, }; const WELLNESS_ACTIVITIES = [ { id: 'learning', label: 'Learning', placeholder: 'e.g. Read 10 pages', icon: Brain, points: 5 }, { id: 'movement', label: 'Movement', placeholder: 'e.g. 30min Run', icon: Dumbbell, points: 5 }, { id: 'journaling', label: 'Journaling', placeholder: 'e.g. Write morning pages', icon: PenTool, points: 5 }, { id: 'mindfulness', label: 'Mindfulness', placeholder: 'e.g. 10min Meditation', icon: Smile, points: 5 }, ]; // --- Helper Components --- const Button = ({ children, onClick, variant = 'primary', className = '', ...props }) => { const variants = { primary: 'bg-indigo-600 text-white hover:bg-indigo-700 shadow-sm', secondary: 'bg-white text-gray-700 border border-gray-300 hover:bg-gray-50', ghost: 'text-gray-600 hover:bg-gray-100', danger: 'bg-red-50 text-red-600 hover:bg-red-100', }; return ( ); }; const Modal = ({ isOpen, onClose, title, children }) => { if (!isOpen) return null; return (

{title}

{children}
); }; // --- Main Application Component --- export default function App() { const [user, setUser] = useState(null); const [loading, setLoading] = useState(true); const [tasks, setTasks] = useState([]); const [dailyPlan, setDailyPlan] = useState({ wellness: {}, reflection: {} }); const [currentDate, setCurrentDate] = useState(new Date().toISOString().split('T')[0]); const [activeTab, setActiveTab] = useState('daily'); const [isSidebarOpen, setIsSidebarOpen] = useState(false); // Modal States const [isTaskModalOpen, setIsTaskModalOpen] = useState(false); const [targetQuadrant, setTargetQuadrant] = useState('do'); // Auth Initialization useEffect(() => { if (!auth) { setLoading(false); return; } const initAuth = async () => { try { if (typeof __initial_auth_token !== 'undefined' && __initial_auth_token) { await signInWithCustomToken(auth, __initial_auth_token); } else { await signInAnonymously(auth); } } catch (error) { console.error("Auth error:", error); } }; initAuth(); const unsubscribe = onAuthStateChanged(auth, (currentUser) => { setUser(currentUser); setLoading(false); }); return () => unsubscribe(); }, []); // Data Fetching useEffect(() => { if (!user || !db) return; // 1. Fetch Tasks for current date const tasksRef = collection(db, 'artifacts', appId, 'users', user.uid, 'tasks'); const unsubscribeTasks = onSnapshot(tasksRef, (snapshot) => { const loadedTasks = snapshot.docs .map(doc => ({ id: doc.id, ...doc.data() })) .filter(t => t.date === currentDate); setTasks(loadedTasks); }, (error) => console.error("Tasks fetch error:", error)); // 2. Fetch Daily Plan Details (Wellness, Reflection) const planRef = doc(db, 'artifacts', appId, 'users', user.uid, 'daily_plans', currentDate); const unsubscribePlan = onSnapshot(planRef, (doc) => { if (doc.exists()) { setDailyPlan(doc.data()); } else { setDailyPlan({ wellness: {}, reflection: {} }); } }, (error) => console.error("Plan fetch error:", error)); return () => { unsubscribeTasks(); unsubscribePlan(); }; }, [user, currentDate]); // --- Actions --- const handleAddTask = async (e) => { e.preventDefault(); const title = e.target.title.value; const quadrant = e.target.quadrant.value; if (!title.trim()) return; // Check limit for Q1 if (quadrant === 'do') { const q1Count = tasks.filter(t => t.quadrant === 'do' && !t.completed).length; if (q1Count >= 3) { alert("The 'Do' quadrant is limited to 3 active tasks to ensure focus!"); return; } } const newTask = { title, quadrant, completed: false, date: currentDate, createdAt: serverTimestamp(), userId: user.uid }; try { await addDoc(collection(db, 'artifacts', appId, 'users', user.uid, 'tasks'), newTask); setIsTaskModalOpen(false); e.target.reset(); } catch (error) { console.error("Error adding task:", error); } }; const toggleTaskComplete = async (task) => { try { const taskRef = doc(db, 'artifacts', appId, 'users', user.uid, 'tasks', task.id); await updateDoc(taskRef, { completed: !task.completed }); } catch (error) { console.error("Error toggling task:", error); } }; const deleteTask = async (taskId) => { if (!window.confirm("Delete this task?")) return; try { await deleteDoc(doc(db, 'artifacts', appId, 'users', user.uid, 'tasks', taskId)); } catch (error) { console.error("Error deleting task:", error); } }; // --- Wellness & Reflection Actions --- const updateWellness = async (activityId, field, value) => { try { const planRef = doc(db, 'artifacts', appId, 'users', user.uid, 'daily_plans', currentDate); const currentActivity = dailyPlan.wellness?.[activityId] || {}; const newWellness = { ...dailyPlan.wellness, [activityId]: { ...currentActivity, [field]: value } }; await setDoc(planRef, { wellness: newWellness, date: currentDate, updatedAt: serverTimestamp() }, { merge: true }); } catch (error) { console.error("Error updating wellness:", error); } }; const updateReflection = async (field, value) => { try { const planRef = doc(db, 'artifacts', appId, 'users', user.uid, 'daily_plans', currentDate); await setDoc(planRef, { reflection: { ...dailyPlan.reflection, [field]: value }, date: currentDate, updatedAt: serverTimestamp() }, { merge: true }); } catch (error) { console.error("Error updating reflection:", error); } }; // --- Score Calculation --- const dailyScore = useMemo(() => { if (!tasks.length && Object.keys(dailyPlan.wellness || {}).length === 0) return 0; let score = 0; const totalTasks = tasks.length; const completedTasks = tasks.filter(t => t.completed).length; // Base score: (completed / total) * 85 if (totalTasks > 0) { score += (completedTasks / totalTasks) * 85; } // Wellness Bonus: 5 points each if completed (max 20) // Now we check for the 'completed' boolean property const wellnessPoints = Object.values(dailyPlan.wellness || {}).reduce((acc, curr) => { return acc + (curr.completed ? 5 : 0); }, 0); score += wellnessPoints; // Q1 Completion Bonus: +10 if all Q1 tasks are done (and there was at least 1) const q1Tasks = tasks.filter(t => t.quadrant === 'do'); if (q1Tasks.length > 0 && q1Tasks.every(t => t.completed)) { score += 10; } // Reflection Bonus: +5 if any reflection field is filled const hasReflection = Object.values(dailyPlan.reflection || {}).some(v => v && v.trim().length > 0); if (hasReflection) score += 5; return Math.min(Math.round(score), 125); }, [tasks, dailyPlan]); // --- Render Functions --- if (loading) { return (

Loading PlannerDada...

); } if (!user && !app) { return (

Configuration Missing

Please provide a valid Firebase Configuration to run this application.

) } if (!user) { return (

PlannerDada

Plan your day. Execute your week. Achieve your year.

By continuing, you enter Guest Mode.

); } return (
{/* Sidebar - Mobile Overlay */} {isSidebarOpen && (
setIsSidebarOpen(false)} /> )} {/* Sidebar - Navigation */} {/* Main Content */}
{/* Header */}

{activeTab === 'daily' ? 'Eisenhower Matrix' : activeTab === 'weekly' ? 'Weekly Scorecard' : activeTab === 'quarterly' ? 'Quarterly OKRs' : 'Annual Vision'}

{new Date(currentDate).toLocaleDateString('en-US', { weekday: 'long', year: 'numeric', month: 'long', day: 'numeric' })}

setCurrentDate(e.target.value)} className="border border-gray-300 rounded-lg px-3 py-1.5 text-sm focus:ring-2 focus:ring-indigo-500 outline-none" />
{/* Scrollable Content Area */}
{activeTab === 'daily' ? (
{/* The Matrix */}
{Object.values(QUADRANTS).map((quadrant) => { const quadrantTasks = tasks.filter(t => t.quadrant === quadrant.id); const isFull = quadrant.limit && quadrantTasks.filter(t => !t.completed).length >= quadrant.limit; return (

{quadrant.title}

{quadrant.subtitle}

{quadrant.limit && ( {quadrantTasks.filter(t => !t.completed).length}/{quadrant.limit} )}
{quadrantTasks.length === 0 ? (
No tasks yet
) : ( quadrantTasks.map(task => (

{task.title}

)) )}
); })}
{/* Wellness & Documenting Section */}
{/* Wellness Planning */}

Daily Wellness Planning

Get +20 points
{WELLNESS_ACTIVITIES.map((activity) => { const activityData = dailyPlan.wellness?.[activity.id] || {}; const isActive = activityData.completed; return (
{activity.label}
updateWellness(activity.id, 'plan', e.target.value)} className="w-full text-sm border-b border-gray-200 bg-transparent py-1 px-1 focus:border-indigo-500 focus:ring-0 outline-none transition-colors" />
); })}
{/* End of Day Reflection */}

End of Day Reflection

+5 bonus points
{[ { id: 'win', label: 'Biggest Win Today', placeholder: 'What went well? e.g. Closed $5k deal', icon: Target }, { id: 'improve', label: 'Improve Tomorrow', placeholder: 'What could be better? e.g. Delegate more', icon: Brain }, { id: 'gratitude', label: 'Gratitude', placeholder: 'I am thankful for... e.g. Team support', icon: Smile } ].map((field) => (