overall updates

This commit is contained in:
joshikannan
2025-11-26 18:24:03 +05:30
parent 12df2e9dc4
commit e71e44319c
35 changed files with 3145 additions and 2404 deletions

View File

@@ -5,11 +5,13 @@ import { Box, Card, CardContent, Grid, Typography } from '@mui/material';
// ===========================|| HOVER SOCIAL CARD ||=========================== //
const HoverSocialCard = ({ primary, secondary,
percentage,
const HoverSocialCard = ({
primary,
secondary,
percentage,
// iconPrimary,
color
}) => {
color
}) => {
// const IconPrimary = iconPrimary;
// const primaryIcon = iconPrimary ? <IconPrimary /> : null;
@@ -20,10 +22,10 @@ const HoverSocialCard = ({ primary, secondary,
background: color,
position: 'relative',
color: '#fff',
// '&:hover svg': {
// opacity: 1,
// transform: 'scale(1.1)'
// }
'&:hover svg': {
opacity: 1,
transform: 'scale(1.1)'
}
}}
>
<CardContent>
@@ -33,19 +35,18 @@ const HoverSocialCard = ({ primary, secondary,
right: 15,
top: 25,
color: '#fff',
// '& svg': {
// width: 36,
// height: 36,
// opacity: 0.5,
// transition: 'all .3s ease-in-out'
// }
'& svg': {
width: 36,
height: 36,
opacity: 0.5,
transition: 'all .3s ease-in-out'
}
}}
>
<Typography variant="h2" color="inherit">
{/* {percentage.toString()} % */}
{(percentage)? `${percentage.toString()} %`:''}
</Typography>
{/* {percentage.toString()} % */}
{percentage ? `${percentage.toString()} %` : ''}
</Typography>
{/* {primaryIcon} */}
</Box>
<Grid container spacing={0}>
@@ -69,7 +70,7 @@ HoverSocialCard.propTypes = {
primary: PropTypes.string,
secondary: PropTypes.string,
// iconPrimary: PropTypes.object,
percentage:PropTypes.string,
percentage: PropTypes.string,
color: PropTypes.string
};

View File

@@ -0,0 +1,55 @@
import { Dialog, DialogTitle, DialogContent, Typography, Stack, Button, DialogActions, Paper } from '@mui/material';
import { DateRangePicker } from 'mui-daterange-picker';
import dayjs from 'dayjs';
import { addDays, addWeeks, addMonths, startOfWeek, endOfWeek, startOfMonth, endOfMonth } from 'date-fns';
export default function DateFilterDialog({ open, onClose, onApply }) {
const definedRanges = [
{ label: 'Today', startDate: new Date(), endDate: new Date() },
{ label: 'Yesterday', startDate: addDays(new Date(), -1), endDate: addDays(new Date(), -1) },
{ label: 'Tomorrow', startDate: addDays(new Date(), 1), endDate: addDays(new Date(), 1) },
{ label: 'This Week', startDate: startOfWeek(new Date()), endDate: endOfWeek(new Date()) },
{ label: 'Last Week', startDate: startOfWeek(addWeeks(new Date(), -1)), endDate: endOfWeek(addWeeks(new Date(), -1)) },
{ label: 'Last 7 Days', startDate: addDays(new Date(), -7), endDate: new Date() },
{ label: 'This Month', startDate: startOfMonth(new Date()), endDate: endOfMonth(new Date()) },
{ label: 'Last Month', startDate: startOfMonth(addMonths(new Date(), -1)), endDate: endOfMonth(addMonths(new Date(), -1)) }
];
const handleSelect = (range) => {
if (!range?.startDate || !range?.endDate) return;
onApply({
startDate: dayjs(range.startDate).format('YYYY-MM-DD'),
endDate: dayjs(range.endDate).format('YYYY-MM-DD'),
label: range.label || ''
});
onClose();
};
return (
<Dialog open={open} onClose={onClose} fullWidth maxWidth="sm">
<DialogTitle disableTypography>
<Stack display="flex" flexDirection="row" justifyContent="space-between" alignItems="center" sx={{ width: '100%' }}>
<Typography variant="h4">Select Date Range</Typography>
</Stack>
</DialogTitle>
<DialogContent
sx={{
'& .MuiPaper-root': {
boxShadow: 'none !important'
}
}}
>
<DateRangePicker open={open} toggle={onClose} definedRanges={definedRanges} onChange={handleSelect} closeOnClickOutside={false} />
</DialogContent>
<DialogActions>
<Button variant="contained" onClick={onClose} sx={{ cursor: 'pointer' }}>
Close
</Button>
</DialogActions>
</Dialog>
);
}

View File

@@ -0,0 +1,58 @@
// SearchBar.jsx
import React, { useEffect, useRef } from 'react';
import { FormControl, OutlinedInput, InputAdornment, IconButton, useTheme } from '@mui/material';
import SearchOutlined from '@mui/icons-material/SearchOutlined';
import ClearIcon from '@mui/icons-material/Clear';
const SearchBar = ({ value, onChange, sx, placeholder = 'Search (Ctrl + K)' }) => {
const theme = useTheme();
const inputRef = useRef(null);
/* ============================================= || handleKeyPress (CTRL + K) and ESC ||============================================= */
useEffect(() => {
const handleKeyPress = (event) => {
// Focus input with CTRL + K / CMD + K
if (event.key === 'k' && (event.metaKey || event.ctrlKey)) {
event.preventDefault();
inputRef.current?.focus();
}
// ESC removes focus
if (event.key === 'Escape' && document.activeElement === inputRef.current) {
inputRef.current.blur();
}
};
document.addEventListener('keydown', handleKeyPress);
return () => document.removeEventListener('keydown', handleKeyPress);
}, []);
return (
<FormControl fullWidth sx={{}}>
<OutlinedInput
inputRef={inputRef}
placeholder={placeholder}
sx={{
borderRadius: 0,
...sx
}}
value={value}
onChange={onChange}
autoComplete="off"
size="large"
startAdornment={
<InputAdornment position="start" sx={{ mr: -0.5, color: theme.palette.primary.main }}>
<SearchOutlined />
</InputAdornment>
}
endAdornment={
<IconButton sx={{ visibility: value ? 'visible' : 'hidden' }} onClick={() => onChange({ target: { value: '' } })}>
<ClearIcon style={{ fontSize: 'large', color: theme.palette.primary.main }} />
</IconButton>
}
/>
</FormControl>
);
};
export default SearchBar;

View File

@@ -0,0 +1,96 @@
import { useEffect, useState, useRef } from 'react';
import { useTheme } from '@mui/material/styles';
import WifiOffIcon from '@mui/icons-material/WifiOff';
import WifiIcon from '@mui/icons-material/Wifi';
const NOTIFICATION_STYLE = {
position: 'fixed',
top: '10px', // Keep top spacing
left: '50%', // Center horizontally
transform: 'translateX(-50%)', // Offset to truly center
padding: '12px 40px',
borderRadius: '8px',
color: 'white',
fontWeight: '500',
fontSize: '14px',
boxShadow: '0 4px 12px rgba(0, 0, 0, 0.15)',
zIndex: 9999,
maxWidth: '90%',
minWidth: 'auto',
textAlign: 'center'
};
const InternetStatus = () => {
const theme = useTheme();
const [isOnline, setIsOnline] = useState(navigator.onLine);
const [showBackOnline, setShowBackOnline] = useState(false);
const wasOffline = useRef(!navigator.onLine);
useEffect(() => {
const handleNetworkChange = () => {
const online = navigator.onLine;
setIsOnline(online);
if (online && wasOffline.current) {
console.log('✅ Back online');
setShowBackOnline(true);
wasOffline.current = false;
// window.location.reload();
setTimeout(() => {
setShowBackOnline(false);
}, 2000);
}
if (!online) {
console.log('❌ No internet connection');
wasOffline.current = true;
setShowBackOnline(false);
}
};
window.addEventListener('online', handleNetworkChange);
window.addEventListener('offline', handleNetworkChange);
return () => {
window.removeEventListener('online', handleNetworkChange);
window.removeEventListener('offline', handleNetworkChange);
};
}, []);
return (
<>
{!isOnline && (
<div
style={{
...NOTIFICATION_STYLE,
backgroundColor: theme.palette.error.main,
display: 'flex',
alignItems: 'center',
gap: '10px'
}}
>
<WifiOffIcon style={{ color: '#fff' }} />
No Internet Connection
</div>
)}
{showBackOnline && (
<div
style={{
...NOTIFICATION_STYLE,
backgroundColor: theme.palette.success.main,
display: 'flex',
alignItems: 'center',
gap: '10px'
}}
>
<WifiIcon style={{ color: '#fff' }} />
Back Online
</div>
)}
</>
);
};
export default InternetStatus;

View File

@@ -0,0 +1,15 @@
import { useEffect, useState } from 'react';
export const useDebounce = (value, delay = 500) => {
const [debouncedValue, setDebouncedValue] = useState(value);
useEffect(() => {
const handler = setTimeout(() => {
setDebouncedValue(value);
}, delay);
return () => clearTimeout(handler); // cleanup on every value change
}, [value, delay]);
return debouncedValue;
};

View File

@@ -0,0 +1,26 @@
import { useEffect } from 'react';
export const useHotkeyFocus = (ref, hotkey = 'k') => {
useEffect(() => {
if (!ref?.current) return;
const handleKeyPress = (event) => {
const isHotkey = event.key.toLowerCase() === hotkey.toLowerCase();
// CTRL + Hotkey
if (isHotkey && (event.metaKey || event.ctrlKey)) {
event.preventDefault();
ref.current?.focus();
}
// ESC to blur
if (event.key === 'Escape' && document.activeElement === ref.current) {
ref.current.blur();
}
};
document.addEventListener('keydown', handleKeyPress);
return () => document.removeEventListener('keydown', handleKeyPress);
}, [ref, hotkey]);
};