feat: integrate GeneralSettings into homepage for dynamic display of logo, description, address, and contact information

This commit is contained in:
Yoga Pangestu 2026-04-24 21:22:55 +07:00
parent abeff9963a
commit f8d6c495fc
2 changed files with 14 additions and 13 deletions

View File

@ -3,6 +3,7 @@
namespace App\Http\Controllers; namespace App\Http\Controllers;
use App\Models\Category; use App\Models\Category;
use App\Models\GeneralSetting;
use App\Models\Product; use App\Models\Product;
class HomepageController extends Controller class HomepageController extends Controller
@ -13,6 +14,7 @@ public function __invoke()
$categorySlug = request('category'); $categorySlug = request('category');
return inertia('homepage', [ return inertia('homepage', [
'setting' => GeneralSetting::first(),
'categories' => Category::active()->get(), 'categories' => Category::active()->get(),
'bestSellers' => Product::with(['categories' => fn ($q) => $q->active(), 'prices']) 'bestSellers' => Product::with(['categories' => fn ($q) => $q->active(), 'prices'])
->when($search, function ($query, $search) { ->when($search, function ($query, $search) {

View File

@ -2,8 +2,9 @@ import { formatCurrency } from '@/lib/formatters';
import { Link, router } from '@inertiajs/react'; import { Link, router } from '@inertiajs/react';
import { ArrowRight, Facebook, Instagram, Phone, Search, X } from 'lucide-react'; import { ArrowRight, Facebook, Instagram, Phone, Search, X } from 'lucide-react';
import { useEffect, useState } from 'react'; import { useEffect, useState } from 'react';
import { GeneralSetting } from '@/types/general-setting';
export default function Homepage({ categories = [], bestSellers, topSellingProducts = [] }: { categories: any[], bestSellers: any, topSellingProducts: any[] }) { export default function Homepage({ categories = [], bestSellers, topSellingProducts = [], setting }: { categories: any[], bestSellers: any, topSellingProducts: any[], setting: GeneralSetting }) {
const [isMenuOpen, setIsMenuOpen] = useState(false); const [isMenuOpen, setIsMenuOpen] = useState(false);
const [isScrolled, setIsScrolled] = useState(false); const [isScrolled, setIsScrolled] = useState(false);
const [selectedProduct, setSelectedProduct] = useState<any>(null); const [selectedProduct, setSelectedProduct] = useState<any>(null);
@ -401,12 +402,12 @@ export default function Homepage({ categories = [], bestSellers, topSellingProdu
<div className="mx-auto max-w-7xl border-x border-[#1e4a6d]/20"> <div className="mx-auto max-w-7xl border-x border-[#1e4a6d]/20">
<div className="grid grid-cols-1 gap-12 border-b border-[#1e4a6d]/10 px-6 py-16 lg:grid-cols-12 lg:px-12"> <div className="grid grid-cols-1 gap-12 border-b border-[#1e4a6d]/10 px-6 py-16 lg:grid-cols-12 lg:px-12">
{/* Brand Info */} {/* Brand Info */}
<div className="lg:col-span-5"> <div className="lg:col-span-6">
<div className="mb-6 flex items-center gap-2 text-xl font-bold uppercase tracking-tighter"> <div className="mb-6 flex items-center gap-2 text-xl font-bold uppercase tracking-tighter">
VN Grup {setting?.logo_url ? <img src={setting.logo_url} alt={setting.name} className="max-h-8" /> : (setting?.name || 'VN Grup')}
</div> </div>
<p className="mb-8 text-sm leading-relaxed opacity-60 lg:max-w-xs"> <p className="mb-8 text-sm leading-relaxed opacity-60">
Menghadirkan produk esensial yang tak lekang oleh waktu dengan fokus pada kualitas, keberlanjutan, dan gaya yang abadi. {setting?.description || 'Menghadirkan produk esensial yang tak lekang oleh waktu dengan fokus pada kualitas, keberlanjutan, dan gaya yang abadi.'}
</p> </p>
<div className="flex gap-4"> <div className="flex gap-4">
<Facebook size={18} className="cursor-pointer hover:opacity-50" /> <Facebook size={18} className="cursor-pointer hover:opacity-50" />
@ -426,23 +427,21 @@ export default function Homepage({ categories = [], bestSellers, topSellingProdu
</div> </div>
{/* Contact Info */} {/* Contact Info */}
<div className="lg:col-span-5"> <div className="lg:col-span-4">
<h3 className="mb-6 text-[10px] font-bold uppercase tracking-[0.2em]">Kontak</h3> <h3 className="mb-6 text-[10px] font-bold uppercase tracking-[0.2em]">Kontak</h3>
<div className="space-y-4 text-sm opacity-60"> <div className="space-y-4 text-sm opacity-60">
<div className="flex gap-3"> <div className="flex gap-3">
<div className="shrink-0 pt-1"> <div className="shrink-0 pt-1">
<Search size={14} className="rotate-45" /> <Search size={14} className="rotate-45" />
</div> </div>
<p className="leading-relaxed"> <p className="leading-relaxed whitespace-pre-line">
Jl. Raya Utama No. 123, <br /> {setting?.address || 'Jl. Raya Utama No. 123, \n Kec. Lengkong, Kota Bandung, \n Jawa Barat 40262'}
Kec. Lengkong, Kota Bandung, <br />
Jawa Barat 40262
</p> </p>
</div> </div>
<div className="flex items-center gap-3"> <div className="flex items-center gap-3">
<Phone size={14} /> <Phone size={14} />
<a href="https://wa.me/628123456789" target="_blank" className="hover:underline"> <a href={`https://wa.me/${(setting?.phone || '+628123456789').replace(/\D/g, '')}`} target="_blank" className="hover:underline">
+62 812 3456 789 {setting?.phone || '+62 812 3456 789'}
</a> </a>
</div> </div>
</div> </div>
@ -451,7 +450,7 @@ export default function Homepage({ categories = [], bestSellers, topSellingProdu
{/* Bottom Bar */} {/* Bottom Bar */}
<div className="px-6 py-6 text-center text-[10px] font-bold uppercase tracking-widest lg:px-12 lg:text-left"> <div className="px-6 py-6 text-center text-[10px] font-bold uppercase tracking-widest lg:px-12 lg:text-left">
<p className="opacity-50">© 2026 VN Grup.</p> <p className="opacity-50">© {new Date().getFullYear()} {setting?.name || 'VN Grup'}.</p>
</div> </div>
</div> </div>
</footer> </footer>