Files
parcer/src/components/molecules/NavBar.tsx

265 lines
6.4 KiB
TypeScript
Raw Normal View History

2024-09-25 20:27:56 +05:30
import React, { useState, useContext } from 'react';
import axios from 'axios';
2024-11-24 00:49:39 +05:30
import { useNavigate } from 'react-router-dom';
import {
IconButton,
Menu,
MenuItem,
Typography,
Tooltip,
Chip
} from "@mui/material";
import {
AccountCircle,
Logout,
Clear,
Brightness4,
Brightness7
} from "@mui/icons-material";
2024-06-24 22:34:54 +05:30
import styled from "styled-components";
2024-11-24 00:49:39 +05:30
2024-06-24 22:34:54 +05:30
import { stopRecording } from "../../api/recording";
import { useGlobalInfoStore } from "../../context/globalInfo";
2024-09-25 20:27:56 +05:30
import { AuthContext } from '../../context/auth';
2024-10-28 19:06:43 +05:30
import { SaveRecording } from '../molecules/SaveRecording';
2024-10-29 08:44:50 +05:30
import DiscordIcon from '../atoms/DiscordIcon';
2024-11-01 08:25:33 +05:30
import { apiUrl } from '../../apiConfig';
2024-11-03 21:18:17 +05:30
import MaxunLogo from "../../assets/maxunlogo.png";
2024-11-07 00:46:47 +05:30
import { useThemeMode } from '../../context/theme-provider';
2024-06-24 22:34:54 +05:30
interface NavBarProps {
recordingName: string;
isRecording: boolean;
}
2024-10-21 01:13:06 +05:30
export const NavBar: React.FC<NavBarProps> = ({ recordingName, isRecording }) => {
2024-11-07 00:46:47 +05:30
const { notify, browserId, setBrowserId } = useGlobalInfoStore();
2024-09-25 20:27:56 +05:30
const { state, dispatch } = useContext(AuthContext);
const { user } = state;
2024-10-28 19:06:43 +05:30
const navigate = useNavigate();
2024-11-07 00:46:47 +05:30
const { darkMode, toggleTheme } = useThemeMode();
2024-10-28 19:06:43 +05:30
const [anchorEl, setAnchorEl] = useState<null | HTMLElement>(null);
2024-10-11 04:57:48 +05:30
2024-10-28 19:06:43 +05:30
const handleMenuOpen = (event: React.MouseEvent<HTMLElement>) => {
setAnchorEl(event.currentTarget);
};
2024-10-11 04:48:25 +05:30
2024-10-28 19:06:43 +05:30
const handleMenuClose = () => {
setAnchorEl(null);
};
2024-06-24 22:34:54 +05:30
2024-09-25 20:27:56 +05:30
const logout = async () => {
dispatch({ type: 'LOGOUT' });
window.localStorage.removeItem('user');
2024-11-01 08:25:33 +05:30
const { data } = await axios.get(`${apiUrl}/auth/logout`);
2024-09-25 20:27:56 +05:30
notify('success', data.message);
navigate('/login');
};
2024-09-10 02:49:30 +05:30
const goToMainMenu = async () => {
2024-06-24 22:34:54 +05:30
if (browserId) {
await stopRecording(browserId);
notify('warning', 'Current Recording was terminated');
setBrowserId(null);
}
2024-09-10 02:52:07 +05:30
navigate('/');
2024-06-24 22:34:54 +05:30
};
2024-11-24 00:49:39 +05:30
const renderBrandSection = () => (
<BrandContainer>
<LogoImage src={MaxunLogo} alt="Maxun Logo" />
<ProjectName mode={darkMode ? 'dark' : 'light'}>Maxun</ProjectName>
<Chip
label="beta"
variant="outlined"
sx={{
marginTop: '10px',
borderColor: '#ff00c3',
color: '#ff00c3'
}}
/>
</BrandContainer>
);
const renderSocialButtons = () => (
<>
<IconButton
component="a"
href="https://discord.gg/5GbPjBUkws"
target="_blank"
rel="noopener noreferrer"
sx={{
...styles.socialButton,
color: darkMode ? '#ffffff' : '#333333',
'&:hover': {
color: '#ff00c3'
}
}}
>
<DiscordIcon sx={{ marginRight: '5px' }} />
</IconButton>
<iframe
src="https://ghbtns.com/github-btn.html?user=getmaxun&repo=maxun&type=star&count=true&size=large"
frameBorder="0"
scrolling="0"
width="170"
height="30"
title="GitHub"
/>
</>
);
const renderUserMenu = () => (
<>
<IconButton
onClick={handleMenuOpen}
sx={styles.userButton(darkMode)}
>
<AccountCircle sx={{ marginRight: '5px' }} />
<Typography variant="body1">{user?.email}</Typography>
</IconButton>
<Menu
anchorEl={anchorEl}
open={Boolean(anchorEl)}
onClose={handleMenuClose}
anchorOrigin={{ vertical: 'bottom', horizontal: 'right' }}
transformOrigin={{ vertical: 'top', horizontal: 'right' }}
PaperProps={{
sx: {
backgroundColor: darkMode ? '#1e2124' : '#ffffff',
color: darkMode ? '#ffffff' : '#333333'
}
}}
>
<MenuItem onClick={() => { handleMenuClose(); logout(); }}>
<Logout sx={{ marginRight: '5px' }} /> Logout
</MenuItem>
</Menu>
</>
);
const renderThemeToggle = () => (
<Tooltip title="Toggle light/dark theme">
<IconButton
onClick={toggleTheme}
sx={{
color: darkMode ? '#ffffff' : '#333333',
'&:hover': {
color: '#ff00c3'
}
}}
>
{darkMode ? <Brightness7 /> : <Brightness4 />}
</IconButton>
</Tooltip>
);
const renderRecordingControls = () => (
<>
<IconButton
onClick={goToMainMenu}
sx={styles.discardButton}
>
<Clear sx={{ marginRight: '5px' }} />
Discard
</IconButton>
<SaveRecording fileName={recordingName} />
</>
);
2024-06-24 22:34:54 +05:30
return (
2024-12-08 05:46:00 +05:30
2024-11-07 00:46:47 +05:30
<NavBarWrapper mode={darkMode ? 'dark' : 'light'}>
2024-11-24 00:49:39 +05:30
{renderBrandSection()}
{user && (
<ControlsContainer>
{!isRecording ? (
2024-11-07 00:46:47 +05:30
<>
2024-11-24 00:49:39 +05:30
{renderSocialButtons()}
{renderUserMenu()}
{renderThemeToggle()}
2024-11-07 00:46:47 +05:30
</>
2024-11-24 00:49:39 +05:30
) : (
renderRecordingControls()
2024-11-07 00:46:47 +05:30
)}
2024-11-24 00:49:39 +05:30
</ControlsContainer>
)}
2024-12-08 05:46:00 +05:30
2024-06-24 22:34:54 +05:30
</NavBarWrapper>
);
};
2024-11-24 00:49:39 +05:30
// Styles
const styles = {
socialButton: {
display: 'flex',
alignItems: 'center',
borderRadius: '5px',
padding: '8px',
marginRight: '30px',
color: '#333333',
'&:hover': {
color: '#ff00c3'
}
},
userButton: (darkMode: boolean) => ({
display: 'flex',
alignItems: 'center',
borderRadius: '5px',
padding: '8px',
marginRight: '10px',
color: darkMode ? '#ffffff' : '#333333',
'&:hover': {
backgroundColor: darkMode ? '#333' : '#F5F5F5',
color: '#ff00c3'
}
}),
discardButton: {
borderRadius: '5px',
padding: '8px',
background: 'red',
color: 'white',
marginRight: '10px',
'&:hover': {
color: 'white',
backgroundColor: '#ff0000'
}
}
};
// Styled Components
2024-11-07 00:46:47 +05:30
const NavBarWrapper = styled.div<{ mode: 'light' | 'dark' }>`
2024-06-24 22:34:54 +05:30
grid-area: navbar;
2024-11-07 00:46:47 +05:30
background-color: ${({ mode }) => (mode === 'dark' ? '#1e2124' : '#ffffff')};
padding: 5px;
2024-06-24 22:34:54 +05:30
display: flex;
justify-content: space-between;
2024-11-07 00:46:47 +05:30
border-bottom: 1px solid ${({ mode }) => (mode === 'dark' ? '#333' : '#e0e0e0')};
2024-06-24 22:34:54 +05:30
`;
2024-11-24 00:49:39 +05:30
const BrandContainer = styled.div`
display: flex;
justify-content: flex-start;
`;
const LogoImage = styled.img.attrs({
width: 45,
height: 40,
})`
border-radius: 5px;
margin: 5px 0px 5px 15px;
`;
2024-11-07 00:46:47 +05:30
const ProjectName = styled.b<{ mode: 'light' | 'dark' }>`
2024-11-24 00:49:39 +05:30
color: ${({ mode }) => (mode === 'dark' ? 'white' : '#333333')};
2024-06-24 22:34:54 +05:30
font-size: 1.3em;
2024-11-24 00:49:39 +05:30
padding: 11px;
2024-06-24 22:34:54 +05:30
`;
2024-11-24 00:49:39 +05:30
const ControlsContainer = styled.div`
display: flex;
align-items: center;
justify-content: flex-end;
2024-12-08 05:41:11 +05:30
`;