import {useEffect, useState} from 'react'; import styled from 'styled-components'; import type {Gender, User} from '../../types/user'; import {Tag, TagsInput, TagsWrap} from './TagsInput'; import {reachGoal} from "../../hooks/useYM"; interface PersonModalProps { isOpen: boolean; user: User | null; availableTags: string[]; onClose: () => void; onSave: (user: User) => void; } interface PersonForm { name: string; gender: Gender; age: string; weight: string; height: string; avoided: string[]; favorite: string[]; } const defaultForm: PersonForm = { name: '', gender: 'm', age: '', weight: '', height: '', avoided: [], favorite: [], }; export function PersonModal({ isOpen, user, availableTags, onClose, onSave, }: PersonModalProps) { const [form, setForm] = useState(defaultForm); const [showExpanded, setShowExpanded] = useState<'' | 'avoid' | 'favorite'>(''); useEffect(() => { if (!isOpen) return; if (user) { reachGoal('ac_family_edit'); setForm({ name: user.name, gender: user.gender, age: String(user.age), weight: user.weight ? String(user.weight) : '', height: user.height ? String(user.height) : '', avoided: user.avoided ?? [], favorite: user.favorite ?? [], }); } else { setForm(defaultForm); } }, [isOpen, user]); if (!isOpen) return null; function updateForm(name: TName, value: PersonForm[TName]) { setForm(current => ({ ...current, [name]: value, })); } function handleAvoidChange(tags: string[]) { setForm(current => ({ ...current, avoided: tags, favorite: current.favorite.filter(tag => !tags.includes(tag)), })); } function handleFavoriteChange(tags: string[]) { setForm(current => ({ ...current, favorite: tags, avoided: current.avoided.filter(tag => !tags.includes(tag)), })); } function handleSave() { const age = Number(form.age); if (!form.name.trim()) { alert('Пожалуйста, введите имя.'); return; } if (!age || age < 7) { alert('Возраст должен быть от 7 лет.'); return; } onSave({ id: user?.id, name: form.name.trim(), gender: form.gender, age, weight: form.weight ? Number(form.weight) : undefined, height: form.height ? Number(form.height) : undefined, avoided: form.avoided, favorite: form.favorite, }); } return ( showExpanded ? setShowExpanded('') : onClose()}> {showExpanded ? ( event.stopPropagation()}>

{showExpanded == 'favorite' ? 'Любимые' : 'Исключить'}

setShowExpanded('')}> ×
{/*{((showExpanded == 'favorite' ? form.favorite : form.avoided) || []).map(tag => (*/} {availableTags.map(tag => ( -1} onClick={() => { if ((showExpanded == 'favorite' ? form.favorite : form.avoided).indexOf(tag) > -1) { (showExpanded == 'favorite' ? handleFavoriteChange : handleAvoidChange)( ((showExpanded == 'favorite' ? form.favorite : form.avoided) || []).filter(item => item != tag) ) } else { (showExpanded == 'favorite' ? handleFavoriteChange : handleAvoidChange)( ((showExpanded == 'favorite' ? form.favorite : form.avoided) || []).concat(tag) ) } }} > {tag} ))}
) : ( event.stopPropagation()}>

{user ? 'Редактировать человека' : 'Добавить человека'}

×
updateForm('name', event.target.value)} /> updateForm('gender', 'f')} > Женский updateForm('gender', 'm')} > Мужской updateForm('age', event.target.value)} /> от 7 лет updateForm('weight', event.target.value)} /> updateForm('height', event.target.value)} /> setShowExpanded('avoid')} /> setShowExpanded('favorite')} /> Сохранить
)}
); } const Overlay = styled.div` height: 100vh; position: fixed; inset: 0; background: rgba(0, 0, 0, 0.4); backdrop-filter: blur(2px); display: flex; align-items: center; justify-content: center; z-index: 1000; padding: 20px; overflow: auto; `; const Content = styled.div` background: #ffffff; border-radius: 12px; width: 100%; max-width: 440px; padding: 24px; box-shadow: 0 8px 30px rgba(0, 0, 0, 0.2); max-height: 95vh; overflow-y: auto; `; const Header = styled.div` display: flex; justify-content: space-between; align-items: center; margin-bottom: 20px; h2 { font-size: 20px; font-weight: 600; color: ${({theme}) => theme.colors.darkGreen}; } `; const CloseButton = styled.button` font-size: 24px; color: #CEDFD0; cursor: pointer; line-height: 1; background: transparent; border: 0; &:hover { color: ${({theme}) => theme.colors.darkGreen}; } `; const FormGroup = styled.div` margin-bottom: 16px; flex: 1; label { display: block; font-size: 16px; color: ${({theme}) => theme.colors.darkGreen}; margin-bottom: 8px; } input { width: 100%; padding: 10px 12px; border: 1px solid #e1e1e1; border-radius: 8px; font-size: 14px; outline: none; transition: 0.2s; height: 44px; &::placeholder { color: #A3ADA2; } &:hover { border-color: ${({theme}) => theme.colors.gray}; } &:focus { border-color: ${({theme}) => theme.colors.green}; } } `; const FormRow = styled.div` display: flex; gap: 16px; margin-bottom: 16px; ${FormGroup} { margin-bottom: 0; } `; const Hint = styled.span` display: block; font-size: 12px; color: ${({theme}) => theme.colors.gray}; margin-top: 4px; `; const GenderToggles = styled.div` display: flex; gap: 16px; margin-bottom: 16px; `; const GenderButton = styled.button<{ $active: boolean }>` flex: 1; padding: 10px; border: 1px solid ${({$active}) => ($active ? '#5EA12D' : '#E7EDE7')}; border-radius: 8px; background: ${({$active}) => ($active ? '#E6F696' : '#ffffff')}; outline: ${({$active}) => ($active ? '1px solid #5EA12D' : '1px solid transparent')}; font-size: 16px; cursor: pointer; transition: 0.1s; font-weight: 370; height: 44px; &:hover { outline: 1px solid #5EA12D; border: 1px solid #5EA12D; } `; const PrefsGrid = styled.div` display: flex; flex-direction: column; gap: 16px; margin-bottom: 20px; border-top: 1px solid #f0f0f0; padding-top: 16px; min-height: 200px; `; const SaveButton = styled.button` width: 100%; padding: 12px; background: ${({theme}) => theme.colors.green}; color: #fff; height: 54px; box-sizing: border-box; border: none; border-radius: 12px; font-size: 16px; font-weight: 370; cursor: pointer; transition: 0.2s; &:hover { background: #5b8f29; } `;