store/resources/js/pages/Home.vue

928 lines
45 KiB
Vue

<script setup lang="ts">
import { Head } from '@inertiajs/vue3';
import {
Search,
ShoppingBag,
X,
Plus,
Minus,
ArrowRight,
Star,
Check,
Info,
ChevronRight,
Phone,
MapPin,
Mail,
LogIn
} from '@lucide/vue';
import { ref, computed } from 'vue';
import ProductCard from '@/components/card/ProductCard.vue';
import ProductModal from '@/components/modal/ProductModal.vue';
import DraggableCarousel from '@/components/ui/carousel/DraggableCarousel.vue';
import { formatRupiah } from '@/lib/rupiah';
import admin from '@/routes/admin';
import type { Product, Variant, Price, Category } from '@/types/product';
import type { MediaItem } from '@/types/media';
interface HomepageData {
hero_image_url: string | null;
about_image_url: string | null;
gallery_images: MediaItem[];
}
const props = defineProps<{
categories: Category[];
products: Product[];
appName: string;
aboutApp: string;
contactEmail: string;
contactPhone: string;
contactAddress: string;
logoUrl: string | null;
instagramUrl: string | null;
facebookUrl: string | null;
tiktokUrl: string | null;
homepage: HomepageData;
}>();
// Search & Catalog Filter State
const searchInput = ref('');
const selectedCategory = ref<string | null>(null);
// Hardcoded order steps
const orderSteps = [
{ title: 'Pilih Produk', description: 'Jelajahi katalog kami dan pilih produk yang Anda sukai.' },
{ title: 'Hubungi Kami', description: 'Hubungi kami melalui WhatsApp untuk konfirmasi pesanan.' },
{ title: 'Pembayaran', description: 'Lakukan pembayaran melalui transfer bank atau metode lainnya.' },
{ title: 'Pesanan Dikirim', description: 'Pesanan Anda akan segera dikirim ke alamat tujuan.' },
];
// Hardcoded about features
const aboutFeatures = [
'Kain Premium & Adem',
'Jahitan Rapi & Berkualitas',
'Motif Eksklusif & Unik',
'Pengiriman ke Seluruh Indonesia',
];
const toggleCategory = (slug: string) => {
selectedCategory.value = selectedCategory.value === slug ? null : slug;
};
// Filtered and Sorted Products
const filteredProducts = computed(() => {
const result = props.products.filter(product => {
// Search filter
const matchesSearch = product.name.toLowerCase().includes(searchInput.value.toLowerCase()) ||
(product.description && product.description.toLowerCase().includes(searchInput.value.toLowerCase()));
// Category filter
const matchesCategory = !selectedCategory.value ||
product.categories.some(cat => cat.slug === selectedCategory.value);
return matchesSearch && matchesCategory;
});
return result;
});
// Image Resolver
const getProductImage = (product: Product, indexOffset = 0) => {
for (const variant of product.variants) {
if (variant.images && variant.images.length > 0) {
return variant.images[0].url;
}
}
// Fallbacks based on category slug
const firstCat = product.categories?.[0]?.slug || '';
const fallbacks: Record<string, string[]> = {
'daster': [
'https://images.unsplash.com/photo-1595777457583-95e059d581b8?w=800&auto=format&fit=crop&q=80',
'https://images.unsplash.com/photo-1572804013309-59a88b7e92f1?w=800&auto=format&fit=crop&q=80'
],
'setelan-celana': [
'https://images.unsplash.com/photo-1539109136881-3be0616acf4b?w=800&auto=format&fit=crop&q=80',
'https://images.unsplash.com/photo-1618244972963-dbee1a7edc95?w=800&auto=format&fit=crop&q=80'
],
'atasan': [
'https://images.unsplash.com/photo-1515886657613-9f3515b0c78f?w=800&auto=format&fit=crop&q=80',
'https://images.unsplash.com/photo-1532244769068-b223ede82d7b?w=800&auto=format&fit=crop&q=80'
],
'bawahan': [
'https://images.unsplash.com/photo-1583496661160-fb4886b36ca7?w=800&auto=format&fit=crop&q=80',
'https://images.unsplash.com/photo-1551163943-3f6a855d1153?w=800&auto=format&fit=crop&q=80'
],
'busui': [
'https://images.unsplash.com/photo-1509631179647-0177331693ae?w=800&auto=format&fit=crop&q=80',
'https://images.unsplash.com/photo-1496747611176-843222e1e57c?w=800&auto=format&fit=crop&q=80'
]
};
const categoryUrls = fallbacks[firstCat] || [
'https://images.unsplash.com/photo-1490481651871-ab68de25d43d?w=800&auto=format&fit=crop&q=80',
'https://images.unsplash.com/photo-1434389677669-e08b4cac3105?w=800&auto=format&fit=crop&q=80'
];
return categoryUrls[indexOffset % categoryUrls.length];
};
// Price Range Resolver
const getProductPriceRange = (product: Product) => {
const prices = product.variants.flatMap(v =>
v.prices.filter(p => p.type === 'retail').map(p => p.price)
);
if (prices.length === 0) {
const fallbackPrices = product.variants.flatMap(v => v.prices.map(p => p.price));
if (fallbackPrices.length === 0) {
return 'Rp 0';
}
const min = Math.min(...fallbackPrices);
const max = Math.max(...fallbackPrices);
return min === max ? `Rp ${formatRupiah(min)}` : `Rp ${formatRupiah(min)} - Rp ${formatRupiah(max)}`;
}
const min = Math.min(...prices);
const max = Math.max(...prices);
return min === max ? `Rp ${formatRupiah(min)}` : `Rp ${formatRupiah(min)} - Rp ${formatRupiah(max)}`;
};
const featuredProducts = computed(() => {
return props.products.slice(0, 3);
});
// Cart System
interface CartItem {
product: Product;
variant: Variant;
price: Price;
quantity: number;
}
const cart = ref<CartItem[]>([]);
const isCartOpen = ref(false);
const addToCart = (product: Product, variant: Variant, price: Price) => {
const existingIndex = cart.value.findIndex(item => item.variant.id === variant.id && item.price.type === price.type);
if (existingIndex > -1) {
if (cart.value[existingIndex].quantity < variant.stock) {
cart.value[existingIndex].quantity += 1;
}
} else {
cart.value.push({
product,
variant,
price,
quantity: 1
});
}
isCartOpen.value = true;
};
const removeFromCart = (variantId: number, priceType: string) => {
cart.value = cart.value.filter(item => !(item.variant.id === variantId && item.price.type === priceType));
};
const updateCartQuantity = (variantId: number, priceType: string, change: number) => {
const item = cart.value.find(item => item.variant.id === variantId && item.price.type === priceType);
if (item) {
const newQty = item.quantity + change;
if (newQty > 0 && newQty <= item.variant.stock) {
item.quantity = newQty;
}
}
};
const cartTotal = computed(() => {
return cart.value.reduce((total, item) => total + (item.price.price * item.quantity), 0);
});
const cartCount = computed(() => {
return cart.value.reduce((count, item) => count + item.quantity, 0);
});
// Centered Modal State
const activeProduct = ref<Product | null>(null);
const openQuickView = (product: Product) => {
activeProduct.value = product;
};
const closeQuickView = () => {
activeProduct.value = null;
};
// Checkout Mock / WhatsApp redirect
const isCheckingOut = ref(false);
const handleWhatsAppCheckout = () => {
if (cart.value.length === 0) {
return;
}
isCheckingOut.value = true;
// Construct WhatsApp message
let message = `Halo ${props.appName}, saya ingin memesan produk berikut:\n\n`;
cart.value.forEach((item, index) => {
message += `${index + 1}. *${item.product.name}*\n`;
message += ` - Varian/Ukuran: ${item.variant.name}\n`;
message += ` - Jenis Harga: ${item.price.type_label}\n`;
message += ` - Jumlah: ${item.quantity} pcs\n`;
message += ` - Subtotal: Rp ${formatRupiah(item.price.price * item.quantity)}\n\n`;
});
message += `*Total Pembayaran: Rp ${formatRupiah(cartTotal.value)}*\n\n`;
message += `Mohon info untuk detail rekening transfer dan pengirimannya. Terima kasih!`;
const formattedPhone = props.contactPhone.replace(/[^0-9]/g, '');
const finalPhone = formattedPhone.startsWith('0') ? '62' + formattedPhone.slice(1) : formattedPhone;
const waUrl = `https://wa.me/${finalPhone || '6281234567890'}?text=${encodeURIComponent(message)}`;
setTimeout(() => {
isCheckingOut.value = false;
window.open(waUrl, '_blank');
}, 800);
};
</script>
<template>
<Head :title="`${appName} | Galeri Pakaian Modern & Sejuk`">
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin="anonymous" />
</Head>
<div
class="min-h-screen bg-linear-to-tr from-amber-50/20 via-[#FDFDFC] to-yellow-50/30 text-slate-800 transition-colors duration-300 font-sans scroll-smooth">
<!-- Sticky Header & Navbar -->
<header class="sticky top-0 z-40 bg-white/70 backdrop-blur-lg border-b border-amber-100/50 transition-all">
<div class="max-w-7xl mx-auto px-6 h-20 flex items-center justify-between">
<!-- Logo Frame from settings -->
<div class="flex items-center space-x-3">
<a href="#" class="flex items-center space-x-2">
<img v-if="logoUrl" :src="logoUrl" :alt="appName"
class="h-10 w-auto object-contain p-1 rounded-lg shadow-sm" />
<span v-else class="font-serif text-2xl font-bold tracking-widest text-amber-600">
{{ appName }}
</span>
</a>
</div>
<!-- Navigation Links (Indonesian) -->
<nav
class="hidden lg:flex items-center space-x-8 text-xs font-semibold uppercase tracking-widest text-slate-600">
<a href="#" class="hover:text-amber-600 transition-colors">Beranda</a>
<a href="#catalog" class="hover:text-amber-600 transition-colors">Produk</a>
<a href="#about" class="hover:text-amber-600 transition-colors">Tentang Kami</a>
<a href="#order-guide" class="hover:text-amber-600 transition-colors">Cara Pesan</a>
<a href="#contact" class="hover:text-amber-600 transition-colors">Hubungi Kami</a>
</nav>
<!-- Action Utilities (Cart & Login) -->
<div class="flex items-center space-x-4">
<!-- Cart button -->
<button @click="isCartOpen = true"
class="relative p-2 rounded-full hover:bg-amber-50 text-slate-600 transition-colors cursor-pointer"
aria-label="Keranjang Belanja">
<ShoppingBag class="w-4.5 h-4.5 text-amber-600" />
<span v-if="cartCount > 0"
class="absolute -top-0.5 -right-0.5 bg-amber-600 text-white text-[9px] font-bold w-4.5 h-4.5 flex items-center justify-center rounded-full shadow-sm animate-bounce">
{{ cartCount }}
</span>
</button>
<!-- Login button -->
<a :href="admin.dashboard.url()"
class="p-2 rounded-full hover:bg-amber-50 text-slate-600 transition-colors cursor-pointer"
aria-label="Login">
<LogIn class="w-4.5 h-4.5 text-amber-600" />
</a>
</div>
</div>
</header>
<!-- Hero Section: Split Screen Visual Masterpiece (Fresh Aqua Palette) -->
<section id="hero" class="relative min-h-[calc(100vh-80px)] flex flex-col justify-between overflow-hidden">
<!-- Split Background Grid with Fresh Cyan Gradients -->
<div class="absolute inset-0 grid grid-cols-1 lg:grid-cols-2 pointer-events-none z-0">
<div class="bg-white/40/30"></div>
<div
class="bg-linear-to-tr from-amber-100/30 via-yellow-100/20 to-orange-50/30 border-l border-amber-100/20">
</div>
</div>
<!-- Main Layout Content -->
<div
class="max-w-7xl mx-auto px-6 w-full lg:grow grid grid-cols-1 lg:grid-cols-12 gap-8 items-center py-12 z-10">
<!-- Left Column: Serif Text and CTA -->
<div class="lg:col-span-5 flex flex-col justify-center space-y-6 lg:pr-6">
<div
class="inline-flex items-center space-x-2 bg-amber-500/10/10 text-[10px] text-amber-700 uppercase tracking-widest px-3 py-1 rounded-full w-fit font-bold shadow-sm">
<span>Hadir dengan Gaya Terbaru</span>
</div>
<h1
class="text-5xl md:text-6xl font-serif leading-[1.1] tracking-tight font-light select-none text-slate-800">
Nyaman <br />
dalam Setiap <span
class="font-normal italic text-amber-600 bg-amber-100/20 px-2 rounded-lg">Penampilan</span>.
</h1>
<p class="text-sm text-slate-500 max-w-md leading-relaxed font-light">
Koleksi fashion wanita dengan sentuhan elegan, material berkualitas, dan kenyamanan yang dapat
Anda rasakan di setiap pemakaian.
</p>
<div class="flex items-center space-x-4 pt-4">
<a href="#catalog"
class="inline-flex items-center justify-center bg-amber-600 text-white px-8 py-3.5 text-xs font-semibold uppercase tracking-widest rounded-xl shadow-lg shadow-amber-200/50 hover:bg-amber-500 hover:-translate-y-0.5 transition-all duration-300 group cursor-pointer">
Beli Sekarang
<ArrowRight
class="w-3.5 h-3.5 ml-2 transform group-hover:translate-x-1 transition-transform" />
</a>
<a href="#about"
class="inline-flex items-center justify-center border border-amber-200 text-xs font-semibold uppercase tracking-widest px-8 py-3.5 rounded-xl hover:bg-amber-500/5 hover:border-amber-400 transition-all cursor-pointer">
Tentang Kami
</a>
</div>
</div>
<!-- Center Column: Visual Model Showcase & Overlapping Titles (Cyan Aura) -->
<div class="lg:col-span-7 relative flex justify-center items-center h-[500px] lg:h-[650px] w-full">
<!-- Massive Overlapping Serif Heading (Behind Model) -->
<div class="absolute inset-0 flex justify-center items-center pointer-events-none select-none z-0">
<div
class="text-[14vw] lg:text-[120px] font-serif font-bold leading-none tracking-tight flex opacity-10[0.03]">
<span class="text-slate-900">DST</span>
<span class="text-amber-600">Collection</span>
</div>
</div>
<!-- Glowing Radial Background and Animated Morphing Blobs -->
<div
class="absolute inset-0 -z-10 flex justify-center items-center pointer-events-none select-none">
<div
class="absolute w-[350px] h-[350px] rounded-full bg-linear-to-tr from-amber-400/25 via-yellow-400/20 to-orange-300/25/15/20/15 blur-3xl animate-blob">
</div>
<div
class="absolute w-[400px] h-[400px] rounded-full bg-linear-to-br from-rose-300/20 via-amber-200/20 to-orange-300/20/15/15/15 blur-3xl animate-blob animation-delay-2000">
</div>
</div>
<!-- Main Model Central Image (With Floating Animation) -->
<div
class="relative w-[310px] h-[440px] lg:w-[390px] lg:h-[540px] rounded-[2rem] overflow-hidden z-10 transition-transform duration-500 hover:scale-[1.02] animate-float-model">
<img :src="homepage.hero_image_url || 'https://images.unsplash.com/photo-1490481651871-ab68de25d43d?w=1000&auto=format&fit=crop&q=80'"
alt="DSTCLO Model Unggulan" class="w-full h-full object-cover" />
</div>
<!-- FLOATING HERO TAG 1: Product Showcase -->
<div v-if="featuredProducts[0]" @click="openQuickView(featuredProducts[0])"
class="absolute top-10 left-4 md:-left-6 z-20 flex items-center space-x-3 bg-white/90 backdrop-blur-md p-3 rounded-2xl shadow-lg border border-amber-100/40 cursor-pointer transform hover:-translate-y-1 transition-all animate-float-tag-1">
<img :src="getProductImage(featuredProducts[0])" alt="Preview Produk"
class="w-10 h-10 object-cover rounded-lg" />
<div class="text-left">
<h4 class="text-[9px] font-bold text-amber-600 uppercase tracking-widest">Terpopuler</h4>
<p class="text-[11px] font-semibold truncate max-w-[100px]">{{ featuredProducts[0].name }}
</p>
<span class="text-[11px] font-bold text-amber-600">{{
getProductPriceRange(featuredProducts[0]) }}</span>
</div>
<div
class="flex items-center justify-center w-6 h-6 rounded-full bg-amber-50/50 text-amber-600">
<Plus class="w-3.5 h-3.5" />
</div>
</div>
<!-- FLOATING HERO TAG 2: Rating -->
<div v-if="featuredProducts[1]" @click="openQuickView(featuredProducts[1])"
class="absolute top-28 right-4 md:-right-6 z-20 flex items-center space-x-3 bg-white/90 backdrop-blur-md p-3 rounded-2xl shadow-lg border border-amber-100/40 cursor-pointer transform hover:-translate-y-1 transition-all animate-float-tag-2">
<img :src="getProductImage(featuredProducts[1], 1)" alt="Preview Produk"
class="w-10 h-10 object-cover rounded-lg" />
<div class="text-left">
<div class="flex items-center text-amber-400 space-x-0.5 mb-0.5">
<Star class="w-2.5 h-2.5 fill-current" v-for="i in 5" :key="i" />
</div>
<p class="text-[11px] font-semibold truncate max-w-[100px]">{{ featuredProducts[1].name }}
</p>
<span class="text-[10px] font-semibold text-emerald-500">Stok Tersedia</span>
</div>
</div>
</div>
</div>
<!-- Scroll Indicator -->
<div
class="max-w-7xl mx-auto px-6 w-full flex items-center justify-between pb-8 z-10 text-xs font-semibold text-slate-500">
<div class="flex items-center space-x-3">
<span class="text-amber-600">#DSTCollection</span>
<span class="w-1 h-1 rounded-full bg-amber-300"></span>
<span>Bahan Adem & Lembut</span>
</div>
<a href="#catalog" class="flex items-center space-x-2 hover:text-amber-600 transition-colors">
<span>Lihat katalog lengkap</span>
<ChevronRight class="w-3.5 h-3.5 transform rotate-90 text-amber-600" />
</a>
</div>
</section>
<!-- Catalog Section with Price Filters & Categories -->
<section id="catalog" class="max-w-7xl mx-auto px-6 py-20 border-t border-amber-100/30">
<div class="space-y-6 mb-12">
<div class="text-center space-y-2">
<h2 class="text-xs uppercase tracking-[0.3em] font-bold text-amber-600">Koleksi Pilihan</h2>
<h3 class="text-3xl font-serif text-slate-800">Temukan Gaya Favoritmu</h3>
<p class="text-sm text-slate-500 max-w-lg mx-auto font-light">
Temukan pilihan terbaik yang memadukan kenyamanan, kualitas, dan desain elegan untuk menemani
setiap aktivitas Anda.
</p>
</div>
<!-- Interactive Filters & Search Controls bar -->
<div
class="bg-white/80 backdrop-blur-md p-6 rounded-3xl shadow-sm border border-amber-100/30 flex flex-col md:flex-row items-center gap-4 justify-between">
<!-- Search Input -->
<div class="relative w-full md:w-80">
<input v-model="searchInput" type="text" placeholder="Cari produk..."
class="w-full bg-slate-50 border border-slate-200 text-xs px-4 py-3 pr-10 rounded-xl outline-none focus:border-amber-500 text-slate-700 transition-all" />
<Search class="absolute right-3 top-3.5 w-4 h-4 text-slate-400" />
</div>
<!-- Category Chips Carousel -->
<DraggableCarousel class="w-full md:w-auto">
<button @click="selectedCategory = null" :class="[
'shrink-0 px-4 py-2 text-[11px] font-semibold uppercase tracking-wider rounded-xl border transition-all cursor-pointer whitespace-nowrap',
!selectedCategory
? 'bg-amber-600 text-white border-transparent shadow-md shadow-amber-200/50'
: 'bg-transparent text-slate-600 border-slate-200 hover'
]">
Semua
</button>
<button v-for="category in categories" :key="category.id" @click="toggleCategory(category.slug)"
:class="[
'shrink-0 px-4 py-2 text-[11px] font-semibold uppercase tracking-wider rounded-xl border transition-all cursor-pointer whitespace-nowrap',
selectedCategory === category.slug
? 'bg-amber-600 text-white border-transparent shadow-md shadow-amber-200/50'
: 'bg-transparent text-slate-600 border-slate-200 hover'
]">
{{ category.name }}
</button>
</DraggableCarousel>
</div>
</div>
<!-- Product Grid -->
<div v-if="filteredProducts.length > 0"
class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-x-8 gap-y-12">
<ProductCard v-for="(product, idx) in filteredProducts" :key="product.id" :product="product"
:index-offset="idx" @quick-view="openQuickView" />
</div>
<!-- Empty Product State -->
<div v-else class="text-center py-20 space-y-3">
<Info class="w-12 h-12 text-amber-300 mx-auto" />
<h3 class="text-lg font-medium text-slate-700">Produk Tidak Ditemukan</h3>
<p class="text-sm text-slate-400">
Mohon maaf, kami tidak menemukan pakaian yang cocok dengan kata kunci pencarian Anda.
</p>
<button @click="searchInput = ''; selectedCategory = null"
class="mt-2 text-xs font-bold uppercase tracking-widest text-amber-600 underline underline-offset-4 cursor-pointer">
Reset Pencarian
</button>
</div>
</section>
<!-- Gallery / Lookbook Section -->
<section id="gallery"
class="w-full bg-linear-to-br from-amber-50/40 via-yellow-50/20 to-orange-50/30 py-24 border-t border-b border-amber-100/30">
<div class="max-w-7xl mx-auto px-6 space-y-12">
<!-- Header -->
<div class="text-center space-y-3 max-w-lg mx-auto">
<span class="text-xs uppercase tracking-[0.3em] font-bold text-amber-600">Galeri Kami</span>
<h3 class="text-4xl font-serif leading-tight">Koleksi Lookbook</h3>
<p class="text-sm text-slate-500 leading-relaxed font-light">
Lihat koleksi busana kami dalam balutan gaya yang elegan.
</p>
</div>
<!-- Gallery Grid -->
<div v-if="homepage.gallery_images.length > 0" class="grid grid-cols-2 md:grid-cols-3 gap-4">
<div v-for="(image, index) in homepage.gallery_images" :key="image.id"
class="group relative aspect-3/4 rounded-2xl overflow-hidden shadow-md border-2 border-white cursor-pointer transition-all duration-300 hover:shadow-xl hover:-translate-y-1">
<img :src="image.url" :alt="`Lookbook ${Number(index) + 1}`"
class="w-full h-full object-cover transition-transform duration-700 group-hover:scale-110" />
<div
class="absolute inset-0 bg-linear-to-t from-amber-950/40 via-transparent to-transparent opacity-0 group-hover:opacity-100 transition-opacity duration-300">
</div>
</div>
</div>
<div v-else class="text-center py-12">
<p class="text-sm text-slate-400">Belum ada foto lookbook yang ditambahkan.</p>
</div>
</div>
</section>
<!-- Cara Pesan Section -->
<section id="order-guide" class="max-w-7xl mx-auto px-6 py-20 border-b border-amber-100/30">
<div class="text-center space-y-3 mb-16">
<h3 class="text-xs uppercase tracking-[0.3em] font-bold text-amber-600">Panduan</h3>
<h4 class="text-3xl font-serif">Cara Pemesanan</h4>
<p class="text-sm text-slate-500 max-w-md mx-auto font-light">
Ikuti langkah-langkah mudah berikut untuk melakukan pemesanan.
</p>
</div>
<div class="grid grid-cols-1 md:grid-cols-4 gap-8">
<div v-for="(step, index) in orderSteps" :key="index"
class="bg-white/50 p-6 rounded-2xl border border-amber-100/30 shadow-sm relative overflow-hidden text-center group hover:-translate-y-1 transition-transform">
<div
class="absolute -top-4 -right-4 w-16 h-16 bg-amber-100/50/50 rounded-full flex items-center justify-center text-amber-600 font-bold text-xl font-serif">
{{ index + 1 }}</div>
<div
class="w-12 h-12 rounded-xl bg-amber-100/30 text-amber-600 flex items-center justify-center mx-auto mb-4">
<ShoppingBag v-if="index === 0" class="w-5 h-5" />
<Star v-else-if="index === 1" class="w-5 h-5" />
<Plus v-else-if="index === 2" class="w-5 h-5" />
<Phone v-else class="w-5 h-5" />
</div>
<h5 class="font-bold text-base mb-2">{{ step.title }}</h5>
<p class="text-xs text-slate-400 leading-relaxed font-light">
{{ step.description }}
</p>
</div>
</div>
</section>
<!-- About Us Section -->
<section id="about" class="max-w-7xl mx-auto px-6 py-20 border-b border-amber-100/30">
<div class="grid grid-cols-1 lg:grid-cols-12 gap-12 items-center">
<!-- Column Left -->
<div
class="lg:col-span-6 relative aspect-square max-w-md mx-auto lg:max-w-none rounded-3xl overflow-hidden shadow-lg border-2 border-white">
<img :src="homepage.about_image_url || 'https://images.unsplash.com/photo-1595777457583-95e059d581b8?w=800&auto=format&fit=crop&q=80'"
alt="Tentang Kami" class="w-full h-full object-cover" />
</div>
<!-- Column Right -->
<div class="lg:col-span-6 space-y-6">
<span class="text-xs uppercase tracking-[0.3em] font-bold text-amber-600">Tentang Kami</span>
<h3 class="text-3xl font-serif">Kami Menghadirkan Busana Berkualitas</h3>
<p class="text-sm text-slate-500 leading-relaxed font-light whitespace-pre-line">
{{ aboutApp || `Kami adalah rumah produksi busana dan batik lokal berkualitas tinggi. Berfokus
pada keindahan motif, ketepatan detail jahitan, dan pemilihan kain adem yang mengedepankan aspek
fungsionalitas dan estetika.` }}
</p>
<div v-for="(feature, index) in aboutFeatures" :key="index"
class="flex items-center space-x-3 text-xs text-slate-500 font-semibold">
<Check class="w-4 h-4 text-emerald-500" />
<span>{{ feature }}</span>
</div>
</div>
</div>
</section>
<!-- Contact Section -->
<section id="contact" class="max-w-7xl mx-auto px-6 py-20">
<div
class="bg-white/60 backdrop-blur-md border border-amber-100/30 p-8 rounded-3xl grid grid-cols-1 lg:grid-cols-2 gap-12 items-center shadow-sm">
<!-- Left -->
<div class="space-y-6">
<span class="text-xs uppercase tracking-[0.3em] font-bold text-amber-600">Hubungi Kami</span>
<h3 class="text-3xl font-serif">Mari Berdiskusi</h3>
<p class="text-sm text-slate-500 leading-relaxed font-light">
Jangan ragu untuk menghubungi kami jika Anda memiliki pertanyaan atau ingin melakukan pemesanan.
</p>
<div class="space-y-4">
<div v-if="contactPhone" class="flex items-center space-x-3 text-sm">
<div
class="w-8 h-8 rounded-lg bg-amber-100/40 text-amber-600 flex items-center justify-center">
<Phone class="w-4 h-4" />
</div>
<span>{{ contactPhone }}</span>
</div>
<div v-if="contactEmail" class="flex items-center space-x-3 text-sm">
<div
class="w-8 h-8 rounded-lg bg-amber-100/40 text-amber-600 flex items-center justify-center">
<Mail class="w-4 h-4" />
</div>
<span>{{ contactEmail }}</span>
</div>
<div v-if="contactAddress" class="flex items-center space-x-3 text-sm">
<div
class="w-8 h-8 rounded-lg bg-amber-100/40 text-amber-600 flex items-center justify-center">
<MapPin class="w-4 h-4" />
</div>
<span>{{ contactAddress }}</span>
</div>
</div>
</div>
<!-- Right Form/Quick Message Mock -->
<div class="bg-slate-50 p-6 rounded-2xl border border-slate-200 space-y-4">
<h4 class="font-bold text-base">Kirim Pesan Cepat</h4>
<div class="space-y-3">
<input type="text" placeholder="Nama Anda"
class="w-full text-xs px-4 py-3 bg-white border border-slate-200 rounded-lg outline-none focus:border-amber-500 text-slate-700" />
<textarea placeholder="Tulis pesan Anda di sini..." rows="4"
class="w-full text-xs px-4 py-3 bg-white border border-slate-200 rounded-lg outline-none focus:border-amber-500 text-slate-700 scrollbar-thin"></textarea>
<!-- WhatsApp Direct Send Button -->
<a :href="`https://wa.me/${contactPhone.replace(/[^0-9]/g, '') || '6281234567890'}`"
target="_blank"
class="w-full inline-flex items-center justify-center bg-emerald-600 hover:bg-emerald-500 text-white py-3 rounded-lg text-xs font-bold uppercase tracking-wider transition-colors">
<Phone class="w-4 h-4 mr-2" />
Kirim Melalui WhatsApp
</a>
</div>
</div>
</div>
</section>
<!-- Brand Footer -->
<footer class="bg-white text-slate-600 py-16 border-t border-amber-100/30">
<div class="max-w-7xl mx-auto px-6 grid grid-cols-1 md:grid-cols-4 gap-8">
<!-- Brand Profile -->
<div class="space-y-4">
<div class="flex items-center space-x-2">
<img v-if="logoUrl" :src="logoUrl" :alt="appName"
class="h-8 w-auto object-contain p-0.5 rounded shadow-sm" />
<span v-else class="font-serif text-xl font-bold tracking-widest text-amber-600">
{{ appName }}
</span>
</div>
<p class="text-xs text-slate-400 leading-relaxed font-light">
Rumah produksi busana dan batik lokal berkualitas tinggi. Menghadirkan desain eksklusif untuk
gaya sehari-hari Anda.
</p>
</div>
<!-- Shop Links -->
<div class="space-y-3">
<h4 class="text-xs uppercase font-bold text-slate-800 tracking-widest">Koleksi Kami</h4>
<ul class="space-y-2 text-xs">
<li><a href="#catalog" class="hover transition-colors">Batik Daster</a></li>
<li><a href="#catalog" class="hover transition-colors">Setelan Celana</a></li>
<li><a href="#catalog" class="hover transition-colors">Daster Menyusui (Busui)</a></li>
<li><a href="#catalog" class="hover transition-colors">Atasan & Bawahan</a></li>
</ul>
</div>
<!-- Info links -->
<div class="space-y-3">
<h4 class="text-xs uppercase font-bold text-slate-800 tracking-widest">Tautan</h4>
<ul class="space-y-2 text-xs">
<li><a href="#about" class="hover transition-colors">Tentang Kami</a></li>
<li><a href="#order-guide" class="hover transition-colors">Cara Pemesanan</a></li>
<li><a href="#contact" class="hover transition-colors">Hubungi Kami</a></li>
<li><a href="/admin/dashboard" class="hover transition-colors font-semibold">Login Dashboard
Admin</a></li>
</ul>
</div>
<!-- Socials -->
<div class="space-y-3">
<h4 class="text-xs uppercase font-bold text-slate-800 tracking-widest">Sosial Media</h4>
<p class="text-xs text-slate-400 font-light">Ikuti sosial media kami untuk mendapatkan update produk
terbaru.</p>
<div class="flex space-x-3 text-xs">
<a v-if="instagramUrl" :href="instagramUrl" target="_blank"
class="text-slate-400 hover">Instagram</a>
<a v-if="facebookUrl" :href="facebookUrl" target="_blank"
class="text-slate-400 hover">Facebook</a>
<a v-if="tiktokUrl" :href="tiktokUrl" target="_blank" class="text-slate-400 hover">TikTok</a>
</div>
</div>
</div>
<div
class="max-w-7xl mx-auto px-6 mt-12 pt-8 border-t border-amber-100/30 flex flex-col sm:flex-row justify-between items-center text-[10px] text-slate-400 font-light space-y-4 sm:space-y-0">
<p>&copy; {{ new Date().getFullYear() }} {{ appName }}. Hak Cipta Dilindungi.</p>
</div>
</footer>
<!-- CENTERED DETAIL MODAL -->
<ProductModal :product="activeProduct" @close="closeQuickView" @add-to-cart="addToCart" />
<!-- FLOATING CART SLIDE-OVER SHEET -->
<div v-if="isCartOpen"
class="fixed inset-0 z-50 flex items-center justify-end bg-black/60 backdrop-blur-sm transition-opacity duration-300"
@click.self="isCartOpen = false">
<div
class="w-full max-w-md h-full bg-[#FDFDFC] p-6 shadow-2xl flex flex-col justify-between overflow-y-auto transform translate-x-0 transition-transform duration-300 border-l border-amber-100/30">
<div class="space-y-6">
<!-- Header -->
<div class="flex justify-between items-center">
<div class="flex items-center space-x-2">
<ShoppingBag class="w-5 h-5 text-amber-600" />
<h3 class="text-lg font-serif text-slate-800">Keranjang Belanja ({{ cartCount }})</h3>
</div>
<button @click="isCartOpen = false"
class="p-2 rounded-full hover:bg-slate-100 transition-colors cursor-pointer">
<X class="w-5 h-5 text-slate-500" />
</button>
</div>
<!-- Cart List -->
<div v-if="cart.length > 0"
class="space-y-4 divide-y divide-slate-100/45 max-h-[calc(100vh-280px)] overflow-y-auto pr-1 scrollbar-thin">
<div v-for="item in cart" :key="`${item.variant.id}-${item.price.type}`"
class="flex space-x-4 pt-4 first:pt-0">
<img :src="getProductImage(item.product)" :alt="item.product.name"
class="w-16 h-20 object-cover rounded-xl bg-slate-50 border border-slate-200/50/50" />
<div class="flex-1 flex flex-col justify-between">
<div class="space-y-1">
<div class="flex justify-between items-start">
<h4 class="text-xs font-semibold text-slate-700 line-clamp-1">
{{ item.product.name }}
</h4>
<button @click="removeFromCart(item.variant.id, item.price.type)"
class="text-slate-400 hover:text-red-500 p-1 cursor-pointer transition-colors">
<X class="w-3.5 h-3.5" />
</button>
</div>
<p class="text-[10px] text-slate-400">
Ukuran: <strong class="text-slate-700 font-semibold">{{ item.variant.name
}}</strong> • Tipe: <strong class="text-slate-700 font-semibold">{{
item.price.type_label }}</strong>
</p>
</div>
<div class="flex justify-between items-center mt-2">
<!-- Quantity Stepper -->
<div
class="flex items-center space-x-2 border border-slate-200 rounded-lg px-2 py-0.5">
<button @click="updateCartQuantity(item.variant.id, item.price.type, -1)"
class="p-1 text-slate-500 hover:text-black:text-white cursor-pointer">
<Minus class="w-3 h-3" />
</button>
<span class="text-xs font-semibold px-1 text-slate-800">{{ item.quantity
}}</span>
<button @click="updateCartQuantity(item.variant.id, item.price.type, 1)"
class="p-1 text-slate-500 hover:text-black:text-white cursor-pointer">
<Plus class="w-3 h-3" />
</button>
</div>
<span class="text-xs font-bold text-amber-600">
{{ `Rp ${formatRupiah(item.price.price * item.quantity)}` }}
</span>
</div>
</div>
</div>
</div>
<!-- Empty Cart -->
<div v-else class="text-center py-20 space-y-4">
<ShoppingBag class="w-12 h-12 text-amber-200 mx-auto" />
<h4 class="text-sm font-semibold text-slate-700">Keranjang Anda masih kosong</h4>
<p class="text-xs text-slate-400 max-w-xs mx-auto font-light leading-relaxed">
Jelajahi produk batik dan pakaian pilihan kami untuk menambahkan item ke dalam keranjang.
</p>
<button @click="isCartOpen = false"
class="bg-amber-600 text-white px-6 py-2.5 text-xs font-semibold uppercase tracking-widest rounded-xl hover:opacity-90 transition-all cursor-pointer shadow-md shadow-amber-200/50">
Lanjutkan Belanja
</button>
</div>
</div>
<!-- Footer Summary Card -->
<div v-if="cart.length > 0" class="border-t border-amber-100/30 pt-6 space-y-4">
<div class="space-y-1.5">
<div class="flex justify-between text-xs text-slate-500">
<span>Subtotal</span>
<span>{{ `Rp ${formatRupiah(cartTotal)}` }}</span>
</div>
<div class="flex justify-between text-xs text-slate-500">
<span>Biaya Kirim</span>
<span class="text-emerald-500 font-medium">GRATIS</span>
</div>
<div
class="flex justify-between text-sm font-bold text-slate-800 pt-1.5 border-t border-slate-100/30">
<span>Estimasi Total</span>
<span class="text-amber-600">{{ `Rp ${formatRupiah(cartTotal)}` }}</span>
</div>
</div>
<button @click="handleWhatsAppCheckout" :disabled="isCheckingOut"
class="w-full flex items-center justify-center bg-emerald-600 text-white hover:bg-emerald-500 py-3.5 text-xs font-bold uppercase tracking-widest rounded-xl transition-all cursor-pointer shadow-md shadow-emerald-100/50">
<span v-if="isCheckingOut"
class="inline-block border-2 border-current border-t-transparent animate-spin rounded-full w-4 h-4 mr-2"></span>
<Phone class="w-4 h-4 mr-2" />
{{ isCheckingOut ? 'Mengalihkan...' : 'Pesan Via WhatsApp' }}
</button>
</div>
</div>
</div>
</div>
</template>
<style>
/* Smooth scrolling */
html {
scroll-behavior: smooth;
}
/* Custom marquee animation */
@keyframes marquee {
0% {
transform: translateX(0%);
}
100% {
transform: translate3d(-50%, 0, 0);
}
}
.animate-marquee {
display: inline-block;
animation: marquee 25s linear infinite;
}
/* Float Animation */
@keyframes float-hero {
0%,
100% {
transform: translateY(0px);
}
50% {
transform: translateY(-12px);
}
}
.animate-float-model {
animation: float-hero 6s infinite ease-in-out;
}
.animate-float-tag-1 {
animation: float-hero 5s infinite ease-in-out;
}
.animate-float-tag-2 {
animation: float-hero 7s infinite ease-in-out;
}
/* Blob morphing background animation */
@keyframes blob-bounce {
0%,
100% {
transform: translate(0px, 0px) scale(1);
}
33% {
transform: translate(30px, -40px) scale(1.12);
}
66% {
transform: translate(-20px, 20px) scale(0.95);
}
}
.animate-blob {
animation: blob-bounce 14s infinite alternate ease-in-out;
}
.animation-delay-2000 {
animation-delay: 2s;
}
/* Animation classes */
@keyframes fadeInUp {
from {
opacity: 0;
transform: translate3d(0, 20px, 0);
}
to {
opacity: 1;
transform: translate3d(0, 0, 0);
}
}
.animate-fade-in-up {
animation: fadeInUp 0.4s cubic-bezier(0.16, 1, 0.3, 1) forwards;
}
</style>