2941b14b38
- Moved contents of main_dc/yalarba/easySite/easySite/ up to easySite/ - Updated docker-compose.yml build context path - Deleted empty nested easySite/ directory
195 lines
7.8 KiB
Vue
195 lines
7.8 KiB
Vue
<template>
|
|
<form class="space-y-6" @submit.prevent="handleSubmit">
|
|
<div class="card">
|
|
<div class="card-header">
|
|
<h3 class="text-lg font-semibold">Основная информация</h3>
|
|
</div>
|
|
<div class="card-body space-y-4">
|
|
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
|
|
<div class="form-group">
|
|
<label class="form-label">Название объекта *</label>
|
|
<input
|
|
v-model="formData.short_name"
|
|
type="text"
|
|
class="form-input"
|
|
required
|
|
placeholder="Короткое название">
|
|
</div>
|
|
<div class="form-group">
|
|
<label class="form-label">Полное название</label>
|
|
<input
|
|
v-model="formData.long_name"
|
|
type="text"
|
|
class="form-input"
|
|
placeholder="Полное название (если отличается)">
|
|
</div>
|
|
</div>
|
|
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
|
|
<div class="form-group">
|
|
<label class="form-label">Тип объекта *</label>
|
|
<select v-model="formData.type" class="form-select" required>
|
|
<option value="">Выберите тип</option>
|
|
<option value="hotel">Гостиница</option>
|
|
<option value="sanatorium">Санаторий</option>
|
|
<option value="guest_house">Гостевой дом</option>
|
|
<option value="tour">Тур</option>
|
|
<option value="excursion">Экскурсия</option>
|
|
<option value="restaurant">Ресторан</option>
|
|
</select>
|
|
</div>
|
|
<div class="form-group">
|
|
<label class="form-label">Статус</label>
|
|
<select v-model="formData.status" class="form-select">
|
|
<option value="draft">Черновик</option>
|
|
<option value="moderation">Отправить на модерацию</option>
|
|
<option value="active">Активен</option>
|
|
</select>
|
|
</div>
|
|
</div>
|
|
<div class="form-group">
|
|
<label class="form-label">Описание</label>
|
|
<textarea
|
|
v-model="formData.description" class="form-input" rows="4"
|
|
placeholder="Подробное описание объекта"/>
|
|
</div>
|
|
<div class="form-group">
|
|
<label class="form-label">Краткое описание</label>
|
|
<textarea
|
|
v-model="formData.short_description" class="form-input" rows="2"
|
|
placeholder="Краткое описание для списка"/>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="card">
|
|
<div class="card-header">
|
|
<h3 class="text-lg font-semibold">Местоположение</h3>
|
|
</div>
|
|
<div class="card-body space-y-4">
|
|
<div class="form-group">
|
|
<label class="form-label">Адрес</label>
|
|
<input
|
|
v-model="formData.address" type="text" class="form-input"
|
|
placeholder="Полный адрес">
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="card">
|
|
<div class="card-header">
|
|
<h3 class="text-lg font-semibold">Цены и контакты</h3>
|
|
</div>
|
|
<div class="card-body space-y-4">
|
|
<div class="grid grid-cols-1 md:grid-cols-3 gap-4">
|
|
<div class="form-group">
|
|
<label class="form-label">Цена</label>
|
|
<input v-model="formData.price" type="number" class="form-input" placeholder="0">
|
|
</div>
|
|
<div class="form-group">
|
|
<label class="form-label">Период цены</label>
|
|
<select v-model="formData.price_period" class="form-select">
|
|
<option value="">Не указано</option>
|
|
<option value="per_night">За ночь</option>
|
|
<option value="per_person">За человека</option>
|
|
<option value="per_tour">За тур</option>
|
|
<option value="per_hour">За час</option>
|
|
</select>
|
|
</div>
|
|
<div class="form-group">
|
|
<label class="form-label">Сайт</label>
|
|
<input
|
|
v-model="formData.site" type="url" class="form-input"
|
|
placeholder="https://">
|
|
</div>
|
|
</div>
|
|
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
|
|
<div class="form-group">
|
|
<label class="form-label">Телефон</label>
|
|
<input
|
|
v-model="formData.phone" type="tel" class="form-input"
|
|
placeholder="+7 (XXX) XXX-XX-XX">
|
|
</div>
|
|
<div class="form-group">
|
|
<label class="form-label">Email</label>
|
|
<input
|
|
v-model="formData.email" type="email" class="form-input"
|
|
placeholder="email@example.com">
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="flex gap-4 justify-end">
|
|
<button type="button" class="btn btn-outline" :disabled="loading" @click="$emit('cancel')">
|
|
Отмена
|
|
</button>
|
|
<button type="submit" class="btn btn-primary" :disabled="loading">
|
|
<span v-if="loading">Сохранение...</span>
|
|
<span v-else>{{ object ? 'Обновить' : 'Создать' }}</span>
|
|
</button>
|
|
</div>
|
|
</form>
|
|
</template>
|
|
|
|
<script setup lang="ts">
|
|
interface ObjectFormData {
|
|
short_name: string
|
|
long_name: string
|
|
type: string
|
|
description: string
|
|
short_description: string
|
|
address: string
|
|
price: number | null
|
|
price_period: string
|
|
phone: string
|
|
email: string
|
|
site: string
|
|
status: string
|
|
}
|
|
|
|
interface Props {
|
|
object?: ObjectFormData | null
|
|
loading?: boolean
|
|
}
|
|
|
|
const props = withDefaults(defineProps<Props>(), {
|
|
object: null,
|
|
loading: false
|
|
})
|
|
|
|
const emit = defineEmits<{
|
|
submit: [formData: ObjectFormData]
|
|
cancel: []
|
|
}>()
|
|
|
|
const formData = reactive<ObjectFormData>({
|
|
short_name: '',
|
|
long_name: '',
|
|
type: '',
|
|
description: '',
|
|
short_description: '',
|
|
address: '',
|
|
price: null,
|
|
price_period: '',
|
|
phone: '',
|
|
email: '',
|
|
site: '',
|
|
status: 'draft'
|
|
})
|
|
|
|
watch(() => props.object, (newObject) => {
|
|
if (newObject) {
|
|
Object.assign(formData, newObject)
|
|
}
|
|
}, { immediate: true })
|
|
|
|
const handleSubmit = () => {
|
|
const data = { ...formData }
|
|
if (data.price === null) {
|
|
delete (data as Record<string, unknown>).price
|
|
}
|
|
if (!data.price_period) delete (data as Record<string, unknown>).price_period
|
|
emit('submit', data)
|
|
}
|
|
</script>
|