diff --git a/src/pages/Profile.jsx b/src/pages/Profile.jsx index 23e6b9f2..d69707d3 100644 --- a/src/pages/Profile.jsx +++ b/src/pages/Profile.jsx @@ -1,43 +1,114 @@ -import React, { useState } from 'react'; +import React, { useState, useEffect } from 'react'; import { useNavigate } from 'react-router-dom'; -import { signOut } from "firebase/auth"; -import { auth } from "../firebase"; -import { toast } from "react-toastify"; -import { FaUser, FaSignOutAlt, FaEdit, FaSave, FaTimes } from 'react-icons/fa'; + +import { FaUser, FaSignOutAlt, FaEdit, FaSave, FaTimes, FaSpinner } from 'react-icons/fa'; +import { auth, db } from "../firebase"; // Assuming db is exported from your firebase config +import { doc, getDoc, setDoc } from "firebase/firestore"; +import { updateProfile, signOut } from "firebase/auth"; +import { toast } from 'react-toastify'; + + const Profile = () => { const navigate = useNavigate(); const [isEditing, setIsEditing] = useState(false); + const [loading, setLoading] = useState(true); + const [isSaving, setIsSaving] = useState(false); const [userInfo, setUserInfo] = useState({ - name: 'Travel Enthusiast', - email: 'user@example.com', - location: 'New York, USA', - bio: 'Love exploring new places and creating memories!', - joinDate: 'January 2024' + name: '', + email: '', + location: '', + bio: '', + joinDate: '' }); const [editInfo, setEditInfo] = useState({ ...userInfo }); -const handleLogout = () => { - signOut(auth) - .then(() => { - toast.success("Logged out successfully!"); + + useEffect(() => { + const fetchUserData = async () => { + if (auth.currentUser) { + const userDocRef = doc(db, "users", auth.currentUser.uid); + try { + const docSnap = await getDoc(userDocRef); + const dbData = docSnap.exists() ? docSnap.data() : {}; + + const fullUserInfo = { + name: auth.currentUser.displayName || dbData.name || 'New User', + email: auth.currentUser.email, + location: dbData.location || '', + bio: dbData.bio || '', + joinDate: auth.currentUser.metadata.creationTime + ? new Date(auth.currentUser.metadata.creationTime).toLocaleDateString() + : 'N/A', + }; + setUserInfo(fullUserInfo); + setEditInfo(fullUserInfo); + } catch (error) { + console.error("Error fetching user data:", error); + toast.error("Could not fetch your profile data."); + } finally { + setLoading(false); + } + } else { + // If no user, stop loading and the component will redirect. + setLoading(false); + } + }; + + fetchUserData(); + }, []); + + const handleLogout = async () => { + try { + await signOut(auth); navigate("/login"); - }) - .catch((error) => { - console.error("Error during logout:", error); - toast.error("Failed to logout. Please try again."); - }); -}; + toast.success("Logged out successfully."); + } catch (error) { + console.error("Error signing out: ", error); + toast.error("Failed to log out."); + } + }; + const handleEdit = () => { setIsEditing(true); setEditInfo({ ...userInfo }); }; - const handleSave = () => { - setUserInfo({ ...editInfo }); - setIsEditing(false); - // Here you would typically save to a database + const handleSave = async () => { + if (!auth.currentUser) return; + setIsSaving(true); + + // 1. Update Firebase Auth profile (for properties like displayName) + if (editInfo.name !== userInfo.name) { + try { + await updateProfile(auth.currentUser, { displayName: editInfo.name }); + } catch (error) { + console.error("Error updating auth profile:", error); + toast.error("Failed to update profile name."); + setIsSaving(false); + return; + } + } + + // 2. Update Firestore document for other details + const userDocRef = doc(db, "users", auth.currentUser.uid); + try { + await setDoc(userDocRef, { + name: editInfo.name, + location: editInfo.location, + bio: editInfo.bio, + }, { merge: true }); + + setUserInfo({ ...editInfo }); + setIsEditing(false); + toast.success("Profile updated successfully!"); + } catch (error) { + console.error("Error saving profile details to Firestore:", error); + toast.error("Failed to save profile details."); + } finally { + setIsSaving(false); + } }; const handleCancel = () => { @@ -49,6 +120,20 @@ const handleLogout = () => { setEditInfo({ ...editInfo, [field]: value }); }; + if (loading) { + return ( +
+

Loading profile...

+
+ ); + } + + if (!auth.currentUser) { + // This should ideally not be hit if routing is correct, but as a safeguard: + navigate('/login'); + return null; + } + return (
@@ -75,9 +160,9 @@ const handleLogout = () => { /> handleInputChange('email', e.target.value)} - className="text-gray-600 dark:text-gray-300 bg-gray-100 dark:bg-gray-700 border border-gray-300 dark:border-gray-600 rounded px-3 py-2 w-full" + value={editInfo.email || ''} + readOnly + className="text-gray-600 dark:text-gray-300 bg-gray-200 dark:bg-gray-800 border border-gray-300 dark:border-gray-600 rounded px-3 py-2 w-full cursor-not-allowed" placeholder="Your Email" /> { ) : (

- {userInfo.name} + {userInfo.name || 'New User'}

-

{userInfo.email}

-

{userInfo.location}

+

{userInfo.email || 'No email provided'}

+

{userInfo.location || 'Location not set'}

{userInfo.bio}

Member since {userInfo.joinDate} @@ -114,9 +199,13 @@ const handleLogout = () => { <>