Files
moonwell-web/resources/js/Pages/Admin/Components/NewsForm.vue
T
2026-07-28 15:11:30 +04:00

95 lines
3.7 KiB
Vue

<script setup>
import { router, useForm } from '@inertiajs/vue3';
const props = defineProps({
item: { type: Object, default: null },
action: { type: String, required: true },
destroyUrl: { type: String, default: null },
allowImage: { type: Boolean, default: false },
labels: { type: Object, required: true },
initial: { type: Object, default: () => ({}) },
});
const form = useForm({
title: props.item?.title ?? props.initial.title ?? '',
sort_order: props.item?.sort_order ?? props.initial.sort_order ?? 0,
is_published: props.item?.is_published ?? props.initial.is_published ?? true,
body: props.item?.body ?? props.initial.body ?? '',
...(props.allowImage ? { image: null } : {}),
});
function submit() {
const hasImage = props.allowImage && Boolean(form.image);
const options = {
preserveScroll: true,
forceFormData: hasImage,
errorBag: props.item ? `news-edit-${props.item.id}` : 'news-create',
onSuccess: () => {
if (!props.item) form.reset();
},
};
form.transform((data) => data);
if (props.item && hasImage) {
form.transform((data) => ({ ...data, _method: 'patch' })).post(props.action, options);
} else if (props.item) {
form.patch(props.action, options);
} else {
form.post(props.action, options);
}
}
function destroyItem() {
if (props.destroyUrl && window.confirm(props.labels.deleteConfirm)) {
router.delete(props.destroyUrl, { preserveScroll: true });
}
}
</script>
<template>
<form class="admin-form" @submit.prevent="submit">
<div class="admin-form-grid">
<label class="admin-field admin-field--wide">
<span>{{ labels.title }}</span>
<input v-model="form.title" maxlength="120" required />
<small v-if="form.errors.title">{{ form.errors.title }}</small>
</label>
<label class="admin-field">
<span>Порядок вывода</span>
<input v-model="form.sort_order" type="number" min="0" max="9999" required />
<small v-if="form.errors.sort_order">{{ form.errors.sort_order }}</small>
</label>
</div>
<label class="admin-check">
<input v-model="form.is_published" type="checkbox" />
<span class="admin-check__box"></span>
<span>{{ labels.published }}</span>
</label>
<label class="admin-field">
<span>{{ labels.body }}</span>
<textarea v-model="form.body" rows="10" required></textarea>
<em v-if="labels.bodyHint">{{ labels.bodyHint }}</em>
<small v-if="form.errors.body">{{ form.errors.body }}</small>
</label>
<label v-if="allowImage" class="admin-field admin-upload">
<span>{{ item ? 'Заменить картинку' : 'Картинка' }}</span>
<input type="file" accept="image/*" @input="form.image = $event.target.files[0]" />
<em>{{ item ? 'Оставь пустым, чтобы сохранить текущую. Максимум 10 МБ.' : 'Максимум 10 МБ. Необязательно.' }}</em>
<small v-if="form.errors.image">{{ form.errors.image }}</small>
</label>
<div class="admin-form-actions">
<button class="btn btn-primary admin-submit" type="submit" :disabled="form.processing">
{{ form.processing ? 'Сохраняем…' : labels.submit }}
</button>
<button v-if="destroyUrl" class="btn btn-ghost admin-danger-button" type="button" @click="destroyItem">
{{ labels.delete }}
</button>
</div>
</form>
</template>