// useModalState.ts import { useRuntimeConfig } from '#app'; type ModalDataType = { phone?: string; name?: string; email?: string; policy: boolean; }; // Состояние открытия модального окна const isModalOpen = ref(false); // Реактивные данные формы const modal_data = reactive({ email: undefined, phone: undefined, name: undefined, policy: false, }); // Реактивные данные состояния формы const modal_form = reactive({ disabled: true, errors: [] as string[], }); // Реактивные данные состояния модального окна const modal_state = reactive({ show_form: true, show_status: null as null | 'loading' | 'success' | 'error', }); export function useModalState(initialState = false) { // Функция для открытия модального окна const openModal = () => { isModalOpen.value = true; }; // Функция для закрытия модального окна const closeModal = () => { resetModalData(); isModalOpen.value = false; }; // Функция для переключения состояния модального окна const toggleModal = () => { resetModalData(); isModalOpen.value = !isModalOpen.value; }; // Функция для сброса данных формы const resetModalData = () => { modal_data.email = undefined; modal_data.phone = undefined; modal_data.name = undefined; modal_data.policy = false; modal_state.show_form = true; modal_state.show_status = null; modal_form.disabled = true; modal_form.errors = []; }; // Функция для открытия формы const openForm = () => { modal_state.show_form = !modal_state.show_form; goal('open_form'); }; // Валидация ввода const validateInput = (evt: KeyboardEvent) => { const valid_symbols = /[a-zA-Z0-9\+(\\)\ @\.]/; if (!valid_symbols.test(evt.key)) { evt.preventDefault(); } }; // Валидация данных формы const validate = () => { const phone_regexp = /^\+?[\d\s-()]{0,14}\d{11}$/; const email_regex = /^[\w-\.]+@([\w-]+\.)+[\w-]{2,4}$/; modal_form.disabled = true; if ( ((modal_data.phone && phone_regexp.test(modal_data.phone)) || (modal_data.email && email_regex.test(modal_data.email))) && modal_data.policy === true ) { modal_form.disabled = false; } }; // Отправка данных на сервер const submit = async () => { goal('submit_form', modal_data); modal_state.show_status = 'loading'; const config = useRuntimeConfig() const apiBase = config.public.apiBase const prefix = config.public.apiPrefix try { const res = await fetch(`${apiBase}/gb/custom_request/`, { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ name: modal_data.name || `ref from site ${new Date()}`, phone: modal_data.phone, email: modal_data.email, privacy: true, fence_info: 'Запрос скамейки' }), }); modal_state.show_status = 'success'; } catch (error) { modal_state.show_status = 'error'; } }; // Наблюдение за изменениями данных формы watch(modal_data, validate); // Наблюдение за состоянием модального окна watch(isModalOpen, (newValue) => { console.log(isModalOpen) if (newValue) { document.body.classList.add('modal-opened'); } else { document.body.classList.remove('modal-opened'); } }); return { isModalOpen, modal_data, modal_form, modal_state, openModal, closeModal, toggleModal, openForm, validateInput, validate, submit, }; }