Changeset e599341 for components/Navbar.tsx
- Timestamp:
- 12/28/25 00:07:22 (7 months ago)
- Branches:
- main
- Children:
- 9c87509
- Parents:
- f7c0b0d
- File:
-
- 1 edited
-
components/Navbar.tsx (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
components/Navbar.tsx
rf7c0b0d re599341 4 4 import Typography from "@mui/material/Typography"; 5 5 import Button from "@mui/material/Button"; 6 import InputBase from "@mui/material/InputBase";7 6 import Box from "@mui/material/Box"; 8 import { styled } from "@mui/material/styles"; 7 import Menu from "@mui/material/Menu"; 8 import MenuItem from "@mui/material/MenuItem"; 9 import KeyboardArrowDownIcon from '@mui/icons-material/KeyboardArrowDown'; 10 import { 11 Dialog, DialogTitle, DialogContent, DialogContentText, DialogActions, ListItemText 12 } from "@mui/material"; 13 14 import MemoryIcon from '@mui/icons-material/Memory'; 15 import DeveloperBoardIcon from '@mui/icons-material/DeveloperBoard'; 16 import StorageIcon from '@mui/icons-material/Storage'; 17 import SdStorageIcon from '@mui/icons-material/SdStorage'; 18 import RouterIcon from '@mui/icons-material/Router'; 19 import LanIcon from '@mui/icons-material/Lan'; 20 import SpeakerIcon from '@mui/icons-material/Speaker'; 21 import AlbumIcon from '@mui/icons-material/Album'; 22 import SdCardIcon from '@mui/icons-material/SdCard'; 23 import CableIcon from '@mui/icons-material/Cable'; 24 9 25 import LogoUrl from '../assets/projectlogo.png'; 10 import { onGetAuthState} from "../pages/+Layout.telefunc";26 import { onGetAuthState } from "../pages/+Layout.telefunc"; 11 27 28 import ComponentDialog from "./ComponentDialog"; 12 29 13 type AuthState = { isLoggedIn: boolean; username: string | null }; 30 type AuthState = { isLoggedIn: boolean; username: string | null; isAdmin?: boolean }; 31 32 const COMPONENT_CATEGORIES = [ 33 { id: 'cpu', label: 'Processors', icon: <MemoryIcon fontSize="small" /> }, 34 { id: 'gpu', label: 'Graphics Cards', icon: <DeveloperBoardIcon fontSize="small" /> }, 35 { id: 'motherboard', label: 'Motherboards', icon: <DeveloperBoardIcon fontSize="small" /> }, 36 { id: 'memory', label: 'Memory (RAM)', icon: <SdStorageIcon fontSize="small" /> }, 37 { id: 'storage', label: 'Storage', icon: <StorageIcon fontSize="small" /> }, 38 { id: 'case', label: 'Cases', icon: <StorageIcon fontSize="small" /> }, 39 { id: 'power_supply', label: 'Power Supplies', icon: <StorageIcon fontSize="small" /> }, 40 { id: 'cooler', label: 'Cooling', icon: <StorageIcon fontSize="small" /> }, 41 42 // Peripherals / Accessories (Missing ones) 43 { id: 'network_adapter', label: 'Network Adapters (WiFi)', icon: <RouterIcon fontSize="small" /> }, 44 { id: 'network_card', label: 'Network Cards (Ethernet)', icon: <LanIcon fontSize="small" /> }, 45 { id: 'sound_card', label: 'Sound Cards', icon: <SpeakerIcon fontSize="small" /> }, 46 { id: 'optical_drive', label: 'Optical Drives', icon: <AlbumIcon fontSize="small" /> }, 47 { id: 'memory_card', label: 'Memory Cards', icon: <SdCardIcon fontSize="small" /> }, 48 { id: 'cables', label: 'Cables', icon: <CableIcon fontSize="small" /> }, 49 ]; 50 14 51 15 52 export default function Navbar() { 16 53 const [auth, setAuth] = useState<AuthState | null>(null); 54 const [openLogoutDialog, setOpenLogoutDialog] = useState(false); 17 55 18 const handleLogout = async (e: React.MouseEvent) => { // funkcija za logout da go resetira auth state, za da ne go pise username-ot u navbar, plus te vrakja na login nazad 56 const [anchorEl, setAnchorEl] = useState<null | HTMLElement>(null); 57 const openMenu = Boolean(anchorEl); 58 59 const [browserOpen, setBrowserOpen] = useState(false); 60 const [selectedCategory, setSelectedCategory] = useState<string | null>(null); 61 62 const handleComponentsClick = (event: React.MouseEvent<HTMLButtonElement>) => { 63 setAnchorEl(event.currentTarget); 64 }; 65 66 const handleMenuClose = () => { 67 setAnchorEl(null); 68 }; 69 70 const handleCategorySelect = (categoryId: string) => { 71 setSelectedCategory(categoryId); 72 setBrowserOpen(true); 73 handleMenuClose(); 74 }; 75 76 const handleLogoutClick = (e: React.MouseEvent) => { 19 77 e.preventDefault(); 78 setOpenLogoutDialog(true); 79 }; 20 80 21 setAuth({ isLoggedIn: false, username: null }); 22 window.location.href = "/api/auth/signout?callbackUrl=/auth/login"; 81 const confirmLogout = async () => { 82 setAuth({ isLoggedIn: false, username: null, isAdmin: false }); 83 setOpenLogoutDialog(false); 84 const csrfRes = await fetch("/api/auth/csrf"); 85 const { csrfToken } = await csrfRes.json(); 86 await fetch("/api/auth/signout", { 87 method: "POST", 88 headers: { "Content-Type": "application/x-www-form-urlencoded" }, 89 body: new URLSearchParams({ csrfToken: csrfToken, callbackUrl: "/" }), 90 }); 91 window.location.href = "/"; 23 92 }; 24 93 … … 26 95 let active = true; 27 96 onGetAuthState() 28 .then((data) => active && setAuth({ isLoggedIn: data.isLoggedIn, username: data.username })) 29 .catch(() => active && setAuth({ isLoggedIn: false, username: null })); 97 .then((data) => active && setAuth({ 98 isLoggedIn: data.isLoggedIn, 99 username: data.username, 100 isAdmin: data.isAdmin 101 })) 102 .catch(() => active && setAuth({ isLoggedIn: false, username: null, isAdmin: false })); 30 103 return () => { active = false; }; 31 104 }, []); 32 105 106 const checkDashboardUrl = auth?.isAdmin ? '/dashboard/admin' : '/dashboard/user'; 33 107 const onHoverNav = { 34 108 color: 'inherit', 35 '&:hover': { 36 backgroundColor: '#ff8201', 37 color: 'white', 38 fontWeight: 'bold', 39 } 109 '&:hover': { backgroundColor: '#ff8201', color: 'white', fontWeight: 'bold' } 40 110 }; 41 111 42 112 return ( 43 <AppBar position="static" color="default" enableColorOnDark> 44 <Toolbar> 45 <Box sx={{ display: 'flex', alignItems: 'center', mr: 4 }}> 46 <Box 47 component="img" 48 src={LogoUrl} 49 alt="PC Forge Logo" 50 sx={{ height: 40, mr: 2, cursor: 'pointer' }} 51 /> 52 <Typography 53 variant="h6" 54 component="a" 55 href="/" 56 sx={{ textDecoration: "none", color: "inherit", fontWeight: "bold" }} 57 > 58 PC Forge 59 </Typography> 60 </Box> 113 <> 114 <AppBar position="static" color="default" enableColorOnDark> 115 <Toolbar> 116 <Box sx={{ display: 'flex', alignItems: 'center', mr: 4 }}> 117 <Box component="img" src={LogoUrl} alt="PC Forge Logo" sx={{ height: 40, mr: 2, cursor: 'pointer' }} onClick={() => window.location.href='/'} /> 118 <Typography variant="h6" component="a" href="/" sx={{ textDecoration: "none", color: "inherit", fontWeight: "bold" }}> 119 PC Forge 120 </Typography> 121 </Box> 61 122 62 <Box sx={{ display: { xs: "none", md: "flex" }, gap: 2}}> 63 <Button color="inherit" href="/forge" sx={onHoverNav}>Forge</Button> 64 <Button color="inherit" href="/components" sx={onHoverNav}>Components</Button> 65 <Button color="inherit" href="/completed-builds" sx={onHoverNav}>Completed Builds</Button> 66 </Box> 123 <Box sx={{ display: { xs: "none", md: "flex" }, gap: 2 }}> 124 <Button color="inherit" href="/forge" sx={onHoverNav}>Forge</Button> 67 125 68 <Box sx={{ flexGrow: 1 }} /> 126 <Button 127 color="inherit" 128 onClick={handleComponentsClick} 129 endIcon={<KeyboardArrowDownIcon />} 130 sx={onHoverNav} 131 > 132 Components 133 </Button> 134 <Menu 135 anchorEl={anchorEl} 136 open={openMenu} 137 onClose={handleMenuClose} 138 MenuListProps={{ 'aria-labelledby': 'basic-button' }} 139 > 140 {COMPONENT_CATEGORIES.map((cat) => ( 141 <MenuItem key={cat.id} onClick={() => handleCategorySelect(cat.id)}> 142 {/*<ListItemIcon>{cat.icon}</ListItemIcon>*/} 143 <ListItemText>{cat.label}</ListItemText> 144 </MenuItem> 145 ))} 146 </Menu> 69 147 70 <Box sx={{ display: 'flex', gap: 1 }}> 71 {auth?.isLoggedIn ? ( 72 <> 73 <Button sx={onHoverNav} color="inherit" href="/dashboard/user">{auth.username}</Button> 74 <Button sx={onHoverNav} color="inherit" onClick={handleLogout}>Logout</Button> 75 </> 76 ) : ( 77 <> 78 <Button color="inherit" href="/auth/login">Login</Button> 79 <Button color="inherit" href="/auth/register">Register</Button> 80 </> 81 )} 82 </Box> 83 </Toolbar> 84 </AppBar> 148 <Button color="inherit" href="/completed-builds" sx={onHoverNav}>Completed Builds</Button> 149 </Box> 150 151 <Box sx={{ flexGrow: 1 }} /> 152 153 <Box sx={{ display: 'flex', gap: 1 }}> 154 {auth?.isLoggedIn ? ( 155 <> 156 <Button sx={onHoverNav} color="inherit" href={checkDashboardUrl}>{auth.username}</Button> 157 <Button sx={onHoverNav} color="inherit" onClick={handleLogoutClick}>Logout</Button> 158 </> 159 ) : ( 160 <> 161 <Button color="inherit" href="/auth/login">Login</Button> 162 <Button color="inherit" href="/auth/register">Register</Button> 163 </> 164 )} 165 </Box> 166 </Toolbar> 167 </AppBar> 168 169 <Dialog open={openLogoutDialog} onClose={() => setOpenLogoutDialog(false)}> 170 <DialogTitle>Confirm Logout</DialogTitle> 171 <DialogContent> 172 <DialogContentText>Are you sure you want to leave the Forge?</DialogContentText> 173 </DialogContent> 174 <DialogActions> 175 <Button onClick={() => setOpenLogoutDialog(false)}>Cancel</Button> 176 <Button onClick={confirmLogout} color="error" variant="contained" autoFocus>Logout</Button> 177 </DialogActions> 178 </Dialog> 179 180 <ComponentDialog 181 open={browserOpen} 182 category={selectedCategory} 183 onClose={() => setBrowserOpen(false)} 184 /> 185 </> 85 186 ); 86 187 }
Note:
See TracChangeset
for help on using the changeset viewer.
