created modal window for settings
parent
69a5e4ade1
commit
328018edfa
|
|
@ -0,0 +1,153 @@
|
||||||
|
import React, { useState, useEffect } from 'react';
|
||||||
|
import {
|
||||||
|
Box,
|
||||||
|
Button,
|
||||||
|
TextField,
|
||||||
|
IconButton,
|
||||||
|
Table,
|
||||||
|
TableBody,
|
||||||
|
TableCell,
|
||||||
|
TableContainer,
|
||||||
|
TableHead,
|
||||||
|
TableRow,
|
||||||
|
Paper,
|
||||||
|
Typography,
|
||||||
|
Divider,
|
||||||
|
Select,
|
||||||
|
MenuItem,
|
||||||
|
FormControl,
|
||||||
|
InputLabel
|
||||||
|
} from '@mui/material';
|
||||||
|
import AddIcon from '@mui/icons-material/Add';
|
||||||
|
import DeleteIcon from '@mui/icons-material/Delete';
|
||||||
|
|
||||||
|
const RangeEditor = ({ metric, onSave, onCancel }) => {
|
||||||
|
const [ranges, setRanges] = useState([...metric.ranges]);
|
||||||
|
const [newRange, setNewRange] = useState({ min: 0, max: 0, status: 1 });
|
||||||
|
|
||||||
|
const handleAddRange = () => {
|
||||||
|
if (newRange.min >= newRange.max) {
|
||||||
|
alert('Минимальное значение должно быть меньше максимального');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Проверка на пересечение с существующими диапазонами
|
||||||
|
const overlaps = ranges.some(range =>
|
||||||
|
(newRange.min >= range.min && newRange.min <= range.max) ||
|
||||||
|
(newRange.max >= range.min && newRange.max <= range.max)
|
||||||
|
);
|
||||||
|
|
||||||
|
if (overlaps) {
|
||||||
|
alert('Диапазон пересекается с существующим');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
setRanges([...ranges, newRange].sort((a, b) => a.min - b.min));
|
||||||
|
setNewRange({ min: 0, max: 0, status: 1 });
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleDeleteRange = (index) => {
|
||||||
|
const newRanges = [...ranges];
|
||||||
|
newRanges.splice(index, 1);
|
||||||
|
setRanges(newRanges);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleSave = () => {
|
||||||
|
onSave({
|
||||||
|
...metric,
|
||||||
|
ranges
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Box sx={{ p: 2 }}>
|
||||||
|
<Typography variant="h6" gutterBottom>
|
||||||
|
Редактирование диапазонов для: {metric.name}
|
||||||
|
</Typography>
|
||||||
|
|
||||||
|
<TableContainer component={Paper} sx={{ mb: 2 }}>
|
||||||
|
<Table size="small">
|
||||||
|
<TableHead>
|
||||||
|
<TableRow>
|
||||||
|
<TableCell>Минимум</TableCell>
|
||||||
|
<TableCell>Максимум</TableCell>
|
||||||
|
<TableCell>Статус</TableCell>
|
||||||
|
<TableCell>Действия</TableCell>
|
||||||
|
</TableRow>
|
||||||
|
</TableHead>
|
||||||
|
<TableBody>
|
||||||
|
{ranges.map((range, index) => (
|
||||||
|
<TableRow key={index}>
|
||||||
|
<TableCell>{range.min}</TableCell>
|
||||||
|
<TableCell>{range.max}</TableCell>
|
||||||
|
<TableCell>{range.status}</TableCell>
|
||||||
|
<TableCell>
|
||||||
|
<IconButton onClick={() => handleDeleteRange(index)}>
|
||||||
|
<DeleteIcon color="error" />
|
||||||
|
</IconButton>
|
||||||
|
</TableCell>
|
||||||
|
</TableRow>
|
||||||
|
))}
|
||||||
|
</TableBody>
|
||||||
|
</Table>
|
||||||
|
</TableContainer>
|
||||||
|
|
||||||
|
<Divider sx={{ my: 2 }} />
|
||||||
|
|
||||||
|
<Typography variant="subtitle1" gutterBottom>
|
||||||
|
Добавить новый диапазон
|
||||||
|
</Typography>
|
||||||
|
|
||||||
|
<Box sx={{ display: 'flex', gap: 2, alignItems: 'center', mb: 2 }}>
|
||||||
|
<TextField
|
||||||
|
label="Минимум"
|
||||||
|
type="number"
|
||||||
|
value={newRange.min}
|
||||||
|
onChange={(e) => setNewRange({ ...newRange, min: parseInt(e.target.value) || 0 })}
|
||||||
|
size="small"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<TextField
|
||||||
|
label="Максимум"
|
||||||
|
type="number"
|
||||||
|
value={newRange.max}
|
||||||
|
onChange={(e) => setNewRange({ ...newRange, max: parseInt(e.target.value) || 0 })}
|
||||||
|
size="small"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<FormControl size="small" sx={{ minWidth: 120 }}>
|
||||||
|
<InputLabel>Статус</InputLabel>
|
||||||
|
<Select
|
||||||
|
value={newRange.status}
|
||||||
|
label="Статус"
|
||||||
|
onChange={(e) => setNewRange({ ...newRange, status: parseInt(e.target.value) })}
|
||||||
|
>
|
||||||
|
<MenuItem value={1}>Норма (1)</MenuItem>
|
||||||
|
<MenuItem value={2}>Предупреждение (2)</MenuItem>
|
||||||
|
<MenuItem value={3}>Опасность (3)</MenuItem>
|
||||||
|
<MenuItem value={4}>Критично (4)</MenuItem>
|
||||||
|
</Select>
|
||||||
|
</FormControl>
|
||||||
|
|
||||||
|
<Button
|
||||||
|
variant="contained"
|
||||||
|
startIcon={<AddIcon />}
|
||||||
|
onClick={handleAddRange}
|
||||||
|
>
|
||||||
|
Добавить
|
||||||
|
</Button>
|
||||||
|
</Box>
|
||||||
|
|
||||||
|
<Box sx={{ display: 'flex', justifyContent: 'flex-end', gap: 2 }}>
|
||||||
|
<Button variant="outlined" onClick={onCancel}>
|
||||||
|
Отмена
|
||||||
|
</Button>
|
||||||
|
<Button variant="contained" onClick={handleSave}>
|
||||||
|
Сохранить
|
||||||
|
</Button>
|
||||||
|
</Box>
|
||||||
|
</Box>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default RangeEditor;
|
||||||
|
|
@ -0,0 +1,196 @@
|
||||||
|
// components/SettingsModal.jsx
|
||||||
|
import React, { useState, useEffect } from 'react';
|
||||||
|
import {
|
||||||
|
Dialog,
|
||||||
|
DialogTitle,
|
||||||
|
DialogContent,
|
||||||
|
DialogActions,
|
||||||
|
Button,
|
||||||
|
Tabs,
|
||||||
|
Tab,
|
||||||
|
Box,
|
||||||
|
Typography,
|
||||||
|
IconButton,
|
||||||
|
styled,
|
||||||
|
CircularProgress,
|
||||||
|
Slide,
|
||||||
|
Snackbar,
|
||||||
|
Alert
|
||||||
|
} from '@mui/material';
|
||||||
|
import CloseIcon from '@mui/icons-material/Close';
|
||||||
|
import SaveIcon from '@mui/icons-material/Save';
|
||||||
|
|
||||||
|
const Transition = React.forwardRef(function Transition(props, ref) {
|
||||||
|
return <Slide direction="up" ref={ref} {...props} />;
|
||||||
|
});
|
||||||
|
|
||||||
|
const StyledDialog = styled(Dialog)(({ theme }) => ({
|
||||||
|
'& .MuiDialog-paper': {
|
||||||
|
minWidth: 600,
|
||||||
|
maxHeight: '80vh',
|
||||||
|
backgroundColor: theme.palette.background.paper,
|
||||||
|
},
|
||||||
|
}));
|
||||||
|
|
||||||
|
const TabPanel = (props) => {
|
||||||
|
const { children, value, index, ...other } = props;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
role="tabpanel"
|
||||||
|
hidden={value !== index}
|
||||||
|
id={`settings-tabpanel-${index}`}
|
||||||
|
aria-labelledby={`settings-tab-${index}`}
|
||||||
|
{...other}
|
||||||
|
>
|
||||||
|
{value === index && (
|
||||||
|
<Box sx={{ p: 3 }}>
|
||||||
|
<Typography component="div">{children}</Typography>
|
||||||
|
</Box>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const SettingsModal = ({ open, onClose }) => {
|
||||||
|
const [tabValue, setTabValue] = useState(0);
|
||||||
|
const [isSaving, setIsSaving] = useState(false);
|
||||||
|
const [showSuccess, setShowSuccess] = useState(false);
|
||||||
|
const [hasChanges, setHasChanges] = useState(false);
|
||||||
|
const [showConfirmClose, setShowConfirmClose] = useState(false);
|
||||||
|
|
||||||
|
const handleTabChange = (event, newValue) => {
|
||||||
|
if (hasChanges) {
|
||||||
|
setShowConfirmClose(true);
|
||||||
|
} else {
|
||||||
|
setTabValue(newValue);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleSave = () => {
|
||||||
|
setIsSaving(true);
|
||||||
|
// Имитация асинхронного сохранения
|
||||||
|
setTimeout(() => {
|
||||||
|
setIsSaving(false);
|
||||||
|
setShowSuccess(true);
|
||||||
|
setHasChanges(false);
|
||||||
|
}, 1500);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleClose = () => {
|
||||||
|
if (hasChanges) {
|
||||||
|
setShowConfirmClose(true);
|
||||||
|
} else {
|
||||||
|
onClose();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleConfirmClose = (shouldClose) => {
|
||||||
|
setShowConfirmClose(false);
|
||||||
|
if (shouldClose) {
|
||||||
|
onClose();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Пример обработчика изменений
|
||||||
|
const handleSettingChange = () => {
|
||||||
|
setHasChanges(true);
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<StyledDialog
|
||||||
|
open={open}
|
||||||
|
onClose={handleClose}
|
||||||
|
aria-labelledby="settings-dialog-title"
|
||||||
|
maxWidth="md"
|
||||||
|
fullWidth
|
||||||
|
TransitionComponent={Transition}
|
||||||
|
>
|
||||||
|
<DialogTitle id="settings-dialog-title">
|
||||||
|
Настройки
|
||||||
|
<IconButton
|
||||||
|
aria-label="close"
|
||||||
|
onClick={handleClose}
|
||||||
|
sx={{
|
||||||
|
position: 'absolute',
|
||||||
|
right: 8,
|
||||||
|
top: 8,
|
||||||
|
color: (theme) => theme.palette.grey[500],
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<CloseIcon />
|
||||||
|
</IconButton>
|
||||||
|
</DialogTitle>
|
||||||
|
|
||||||
|
<Box sx={{ borderBottom: 1, borderColor: 'divider' }}>
|
||||||
|
<Tabs value={tabValue} onChange={handleTabChange} aria-label="settings tabs">
|
||||||
|
<Tab label="Меню" id="settings-tab-0" aria-controls="settings-tabpanel-0" />
|
||||||
|
<Tab label="Внешний вид" id="settings-tab-1" aria-controls="settings-tabpanel-1" />
|
||||||
|
{/* Добавляйте новые вкладки здесь */}
|
||||||
|
</Tabs>
|
||||||
|
</Box>
|
||||||
|
|
||||||
|
<DialogContent dividers>
|
||||||
|
<TabPanel value={tabValue} index={0}>
|
||||||
|
<Typography variant="h6">Настройки меню</Typography>
|
||||||
|
{/* Добавьте содержимое для вкладки меню */}
|
||||||
|
</TabPanel>
|
||||||
|
|
||||||
|
<TabPanel value={tabValue} index={1}>
|
||||||
|
<Typography variant="h6">Настройки внешнего вида</Typography>
|
||||||
|
{/* Добавьте содержимое для вкладки внешнего вида */}
|
||||||
|
</TabPanel>
|
||||||
|
|
||||||
|
{/* Добавляйте новые TabPanel для новых вкладок */}
|
||||||
|
</DialogContent>
|
||||||
|
|
||||||
|
<DialogActions>
|
||||||
|
<Button onClick={handleClose}>Закрыть</Button>
|
||||||
|
<Button
|
||||||
|
onClick={handleSave}
|
||||||
|
variant="contained"
|
||||||
|
color="primary"
|
||||||
|
disabled={isSaving || !hasChanges}
|
||||||
|
startIcon={isSaving ? <CircularProgress size={20} /> : <SaveIcon />}
|
||||||
|
>
|
||||||
|
{isSaving ? 'Сохранение...' : 'Сохранить'}
|
||||||
|
</Button>
|
||||||
|
</DialogActions>
|
||||||
|
</StyledDialog>
|
||||||
|
|
||||||
|
{/* Уведомление об успешном сохранении */}
|
||||||
|
<Snackbar
|
||||||
|
open={showSuccess}
|
||||||
|
autoHideDuration={3000}
|
||||||
|
onClose={() => setShowSuccess(false)}
|
||||||
|
anchorOrigin={{ vertical: 'bottom', horizontal: 'right' }}
|
||||||
|
>
|
||||||
|
<Alert onClose={() => setShowSuccess(false)} severity="success" sx={{ width: '100%' }}>
|
||||||
|
Настройки успешно сохранены!
|
||||||
|
</Alert>
|
||||||
|
</Snackbar>
|
||||||
|
|
||||||
|
{/* Диалог подтверждения закрытия */}
|
||||||
|
<Dialog
|
||||||
|
open={showConfirmClose}
|
||||||
|
onClose={() => handleConfirmClose(false)}
|
||||||
|
aria-labelledby="alert-dialog-title"
|
||||||
|
aria-describedby="alert-dialog-description"
|
||||||
|
>
|
||||||
|
<DialogTitle id="alert-dialog-title">Есть несохраненные изменения</DialogTitle>
|
||||||
|
<DialogContent>
|
||||||
|
<Typography>Вы уверены, что хотите закрыть без сохранения изменений?</Typography>
|
||||||
|
</DialogContent>
|
||||||
|
<DialogActions>
|
||||||
|
<Button onClick={() => handleConfirmClose(false)}>Отмена</Button>
|
||||||
|
<Button onClick={() => handleConfirmClose(true)} autoFocus color="error">
|
||||||
|
Закрыть без сохранения
|
||||||
|
</Button>
|
||||||
|
</DialogActions>
|
||||||
|
</Dialog>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default SettingsModal;
|
||||||
|
|
@ -3,17 +3,10 @@ import React, { useState, useEffect } from "react";
|
||||||
import {
|
import {
|
||||||
Drawer,
|
Drawer,
|
||||||
List,
|
List,
|
||||||
Typography,
|
|
||||||
styled,
|
styled,
|
||||||
IconButton,
|
IconButton,
|
||||||
Tooltip,
|
Tooltip,
|
||||||
Box,
|
Box,
|
||||||
Dialog,
|
|
||||||
DialogTitle,
|
|
||||||
DialogContent,
|
|
||||||
DialogActions,
|
|
||||||
Button,
|
|
||||||
TextField
|
|
||||||
} from "@mui/material";
|
} from "@mui/material";
|
||||||
import MenuItem from "./SidebarMenuComponents/MenuItem";
|
import MenuItem from "./SidebarMenuComponents/MenuItem";
|
||||||
import SidebarFooter from "./SidebarMenuComponents/SidebarFooter";
|
import SidebarFooter from "./SidebarMenuComponents/SidebarFooter";
|
||||||
|
|
@ -27,12 +20,7 @@ const SidebarMenu = ({
|
||||||
data,
|
data,
|
||||||
isDarkMode,
|
isDarkMode,
|
||||||
setIsDarkMode,
|
setIsDarkMode,
|
||||||
onEditItem,
|
onSelectItem
|
||||||
onSelectItem,
|
|
||||||
editModalOpen,
|
|
||||||
editingItem,
|
|
||||||
onCloseEditModal,
|
|
||||||
onSaveChanges
|
|
||||||
}) => {
|
}) => {
|
||||||
const [collapsed, setCollapsed] = useState(false);
|
const [collapsed, setCollapsed] = useState(false);
|
||||||
const { sidebarWidth, startResizing } = useSidebarResize(290);
|
const { sidebarWidth, startResizing } = useSidebarResize(290);
|
||||||
|
|
@ -148,7 +136,7 @@ const SidebarMenu = ({
|
||||||
item={data}
|
item={data}
|
||||||
collapsed={collapsed}
|
collapsed={collapsed}
|
||||||
level={0}
|
level={0}
|
||||||
onEdit={onEditItem}
|
|
||||||
onSelectItem={onSelectItem}
|
onSelectItem={onSelectItem}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
|
@ -160,74 +148,12 @@ const SidebarMenu = ({
|
||||||
setIsDarkMode={setIsDarkMode}
|
setIsDarkMode={setIsDarkMode}
|
||||||
/>
|
/>
|
||||||
</Box>
|
</Box>
|
||||||
|
|
||||||
{!collapsed && (
|
{!collapsed && (
|
||||||
<SidebarResizer onMouseDown={startResizing} />
|
<SidebarResizer onMouseDown={startResizing} />
|
||||||
)}
|
)}
|
||||||
</Drawer>
|
</Drawer>
|
||||||
|
|
||||||
{/* Модальное окно редактирования */}
|
|
||||||
<EditMenuItemDialog
|
|
||||||
open={editModalOpen}
|
|
||||||
item={editingItem}
|
|
||||||
onClose={onCloseEditModal}
|
|
||||||
onSave={onSaveChanges}
|
|
||||||
/>
|
|
||||||
</Box>
|
</Box>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
const EditMenuItemDialog = ({ open, item, onClose, onSave }) => {
|
|
||||||
const [formData, setFormData] = useState(item || {});
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
setFormData(item || {});
|
|
||||||
}, [item]);
|
|
||||||
|
|
||||||
const handleChange = (e) => {
|
|
||||||
const { name, value } = e.target;
|
|
||||||
setFormData(prev => ({ ...prev, [name]: value }));
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleSubmit = () => {
|
|
||||||
onSave(formData);
|
|
||||||
};
|
|
||||||
|
|
||||||
if (!item) return null;
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Dialog open={open} onClose={onClose} maxWidth="sm" fullWidth>
|
|
||||||
<DialogTitle>Редактирование элемента меню</DialogTitle>
|
|
||||||
<DialogContent>
|
|
||||||
<Box sx={{ mt: 2 }}>
|
|
||||||
<TextField
|
|
||||||
fullWidth
|
|
||||||
label="Название"
|
|
||||||
name="title"
|
|
||||||
value={formData.title || ''}
|
|
||||||
onChange={handleChange}
|
|
||||||
sx={{ mb: 2 }}
|
|
||||||
/>
|
|
||||||
<TextField
|
|
||||||
fullWidth
|
|
||||||
label="ID"
|
|
||||||
name="id"
|
|
||||||
value={formData.id || ''}
|
|
||||||
onChange={handleChange}
|
|
||||||
disabled
|
|
||||||
sx={{ mb: 2 }}
|
|
||||||
/>
|
|
||||||
{/* Дополнительные поля для редактирования */}
|
|
||||||
</Box>
|
|
||||||
</DialogContent>
|
|
||||||
<DialogActions>
|
|
||||||
<Button onClick={onClose}>Отмена</Button>
|
|
||||||
<Button onClick={handleSubmit} variant="contained" color="primary">
|
|
||||||
Сохранить
|
|
||||||
</Button>
|
|
||||||
</DialogActions>
|
|
||||||
</Dialog>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default SidebarMenu;
|
export default SidebarMenu;
|
||||||
|
|
@ -7,11 +7,10 @@ import {
|
||||||
Collapse,
|
Collapse,
|
||||||
List,
|
List,
|
||||||
styled,
|
styled,
|
||||||
IconButton,
|
|
||||||
Menu,
|
Menu,
|
||||||
MenuItem as MuiMenuItem
|
MenuItem as MuiMenuItem
|
||||||
} from "@mui/material";
|
} from "@mui/material";
|
||||||
import { ExpandLess, ExpandMore, Folder, FolderOpen, Edit } from "@mui/icons-material";
|
import { ExpandLess, ExpandMore, Folder, FolderOpen } from "@mui/icons-material";
|
||||||
import StatusIndicator from "./StatusIndicator";
|
import StatusIndicator from "./StatusIndicator";
|
||||||
|
|
||||||
const StyledListItem = styled(ListItem)(({ theme, level }) => ({
|
const StyledListItem = styled(ListItem)(({ theme, level }) => ({
|
||||||
|
|
@ -44,11 +43,6 @@ const MenuItem = ({ item, onSelectItem, level = 0, collapsed, onEdit }) => {
|
||||||
setContextMenu(null);
|
setContextMenu(null);
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleEditClick = () => {
|
|
||||||
onEdit(item);
|
|
||||||
handleCloseContextMenu();
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleToggle = (e) => {
|
const handleToggle = (e) => {
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
setIsOpen(!isOpen);
|
setIsOpen(!isOpen);
|
||||||
|
|
@ -87,19 +81,6 @@ const MenuItem = ({ item, onSelectItem, level = 0, collapsed, onEdit }) => {
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
{hasChildren && (isOpen ? <ExpandLess /> : <ExpandMore />)}
|
{hasChildren && (isOpen ? <ExpandLess /> : <ExpandMore />)}
|
||||||
|
|
||||||
{level > 0 && (
|
|
||||||
<IconButton
|
|
||||||
size="small"
|
|
||||||
onClick={(e) => {
|
|
||||||
e.stopPropagation();
|
|
||||||
handleEditClick();
|
|
||||||
}}
|
|
||||||
sx={{ ml: 1 }}
|
|
||||||
>
|
|
||||||
<Edit fontSize="small" />
|
|
||||||
</IconButton>
|
|
||||||
)}
|
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
</StyledListItem>
|
</StyledListItem>
|
||||||
|
|
@ -114,9 +95,7 @@ const MenuItem = ({ item, onSelectItem, level = 0, collapsed, onEdit }) => {
|
||||||
: undefined
|
: undefined
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
<MuiMenuItem onClick={handleEditClick}>
|
|
||||||
<Edit fontSize="small" sx={{ mr: 1 }} /> Редактировать
|
|
||||||
</MuiMenuItem>
|
|
||||||
</Menu>
|
</Menu>
|
||||||
|
|
||||||
{hasChildren && !collapsed && (
|
{hasChildren && !collapsed && (
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
import React from "react";
|
// components/SidebarMenuComponents/SidebarFooter.jsx
|
||||||
|
import React, { useState } from "react";
|
||||||
import { Brightness4, Brightness7 } from "@mui/icons-material";
|
import { Brightness4, Brightness7 } from "@mui/icons-material";
|
||||||
import { IconButton, Tooltip } from "@mui/material";
|
import { IconButton, Tooltip } from "@mui/material";
|
||||||
import {
|
import {
|
||||||
|
|
@ -7,8 +8,10 @@ import {
|
||||||
ListItemText,
|
ListItemText,
|
||||||
styled,
|
styled,
|
||||||
Switch,
|
Switch,
|
||||||
Box
|
Box,
|
||||||
|
Button
|
||||||
} from "@mui/material";
|
} from "@mui/material";
|
||||||
|
import SettingsModal from "../SettingsModal";
|
||||||
|
|
||||||
const FooterList = styled(List)(({ theme }) => ({
|
const FooterList = styled(List)(({ theme }) => ({
|
||||||
backgroundColor: theme.palette.custom.sidebar,
|
backgroundColor: theme.palette.custom.sidebar,
|
||||||
|
|
@ -28,50 +31,75 @@ const FooterListItem = styled(ListItem)(({ theme }) => ({
|
||||||
}));
|
}));
|
||||||
|
|
||||||
const SidebarFooter = ({ collapsed, isDarkMode, setIsDarkMode }) => {
|
const SidebarFooter = ({ collapsed, isDarkMode, setIsDarkMode }) => {
|
||||||
return (
|
const [settingsOpen, setSettingsOpen] = useState(false);
|
||||||
<FooterList>
|
|
||||||
{!collapsed && (
|
|
||||||
<FooterListItem button>
|
|
||||||
<ListItemText
|
|
||||||
primary="Помощь"
|
|
||||||
primaryTypographyProps={{
|
|
||||||
color: 'custom.sidebarText',
|
|
||||||
variant: 'body2'
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</FooterListItem>
|
|
||||||
)}
|
|
||||||
<FooterListItem>
|
|
||||||
{!collapsed && (
|
|
||||||
<ListItemText
|
|
||||||
primary="Настройка"
|
|
||||||
primaryTypographyProps={{
|
|
||||||
color: 'custom.sidebarText',
|
|
||||||
variant: 'body2'
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
|
|
||||||
<Box sx={{ display: 'flex', alignItems: 'center', gap: 1 }}>
|
const handleSettingsOpen = () => {
|
||||||
<Tooltip title="Переключить тему">
|
setSettingsOpen(true);
|
||||||
<IconButton
|
};
|
||||||
size="small"
|
|
||||||
onClick={() => setIsDarkMode(!isDarkMode)}
|
const handleSettingsClose = () => {
|
||||||
sx={{ color: 'custom.sidebarText' }}
|
setSettingsOpen(false);
|
||||||
>
|
};
|
||||||
{isDarkMode ? <Brightness4 /> : <Brightness7 />}
|
|
||||||
</IconButton>
|
return (
|
||||||
</Tooltip>
|
<>
|
||||||
{!collapsed && (
|
<FooterList>
|
||||||
<Switch
|
{!collapsed && (
|
||||||
checked={isDarkMode}
|
<FooterListItem button>
|
||||||
onChange={() => setIsDarkMode(!isDarkMode)}
|
<ListItemText
|
||||||
size="small"
|
primary="Помощь"
|
||||||
|
primaryTypographyProps={{
|
||||||
|
color: 'custom.sidebarText',
|
||||||
|
variant: 'body2'
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
|
</FooterListItem>
|
||||||
|
)}
|
||||||
|
<FooterListItem>
|
||||||
|
{!collapsed && (
|
||||||
|
<Button
|
||||||
|
onClick={handleSettingsOpen}
|
||||||
|
sx={{
|
||||||
|
color: 'custom.sidebarText',
|
||||||
|
textTransform: 'none',
|
||||||
|
minWidth: 0,
|
||||||
|
padding: 0,
|
||||||
|
marginRight: 'auto'
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<ListItemText
|
||||||
|
primary="Настройки"
|
||||||
|
primaryTypographyProps={{
|
||||||
|
color: 'custom.sidebarText',
|
||||||
|
variant: 'body2'
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</Button>
|
||||||
)}
|
)}
|
||||||
</Box>
|
|
||||||
</FooterListItem>
|
<Box sx={{ display: 'flex', alignItems: 'center', gap: 1 }}>
|
||||||
</FooterList>
|
<Tooltip title="Переключить тему">
|
||||||
|
<IconButton
|
||||||
|
size="small"
|
||||||
|
onClick={() => setIsDarkMode(!isDarkMode)}
|
||||||
|
sx={{ color: 'custom.sidebarText' }}
|
||||||
|
>
|
||||||
|
{isDarkMode ? <Brightness4 /> : <Brightness7 />}
|
||||||
|
</IconButton>
|
||||||
|
</Tooltip>
|
||||||
|
{!collapsed && (
|
||||||
|
<Switch
|
||||||
|
checked={isDarkMode}
|
||||||
|
onChange={() => setIsDarkMode(!isDarkMode)}
|
||||||
|
size="small"
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</Box>
|
||||||
|
</FooterListItem>
|
||||||
|
</FooterList>
|
||||||
|
|
||||||
|
<SettingsModal open={settingsOpen} onClose={handleSettingsClose} />
|
||||||
|
</>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue