/
GEOSHEV
/
StudLab
Обзор
Документация
Войти
/
GEOSHEV
/
StudLab
Код
Запросы
1
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
develop
src/components/menu/Menu.tsx
227 строк
8 KB
George
Обновил: Линтер по всем файлам
21 мар 2025, 14:25
21 мар 2025, 14:25
2b503d4
Код
Авторство
О чём код?
import { useEffect, useState } from 'react'; import { useReservoirs } from '../../context/useReservoirs'; import Input from '../../ui/input/Input'; import BtnDelete from '../buttons/BtnDelete'; import './Menu.css'; import axios from 'axios'; import LockToggle from '../buttons/LockToggle'; import confirmIcon from '../../assets/confirm-icon.svg'; import cancelIcon from '../../assets/cancel-icon.svg'; import VolumeToggle from '../buttons/VolumeToggle'; import { useVolumeControl } from '../hooks/useVolumeControl'; const API_PRODUCT_URL = '/api/products/'; interface Product { id: number; name: string; } function Menu() { const { selectedReservoir, updateReservoir } = useReservoirs(); const [products, setProducts] = useState<Product[]>([]); const [selectedProduct, setSelectedProduct] = useState<number | null>(null); const [isEditing, setIsEditing] = useState(false); const [tempName, setTempName] = useState(selectedReservoir?.name || ''); const [hasChanges, setHasChanges] = useState(false); const { isPercentageMode, tempVolume, setIsEditingVolume, handleModeChange, handleVolumeChange, handleConfirmVolume, handleCancelEdit, } = useVolumeControl(); useEffect(() => { axios .get<Product[]>(API_PRODUCT_URL) .then(response => setProducts(response.data)) .catch(error => console.error('Ошибка при загрузке продуктов', error), ); }, []); useEffect(() => { if (selectedReservoir) { setSelectedProduct(selectedReservoir.productId); setTempName(selectedReservoir.name); } }, [selectedReservoir]); const handleChangeName = (event: React.ChangeEvent<HTMLInputElement>) => { setTempName(event.target.value); setHasChanges(true); }; const handleConfirmName = async () => { if (selectedReservoir) { try { updateReservoir(selectedReservoir.id, { ...selectedReservoir, name: tempName, }); setIsEditing(false); } catch (error) { console.error( 'Ошибка при обновлении названия резервуара', error, ); } } }; const handleCancelName = () => { if (selectedReservoir) { setTempName(selectedReservoir.name); setIsEditing(false); } }; const handleCancelVolume = () => { handleCancelEdit(); setHasChanges(false); }; const handleChangeProduct = ( event: React.ChangeEvent<HTMLSelectElement>, ) => { const newProductId = Number(event.target.value); setSelectedProduct(newProductId); setHasChanges(true); if (selectedReservoir) { updateReservoir(selectedReservoir.id, { ...selectedReservoir, productId: newProductId, }); } }; if (!selectedReservoir) { return <p className="menu menu-choice">Выберите резервуар</p>; } return ( <div className="menu"> <div className="menu-header"> <span>Информация о резервуаре</span> </div> <div className="tank-container"> <img className="tank" src="./src/assets/tank_icon.svg" alt="Резервуар" /> </div> <div className="changes-container"> <div className="editable-input-container"> <Input icon="./src/assets/tank-icon.svg" placeholder="Название" value={tempName} onChange={handleChangeName} onFocus={() => setIsEditing(true)} disabled={selectedReservoir.isLocked} /> {isEditing && !selectedReservoir.isLocked && ( <div className="edit-buttons"> <button className="edit-btn confirm" onClick={handleConfirmName} > <img src={confirmIcon} alt="Confirm" /> </button> <button className="edit-btn cancel" onClick={handleCancelName} > <img src={cancelIcon} alt="Cancel" /> </button> </div> )} </div> <div className="dropdown-container"> <select id="product-select" value={selectedProduct || ''} onChange={handleChangeProduct} disabled={selectedReservoir.isLocked} > {products.map(product => ( <option key={product.id} value={product.id}> {product.name} </option> ))} </select> </div> <div className="input-container"> <Input icon="./src/assets/max-volume.svg" placeholder="Вместимость" readOnly value={selectedReservoir.capacity} /> </div> <VolumeToggle isPercentageMode={isPercentageMode} onToggle={handleModeChange} /> <div className="input-container"> <Input icon="./src/assets/weight-icon.svg" placeholder={ isPercentageMode ? 'Введите %' : 'Введите объем' } value={ isPercentageMode ? Math.round(tempVolume) : tempVolume } onChange={e => { handleVolumeChange(Number(e.target.value)); setHasChanges(true); }} onFocus={() => setIsEditingVolume(true)} disabled={selectedReservoir.isLocked} /> </div> <div className="buttons-container"> <button className="volume-save-btn" onClick={() => { handleConfirmVolume(); handleModeChange(false); }} disabled={!hasChanges || selectedReservoir.isLocked} > Сохранить </button> <button className="volume-cancel-btn" onClick={handleCancelVolume} disabled={!hasChanges || selectedReservoir.isLocked} > Отменить </button> </div> </div> <div className="menu-bottom"> <LockToggle isLocked={selectedReservoir.isLocked} reservoirId={selectedReservoir.id} /> <BtnDelete /> </div> </div> ); } export default Menu;