161 lines
5.4 KiB
Vue
161 lines
5.4 KiB
Vue
<template>
|
|
<div class="min-h-screen bg-gradient-to-br from-yellow-200 via-yellow-300 to-yellow-400 relative overflow-hidden">
|
|
<!-- Navigation -->
|
|
<nav
|
|
v-if="currentSection !== 'landing'"
|
|
class="absolute top-4 left-1/2 transform -translate-x-1/2 z-20"
|
|
>
|
|
<ul
|
|
class="flex space-x-6 bg-white/40 backdrop-blur-md px-6 py-3 rounded-full shadow-md text-sm font-semibold text-gray-800"
|
|
>
|
|
<li><button @click="switchSection('introduction')" :class="navClass('introduction')">Intro</button></li>
|
|
<li><button @click="switchSection('event')" :class="navClass('event')">Event</button></li>
|
|
<li><button @click="switchSection('gallery')" :class="navClass('gallery')">Gallery</button></li>
|
|
<li><button @click="switchSection('guestbook')" :class="navClass('guestbook')">Guest Book</button></li>
|
|
<li><button @click="switchSection('thanks')" :class="navClass('thanks')">Thanks</button></li>
|
|
</ul>
|
|
</nav>
|
|
|
|
<!-- Tombol Musik -->
|
|
<div class="fixed bottom-4 left-4 z-30" v-if="currentSection !== 'landing'">
|
|
<button
|
|
@click="toggleMusic"
|
|
class="bg-yellow-600 hover:bg-yellow-700 p-3 rounded-full text-white shadow-lg transition-transform hover:scale-110"
|
|
>
|
|
{{ isPlaying ? '⏸️' : '▶️' }}
|
|
</button>
|
|
</div>
|
|
|
|
<!-- Main Section -->
|
|
<main
|
|
class="relative z-10 min-h-screen flex items-center justify-center p-4 transition-all duration-700 ease-in-out"
|
|
>
|
|
<!-- Landing -->
|
|
<Landing
|
|
v-if="currentSection === 'landing'"
|
|
:childName="formData.nama_panggilan"
|
|
:guestName="data.nama_tamu"
|
|
@open-invitation="switchSection('introduction')"
|
|
/>
|
|
|
|
<!-- Introduction -->
|
|
<Introduction
|
|
v-if="currentSection === 'introduction'"
|
|
:age="formData.umur_yang_dirayakan"
|
|
:childName="formData.nama_lengkap"
|
|
:childOrder="formData.anak_ke"
|
|
:parentsName="`${formData.nama_bapak} & ${formData.nama_ibu}`"
|
|
:childPhoto="formData.foto && formData.foto.length ? `${backendUrl}/storage/${formData.foto[0]}` : null"
|
|
/>
|
|
|
|
<!-- Event -->
|
|
<Event
|
|
v-if="currentSection === 'event'"
|
|
:hari_tanggal_acara="formData.hari_tanggal_acara"
|
|
:waktu="formData.waktu"
|
|
:alamat="formData.alamat"
|
|
:link_gmaps="formData.link_gmaps"
|
|
:hitung_mundur="formData.hitung_mundur"
|
|
/>
|
|
|
|
<!-- Gallery -->
|
|
<Gallery v-if="currentSection === 'gallery'" :images="galleryImages" />
|
|
|
|
<!-- Guest Book -->
|
|
<GuestBook
|
|
v-if="currentSection === 'guestbook'"
|
|
:guestName="data.nama_tamu"
|
|
:messages="messages"
|
|
@addMessage="addMessage"
|
|
/>
|
|
|
|
<!-- Thank You -->
|
|
<ThankYou
|
|
v-if="currentSection === 'thanks'"
|
|
:childName="formData.nama_panggilan"
|
|
:jsonData="formData"
|
|
/>
|
|
</main>
|
|
|
|
<!-- Footer -->
|
|
<footer
|
|
class="bg-white/40 backdrop-blur-md text-center py-4 text-gray-700 font-medium border-t border-yellow-300"
|
|
>
|
|
<p>© {{ new Date().getFullYear() }} Undangan Ulang Tahun Basic | Dibuat dengan 💛 oleh Arief Dwi Wicaksono</p>
|
|
</footer>
|
|
</div>
|
|
</template>
|
|
|
|
<script setup>
|
|
import { ref, computed, watchEffect } from 'vue'
|
|
import { useRuntimeConfig } from '#app'
|
|
|
|
// Import Komponen
|
|
import Landing from '~/components/templates/UltahBasic/Landing.vue'
|
|
import Introduction from '~/components/templates/UltahBasic/Introduction.vue'
|
|
import Event from '~/components/templates/UltahBasic/Event.vue'
|
|
import Gallery from '~/components/templates/UltahBasic/Gallery.vue'
|
|
import GuestBook from '~/components/templates/UltahBasic/GuestBook.vue'
|
|
import ThankYou from '~/components/templates/UltahBasic/ThankYou.vue'
|
|
|
|
// Props dari halaman induk
|
|
const props = defineProps({
|
|
data: { type: Object, required: true }
|
|
})
|
|
|
|
// Runtime config (untuk backend URL)
|
|
const config = useRuntimeConfig()
|
|
const backendUrl = config.public.apiBaseUrl
|
|
|
|
// Data dari backend
|
|
const formData = computed(() => props.data.form || {})
|
|
|
|
// Galeri gambar (support foto array atau field lama)
|
|
const galleryImages = computed(() => {
|
|
const f = formData.value.foto
|
|
if (Array.isArray(f)) {
|
|
return f.map(img => `${backendUrl}/storage/${img}`)
|
|
}
|
|
return [
|
|
formData.value.foto_1,
|
|
formData.value.foto_2,
|
|
formData.value.foto_3,
|
|
formData.value.foto_4,
|
|
formData.value.foto_5
|
|
].filter(Boolean).map(img => `${backendUrl}/${img}`)
|
|
})
|
|
|
|
watchEffect(() => {
|
|
console.log("🧾 formData:", formData.value)
|
|
console.log("🖼️ galleryImages:", galleryImages.value)
|
|
})
|
|
|
|
// Navigasi antar bagian
|
|
const currentSection = ref('landing')
|
|
const switchSection = (s) => (currentSection.value = s)
|
|
|
|
// Musik toggle
|
|
const isPlaying = ref(false)
|
|
const toggleMusic = () => (isPlaying.value = !isPlaying.value)
|
|
|
|
// Buku tamu
|
|
const messages = ref([])
|
|
const addMessage = (msg) => messages.value.push(msg)
|
|
|
|
// Style untuk navigasi aktif
|
|
const navClass = (s) =>
|
|
currentSection.value === s
|
|
? 'text-yellow-800 underline underline-offset-4'
|
|
: 'hover:text-yellow-600 transition-colors'
|
|
</script>
|
|
|
|
<style scoped>
|
|
html {
|
|
scroll-behavior: smooth;
|
|
}
|
|
|
|
button {
|
|
transition: all 0.3s ease;
|
|
}
|
|
</style>
|
|
|