This commit is contained in:
Farhaan4 2025-10-07 10:52:14 +07:00
parent 1ef83feac9
commit 9fd4dac382

View File

@ -1,19 +1,63 @@
<script setup> <script setup>
import { ref, computed } from 'vue' import { ref, computed } from 'vue'
// id template yang mau ditampilkan // ID template yang mau ditampilkan
const selectedIds = [1, 2, 3, 5, 6] const selectedIds = [1, 2, 3, 5, 6]
// state dropdown (buat fitur paket aja sekarang) // State dropdown
const openDropdownId = ref(null) const openDropdownId = ref(null)
const toggleDropdown = (templateId) => { const toggleDropdown = (templateId) => {
openDropdownId.value = openDropdownId.value === templateId ? null : templateId openDropdownId.value = openDropdownId.value === templateId ? null : templateId
} }
// fetch API dari Laravel // Paket & fitur hardcode
const paketData = [
{
paket: 'Starter',
fiturs: [
'1x Acara',
'Masa Aktif 3 Bulan',
'Nama Tamu Personal',
'Maks. 100 Tamu',
'Request Musik'
]
},
{
paket: 'Basic',
fiturs: [
'1x Acara',
'6 Galeri Foto',
'Hitung Mundur Waktu Acara',
'Buku Tamu + Data Kehadiran',
'Masa Aktif 6 Bulan',
'Nama Tamu Personal',
'Maks. 200 Tamu',
'Request Musik'
]
},
{
paket: 'Premium',
fiturs: [
'Maksimal 3x Acara (Akad, Resepsi, Syukuran)',
'Unlimited Galeri Foto',
'Timeline Story',
'Google Maps',
'Reminder Google Calendar',
'Link Instagram Live Streaming',
'Amplop Digital',
'Placement Video Cinematic',
'Bonus Undangan Image Post Story',
'Masa Aktif 12 Bulan',
'Nama Tamu Personal Unlimited Tamu',
'Request Musik'
]
}
]
// Fetch data template dari backend (nama_template, harga, kategori, foto)
const { data: templatesData, error } = await useFetch('http://localhost:8000/api/templates') const { data: templatesData, error } = await useFetch('http://localhost:8000/api/templates')
// mapping template: nama_template & harga dari backend, paket & fiturs hardcode // Mapping template: gabungkan backend + paket & fitur hardcode
const templates = computed(() => const templates = computed(() =>
(templatesData.value || []) (templatesData.value || [])
.filter(t => selectedIds.includes(t.id)) .filter(t => selectedIds.includes(t.id))
@ -21,9 +65,10 @@ const templates = computed(() =>
id: t.id, id: t.id,
nama_template: t.nama_template, nama_template: t.nama_template,
harga: t.harga, harga: t.harga,
foto: t.foto || '/default.jpg', // fallback jika foto kosong
paket: paketData[index % paketData.length].paket, paket: paketData[index % paketData.length].paket,
fiturs: paketData[index % paketData.length].fiturs.map((f, i) => ({ id: i + 1, deskripsi: f })), fiturs: paketData[index % paketData.length].fiturs.map((f, i) => ({ id: i + 1, deskripsi: f })),
kategori: t.kategori // tetap disimpan agar bisa untuk routing Order kategori: t.kategori
})) }))
) )
</script> </script>
@ -40,17 +85,9 @@ const templates = computed(() =>
<!-- Grid Template --> <!-- Grid Template -->
<div v-if="templates.length" class="grid gap-8 max-w-[1100px] mx-auto grid-cols-1 sm:grid-cols-2 lg:grid-cols-3"> <div v-if="templates.length" class="grid gap-8 max-w-[1100px] mx-auto grid-cols-1 sm:grid-cols-2 lg:grid-cols-3">
<div <div v-for="t in templates" :key="t.id" class="bg-white border rounded-lg overflow-hidden shadow-md hover:shadow-xl transition-shadow duration-300">
v-for="t in templates" <!-- Gambar -->
:key="t.id" <img :src="`http://localhost:8000${t.foto}`" :alt="t.nama_template" class="w-full h-48 object-cover" />
class="bg-white border rounded-lg overflow-hidden shadow-md hover:shadow-xl transition-shadow duration-300"
>
<!-- Image -->
<img
:src="`http://localhost:8000${t.foto}`"
:alt="t.nama_template"
class="w-full h-48 object-cover"
/>
<!-- Body --> <!-- Body -->
<div class="p-5 text-center"> <div class="p-5 text-center">
@ -58,41 +95,39 @@ const templates = computed(() =>
<p class="text-green-600 font-semibold text-xl mb-1"> <p class="text-green-600 font-semibold text-xl mb-1">
Rp {{ Number(t.harga).toLocaleString('id-ID') }} Rp {{ Number(t.harga).toLocaleString('id-ID') }}
</p> </p>
<p class="text-gray-500 mb-4 font-medium">Paket: {{ t.paket }}</p>
<!-- Dropdown fitur --> <!-- Dropdown fitur -->
<div v-if="t.fiturs && t.fiturs.length > 0" class="relative mb-4"> <div v-if="t.fiturs && t.fiturs.length > 0" class="relative mb-4">
<button <button @click="toggleDropdown(t.id)"
@click="toggleDropdown(t.id)" class="w-full bg-white border border-gray-300 rounded-md shadow-sm px-4 py-2 inline-flex justify-between items-center">
class="w-full bg-white border border-gray-300 rounded-md shadow-sm px-4 py-2 inline-flex justify-between items-center"
>
<span class="mx-auto text-gray-700 font-semibold">FITUR YANG TERSEDIA</span> <span class="mx-auto text-gray-700 font-semibold">FITUR YANG TERSEDIA</span>
<svg class="h-5 w-5 text-gray-400" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor"> <svg class="h-5 w-5 text-gray-400" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor">
<path fill-rule="evenodd" d="M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z" clip-rule="evenodd" /> <path fill-rule="evenodd" d="M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z" clip-rule="evenodd" />
</svg> </svg>
</button> </button>
<div v-if="openDropdownId === t.id"> <transition name="fade">
<ul class="mt-4 space-y-2 text-gray-600 text-left"> <div v-if="openDropdownId === t.id" class="mt-4">
<li v-for="f in t.fiturs" :key="f.id" class="flex items-center"> <ul class="space-y-2 text-gray-600 text-left max-h-60 overflow-y-auto px-3 py-2 border border-gray-200 rounded-md shadow-inner bg-gray-50">
<svg class="h-4 w-4 text-green-500 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24"> <li v-for="f in t.fiturs" :key="f.id" class="flex items-center">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7"/> <svg class="h-4 w-4 text-green-500 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
</svg> <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7" />
{{ f.deskripsi }} </svg>
</li> {{ f.deskripsi }}
</ul> </li>
</div> </ul>
</div>
</transition>
</div> </div>
<!-- Tombol --> <!-- Tombol -->
<div class="flex items-center gap-3 mt-6"> <div class="flex items-center gap-3 mt-6">
<button <button class="w-full bg-white border border-gray-300 text-gray-800 font-semibold py-2 px-4 rounded-lg hover:bg-gray-100 transition-colors">
class="w-full bg-white border border-gray-300 text-gray-800 font-semibold py-2 px-4 rounded-lg hover:bg-gray-100 transition-colors">
Preview Preview
</button> </button>
<NuxtLink <NuxtLink :to="`/form/${t.kategori ? t.kategori.toLowerCase().replace(/ /g, '-') : 'lainnya'}?template_id=${t.id}`"
:to="`/form/${t.kategori.nama.toLowerCase().replace(/ /g, '-')}` + `?template_id=${t.id}`" class="w-full bg-blue-600 text-white font-semibold py-2 px-4 rounded-lg hover:bg-blue-700 transition-colors text-center">
class="w-full bg-blue-600 text-white font-semibold py-2 px-4 rounded-lg hover:bg-blue-700 transition-colors text-center"
>
Order Order
</NuxtLink> </NuxtLink>
</div> </div>
@ -100,7 +135,7 @@ const templates = computed(() =>
</div> </div>
</div> </div>
<!-- Jika error --> <!-- Jika error atau kosong -->
<div v-else class="text-gray-500">Tidak ada template yang bisa ditampilkan</div> <div v-else class="text-gray-500">Tidak ada template yang bisa ditampilkan</div>
<!-- See more --> <!-- See more -->