Files
parcer/src/components/dashboard/MainMenu.tsx

284 lines
9.9 KiB
TypeScript
Raw Normal View History

2026-01-19 14:33:24 +05:30
import React, { useState, useEffect } from 'react';
2024-06-24 22:42:37 +05:30
import Tabs from '@mui/material/Tabs';
import Tab from '@mui/material/Tab';
import Box from '@mui/material/Box';
2025-09-19 01:01:24 +05:30
import { useNavigate, useLocation } from 'react-router-dom';
2025-10-13 18:02:32 +05:30
import { Paper, Button, useTheme, Modal, Typography, Stack, Divider } from "@mui/material";
2026-01-19 14:32:31 +05:30
import { AutoAwesome, VpnKey, Usb, CloudQueue, Description, Favorite, SlowMotionVideo, PlayArrow, ArrowForwardIos, Star } from "@mui/icons-material";
2024-12-10 20:40:59 +05:30
import { useTranslation } from 'react-i18next';
2024-06-24 22:42:37 +05:30
interface MainMenuProps {
value: string;
handleChangeContent: (newValue: string) => void;
}
2025-01-09 23:17:58 +05:30
export const MainMenu = ({ value = 'robots', handleChangeContent }: MainMenuProps) => {
2024-11-07 00:46:47 +05:30
const theme = useTheme();
2025-01-09 17:15:26 +05:30
const { t } = useTranslation();
const navigate = useNavigate();
2025-09-19 01:01:24 +05:30
const location = useLocation();
2025-07-31 23:54:21 +05:30
2025-07-31 23:19:05 +05:30
const [sponsorModalOpen, setSponsorModalOpen] = useState(false);
const [docModalOpen, setDocModalOpen] = useState(false);
2026-01-19 14:32:31 +05:30
const [starCount, setStarCount] = useState<number | null>(null);
const [isLoading, setIsLoading] = useState(false);
2025-07-31 23:19:05 +05:30
2026-01-19 14:32:31 +05:30
useEffect(() => {
const fetchStarCount = async () => {
setIsLoading(true);
try {
const response = await fetch('https://api.github.com/repos/getmaxun/maxun', {
headers: {
'Accept': 'application/vnd.github.v3+json'
}
});
if (response.ok) {
const data = await response.json();
setStarCount(data.stargazers_count);
} else {
console.error('Failed to fetch GitHub star count');
}
} catch (error) {
console.error('Error fetching GitHub star count:', error);
} finally {
setIsLoading(false);
}
};
fetchStarCount();
// Optional: Refresh star count every 5 minutes
const intervalId = setInterval(fetchStarCount, 5 * 60 * 1000);
return () => clearInterval(intervalId);
}, []);
2024-06-24 22:42:37 +05:30
const handleChange = (event: React.SyntheticEvent, newValue: string) => {
2025-01-09 23:14:03 +05:30
navigate(`/${newValue}`);
2024-06-24 22:42:37 +05:30
handleChangeContent(newValue);
};
2025-09-19 01:01:24 +05:30
const handleRobotsClick = () => {
if (location.pathname !== '/robots') {
navigate('/robots');
handleChangeContent('robots');
}
};
const defaultcolor = theme.palette.mode === 'light' ? 'black' : 'white';
2025-01-08 21:31:17 +05:30
const buttonStyles = {
justifyContent: 'flex-start',
textAlign: 'left',
2026-01-19 14:13:36 +05:30
fontSize: '15px',
2025-08-25 19:59:35 +05:30
letterSpacing: '0.02857em',
padding: '20px 20px 20px 22px',
2025-01-08 21:31:17 +05:30
minHeight: '48px',
minWidth: '100%',
display: 'flex',
alignItems: 'center',
textTransform: 'none',
color: theme.palette.mode === 'light' ? '#6C6C6C' : 'inherit',
2025-08-25 20:05:20 +05:30
'&:hover': {
2025-08-25 19:59:35 +05:30
color: theme.palette.mode === 'light' ? '#6C6C6C' : 'inherit',
2025-06-27 17:04:31 +05:30
backgroundColor: theme.palette.mode === 'light' ? '#f5f5f5' : 'inherit',
2025-06-13 19:10:12 +05:30
},
2025-01-08 21:31:17 +05:30
};
2025-01-09 17:15:26 +05:30
2026-01-19 14:32:31 +05:30
const starButtonStyles = {
justifyContent: 'flex-start',
textAlign: 'left',
fontSize: '15px',
padding: '12px 20px 12px 22px',
minHeight: '48px',
minWidth: '100%',
display: 'flex',
alignItems: 'center',
textTransform: 'none',
color: theme.palette.mode === 'light' ? '#6C6C6C' : 'inherit',
backgroundColor: theme.palette.mode === 'light' ? '#fafafa' : 'rgba(255, 255, 255, 0.04)',
'&:hover': {
color: theme.palette.mode === 'light' ? '#6C6C6C' : 'inherit',
backgroundColor: theme.palette.mode === 'light' ? '#f0f0f0' : 'rgba(255, 255, 255, 0.08)',
},
};
2025-08-25 19:59:35 +05:30
2024-06-24 22:42:37 +05:30
return (
2025-07-31 23:19:05 +05:30
<>
<Paper
sx={{
height: '100%',
2025-11-05 22:03:59 +05:30
width: '230px',
2025-07-31 23:19:05 +05:30
backgroundColor: theme.palette.background.paper,
color: defaultcolor,
2026-01-19 14:32:31 +05:30
display: 'flex',
flexDirection: 'column',
2025-07-31 23:19:05 +05:30
}}
variant="outlined"
square
>
2026-01-19 14:32:31 +05:30
<Box sx={{
width: '100%',
paddingBottom: '1rem',
flexGrow: 1,
overflowY: 'auto'
}}>
2025-07-31 23:19:05 +05:30
<Tabs
2025-10-22 15:23:55 +05:30
value={value}
onChange={handleChange}
textColor="primary"
indicatorColor="primary"
orientation="vertical"
2026-01-19 14:32:31 +05:30
sx={{
alignItems: 'flex-start',
'& .MuiTabs-indicator': { display: 'none' },
paddingTop: '0.5rem'
}}
2025-10-22 15:23:55 +05:30
>
2025-10-13 16:52:51 +05:30
<Tab
value="robots"
label={t('mainmenu.recordings')}
2026-01-19 14:13:36 +05:30
icon={<AutoAwesome sx={{ fontSize: 20 }} />}
2025-10-13 16:52:51 +05:30
iconPosition="start"
2025-10-13 16:53:16 +05:30
disableRipple={true}
2026-01-19 14:13:36 +05:30
sx={{ justifyContent: 'flex-start', textAlign: 'left', fontSize: '16px' }}
2025-10-13 16:52:51 +05:30
onClick={handleRobotsClick} />
<Tab value="runs"
label={t('mainmenu.runs')}
2026-01-19 14:13:36 +05:30
icon={<PlayArrow sx={{ fontSize: 20 }} />}
2025-10-13 16:52:51 +05:30
iconPosition="start"
2025-10-13 16:53:24 +05:30
disableRipple={true}
2026-01-19 14:13:36 +05:30
sx={{ justifyContent: 'flex-start', textAlign: 'left', fontSize: '16px' }} />
2025-10-13 16:52:51 +05:30
<Tab value="proxy"
label={t('mainmenu.proxy')}
2026-01-19 14:13:36 +05:30
icon={<Usb sx={{ fontSize: 20 }} />}
2025-10-13 16:52:51 +05:30
iconPosition="start"
2025-10-13 16:53:33 +05:30
disableRipple={true}
2026-01-19 14:13:36 +05:30
sx={{ justifyContent: 'flex-start', textAlign: 'left', fontSize: '16px' }} />
2025-10-13 16:52:51 +05:30
<Tab value="apikey"
label={t('mainmenu.apikey')}
2026-01-19 14:13:36 +05:30
icon={<VpnKey sx={{ fontSize: 20 }}/>}
2025-10-13 16:52:51 +05:30
iconPosition="start"
2025-10-13 16:53:44 +05:30
disableRipple={true}
2026-01-19 14:13:36 +05:30
sx={{ justifyContent: 'flex-start', textAlign: 'left', fontSize: '16px' }} />
2025-07-31 23:19:05 +05:30
</Tabs>
2025-10-13 18:02:11 +05:30
<Divider sx={{ borderColor: theme.palette.mode === 'dark' ? "#080808ff" : "" }} />
2025-07-31 23:19:05 +05:30
<Box sx={{ display: 'flex', flexDirection: 'column', textAlign: 'left' }}>
2026-01-19 13:57:32 +05:30
<Button
href='https://docs.maxun.dev/sdk/sdk-overview'
target="_blank"
rel="noopener noreferrer"
2026-01-19 14:05:51 +05:30
sx={buttonStyles} startIcon={<ArrowForwardIos sx={{ fontSize: 20 }} />}>
2026-01-19 13:57:32 +05:30
SDK
</Button>
<Button
onClick={() => setDocModalOpen(true)}
sx={buttonStyles}
2025-10-09 00:02:28 +05:30
startIcon={<Description sx={{ fontSize: 20 }} />}
>
2025-07-31 23:19:05 +05:30
Documentation
</Button>
<Modal open={docModalOpen ?? false} onClose={() => setDocModalOpen(false)}>
<Box sx={{ position: 'absolute', top: '50%', left: '50%', transform: 'translate(-50%, -50%)', bgcolor: 'background.paper', borderRadius: 2, p: 4, width: 400 }}>
2025-09-29 17:12:22 +05:30
<Stack spacing={2}>
<Button
href="https://docs.maxun.dev"
target="_blank"
rel="noopener noreferrer"
variant="outlined"
startIcon={<Description />}
fullWidth
>
Documentation
</Button>
<Button
href="https://www.youtube.com/@MaxunOSS/videos"
target="_blank"
rel="noopener noreferrer"
variant="outlined"
startIcon={<SlowMotionVideo />}
fullWidth
>
Video Tutorials
</Button>
</Stack>
</Box>
</Modal>
2025-09-29 17:12:22 +05:30
<Button
href='https://app.maxun.dev/'
target="_blank"
rel="noopener noreferrer"
2026-01-19 14:13:36 +05:30
sx={buttonStyles} startIcon={<CloudQueue sx={{ fontSize: 16 }} />}>
2025-07-31 23:21:50 +05:30
Join Maxun Cloud
2025-07-31 23:19:05 +05:30
</Button>
2026-01-19 14:13:36 +05:30
<Button onClick={() => setSponsorModalOpen(true)} sx={buttonStyles} startIcon={<Favorite sx={{ fontSize: 16 }} />}>
2025-07-31 23:19:05 +05:30
Sponsor Us
</Button>
</Box>
</Box>
2026-01-19 14:32:31 +05:30
<Button
href="https://github.com/getmaxun/maxun"
target="_blank"
rel="noopener noreferrer"
sx={starButtonStyles}
startIcon={
<Star
sx={{
fontSize: 16,
color: theme.palette.mode === 'light' ? '#ffb400' : '#ffd740'
}}
/>
}
>
<Box sx={{ display: 'flex', alignItems: 'center', gap: 1 }}>
<span>Star us on GitHub</span>
{isLoading ? (
<Typography
variant="caption"
sx={{
color: theme.palette.mode === 'light' ? '#666' : '#aaa',
fontSize: '0.75rem'
}}
>
...
</Typography>
) : starCount !== null ? (
<Box
sx={{
backgroundColor: theme.palette.mode === 'light' ? '#f0f0f0' : 'rgba(255, 255, 255, 0.1)',
borderRadius: '12px',
padding: '2px 8px',
fontSize: '0.75rem',
color: theme.palette.mode === 'light' ? '#666' : '#ccc',
fontWeight: 500,
}}
>
{starCount.toLocaleString()}
</Box>
) : null}
</Box>
</Button>
2025-07-31 23:19:05 +05:30
</Paper>
2026-01-19 14:32:31 +05:30
2025-07-31 23:19:05 +05:30
<Modal open={sponsorModalOpen} onClose={() => setSponsorModalOpen(false)}>
2025-11-15 17:48:19 +05:30
<Box sx={{ position: 'absolute', top: '50%', left: '50%', transform: 'translate(-50%, -50%)', bgcolor: 'rgba(13, 13, 13, 1)', borderRadius: 2, p: 4, width: 600 }}>
2025-07-31 23:35:23 +05:30
<Typography variant="h6" marginBottom={4}>
2025-07-31 23:19:05 +05:30
Support Maxun Open Source
</Typography>
<Typography variant="body1" gutterBottom>
2025-07-31 23:31:29 +05:30
Maxun is built by a small, full-time team. Your donations directly contribute to making it better.
<br />
2025-10-13 19:34:43 +05:30
Thank you for your support! 🩷
2025-07-31 23:19:05 +05:30
</Typography>
2025-10-13 19:38:06 +05:30
<Stack direction="row" spacing={2} mt={4}>
2025-10-13 19:33:50 +05:30
<Button href="https://github.com/sponsors/amhsirak" target="_blank" rel="noopener noreferrer" variant="outlined" fullWidth>
2025-10-13 19:32:45 +05:30
Sponsor Maxun on GitHub Sponsors
2025-07-31 23:19:05 +05:30
</Button>
</Stack>
</Box>
</Modal>
</>
2024-06-24 22:42:37 +05:30
);
2026-01-19 14:32:31 +05:30
};