Skip to content

Commit 1b0cdd4

Browse files
committed
Closes #3 and Closes #5
1 parent 7f8351b commit 1b0cdd4

File tree

3 files changed

+147
-72
lines changed

3 files changed

+147
-72
lines changed

src/components/Navbar.tsx

Lines changed: 103 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ import { useAuth } from "../utils/auth";
44
import { logout } from "../utils/firebase";
55
import { Button } from "@/components/ui/button";
66
import { Moon, Sun } from "lucide-react";
7+
import { db } from "../utils/firebase";
8+
import { collection, where, query, getDocs } from "firebase/firestore";
79
import {
810
DropdownMenu,
911
DropdownMenuContent,
@@ -15,6 +17,7 @@ import {
1517
import { Avatar, AvatarImage, AvatarFallback } from "@/components/ui/avatar";
1618

1719
const Navbar: React.FC = () => {
20+
const [userInitials, setUserInitials] = useState("U");
1821
const { currentUser } = useAuth();
1922
const navigate = useNavigate();
2023

@@ -37,71 +40,111 @@ const Navbar: React.FC = () => {
3740
}
3841
}, []);
3942

40-
return (
41-
<div className="bg-background border-b">
42-
<div className="container flex h-16 items-center justify-between py-4">
43-
<Link to="/" className="flex items-center space-x-2">
44-
<span className="font-bold text-xl tracking-tight text-primary transition-opacity duration-200">
45-
Pure<span className="text-foreground">Path</span>
46-
</span>
47-
</Link>
43+
44+
useEffect(() => {
45+
const fetchUserInitials = async () => {
46+
if (currentUser && currentUser.email) {
47+
try {
48+
const usersRef = collection(db, "users");
49+
const q = query(usersRef, where("email", "==", currentUser.email));
50+
const querySnapshot = await getDocs(q);
51+
console.log(q);
52+
if (!querySnapshot.empty) {
53+
// Assuming only one document matches the email.
54+
const userDoc = querySnapshot.docs[0].data();
55+
const firstname = userDoc.firstName || "";
56+
const lastname = userDoc.lastName || "";
4857

49-
<nav>
50-
<Button
51-
variant="ghost"
52-
size="icon"
53-
onClick={toggleDarkMode}
54-
className="ml-4"
55-
aria-label="Toggle dark mode"
56-
>
57-
{isDarkMode ? (
58-
<Sun className="h-5 w-5 text-yellow-400" />
59-
) : (
60-
<Moon className="h-5 w-5" />
61-
)}
62-
</Button>
58+
if (firstname || lastname) {
59+
const initials =
60+
(firstname.charAt(0).toUpperCase() || "") +
61+
(lastname.charAt(0).toUpperCase() || "");
62+
setUserInitials(initials);
63+
} else {
64+
setUserInitials("U");
65+
}
66+
} else {
67+
setUserInitials("U"); // No document found for this email.
68+
}
69+
} catch (error) {
70+
console.error("Error fetching user initials:", error);
71+
setUserInitials("U"); // Fallback in case of an error.
72+
}
73+
}
74+
};
6375

64-
{currentUser ? (
65-
<DropdownMenu>
66-
<DropdownMenuTrigger asChild>
67-
<Button
68-
variant="ghost"
69-
className="relative h-8 w-8 rounded-full"
70-
>
71-
<Avatar>
72-
<AvatarImage src="/placeholder.svg" alt="User" />
73-
<AvatarFallback>
74-
{currentUser.email?.charAt(0).toUpperCase()}
75-
</AvatarFallback>
76-
</Avatar>
77-
</Button>
78-
</DropdownMenuTrigger>
79-
<DropdownMenuContent align="end">
80-
<DropdownMenuLabel>My Account</DropdownMenuLabel>
81-
<DropdownMenuSeparator />
82-
<DropdownMenuItem asChild>
83-
<Link to="/dashboard">Dashboard</Link>
84-
</DropdownMenuItem>
85-
<DropdownMenuItem asChild>
86-
<Link to="/profile">Profile</Link>
87-
</DropdownMenuItem>
88-
<DropdownMenuSeparator />
89-
<DropdownMenuItem onClick={handleLogout}>
90-
Logout
91-
</DropdownMenuItem>
92-
</DropdownMenuContent>
93-
</DropdownMenu>
76+
fetchUserInitials();
77+
}, [currentUser]);
78+
79+
80+
return (<div className="bg-background border-b">
81+
<div className="container flex h-16 items-center justify-between py-4">
82+
<Link to="/" className="flex items-center space-x-2">
83+
<span className="font-bold text-xl tracking-tight text-primary transition-opacity duration-200">
84+
Pure<span className="text-foreground">Path</span>
85+
</span>
86+
</Link>
87+
88+
<nav className="flex items-center space-x-4">
89+
{/* Dark Mode Button */}
90+
<Button
91+
variant="ghost"
92+
size="icon"
93+
onClick={toggleDarkMode}
94+
className="ml-auto p-2 border rounded-md shadow-sm hover:bg-secondary transition-all"
95+
aria-label="Toggle dark mode"
96+
>
97+
{isDarkMode ? (
98+
<Sun className="h-5 w-5 text-yellow-400" />
9499
) : (
95-
<div>
96-
<Link to="/login" className="mr-4">
97-
Login
98-
</Link>
99-
<Link to="/register">Register</Link>
100-
</div>
100+
<Moon className="h-5 w-5" />
101101
)}
102-
</nav>
103-
</div>
102+
</Button>
103+
104+
{/* Dropdown Menu */}
105+
{currentUser ? (
106+
<DropdownMenu>
107+
<DropdownMenuTrigger asChild>
108+
<Button
109+
variant="ghost"
110+
size="icon"
111+
className="relative h-8 w-8 rounded-full ml-4"
112+
>
113+
<Avatar>
114+
<AvatarFallback>{userInitials}</AvatarFallback>
115+
</Avatar>
116+
</Button>
117+
</DropdownMenuTrigger>
118+
{/* Dropdown Menu Content */}
119+
<DropdownMenuContent
120+
align="end"
121+
className="mt-2 w-56 animate-scale-in shadow-lg border rounded-md bg-background"
122+
>
123+
<DropdownMenuLabel>My Account</DropdownMenuLabel>
124+
<DropdownMenuSeparator />
125+
<DropdownMenuItem asChild>
126+
<Link to="/dashboard">Dashboard</Link>
127+
</DropdownMenuItem>
128+
<DropdownMenuItem asChild>
129+
<Link to="/profile">Profile</Link>
130+
</DropdownMenuItem>
131+
<DropdownMenuSeparator />
132+
<DropdownMenuItem onClick={handleLogout}>
133+
Logout
134+
</DropdownMenuItem>
135+
</DropdownMenuContent>
136+
</DropdownMenu>
137+
) : (
138+
<div className="flex items-center space-x-4">
139+
<Link to="/login" className="mr-4">
140+
Login
141+
</Link>
142+
<Link to="/register">Register</Link>
143+
</div>
144+
)}
145+
</nav>
104146
</div>
147+
</div>
105148
);
106149
};
107150

src/pages/Profile.tsx

Lines changed: 44 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import React, { useState, useEffect } from "react";
22
import { useNavigate } from "react-router-dom";
33
import { updateUserProfile, updateUserPassword } from "../utils/firebase";
4-
import {doc, deleteDoc} from "firebase/firestore";
4+
import {doc, deleteDoc, collection, getDocs, query, where} from "firebase/firestore";
55
import { useAuth } from "../utils/auth";
66
import { Button } from "@/components/ui/button";
77
import { Input } from "@/components/ui/input";
@@ -39,7 +39,7 @@ import * as z from "zod";
3939
import { db } from "../utils/firebase";
4040
import { Trash2, User, Link as LinkIcon } from "lucide-react";
4141
import SocialMediaLinks from "@/components/SocialMedia";
42-
const currentUser = useAuth;
42+
4343

4444
// Profile form schema
4545
const profileFormSchema = z.object({
@@ -86,6 +86,7 @@ type ProfileFormValues = z.infer<typeof profileFormSchema>;
8686
type PasswordFormValues = z.infer<typeof passwordFormSchema>;
8787

8888
const Profile: React.FC = () => {
89+
const [userInitials, setUserInitials] = useState("U");
8990
const { currentUser, userProfile, isLoading } = useAuth();
9091
const navigate = useNavigate();
9192
const [updateLoading, setUpdateLoading] = useState(false);
@@ -115,6 +116,44 @@ const Profile: React.FC = () => {
115116
},
116117
});
117118

119+
// Get user initials
120+
121+
useEffect(() => {
122+
const fetchUserInitials = async () => {
123+
if (currentUser && currentUser.email) {
124+
try {
125+
const usersRef = collection(db, "users");
126+
const q = query(usersRef, where("email", "==", currentUser.email));
127+
const querySnapshot = await getDocs(q);
128+
console.log(q);
129+
if (!querySnapshot.empty) {
130+
// Assuming only one document matches the email.
131+
const userDoc = querySnapshot.docs[0].data();
132+
const firstname = userDoc.firstName || "";
133+
const lastname = userDoc.lastName || "";
134+
135+
if (firstname || lastname) {
136+
const initials =
137+
(firstname.charAt(0).toUpperCase() || "") +
138+
(lastname.charAt(0).toUpperCase() || "");
139+
setUserInitials(initials);
140+
} else {
141+
setUserInitials("U");
142+
}
143+
} else {
144+
setUserInitials("U"); // No document found for this email.
145+
}
146+
} catch (error) {
147+
console.error("Error fetching user initials:", error);
148+
setUserInitials("U"); // Fallback in case of an error.
149+
}
150+
}
151+
};
152+
153+
fetchUserInitials();
154+
}, [currentUser]);
155+
156+
118157
// Update form when userProfile changes
119158
useEffect(() => {
120159
if (userProfile) {
@@ -210,13 +249,7 @@ const Profile: React.FC = () => {
210249
);
211250
}
212251

213-
// Create user initials for avatar
214-
const getInitials = () => {
215-
if (userProfile.username) {
216-
return userProfile.username.charAt(0).toUpperCase();
217-
}
218-
return currentUser.email?.charAt(0).toUpperCase() || "U";
219-
};
252+
220253
const deleteAccount = async (userId: string) => {
221254
try {
222255
// Delete user data from Firestore
@@ -251,11 +284,11 @@ const Profile: React.FC = () => {
251284
<div className="flex flex-col items-center">
252285
<Avatar className="h-20 w-20 mb-4">
253286
<AvatarFallback className="text-xl">
254-
{getInitials()}
287+
{userInitials}
255288
</AvatarFallback>
256289
</Avatar>
257290
<CardTitle className="text-center">
258-
{userProfile.username || "User"}
291+
{userProfile.firstName + " " + userProfile.lastName || "User"}
259292
</CardTitle>
260293
<CardDescription className="text-center mt-1">
261294
{currentUser.email}

src/utils/firebase.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,6 @@ const firebaseConfig = {
3838
measurementId: import.meta.env.VITE_FIREBASE_MEASUREMENT_ID
3939
};
4040

41-
console.log("Firebase config:", firebaseConfig);
4241

4342
// Initialize Firebase with better error handling
4443
let app, auth, db;

0 commit comments

Comments
 (0)