feat: github star counter

This commit is contained in:
amhsirak
2026-01-19 14:32:31 +05:30
parent 5c993d73fe
commit d96811cf99

View File

@@ -1,10 +1,10 @@
import React, { useState } from 'react'; import React, { useState, useEffect } from 'react'; // Added useEffect
import Tabs from '@mui/material/Tabs'; import Tabs from '@mui/material/Tabs';
import Tab from '@mui/material/Tab'; import Tab from '@mui/material/Tab';
import Box from '@mui/material/Box'; import Box from '@mui/material/Box';
import { useNavigate, useLocation } from 'react-router-dom'; import { useNavigate, useLocation } from 'react-router-dom';
import { Paper, Button, useTheme, Modal, Typography, Stack, Divider } from "@mui/material"; import { Paper, Button, useTheme, Modal, Typography, Stack, Divider } from "@mui/material";
import { AutoAwesome, VpnKey, Usb, CloudQueue, Description, Favorite, SlowMotionVideo, PlayArrow, ArrowForwardIos } from "@mui/icons-material"; import { AutoAwesome, VpnKey, Usb, CloudQueue, Description, Favorite, SlowMotionVideo, PlayArrow, ArrowForwardIos, Star } from "@mui/icons-material";
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
import { useGlobalInfoStore } from "../../context/globalInfo"; import { useGlobalInfoStore } from "../../context/globalInfo";
@@ -22,9 +22,42 @@ export const MainMenu = ({ value = 'robots', handleChangeContent }: MainMenuProp
const [sponsorModalOpen, setSponsorModalOpen] = useState(false); const [sponsorModalOpen, setSponsorModalOpen] = useState(false);
const [docModalOpen, setDocModalOpen] = useState(false); const [docModalOpen, setDocModalOpen] = useState(false);
const [starCount, setStarCount] = useState<number | null>(null);
const [isLoading, setIsLoading] = useState(false);
const ossDiscountCode = "MAXUNOSS8"; const ossDiscountCode = "MAXUNOSS8";
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);
}, []);
const handleChange = (event: React.SyntheticEvent, newValue: string) => { const handleChange = (event: React.SyntheticEvent, newValue: string) => {
navigate(`/${newValue}`); navigate(`/${newValue}`);
handleChangeContent(newValue); handleChangeContent(newValue);
@@ -66,6 +99,23 @@ export const MainMenu = ({ value = 'robots', handleChangeContent }: MainMenuProp
}, },
}; };
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)',
},
};
return ( return (
<> <>
@@ -74,20 +124,30 @@ export const MainMenu = ({ value = 'robots', handleChangeContent }: MainMenuProp
height: '100%', height: '100%',
width: '230px', width: '230px',
backgroundColor: theme.palette.background.paper, backgroundColor: theme.palette.background.paper,
paddingTop: '0.5rem',
color: defaultcolor, color: defaultcolor,
display: 'flex',
flexDirection: 'column',
}} }}
variant="outlined" variant="outlined"
square square
> >
<Box sx={{ width: '100%', paddingBottom: '1rem' }}> <Box sx={{
width: '100%',
paddingBottom: '1rem',
flexGrow: 1,
overflowY: 'auto'
}}>
<Tabs <Tabs
value={value} value={value}
onChange={handleChange} onChange={handleChange}
textColor="primary" textColor="primary"
indicatorColor="primary" indicatorColor="primary"
orientation="vertical" orientation="vertical"
sx={{ alignItems: 'flex-start', '& .MuiTabs-indicator': { display: 'none' }}} sx={{
alignItems: 'flex-start',
'& .MuiTabs-indicator': { display: 'none' },
paddingTop: '0.5rem'
}}
> >
<Tab <Tab
value="robots" value="robots"
@@ -170,7 +230,51 @@ export const MainMenu = ({ value = 'robots', handleChangeContent }: MainMenuProp
</Button> </Button>
</Box> </Box>
</Box> </Box>
<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>
</Paper> </Paper>
<Modal open={sponsorModalOpen} onClose={() => setSponsorModalOpen(false)}> <Modal open={sponsorModalOpen} onClose={() => setSponsorModalOpen(false)}>
<Box sx={{ position: 'absolute', top: '50%', left: '50%', transform: 'translate(-50%, -50%)', bgcolor: 'rgba(13, 13, 13, 1)', borderRadius: 2, p: 4, width: 600 }}> <Box sx={{ position: 'absolute', top: '50%', left: '50%', transform: 'translate(-50%, -50%)', bgcolor: 'rgba(13, 13, 13, 1)', borderRadius: 2, p: 4, width: 600 }}>
<Typography variant="h6" marginBottom={4}> <Typography variant="h6" marginBottom={4}>
@@ -190,4 +294,4 @@ export const MainMenu = ({ value = 'robots', handleChangeContent }: MainMenuProp
</Modal> </Modal>
</> </>
); );
}; };