store/resources/js/components/admin/setting/SystemSection.vue

144 lines
5.7 KiB
Vue

<script setup lang="ts">
import { router, useForm } from '@inertiajs/vue3';
import { Save } from '@lucide/vue';
import { toast } from 'vue-sonner';
import { Button } from '@/components/ui/button';
import { Card, CardContent } from '@/components/ui/card';
import { Field, FieldError, FieldGroup, FieldLabel, FieldSet } from '@/components/ui/field';
import { ImageUploadField } from '@/components/form/image-upload-field';
import { Input } from '@/components/ui/input';
import { PhoneNumberInput } from '@/components/form/phone-number-input';
import { Textarea } from '@/components/ui/textarea';
import { formErrors } from '@/lib/form';
import type { SystemSettingsData } from '@/types/setting';
const props = defineProps<{
data: SystemSettingsData;
}>();
const form = useForm({
app_name: props.data.app_name,
about_app: props.data.about_app ?? '',
email: props.data.email ?? '',
phone: props.data.phone ?? '',
address: props.data.address ?? '',
logo: null as File | null,
login_cover: null as File | null,
});
function buildFormData(): FormData {
const formData = new FormData();
formData.append('app_name', form.app_name);
formData.append('about_app', form.about_app);
formData.append('email', form.email);
formData.append('phone', form.phone);
formData.append('address', form.address);
if (form.logo) {
formData.append('logo', form.logo);
}
if (form.login_cover) {
formData.append('login_cover', form.login_cover);
}
return formData;
}
function submit() {
const payload = buildFormData();
form.transform(() => payload).post('/admin/system/setting/system', {
preserveScroll: true,
onSuccess: () => {
router.reload({ only: ['name', 'address'] });
},
onError: () => {
toast.error('Gagal menyimpan pengaturan sistem.');
},
});
}
</script>
<template>
<div class="flex flex-col gap-4 sm:flex-row sm:items-center sm:justify-between">
<div class="space-y-1">
<h2 class="text-2xl font-bold tracking-tight">
</h2>
</div>
</div>
<form @submit.prevent="submit">
<div class="grid gap-6">
<Card>
<CardContent>
<FieldSet>
<FieldGroup class="grid gap-4 sm:grid-cols-2">
<Field class="sm:col-span-2">
<FieldLabel for="app_name" required>
Nama Aplikasi
</FieldLabel>
<Input id="app_name" v-model="form.app_name" placeholder="DST Collection" />
<FieldError :errors="formErrors(form, 'app_name')" />
</Field>
<Field class="sm:col-span-2">
<FieldLabel for="about_app" required>
Tentang Aplikasi
</FieldLabel>
<Textarea id="about_app" v-model="form.about_app" rows="4"
placeholder="Deskripsi singkat tentang bisnis atau aplikasi Anda." />
<FieldError :errors="formErrors(form, 'about_app')" />
</Field>
<Field class="sm:col-span-2">
<FieldLabel for="address" required>
Alamat
</FieldLabel>
<Textarea id="address" v-model="form.address" rows="3"
placeholder="Alamat toko yang ditampilkan di struk." />
<FieldError :errors="formErrors(form, 'address')" />
</Field>
<Field>
<FieldLabel for="email" required>
Email
</FieldLabel>
<Input id="email" v-model="form.email" type="email" placeholder="info@perusahaan.com" />
<FieldError :errors="formErrors(form, 'email')" />
</Field>
<Field>
<FieldLabel for="phone" required>
Nomor Telepon
</FieldLabel>
<PhoneNumberInput id="phone" v-model="form.phone" />
<FieldError :errors="formErrors(form, 'phone')" />
</Field>
</FieldGroup>
<FieldGroup class="grid gap-6 sm:grid-cols-2">
<ImageUploadField id="logo" v-model="form.logo" label="Logo" required
description="Disarankan PNG transparan, maks. 2 MB." :current-url="data.logo_url"
:errors="formErrors(form, 'logo')" />
<ImageUploadField id="login_cover" v-model="form.login_cover" label="Cover Login" required
description="Gambar latar halaman login, maks. 5 MB."
:current-url="data.login_cover_url" :errors="formErrors(form, 'login_cover')" />
</FieldGroup>
</FieldSet>
</CardContent>
</Card>
<div class="flex justify-end">
<Button type="submit" :disabled="form.processing">
<Save class="size-4" />
{{ form.processing ? 'Menyimpan...' : 'Simpan' }}
</Button>
</div>
</div>
</form>
</template>