Реализация функционала настроек
This commit is contained in:
parent
11237605b9
commit
b462a2b1ec
14 changed files with 466 additions and 243 deletions
|
|
@ -1,9 +1,8 @@
|
|||
// components/modalContainers/NoteDevice.tsx
|
||||
import { ModalContainer, ModalTitle, ModalContent, ButtonContainer } from "../modalwindows/style";
|
||||
import { MainButton } from "../UI/buttons/mainButton";
|
||||
import {useEffect, useMemo, useState} from "react";
|
||||
import {useCallback, useEffect, useMemo, useState} from "react";
|
||||
import styled from "styled-components";
|
||||
import {Setting, useSettingsStore} from "../../store/settingsStore";
|
||||
import {Setting, useSettingsStore} from "../../store/settings/settingsStore";
|
||||
import {SettingItem} from "./SettingItem";
|
||||
import {IconComponent} from "../../const/buttons/icons";
|
||||
import {buttonNames} from "../../const/buttons/names";
|
||||
|
|
@ -51,16 +50,31 @@ const SectionLine = styled.span`
|
|||
const CloseBtn = styled.span`
|
||||
cursor: pointer;
|
||||
`
|
||||
export const Settings = ({ onClose }: Props) => {
|
||||
const settingsConfig = useSettingsStore(state => state.settingsConfig);
|
||||
const settingsValues = useSettingsStore(state => state.settingsValues);
|
||||
const activeSection = useSettingsStore(state => state.activeSection);
|
||||
const pendingChanges = useSettingsStore(state => state.pendingChanges);
|
||||
const setActiveSection = useSettingsStore(state => state.setActiveSection);
|
||||
const updateSetting = useSettingsStore(state => state.updateSetting);
|
||||
const applyChanges = useSettingsStore(state => state.applyChanges);
|
||||
const discardChanges = useSettingsStore(state => state.discardChanges);
|
||||
const getSetting = useSettingsStore(state => state.getSetting);
|
||||
const initializeSettings = useSettingsStore(state => state.initializeSettings);
|
||||
|
||||
export const Settings = ({onClose}: Props) => {
|
||||
const {
|
||||
settingsConfig,
|
||||
settingsValues,
|
||||
activeSection,
|
||||
setActiveSection,
|
||||
initializeSettings,
|
||||
updateSetting
|
||||
} = useSettingsStore();
|
||||
const [fieldErrors, setFieldErrors] = useState<Record<string, string>>({});
|
||||
|
||||
const handleValidationError = useCallback((fieldId: string, error: string | null) => {
|
||||
setFieldErrors(prev => {
|
||||
const newErrors = { ...prev };
|
||||
if (error) {
|
||||
newErrors[fieldId] = error;
|
||||
} else {
|
||||
delete newErrors[fieldId];
|
||||
}
|
||||
return newErrors;
|
||||
});
|
||||
}, []);
|
||||
|
||||
const settingsBySection = useMemo(() => {
|
||||
return settingsConfig.reduce((acc, setting) => {
|
||||
|
|
@ -75,7 +89,7 @@ export const Settings = ({onClose}: Props) => {
|
|||
}, {} as Record<string, Setting[]>);
|
||||
}, [settingsConfig, settingsValues]);
|
||||
|
||||
const sections = Object.keys(settingsBySection);
|
||||
const sections = useMemo(() => Object.keys(settingsBySection), [settingsBySection]);
|
||||
|
||||
useEffect(() => {
|
||||
initializeSettings();
|
||||
|
|
@ -87,17 +101,40 @@ export const Settings = ({onClose}: Props) => {
|
|||
}
|
||||
}, [sections, activeSection, setActiveSection]);
|
||||
|
||||
const handleSave = () => {
|
||||
onClose();
|
||||
};
|
||||
const handleSave = useCallback(() => {
|
||||
const hasErrors = Object.values(fieldErrors).some(error => error?.trim());
|
||||
if (hasErrors) {
|
||||
alert('Исправьте ошибки перед сохранением');
|
||||
return;
|
||||
}
|
||||
|
||||
const requiredFields = settingsConfig.filter(s => s.required);
|
||||
const emptyRequiredFields = requiredFields.filter(f => {
|
||||
const value = pendingChanges[f.id] ?? settingsValues[f.id] ?? f.defaultValue;
|
||||
return value == null || value === '';
|
||||
});
|
||||
|
||||
if (emptyRequiredFields.length > 0) {
|
||||
alert('Заполните все обязательные поля');
|
||||
return;
|
||||
}
|
||||
|
||||
applyChanges();
|
||||
onClose();
|
||||
}, [fieldErrors, settingsConfig, pendingChanges, settingsValues, applyChanges, onClose]);
|
||||
|
||||
const handleCancel = useCallback(() => {
|
||||
discardChanges();
|
||||
setFieldErrors({});
|
||||
onClose();
|
||||
}, [discardChanges, onClose]);
|
||||
|
||||
return (
|
||||
<ModalContainer style={{ height: '60vh', width: '50vw'}}>
|
||||
<ModalTitle>
|
||||
<h3>Настройки</h3>
|
||||
<CloseBtn>
|
||||
<IconComponent name={buttonNames[12]} width="30" height="30" onClick={() => onClose()} />
|
||||
<IconComponent name={buttonNames[12]} width="30" height="30" onClick={handleCancel} />
|
||||
</CloseBtn>
|
||||
</ModalTitle>
|
||||
|
||||
|
|
@ -121,7 +158,8 @@ export const Settings = ({onClose}: Props) => {
|
|||
<SettingItem
|
||||
key={setting.id}
|
||||
setting={setting}
|
||||
value={settingsValues[setting.id] ?? setting.defaultValue}
|
||||
value={getSetting(setting.id).currentValue}
|
||||
onValidationError={(error) => handleValidationError(setting.id, error)}
|
||||
onChange={(value) => updateSetting(setting.id, value)}
|
||||
/>
|
||||
))}
|
||||
|
|
@ -136,6 +174,7 @@ export const Settings = ({onClose}: Props) => {
|
|||
size="small"
|
||||
title='Сохранить'
|
||||
onClick={handleSave}
|
||||
|
||||
/>
|
||||
</ButtonContainer>
|
||||
</ModalContainer>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue