import React, { useState, useEffect } from 'react'; import { initializeApp } from 'firebase/app'; import { getAuth, createUserWithEmailAndPassword, signInWithEmailAndPassword, signOut, onAuthStateChanged, updateProfile, signInWithCustomToken } from 'firebase/auth'; import { getFirestore, collection, addDoc, onSnapshot, doc, updateDoc, deleteDoc, serverTimestamp, query } from 'firebase/firestore'; import { Loader2, LogOut, Plus, Trash2, Edit2, CheckCircle2, Circle, X, Save, Layout, ListTodo } from 'lucide-react'; // --- Firebase Configuration & Initialization --- // Import the functions you need from the SDKs you need import { initializeApp } from "firebase/app"; // TODO: Add SDKs for Firebase products that you want to use // https://firebase.google.com/docs/web/setup#available-libraries // Your web app's Firebase configuration const firebaseConfig = { apiKey: "AIzaSyDByV4VYyRydQafZD1e0YUgmIgZOZze4IM", authDomain: "taskflow-app-68523.firebaseapp.com", projectId: "taskflow-app-68523", storageBucket: "taskflow-app-68523.firebasestorage.app", messagingSenderId: "852660449313", appId: "1:852660449313:web:1448f523688b22ebc53360" }; // Initialize Firebase const app = initializeApp(firebaseConfig); // --- Main Application Component --- export default function App() { const [user, setUser] = useState(null); const [loading, setLoading] = useState(true); const [authError, setAuthError] = useState(''); // Initial Auth Setup useEffect(() => { // Safety timer: If Firebase takes too long to initialize (common in iframes/laptops // with strict privacy settings), force the loading screen to disappear so you can try logging in. const safetyTimer = setTimeout(() => { setLoading((currentLoading) => { if (currentLoading) { console.warn("Auth listener timed out - forcing UI load"); return false; } return currentLoading; }); }, 2500); const initAuth = async () => { // If the environment provides a specific token, we prioritize it if (typeof __initial_auth_token !== 'undefined' && __initial_auth_token) { try { await signInWithCustomToken(auth, __initial_auth_token); } catch (e) { console.error("Custom token auth failed", e); } } // Note: We don't force anonymous sign-in here because we want explicit // Email/Password login for this specific demo requirements. }; initAuth(); const unsubscribe = onAuthStateChanged(auth, (currentUser) => { clearTimeout(safetyTimer); setUser(currentUser); setLoading(false); }); return () => { unsubscribe(); clearTimeout(safetyTimer); }; }, []); if (loading) { return (
); } return (
{!user ? ( ) : ( )}
); } // --- Authentication Screen (Login/Register) --- function AuthScreen({ onAuthError, authError }) { const [isLogin, setIsLogin] = useState(true); const [email, setEmail] = useState(''); const [password, setPassword] = useState(''); const [isSubmitting, setIsSubmitting] = useState(false); const handleSubmit = async (e) => { e.preventDefault(); setIsSubmitting(true); onAuthError(''); try { if (isLogin) { await signInWithEmailAndPassword(auth, email, password); } else { await createUserWithEmailAndPassword(auth, email, password); } } catch (error) { console.error(error); let msg = "An error occurred."; if (error.code === 'auth/invalid-email') msg = "Invalid email address."; if (error.code === 'auth/user-disabled') msg = "User account disabled."; if (error.code === 'auth/user-not-found') msg = "No account found with this email."; if (error.code === 'auth/wrong-password') msg = "Incorrect password."; if (error.code === 'auth/email-already-in-use') msg = "Email already in use."; if (error.code === 'auth/weak-password') msg = "Password should be at least 6 characters."; onAuthError(msg); } finally { setIsSubmitting(false); } }; return (

{isLogin ? 'Welcome Back' : 'Create Account'}

{isLogin ? 'Enter your details to access your tasks' : 'Start organizing your life today'}

{authError && (
{authError}
)}
setEmail(e.target.value)} />
setPassword(e.target.value)} />
); } // --- Dashboard Component (CRUD Operations) --- function Dashboard({ user }) { const [tasks, setTasks] = useState([]); const [newTask, setNewTask] = useState(''); const [editingId, setEditingId] = useState(null); const [editTitle, setEditTitle] = useState(''); const [loadingData, setLoadingData] = useState(true); // Firestore: Real-time Listener useEffect(() => { if (!user) return; // RULE 1: Correct Path for User Data const tasksCollection = collection(db, 'artifacts', appId, 'users', user.uid, 'tasks'); // RULE 2: Simple Query (Filtering done in client if needed, sorting here is memory-based later) const q = query(tasksCollection); const unsubscribe = onSnapshot(q, (snapshot) => { const taskList = snapshot.docs.map(doc => ({ id: doc.id, ...doc.data() })); // Sort manually since we avoid complex queries taskList.sort((a, b) => (b.createdAt?.seconds || 0) - (a.createdAt?.seconds || 0)); setTasks(taskList); setLoadingData(false); }, (error) => { console.error("Error fetching tasks:", error); setLoadingData(false); }); return () => unsubscribe(); }, [user]); // Create const handleAddTask = async (e) => { e.preventDefault(); if (!newTask.trim()) return; try { const tasksCollection = collection(db, 'artifacts', appId, 'users', user.uid, 'tasks'); await addDoc(tasksCollection, { title: newTask, completed: false, createdAt: serverTimestamp() }); setNewTask(''); } catch (error) { console.error("Error adding task:", error); } }; // Update (Toggle Complete) const toggleComplete = 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 updating task:", error); } }; // Update (Edit Title) const startEdit = (task) => { setEditingId(task.id); setEditTitle(task.title); }; const saveEdit = async () => { if (!editTitle.trim()) return; try { const taskRef = doc(db, 'artifacts', appId, 'users', user.uid, 'tasks', editingId); await updateDoc(taskRef, { title: editTitle }); setEditingId(null); } catch (error) { console.error("Error saving edit:", error); } }; // Delete const deleteTask = async (id) => { if (!window.confirm("Delete this task?")) return; try { const taskRef = doc(db, 'artifacts', appId, 'users', user.uid, 'tasks', id); await deleteDoc(taskRef); } catch (error) { console.error("Error deleting task:", error); } }; const handleLogout = async () => { try { await signOut(auth); } catch (error) { console.error("Error signing out:", error); } }; return (
{/* Header */}

TaskFlow

Welcome, {user.email}

{/* Add Task Form */}
setNewTask(e.target.value)} placeholder="What needs to be done?" className="w-full pl-6 pr-32 py-4 bg-white border border-slate-200 rounded-xl shadow-sm focus:ring-2 focus:ring-indigo-500 focus:border-indigo-500 outline-none transition-all text-lg" />
{/* Task List */}
{loadingData ? (

Loading your tasks...

) : tasks.length === 0 ? (

No tasks yet

Add a task above to get started!

) : ( )}

Data is stored securely in Firebase Firestore.

Collection Path: users/{user.uid}/tasks

); }