Skip to content

Commit 63f6b5d

Browse files
committed
show user profile in header
1 parent f4f8f71 commit 63f6b5d

5 files changed

Lines changed: 38 additions & 6 deletions

File tree

frontend/package-lock.json

Lines changed: 10 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

frontend/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
"dependencies": {
1313
"@react-oauth/google": "^0.13.4",
1414
"framer-motion": "^12.38.0",
15+
"jwt-decode": "^4.0.0",
1516
"lucide-react": "^1.7.0",
1617
"react": "^19.2.4",
1718
"react-dom": "^19.2.4"

frontend/src/App.jsx

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import { ALL_PRODUCTS } from './data/products'
77
import { motion, AnimatePresence } from 'framer-motion'
88
import { X, ShoppingBag, Heart, User, Trash2 } from 'lucide-react'
99
import { GoogleLogin } from '@react-oauth/google'
10+
import { jwtDecode } from 'jwt-decode'
1011

1112
function App() {
1213
const [selectedCategories, setSelectedCategories] = useState([]);
@@ -18,6 +19,7 @@ function App() {
1819
const [sortOption, setSortOption] = useState('recommended');
1920
const [activeNav, setActiveNav] = useState('MEN');
2021
const [sneakersView, setSneakersView] = useState(false);
22+
const [loggedInUser, setLoggedInUser] = useState(null);
2123

2224
const toggleFilter = (item, type) => {
2325
if (type === 'category') {
@@ -90,6 +92,8 @@ function App() {
9092
cartCount={cartItems.reduce((sum, i) => sum + i.qty, 0)}
9193
wishlistCount={wishlistItems.length}
9294
activeNav={activeNav}
95+
loggedInUser={loggedInUser}
96+
onLogout={() => setLoggedInUser(null)}
9397
/>
9498

9599
<main className="app-main">
@@ -159,14 +163,15 @@ function App() {
159163
wishlistItems={wishlistItems}
160164
onRemoveFromCart={removeFromCart}
161165
onToggleWishlist={toggleWishlist}
166+
onLoginSuccess={setLoggedInUser}
162167
/>
163168
)}
164169
</AnimatePresence>
165170
</div>
166171
)
167172
}
168173

169-
const Overlay = ({ type, onClose, cartItems, wishlistItems, onRemoveFromCart, onToggleWishlist }) => {
174+
const Overlay = ({ type, onClose, cartItems, wishlistItems, onRemoveFromCart, onToggleWishlist, onLoginSuccess }) => {
170175
const [isSignUp, setIsSignUp] = useState(false);
171176
const isDrawer = type === 'cart' || type === 'wishlist';
172177
const cartTotal = cartItems.reduce((sum, i) => sum + i.price * i.qty, 0);
@@ -276,7 +281,8 @@ const Overlay = ({ type, onClose, cartItems, wishlistItems, onRemoveFromCart, on
276281
<div className="google-btn-wrap">
277282
<GoogleLogin
278283
onSuccess={(credentialResponse) => {
279-
console.log('Google login success', credentialResponse);
284+
const decoded = jwtDecode(credentialResponse.credential);
285+
onLoginSuccess(decoded);
280286
onClose();
281287
}}
282288
onError={() => console.log('Google login failed')}

frontend/src/components/Header.jsx

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import React, { useState } from 'react';
22
import { Search, ShoppingCart, Heart, User, Menu, X } from 'lucide-react';
33

4-
const Header = ({ onOpenOverlay, onNavigate, cartCount, wishlistCount, activeNav }) => {
4+
const Header = ({ onOpenOverlay, onNavigate, cartCount, wishlistCount, activeNav, loggedInUser, onLogout }) => {
55
const [isSearchFocused, setIsSearchFocused] = useState(false);
66
const [isMobileMenuOpen, setIsMobileMenuOpen] = useState(false);
77

@@ -51,9 +51,17 @@ const Header = ({ onOpenOverlay, onNavigate, cartCount, wishlistCount, activeNav
5151
</div>
5252

5353
<div className="user-actions">
54-
<button className="action-btn" title="Profile" onClick={() => onOpenOverlay('login')}>
55-
<User size={22} />
56-
</button>
54+
{loggedInUser ? (
55+
<div className="user-profile-btn">
56+
<img src={loggedInUser.picture} alt={loggedInUser.name} className="user-avatar" />
57+
<span className="user-name">{loggedInUser.name.split(' ')[0]}</span>
58+
<button className="logout-btn" onClick={onLogout}>Logout</button>
59+
</div>
60+
) : (
61+
<button className="action-btn" title="Profile" onClick={() => onOpenOverlay('login')}>
62+
<User size={22} />
63+
</button>
64+
)}
5765
<button className="action-btn" title="Wishlist" onClick={() => onOpenOverlay('wishlist')}>
5866
<Heart size={22} />
5967
{wishlistCount > 0 && <span className="badge">{wishlistCount}</span>}

frontend/src/index.css

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1004,3 +1004,10 @@ ul {
10041004
/* Google Login Button */
10051005
.google-btn-wrap { display: flex; justify-content: center; width: 100%; margin-top: 4px; }
10061006
.google-btn-wrap > div { width: 100% !important; }
1007+
1008+
/* User Profile in Header */
1009+
.user-profile-btn { display: flex; align-items: center; gap: 8px; }
1010+
.user-avatar { width: 32px; height: 32px; border-radius: 50%; object-fit: cover; }
1011+
.user-name { font-size: 13px; font-weight: 600; }
1012+
.logout-btn { font-size: 12px; background: none; border: 1px solid #ddd; border-radius: 6px; padding: 4px 10px; cursor: pointer; color: #666; }
1013+
.logout-btn:hover { border-color: #e85d04; color: #e85d04; }

0 commit comments

Comments
 (0)