Undangan/proyek-frontend/app/components/forms/KhitanForm.vue
2025-09-18 10:01:21 +07:00

275 lines
10 KiB
Vue

<template>
<div class="max-w-5xl mx-auto p-8 bg-gradient-to-b from-green-50 to-blue-50 shadow-lg rounded-xl">
<!-- Judul Form -->
<div class="text-center mb-10">
<h1 class="text-3xl md:text-4xl font-extrabold text-green-700 drop-shadow-sm">
🕌 Form Pemesanan Undangan Khitan
</h1>
<p class="text-gray-600 mt-2">
Isi data berikut dengan lengkap untuk pemesanan undangan khitan.
</p>
</div>
<form @submit.prevent="submitForm" class="space-y-10">
<!-- Tema Undangan -->
<section class="p-6 bg-white rounded-xl shadow-sm border border-gray-200">
<h2 class="text-lg font-bold text-gray-800 mb-4 flex items-center gap-2">
<span class="w-1.5 h-6 bg-blue-600 rounded-full"></span> Tema Undangan
</h2>
<div class="grid grid-cols-2 md:grid-cols-4 gap-4">
<input :value="form.nama_template" type="text" placeholder="Nama Template" class="input-readonly" readonly />
<input :value="form.kategori" type="text" placeholder="Kategori" class="input-readonly" readonly />
<input :value="form.harga" type="text" placeholder="Harga" class="input-readonly" readonly />
<input :value="form.tanggal_pemesanan" type="text" placeholder="Tanggal Pemesanan" class="input-readonly" readonly />
</div>
</section>
<!-- Pemesan Undangan -->
<section class="p-6 bg-white rounded-xl shadow-sm border border-gray-200">
<h2 class="text-lg font-bold text-gray-800 mb-4 flex items-center gap-2">
<span class="w-1.5 h-6 bg-blue-600 rounded-full"></span> Pemesan Undangan
</h2>
<div class="space-y-4">
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
<input v-model="form.nama_pemesan" type="text" placeholder="Nama Pemesan" class="input" required />
<input v-model="form.no_hp" type="text" placeholder="No. WhatsApp" class="input" required />
</div>
<input v-model="form.email" type="email" placeholder="Email" class="input" required />
</div>
</section>
<!-- Detail Khitan -->
<section class="p-6 bg-white rounded-xl shadow-sm border border-gray-200">
<h2 class="text-lg font-bold text-gray-800 mb-4">Detail Khitan</h2>
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
<input v-model="form.nama_lengkap_anak" type="text" placeholder="Nama Lengkap Anak" class="input" required />
<input v-model="form.nama_panggilan_anak" type="text" placeholder="Nama Panggilan Anak" class="input" required />
<input v-model="form.bapak_anak" type="text" placeholder="Nama Bapak" class="input" />
<input v-model="form.ibu_anak" type="text" placeholder="Nama Ibu" class="input" />
</div>
</section>
<!-- Jadwal Acara -->
<section class="p-6 bg-white rounded-xl shadow-sm border border-gray-200">
<h2 class="text-lg font-bold text-gray-800 mb-4">Jadwal Acara</h2>
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
<input v-model="form.hari_tanggal_acara" type="date" class="input" />
<input v-model="form.waktu_acara" type="text" placeholder="08.00 WIB" class="input" />
<textarea v-model="form.alamat_acara" placeholder="Alamat Acara" rows="3" class="input col-span-2"></textarea>
<input v-model="form.maps_acara" type="text" placeholder="Link Google Maps" class="input col-span-2" />
</div>
</section>
<!-- Rekening, Musik, Galeri -->
<section class="grid grid-cols-1 md:grid-cols-2 gap-6">
<div class="space-y-6">
<div class="p-6 bg-white rounded-xl shadow-sm border border-gray-200 space-y-4">
<h2 class="text-lg font-bold text-gray-800">No. Rekening</h2>
<input v-model="form.no_rekening1" type="text" placeholder="Rekening 1" class="input" />
<input v-model="form.no_rekening2" type="text" placeholder="Rekening 2" class="input" />
</div>
<div class="p-6 bg-white rounded-xl shadow-sm border border-gray-200">
<h2 class="text-lg font-bold text-gray-800">Musik</h2>
<input v-model="form.link_musik" type="text" placeholder="Link Musik" class="input" />
</div>
</div>
<div class="p-6 bg-white rounded-xl shadow-sm border border-gray-200">
<h2 class="text-lg font-bold text-gray-800 mb-4">Galeri (max 5 gambar)</h2>
<input type="file" multiple accept="image/*" @change="handleFileUpload" class="hidden" id="gallery-upload" />
<div class="grid grid-cols-2 md:grid-cols-3 gap-3">
<div v-for="(img, i) in previewImages" :key="i" class="relative w-full aspect-square rounded-lg overflow-hidden shadow-sm group">
<img :src="img" alt="Preview" class="object-cover w-full h-full" />
<button
type="button"
@click="removeImage(i)"
class="absolute top-1 right-1 bg-red-600 text-white rounded-full w-6 h-6 flex items-center justify-center opacity-0 group-hover:opacity-100 transition-opacity font-bold"
aria-label="Hapus gambar"
>
&times;
</button>
</div>
<label v-if="previewImages.length < 5" for="gallery-upload" class="flex items-center justify-center w-full aspect-square bg-gray-50 border-2 border-dashed border-gray-300 rounded-lg cursor-pointer hover:bg-gray-100 transition">
<svg xmlns="http://www.w3.org/2000/svg" class="h-10 w-10 text-gray-400" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 4v16m8-8H4" />
</svg>
</label>
</div>
</div>
</section>
</form>
<!-- Submit -->
<div class="mt-10 text-center">
<button @click="submitForm" class="bg-blue-600 text-white px-10 py-3 rounded-xl font-semibold shadow-md hover:bg-blue-700 hover:shadow-lg transition" :disabled="loading">
{{ loading ? "Mengirim..." : "Kirim & Konfirmasi Admin" }}
</button>
</div>
<!-- Alert -->
<div v-if="success" class="mt-6 p-4 text-green-800 bg-green-100 rounded-lg text-center font-medium">
✅ Form berhasil dikirim!
</div>
<div v-if="error" class="mt-6 p-4 text-red-800 bg-red-100 rounded-lg text-center font-medium">
Gagal mengirim form. Pastikan semua data yang wajib diisi sudah lengkap.
</div>
</div>
</template>
<script setup>
import { ref, onMounted } from "vue";
import { useRoute } from "vue-router";
const route = useRoute();
const form = ref({
template_id: "",
nama_template: "",
kategori: "",
harga: "",
tanggal_pemesanan: new Date().toISOString().split("T")[0],
nama_pemesan: "",
no_hp: "",
email: "",
nama_lengkap_anak: "",
nama_panggilan_anak: "",
bapak_anak: "",
ibu_anak: "",
hari_tanggal_acara: "",
waktu_acara: "",
alamat_acara: "",
maps_acara: "",
no_rekening1: "",
no_rekening2: "",
link_musik: "",
galeri: [],
});
const previewImages = ref([]);
const loading = ref(false);
const success = ref(false);
const error = ref(false);
onMounted(async () => {
if (route.query.template_id) {
try {
const template = await $fetch(`http://localhost:8000/api/templates/${route.query.template_id}`);
form.value.template_id = template.id;
form.value.nama_template = template.nama_template;
form.value.kategori_id = template.kategori_id;
form.value.kategori = template.kategori?.nama || "-";
form.value.harga = template.harga;
form.value.fiturs = template.fiturs.map(f => f.deskripsi);
} catch (err) {
console.error("Gagal ambil template", err);
}
}
});
// FUNGSI UNTUK MENAMBAH GAMBAR
const handleFileUpload = (event) => {
const newFiles = Array.from(event.target.files);
const combinedFiles = [...form.value.galeri, ...newFiles];
// Batasi total file menjadi 5
form.value.galeri = combinedFiles.slice(0, 5);
// Buat ulang array preview berdasarkan data file yang sudah final
previewImages.value = [];
form.value.galeri.forEach(file => {
const reader = new FileReader();
reader.onload = (e) => {
previewImages.value.push(e.target.result);
};
reader.readAsDataURL(file);
});
// Reset input agar bisa memilih file yang sama lagi
event.target.value = null;
};
// FUNGSI UNTUK MENGHAPUS GAMBAR (SEKARANG DI LUAR)
const removeImage = (index) => {
form.value.galeri.splice(index, 1);
previewImages.value.splice(index, 1);
};
const submitForm = async () => {
loading.value = true;
success.value = false;
error.value = false;
try {
const body = new FormData();
for (const key in form.value) {
if (key === "galeri") {
form.value.galeri.forEach((file) => body.append("galeri[]", file));
} else {
body.append(key, form.value[key]);
}
}
await $fetch("http://localhost:8000/api/form/khitan", {
method: "POST",
body,
});
success.value = true;
const adminNumber = "62895602603247";
// ✅ Susun pesan otomatis
const message = `
Halo Admin, ada pemesanan undangan khitan baru 🎉
📌 Data Pemesan:
Nama Pemesan: ${form.value.nama_pemesan}
No WA: ${form.value.no_hp}
Email: ${form.value.email}
👦 Data Anak:
Nama Lengkap: ${form.value.nama_lengkap_anak}
Nama Panggilan: ${form.value.nama_panggilan_anak}
Ayah: ${form.value.bapak_anak || "-"}
Ibu: ${form.value.ibu_anak || "-"}
📅 Jadwal Acara:
Tanggal: ${form.value.hari_tanggal_acara}
Waktu: ${form.value.waktu_acara}
Alamat: ${form.value.alamat_acara}
Google Maps: ${form.value.maps_acara || "-"}
💳 Informasi Tambahan:
Rekening 1: ${form.value.no_rekening1 || "-"}
Rekening 2: ${form.value.no_rekening2 || "-"}
Musik: ${form.value.link_musik || "-"}
🎨 Template & Order:
Template: ${form.value.nama_template} (${form.value.kategori})
Harga: ${form.value.harga}
Tanggal Pemesanan: ${form.value.tanggal_pemesanan}
`;
// ✅ Redirect ke WhatsApp
const waUrl = `https://wa.me/${adminNumber}?text=${encodeURIComponent(message)}`;
window.location.href = waUrl;
} catch (err) {
console.error(err);
error.value = true;
} finally {
loading.value = false;
}
};
</script>