Files
team-planner/frontend/src/components/SettingsPage/SettingsPage.tsx
vigdorov 4d80480d0f
All checks were successful
continuous-integration/drone/push Build is passing
add broker
2026-02-07 20:24:31 +03:00

111 lines
3.4 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { useState, useEffect } from 'react';
import {
Box,
Typography,
TextField,
Button,
Paper,
Alert,
} from '@mui/material';
import { useSettingsQuery, useUpdateSettings } from '../../hooks/useSettings';
import { DEFAULT_ESTIMATE_CONFIG } from '../../utils/estimate';
export function SettingsPage() {
const { data: settings, isLoading } = useSettingsQuery();
const updateSettings = useUpdateSettings();
const [hoursPerDay, setHoursPerDay] = useState(
String(DEFAULT_ESTIMATE_CONFIG.hoursPerDay),
);
const [daysPerWeek, setDaysPerWeek] = useState(
String(DEFAULT_ESTIMATE_CONFIG.daysPerWeek),
);
useEffect(() => {
if (settings) {
setHoursPerDay(
String(settings.hoursPerDay ?? DEFAULT_ESTIMATE_CONFIG.hoursPerDay),
);
setDaysPerWeek(
String(settings.daysPerWeek ?? DEFAULT_ESTIMATE_CONFIG.daysPerWeek),
);
}
}, [settings]);
const handleSave = () => {
const hpd = Number(hoursPerDay);
const dpw = Number(daysPerWeek);
if (hpd > 0 && hpd <= 24 && dpw > 0 && dpw <= 7) {
updateSettings.mutate({ hoursPerDay: hpd, daysPerWeek: dpw });
}
};
const hpdNum = Number(hoursPerDay);
const dpwNum = Number(daysPerWeek);
const isValid =
hpdNum > 0 && hpdNum <= 24 && dpwNum > 0 && dpwNum <= 7;
if (isLoading) return null;
return (
<Box sx={{ maxWidth: 500 }}>
<Typography variant="h5" sx={{ mb: 3 }}>
Настройки
</Typography>
<Paper sx={{ p: 3 }}>
<Typography variant="h6" sx={{ mb: 2 }}>
Формат оценки трудозатрат
</Typography>
<Typography variant="body2" color="text.secondary" sx={{ mb: 3 }}>
Эти значения используются для конвертации оценок из формата «1w 3d 7h»
в часы и обратно.
</Typography>
<Box sx={{ display: 'flex', flexDirection: 'column', gap: 2 }}>
<TextField
label="Часов в рабочем дне"
type="number"
value={hoursPerDay}
onChange={(e) => setHoursPerDay(e.target.value)}
slotProps={{ htmlInput: { min: 1, max: 24 } }}
helperText="От 1 до 24"
error={!hpdNum || hpdNum < 1 || hpdNum > 24}
size="small"
/>
<TextField
label="Рабочих дней в неделе"
type="number"
value={daysPerWeek}
onChange={(e) => setDaysPerWeek(e.target.value)}
slotProps={{ htmlInput: { min: 1, max: 7 } }}
helperText="От 1 до 7"
error={!dpwNum || dpwNum < 1 || dpwNum > 7}
size="small"
/>
</Box>
<Box sx={{ mt: 3, display: 'flex', alignItems: 'center', gap: 2 }}>
<Button
variant="contained"
onClick={handleSave}
disabled={!isValid || updateSettings.isPending}
>
Сохранить
</Button>
{updateSettings.isSuccess && (
<Alert severity="success" sx={{ py: 0 }}>
Сохранено
</Alert>
)}
{updateSettings.isError && (
<Alert severity="error" sx={{ py: 0 }}>
Ошибка сохранения
</Alert>
)}
</Box>
</Paper>
</Box>
);
}