diff --git a/frontend/src/components/Navbar.tsx b/frontend/src/components/Navbar.tsx new file mode 100644 index 0000000..eefb606 --- /dev/null +++ b/frontend/src/components/Navbar.tsx @@ -0,0 +1,94 @@ +import { useState, useEffect } from "react"; +import { Link } from "react-router-dom"; +import LightModeToggle from "@/components/LightModeToggle"; +import { Separator } from "@/components/ui/separator"; +import { logout } from "@/services/auth"; // Import the logout function + +import ProfileDropdown from "@/components/ProfileDropdown"; +import UserDropdown from "@/components/UserDropdown"; + +const Navbar = () => { + const [isOpen, setIsOpen] = useState(false); + const [isLoggedIn, setIsLoggedIn] = useState(false); + + // Check login status on component mount + useEffect(() => { + const token = localStorage.getItem("access_token"); + setIsLoggedIn(!!token); // Convert token presence to boolean + }, []); + + return ( + + ); +}; + +export default Navbar; + diff --git a/frontend/src/components/UserDropdown.tsx b/frontend/src/components/UserDropdown.tsx new file mode 100644 index 0000000..d052f2c --- /dev/null +++ b/frontend/src/components/UserDropdown.tsx @@ -0,0 +1,117 @@ +import { useState, useEffect } from "react"; +import { Link } from "react-router-dom"; +import { Switch } from "@/components/ui/switch"; +import { Button } from "@/components/ui/button"; +import { + DropdownMenu, + DropdownMenuContent, + DropdownMenuItem, + DropdownMenuTrigger, +} from "@/components/ui/dropdown-menu"; +import { Skeleton } from "@/components/ui/skeleton"; + +import apiInstance from "@/services/api"; +import { logout } from "@/services/auth"; + +interface UserProfile { + username: string; + email: string; + profile: { + show_mature: boolean; + }; +} + +const UserDropdown = () => { + const [user, setUser] = useState(null); + const [loading, setLoading] = useState(true); + const [nsfwEnabled, setNsfwEnabled] = useState(false); + + useEffect(() => { + const fetchUser = async () => { + try { + const response = await apiInstance.get("user/profile/"); + setUser(response.data); + setNsfwEnabled(response.data.profile.show_mature); + } catch (error) { + console.error("Failed to fetch user:", error); + } finally { + setLoading(false); + } + }; + fetchUser(); + }, []); + + const handleNsfwToggle = async () => { + if (!user) return; + const newSetting = !nsfwEnabled; + setNsfwEnabled(newSetting); + + try { + await apiInstance.patch("user/profile/", { + profile: { show_mature: newSetting }, + }); + } catch (error) { + console.error("Failed to update NSFW setting:", error); + setNsfwEnabled(!newSetting); + } + }; + + const handleLogout = () => { + logout(); + }; + + return ( + + + + {loading ? ( + + ) : ( +
+ {user?.username.charAt(0).toUpperCase()} +
+ )} + +
+ + + {loading ? ( +
+ + + +
+ ) : ( +
+ {/* User Info */} +
+

{user?.username}

+

{user?.email}

+
+ +
+ + {/* NSFW Toggle (Prevent Dropdown from Closing) */} + +
e.stopPropagation()} // Prevents dropdown from closing + > + Show NSFW Content + +
+
+ + {/* Logout Button */} + +
+ )} +
+
+ ); +}; + +export default UserDropdown; +