/
Pitonx
/
MyFinance
Обзор
Документация
Войти
/
Pitonx
/
MyFinance
Код
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
master
src/components/EntityModal.js
87 строк
3 KB
agent
feat(returns): create from expense form, show return indicators
13 июн 2026, 14:48
13 июн 2026, 14:48
a653ce7
Код
Авторство
О чём код?
import React, { useState, useRef, useEffect, useCallback } from 'react'; import { ICONS, ENTITY_LABELS } from '../config/entities'; import EntityForm from './EntityForm'; export default function EntityModal({ entity, item, defaults, operationalDate, onClose, onSave, onSaveOnly, onCreateReturn }) { const [position, setPosition] = useState({ x: 0, y: 0 }); const [isDragging, setIsDragging] = useState(false); const [isMobile, setIsMobile] = useState(() => window.matchMedia('(max-width: 768px)').matches); const dragStart = useRef({ mouseX: 0, mouseY: 0, posX: 0, posY: 0 }); const modalRef = useRef(null); useEffect(() => { const mq = window.matchMedia('(max-width: 768px)'); const handler = (e) => setIsMobile(e.matches); mq.addEventListener('change', handler); return () => mq.removeEventListener('change', handler); }, []); const handleMouseDown = useCallback((e) => { if (isMobile) return; // draggable отключён на мобильных if (e.button !== 0) return; if (e.target.closest('.modal-close')) return; setIsDragging(true); dragStart.current = { mouseX: e.clientX, mouseY: e.clientY, posX: position.x, posY: position.y, }; e.preventDefault(); }, [position, isMobile]); const handleMouseMove = useCallback((e) => { if (!isDragging) return; const dx = e.clientX - dragStart.current.mouseX; const dy = e.clientY - dragStart.current.mouseY; setPosition({ x: dragStart.current.posX + dx, y: dragStart.current.posY + dy, }); }, [isDragging]); const handleMouseUp = useCallback(() => { setIsDragging(false); }, []); useEffect(() => { if (isDragging) { window.addEventListener('mousemove', handleMouseMove); window.addEventListener('mouseup', handleMouseUp); return () => { window.removeEventListener('mousemove', handleMouseMove); window.removeEventListener('mouseup', handleMouseUp); }; } }, [isDragging, handleMouseMove, handleMouseUp]); const handleSubmit = (formData) => { const { _newCategoryName, _newSubcategory, ...cleanData } = formData; onSave(cleanData); }; return ( <div className="modal-overlay" onClick={onClose}> <div className="modal-window" ref={modalRef} onClick={e => e.stopPropagation()} style={isMobile ? undefined : { transform: `translate(${position.x}px, ${position.y}px)`, }} > <div className="modal-title-bar" onMouseDown={handleMouseDown} style={{ cursor: isMobile ? 'default' : (isDragging ? 'grabbing' : 'grab'), userSelect: 'none' }} title={isMobile ? undefined : 'Перетащите за заголовок'} > <span className="modal-icon">{ICONS.form}</span> <h2>{item ? 'Редактирование' : 'Создание'}: {ENTITY_LABELS[entity]}</h2> <button className="modal-close" onClick={onClose}>{ICONS.close}</button> </div> <EntityForm entity={entity} item={item} defaults={defaults} operationalDate={operationalDate} onSubmit={handleSubmit} onCancel={onClose} onSaveOnly={onSaveOnly} onCreateReturn={onCreateReturn} /> </div> </div> ); }