241 lines
8.5 KiB
Vue
241 lines
8.5 KiB
Vue
<template>
|
|
<div class="max-w-6xl mx-auto p-8 bg-gradient-to-b from-pink-50 to-red-50 shadow-lg rounded-xl">
|
|
<!-- Judul -->
|
|
<div class="text-center mb-10">
|
|
<h1 class="text-3xl md:text-4xl font-extrabold text-red-700 drop-shadow-sm">
|
|
💍 Form Pemesanan Undangan Pernikahan 💐
|
|
</h1>
|
|
<p class="text-gray-600 mt-2">Isi data berikut untuk membuat undangan pernikahan Anda</p>
|
|
</div>
|
|
|
|
<form @submit.prevent="submitForm" class="space-y-10">
|
|
|
|
<!-- Paket Starter (Informasi) -->
|
|
<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">Paket Undangan</h2>
|
|
<div class="p-4 border rounded-xl bg-blue-50">
|
|
<div class="font-semibold text-gray-800 mb-2">Starter</div>
|
|
<div class="text-gray-600 mb-2">Fitur:</div>
|
|
<ul class="list-disc list-inside text-gray-600">
|
|
<li>1x Acara</li>
|
|
<li>Masa Aktif 3 Bulan</li>
|
|
<li>Fitur standar: Nama Tamu Personal, maks. 100 Tamu, Request Musik</li>
|
|
</ul>
|
|
</div>
|
|
</section>
|
|
|
|
<!-- Info Template -->
|
|
<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">Template & Detail Paket</h2>
|
|
<div class="grid grid-cols-2 md:grid-cols-4 gap-4">
|
|
<input v-model="form.nama_template" type="text" placeholder="Nama Template" class="input-readonly" readonly />
|
|
<input v-model="form.kategori" type="text" placeholder="Kategori" class="input-readonly" readonly />
|
|
<input v-model="form.harga" type="text" placeholder="Harga" class="input-readonly" readonly />
|
|
<input v-model="form.tanggal_pemesanan" type="text" placeholder="Tanggal Pemesanan" class="input-readonly"
|
|
readonly />
|
|
</div>
|
|
</section>
|
|
|
|
<!-- Data Pemesan -->
|
|
<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">Data Pemesan</h2>
|
|
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
|
|
<div>
|
|
<label class="block text-sm text-gray-600 mb-1">Nama Pemesan</label>
|
|
<input v-model="form.nama_pemesan" type="text" class="input" required />
|
|
</div>
|
|
<div>
|
|
<label class="block text-sm text-gray-600 mb-1">No. WhatsApp</label>
|
|
<input v-model="form.no_hp" type="text" class="input" required />
|
|
</div>
|
|
<div class="md:col-span-2">
|
|
<label class="block text-sm text-gray-600 mb-1">Email</label>
|
|
<input v-model="form.email" type="email" class="input" required />
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
<!-- Data Pengantin -->
|
|
<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">Data Pengantin</h2>
|
|
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
|
|
<div>
|
|
<label class="block text-sm mb-1">Nama Pengantin Pria</label>
|
|
<input v-model="form.nama_pria" type="text" class="input" required />
|
|
</div>
|
|
<div>
|
|
<label class="block text-sm mb-1">Nama Pengantin Wanita</label>
|
|
<input v-model="form.nama_wanita" type="text" class="input" required />
|
|
</div>
|
|
<div>
|
|
<label class="block text-sm mb-1">Orang Tua Pengantin Pria</label>
|
|
<input v-model="form.ortu_pria" type="text" class="input" />
|
|
</div>
|
|
<div>
|
|
<label class="block text-sm mb-1">Orang Tua Pengantin Wanita</label>
|
|
<input v-model="form.ortu_wanita" type="text" class="input" />
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
<!-- Data 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">Detail Acara (1x Acara)</h2>
|
|
<div v-for="(acara, index) in form.acaras" :key="index" class="mb-6 border-b pb-4">
|
|
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
|
|
<div>
|
|
<label class="block text-sm mb-1">Nama Acara</label>
|
|
<input v-model="acara.nama" type="text" class="input" required />
|
|
</div>
|
|
<div>
|
|
<label class="block text-sm mb-1">Tanggal Acara</label>
|
|
<input v-model="acara.tanggal" type="date" class="input" required />
|
|
</div>
|
|
<div>
|
|
<label class="block text-sm mb-1">Jam</label>
|
|
<input v-model="acara.jam" type="time" class="input" />
|
|
</div>
|
|
<div>
|
|
<label class="block text-sm mb-1">Lokasi</label>
|
|
<input v-model="acara.lokasi" type="text" class="input" required />
|
|
</div>
|
|
<!-- Request Lagu -->
|
|
<div class="md:col-span-2">
|
|
<label class="block text-sm mb-1">Request Lagu</label>
|
|
<input v-model="acara.request_lagu" type="text" class="input"
|
|
placeholder="Contoh: Lagu pengantin, playlist, dsb." />
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
<!-- Submit -->
|
|
<div class="mt-10 text-center">
|
|
<button type="submit"
|
|
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! Tunggu konfirmasi admin.
|
|
</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. Cek kembali inputan Anda.
|
|
</div>
|
|
</form>
|
|
</div>
|
|
</template>
|
|
|
|
<script setup>
|
|
import { ref } from "vue"
|
|
|
|
const form = ref({
|
|
selectedPaket: "starter",
|
|
nama_template: "undangan minimalis",
|
|
kategori: "Pernikahan",
|
|
harga: "100.000",
|
|
tanggal_pemesanan: new Date().toLocaleDateString("id-ID"),
|
|
nama_pemesan: "",
|
|
no_hp: "",
|
|
email: "",
|
|
nama_pria: "",
|
|
nama_wanita: "",
|
|
ortu_pria: "",
|
|
ortu_wanita: "",
|
|
acaras: [{ nama: "", tanggal: "", jam: "", lokasi: "", request_lagu: "" }],
|
|
})
|
|
|
|
const loading = ref(false)
|
|
const success = ref(false)
|
|
const error = ref(false)
|
|
const template = ref(null)
|
|
const route = useRoute()
|
|
|
|
onMounted(async () => {
|
|
try {
|
|
const templateId = route.query.template_id // ⬅️ ambil dari query string
|
|
if (!templateId) throw new Error("Template ID tidak ditemukan di URL")
|
|
|
|
const res = await fetch(`http://localhost:8000/api/templates/${templateId}`)
|
|
if (!res.ok) throw new Error("Gagal ambil template")
|
|
template.value = await res.json()
|
|
|
|
// isi form info template
|
|
form.value.nama_template = template.value.nama_template
|
|
form.value.kategori = template.value.kategori?.nama || ""
|
|
form.value.harga = template.value.harga
|
|
form.value.tanggal_pemesanan = new Date().toLocaleDateString("id-ID")
|
|
} catch (err) {
|
|
console.error("Error fetch template:", err)
|
|
}
|
|
})
|
|
|
|
|
|
const submitForm = async () => {
|
|
try {
|
|
loading.value = true
|
|
success.value = false
|
|
error.value = false
|
|
|
|
const res = await fetch("http://localhost:8000/api/pelanggans", {
|
|
method: "POST",
|
|
headers: {
|
|
"Content-Type": "application/json",
|
|
},
|
|
body: JSON.stringify({
|
|
nama_pemesan: form.value.nama_pemesan,
|
|
email: form.value.email,
|
|
no_tlpn: form.value.no_hp,
|
|
template_id: template.value.id,
|
|
form: {
|
|
nama_pengantin: form.value.nama_pria + " & " + form.value.nama_wanita,
|
|
tanggal_acara: form.value.acaras[0].tanggal,
|
|
lokasi: form.value.acaras[0].lokasi
|
|
}
|
|
}),
|
|
})
|
|
|
|
// parse JSON dulu
|
|
const data = await res.json()
|
|
console.log("Respon backend:", data)
|
|
|
|
if (!res.ok) {
|
|
console.error("Status:", res.status)
|
|
console.error("Error full:", data)
|
|
console.error("Error detail:", data.errors)
|
|
throw new Error(data.message || "Gagal simpan data")
|
|
}
|
|
|
|
success.value = true
|
|
} catch (err) {
|
|
console.error("Catch error:", err)
|
|
error.value = true
|
|
} finally {
|
|
loading.value = false
|
|
}
|
|
}
|
|
|
|
|
|
</script>
|
|
|
|
<style>
|
|
.input {
|
|
border: 1px solid #d1d5db;
|
|
padding: 0.5rem 0.75rem;
|
|
border-radius: 0.5rem;
|
|
width: 100%;
|
|
font-size: 0.875rem;
|
|
}
|
|
|
|
.input-readonly {
|
|
border: 1px solid #d1d5db;
|
|
padding: 0.5rem 0.75rem;
|
|
border-radius: 0.5rem;
|
|
background-color: #f9fafb;
|
|
color: #4b5563;
|
|
}
|
|
</style>
|