mns-mini-zabor/components/modal.vue

145 lines
5.5 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<script setup lang="ts">
import { getColorNameFromRal } from '@/components/ral'
import type { ralTypes } from '@/components/ral'
const config = useRuntimeConfig()
const apiBase = config.public.apiBase
const { data: calculatorData } = await useFetch(`${apiBase}/calculator/5/`)
const isModalOpen = useState('modal_open', () => false)
const lamelles_count = useState<number>('lamelles_count')
const fence_section = useState<number>('fence_section')
const pillar_color = useState<ralTypes>('pillar_color')
const lamelle_color = useState<ralTypes>('lamelle_color')
const section_count = useState('section_count')
const extra_section = useState('extra_section')
const total_length = useState('total_length')
const toggleModal = () => {
modal_data.phone = undefined
modal_data.name = undefined
modal_state.show_form = false
isModalOpen.value = !isModalOpen.value
}
type modalDataType = {
phone?: string
name?: string
}
const modal_data = reactive<modalDataType>({
phone: undefined,
name: undefined
})
const modal_form = reactive({
disabled: true,
errors: [],
})
const modal_state = reactive({
show_form: false
})
const openForm = () => {
modal_state.show_form = !modal_state.show_form
}
const validateInput = (evt: KeyboardEvent) => {
const valid_symbols = /[a-zA-Z0-9\+(\\)\ @\.]/
if (!valid_symbols.test(evt.key)) {
evt.preventDefault()
return
}
}
const validate = () => {
const phone_regexp = /^\+?[\d\s-()]{0,14}\d{11}$/
const email_regex = /^[\w-\.]+@([\w-]+\.)+[\w-]{2,4}$/
if (!modal_data.phone) {
modal_form.disabled = true
return
}
if (modal_data.phone.length < 3) {
modal_form.disabled = true
return
}
if (phone_regexp.test(modal_data.phone) || email_regex.test(modal_data.phone)) {
modal_form.disabled = false
return
}
}
const submit = (e: any) => {
fetch(`${apiBase}/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,
fence_info: `Ширина секции: ${fence_section.value}
Ламелей в секции: ${lamelles_count.value}
Всего секций: ${section_count.value}
Дополнительная секция: ${extra_section.value}
Общая длина забора: ${total_length.value}
Цвет ламелей ${lamelle_color.value} (${getColorNameFromRal(lamelle_color.value)})
Цвет столбов ${pillar_color.value} (${getColorNameFromRal(pillar_color.value)})`
})
})
modal_data.phone = undefined
modal_data.name = undefined
isModalOpen.value = false
}
const roubleSign = new Intl.NumberFormat('ru-RU', {
style: 'currency',
currency: 'RUB',
});
const total = computed(() => {
const { mortgage, pillar, lamella } = calculatorData.value
const pillar_count = (section_count.value + 1)
const pil = (parseFloat(mortgage) + parseFloat(pillar)) * pillar_count
const lam_count = lamelles_count.value * section_count.value
const lam = lam_count * lamella
const top_count = section_count.value
const top = top_count * lamella
return [
`Столб, ${pillar_count}: ${roubleSign.format(pil)}`,
`Ламели, ${lam_count}: ${roubleSign.format(lam)}`,
`Верхняя планка, ${top_count}: ${roubleSign.format(top)}`,
]
})
</script>
<template>
<div v-if="isModalOpen" class="modal-backdrop" @click.self="toggleModal">
<div class="modal">
<template v-if="modal_state.show_form">
<h2>Оставьте контакты для связи </h2>
<form @submit.prevent="submit">
<input type="text" placeholder="Ваше имя" v-model="modal_data.name" @keyup="validate" />
<input type="phone" placeholder="Номер телефона или e-mail" v-model="modal_data.phone"
@keypress="validateInput" @keyup="validate" />
<div class="flex gap-4">
<button class="not-prose" :disabled="modal_form.disabled" type="submit">Отправить</button>
<button class="not-prose" type="reset" @click="toggleModal">Отмена</button>
</div>
</form>
</template>
<template v-else>
<h2>данные расчета</h2>
<div class="flex gap-4 flex-col mb-4">
<p>Ламелей: {{ lamelles_count }}<br />
Длина секции: {{ fence_section * 1000 }}<br />
Общая длина: {{ total_length }}<br />
Секций: {{ section_count }}<br />
Цвет столба: {{ getColorNameFromRal(pillar_color) }}<br />
Цвет ламелей: {{ getColorNameFromRal(lamelle_color) }}</p>
<p>
<template v-for="i in total">{{ i }}<br /></template>
</p>
</div>
<div class="flex gap-4">
<button class="not-prose" @click="openForm">Данные верны</button>
<button class="not-prose neutral" @click="toggleModal">Закрыть окно</button>
</div>
</template>
</div>
</div>
</template>