@ -1,166 +1,427 @@
import React , { useEffect , useState } from 'react' ;
import type { ReactElement } from 'react' ;
import Head from 'next/head' ;
import Link from 'next/link' ;
import BaseButton from '../components/BaseButton' ;
import CardBox from '../components/CardBox' ;
import SectionFullScreen from '../components/SectionFullScreen' ;
import axios from 'axios' ;
import { mdiCart , mdiSilverwareForkKnife , mdiClockOutline , mdiCheckDecagram , mdiArrowRight } from '@mdi/js' ;
import LayoutGuest from '../layouts/Guest' ;
import BaseDivider from '../components/BaseDivider' ;
import BaseButtons from '../components/BaseButtons' ;
import { getPageTitle } from '../config' ;
import { useAppSelector } from '../stores/hooks' ;
import CardBoxComponentTitle from "../components/CardBoxComponentTitle" ;
import { getPexelsImage , getPexelsVideo } from '../helpers/pexels' ;
import SectionMain from '../components/SectionMain' ;
import CardBox from '../components/CardBox' ;
import BaseButton from '../components/BaseButton' ;
import BaseButtons from '../components/BaseButtons' ;
import BaseIcon from '../components/BaseIcon' ;
import ImageField from '../components/ImageField' ;
import LoadingSpinner from '../components/LoadingSpinner' ;
import CardBoxModal from '../components/CardBoxModal' ;
import FormField from '../components/FormField' ;
export default function LandingPage() {
const [ menus , setMenus ] = useState ( [ ] ) ;
const [ loading , setLoading ] = useState ( true ) ;
const [ isOrderModalOpen , setIsOrderModalOpen ] = useState ( false ) ;
const [ selectedProduct , setSelectedProduct ] = useState < any > ( null ) ;
const [ orderData , setOrderData ] = useState ( {
nama_pemesan : '' ,
quantity : 1 ,
metode_pembayaran : 'tunai'
} ) ;
const [ isSubmitting , setIsSubmitting ] = useState ( false ) ;
const [ orderSuccess , setOrderSuccess ] = useState ( false ) ;
export default function Starter() {
const [ illustrationImage , setIllustrationImage ] = useState ( {
src : undefined ,
photographer : undefined ,
photographer_url : undefined ,
} )
const [ illustrationVideo , setIllustrationVideo ] = useState ( { video_files : [ ] } )
const [ contentType , setContentType ] = useState ( 'image' ) ;
const [ contentPosition , setContentPosition ] = useState ( 'left' ) ;
const textColor = useAppSelector ( ( state ) = > state . style . linkColor ) ;
const title = 'Croissant Order Laravel'
// Fetch Pexels image/video
useEffect ( ( ) = > {
async function fetchData() {
const image = await getPexelsImage ( ) ;
const video = await getPexelsVideo ( ) ;
setIllustrationImage ( image ) ;
setIllustrationVideo ( video ) ;
}
fetchData ( ) ;
} , [ ] ) ;
const imageBlock = ( image ) = > (
< div
className = 'hidden md:flex flex-col justify-end relative flex-grow-0 flex-shrink-0 w-1/3'
style = { {
backgroundImage : ` ${
image
? ` url( ${ image ? . src ? . original } ) `
: 'linear-gradient(rgba(255, 255, 255, 0.5), rgba(255, 255, 255, 0.5))'
} ` ,
backgroundSize : 'cover' ,
backgroundPosition : 'left center' ,
backgroundRepeat : 'no-repeat' ,
} }
>
< div className = 'flex justify-center w-full bg-blue-300/20' >
< a
className = 'text-[8px]'
href = { image ? . photographer_url }
target = '_blank'
rel = 'noreferrer'
>
Photo by { image ? . photographer } on Pexels
< / a >
< / div >
< / div >
) ;
const videoBlock = ( video ) = > {
if ( video ? . video_files ? . length > 0 ) {
return (
< div className = 'hidden md:flex flex-col justify-end relative flex-grow-0 flex-shrink-0 w-1/3' >
< video
className = 'absolute top-0 left-0 w-full h-full object-cover'
autoPlay
loop
muted
>
< source src = { video ? . video_files [ 0 ] ? . link } type = 'video/mp4' / >
Your browser does not support the video tag .
< / video >
< div className = 'flex justify-center w-full bg-blue-300/20 z-10' >
< a
className = 'text-[8px]'
href = { video ? . user ? . url }
target = '_blank'
rel = 'noreferrer'
>
Video by { video . user . name } on Pexels
< / a >
< / div >
< / div > )
}
useEffect ( ( ) = > {
const fetchMenus = async ( ) = > {
try {
const response = await axios . get ( '/menus' ) ;
setMenus ( response . data . rows || [ ] ) ;
} catch ( error ) {
console . error ( 'Failed to fetch menus:' , error ) ;
} finally {
setLoading ( false ) ;
}
} ;
fetchMenus ( ) ;
} , [ ] ) ;
const handleOrderClick = ( product : any ) = > {
setSelectedProduct ( product ) ;
setIsOrderModalOpen ( true ) ;
setOrderSuccess ( false ) ;
} ;
const handleOrderSubmit = async ( ) = > {
if ( ! orderData . nama_pemesan ) {
alert ( 'Mohon isi nama pemesan' ) ;
return ;
}
setIsSubmitting ( true ) ;
try {
const total_harga = ( selectedProduct . harga || 0 ) * orderData . quantity ;
const payload = {
nama_pemesan : orderData.nama_pemesan ,
total_harga : total_harga ,
metode_pembayaran : orderData.metode_pembayaran ,
status_pesanan : 'belum_dibuat' ,
status_pembayaran : 'belum_dibayar' ,
ordered_at : new Date ( ) . toISOString ( ) ,
orderItems : [
{
menuId : selectedProduct.id ,
quantity : orderData.quantity ,
harga : selectedProduct.harga
}
]
} ;
await axios . post ( '/orders' , { data : payload } ) ;
setOrderSuccess ( true ) ;
setTimeout ( ( ) = > {
setIsOrderModalOpen ( false ) ;
setOrderData ( { nama_pemesan : '' , quantity : 1 , metode_pembayaran : 'tunai' } ) ;
} , 3000 ) ;
} catch ( error ) {
console . error ( 'Failed to submit order:' , error ) ;
alert ( 'Gagal mengirim pesanan. Silakan coba lagi.' ) ;
} finally {
setIsSubmitting ( false ) ;
}
} ;
return (
< div
style = {
contentPosition === 'background'
? {
backgroundImage : ` ${
illustrationImage
? ` url( ${ illustrationImage . src ? . original } ) `
: 'linear-gradient(rgba(255, 255, 255, 0.5), rgba(255, 255, 255, 0.5))'
} ` ,
backgroundSize : 'cover' ,
backgroundPosition : 'left center' ,
backgroundRepeat : 'no-repeat' ,
}
: { }
}
>
< div className = "bg-orange-50/30 min-h-screen font-sans selection:bg-orange-200" >
< Head >
< title > { getPageTitle ( 'Starter Page' ) } < / title >
< title > { getPageTitle ( 'Croissant Delight - Artisanal Bakery' ) } < / title >
< / Head >
< SectionFullScreen bg = 'violet' >
< div
className = { ` flex ${
contentPosition === 'right' ? 'flex-row-reverse' : 'flex-row'
} min - h - screen w - full ` }
>
{ contentType === 'image' && contentPosition !== 'background'
? imageBlock ( illustrationImage )
: null }
{ contentType === 'video' && contentPosition !== 'background'
? videoBlock ( illustrationVideo )
: null }
< div className = 'flex items-center justify-center flex-col space-y-4 w-full lg:w-full' >
< CardBox className = 'w-full md:w-3/5 lg:w-2/3' >
< CardBoxComponentTitle title = "Welcome to your Croissant Order Laravel app!" / >
< div className = "space-y-3" >
< p className = 'text-center text-gray-500' > This is a React . js / Node . js app generated by the < a className = { ` ${ textColor } ` } href = "https://flatlogic.com/generator" > Flatlogic Web App Generator < / a > < / p >
< p className = 'text-center text-gray-500' > For guides and documentation please check
your local README . md and the < a className = { ` ${ textColor } ` } href = "https://flatlogic.com/documentation" > Flatlogic documentation < / a > < / p >
{ /* Header/Navigation */ }
< nav className = "fixed top-0 w-full z-50 bg-white/80 backdrop-blur-md border-b border-orange-100" >
< div className = "max-w-7xl mx-auto px-4 sm:px-6 lg:px-8" >
< div className = "flex justify-between h-16 items-center" >
< div className = "flex items-center space-x-2" >
< span className = "text-2xl" > 🥐 < / span >
< span className = "text-xl font-bold bg-gradient-to-r from-amber-700 to-orange-600 bg-clip-text text-transparent" >
Croissant Delight
< / span >
< / div >
< BaseButtons >
< BaseButton
href = '/login'
label = 'Login'
color = 'info'
className = 'w-full'
/ >
< div className = "hidden md:flex space-x-8 text-sm font-medium text-gray-600" >
< a href = "#" className = "hover:text-orange-600 transition-colors" > Home < / a >
< a href = "#menu-section" className = "hover:text-orange-600 transition-colors" > Menu < / a >
< a href = "#about" className = "hover:text-orange-600 transition-colors" > About Us < / a >
< / div >
< BaseButton
href = "/login"
label = "Admin"
color = "warning"
outline
small
className = "rounded-full px-6"
/ >
< / div >
< / div >
< / nav >
< / BaseButtons >
< / CardBox >
{ /* Hero Section */ }
< div className = "relative pt-16 overflow-hidden" >
< div className = "absolute top-0 right-0 -translate-y-1/4 translate-x-1/4 w-96 h-96 bg-orange-200 rounded-full blur-3xl opacity-30 animate-pulse" > < / div >
< div className = "absolute bottom-0 left-0 translate-y-1/4 -translate-x-1/4 w-96 h-96 bg-amber-200 rounded-full blur-3xl opacity-30 animate-pulse delay-1000" > < / div >
< div className = "relative max-w-7xl mx-auto px-4 pt-20 pb-24 sm:px-6 lg:px-8 lg:pt-32 lg:flex lg:items-center lg:gap-12" >
< div className = "lg:flex-1 text-center lg:text-left" >
< div className = "inline-flex items-center px-4 py-1.5 rounded-full bg-orange-100 text-orange-700 text-sm font-semibold mb-6 animate-bounce" >
< span > Freshly baked every morning ! ✨ < / span >
< / div >
< h1 className = "text-5xl font-extrabold tracking-tight text-gray-900 sm:text-6xl lg:text-7xl mb-6 leading-tight" >
Croissant Hangat , < br / >
< span className = "text-orange-600 italic" > Fresh Setiap Hari 🥐 < / span >
< / h1 >
< p className = "max-w-2xl mx-auto lg:mx-0 text-xl text-gray-600 mb-10 leading-relaxed" >
Dibuat dengan bahan premium , butter asli Perancis , dan dipanggang segar setiap pagi untuk menghadirkan kebahagiaan di setiap gigitan .
< / p >
< div className = "flex flex-col sm:flex-row justify-center lg:justify-start gap-4" >
< BaseButton
label = "Pesan Sekarang"
color = "warning"
onClick = { ( ) = > document . getElementById ( 'menu-section' ) ? . scrollIntoView ( { behavior : 'smooth' } ) }
className = "px-10 py-4 text-lg rounded-2xl shadow-lg shadow-orange-200 hover:shadow-orange-300 transition-all active:scale-95"
icon = { mdiArrowRight }
/ >
< BaseButton
href = "#menu-section"
label = "Lihat Semua Menu"
color = "white"
className = "px-10 py-4 text-lg rounded-2xl border border-gray-200 hover:border-orange-300 hover:bg-orange-50 transition-all active:scale-95"
/ >
< / div >
< / div >
< div className = "hidden lg:block lg:flex-1" >
< div className = "relative" >
< div className = "absolute inset-0 bg-gradient-to-tr from-orange-400 to-amber-300 rounded-[3rem] rotate-6 scale-95 opacity-20" > < / div >
< img
src = "https://images.pexels.com/photos/3892469/pexels-photo-3892469.jpeg?auto=compress&cs=tinysrgb&w=800"
alt = "Fresh Croissants"
className = "relative rounded-[3rem] shadow-2xl rotate-2 hover:rotate-0 transition-transform duration-700 object-cover w-full h-[500px]"
/ >
< div className = "absolute -bottom-6 -left-6 bg-white p-6 rounded-3xl shadow-xl flex items-center gap-4 animate-float" >
< div className = "w-12 h-12 bg-green-100 rounded-full flex items-center justify-center" >
< BaseIcon path = { mdiCheckDecagram } className = "text-green-600" size = { 24 } / >
< / div >
< div >
< p className = "font-bold text-gray-900 text-lg" > 100 % Halal < / p >
< p className = "text-gray-500 text-sm" > Bahan Premium < / p >
< / div >
< / div >
< / div >
< / div >
< / div >
< / div >
< / SectionFullScreen >
< div className = 'bg-black text-white flex flex-col text-center justify-center md:flex-row' >
< p className = 'py-6 text-sm' > © 2026 < span > { title } < / span > . All rights reserved < / p >
< Link className = 'py-6 ml-4 text-sm' href = '/privacy-policy/' >
Privacy Policy
< / Link >
{ /* Features - Minimalist style */ }
< div id = "about" className = "py-24 bg-white/50 backdrop-blur-sm" >
< div className = "max-w-7xl mx-auto px-4 sm:px-6 lg:px-8" >
< div className = "grid grid-cols-1 md:grid-cols-3 gap-12" >
{ [
{ icon : mdiSilverwareForkKnife , title : 'Artisanal Quality' , desc : 'Setiap adonan dibuat dengan teknik tradisional untuk tekstur yang sempurna.' } ,
{ icon : mdiClockOutline , title : 'Freshly Baked' , desc : 'Kami tidak pernah menyajikan produk sisa kemarin. Selalu baru setiap jam 7 pagi.' } ,
{ icon : mdiCart , title : 'Easy Delivery' , desc : 'Pesan melalui website dan kami akan kirimkan ke tempat Anda dengan aman.' }
] . map ( ( feature , idx ) = > (
< div key = { idx } className = "group p-8 rounded-3xl hover:bg-white hover:shadow-xl transition-all duration-500 border border-transparent hover:border-orange-100" >
< div className = "w-16 h-16 bg-orange-100 rounded-2xl flex items-center justify-center mb-6 group-hover:scale-110 group-hover:bg-orange-600 transition-all duration-500" >
< BaseIcon path = { feature . icon } size = { 32 } className = "text-orange-600 group-hover:text-white transition-colors" / >
< / div >
< h3 className = "text-2xl font-bold text-gray-900 mb-3" > { feature . title } < / h3 >
< p className = "text-gray-600 leading-relaxed" > { feature . desc } < / p >
< / div >
) ) }
< / div >
< / div >
< / div >
< SectionMain id = "menu-section" className = "py-24" >
< div className = "text-center max-w-3xl mx-auto mb-16" >
< h2 className = "text-4xl font-extrabold text-gray-900 sm:text-5xl mb-6" > Menu Unggulan Kami < / h2 >
< p className = "text-xl text-gray-600 leading-relaxed" > Dari varian klasik hingga kreasi modern , temukan rasa yang paling menggugah seleramu hari ini . < / p >
< / div >
{ loading ? (
< div className = "flex flex-col items-center justify-center py-20 space-y-4" >
< LoadingSpinner / >
< p className = "text-orange-600 font-medium animate-pulse" > Menyiapkan menu segar . . . < / p >
< / div >
) : (
< div className = "grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-10" >
{ menus . map ( ( menu : any ) = > (
< div key = { menu . id } className = "group relative bg-white rounded-[2.5rem] p-4 shadow-sm hover:shadow-2xl transition-all duration-500 flex flex-col h-full border border-orange-50 hover:border-orange-200" >
< div className = "relative h-64 w-full mb-6 overflow-hidden rounded-[2rem]" >
< ImageField
image = { menu . foto }
className = "w-full h-full transform group-hover:scale-110 transition-transform duration-700"
imageClassName = "w-full h-full object-cover"
/ >
{ menu . status === 'habis' && (
< div className = "absolute inset-0 bg-black/40 backdrop-blur-[2px] flex items-center justify-center" >
< span className = "bg-red-600 text-white px-6 py-2 rounded-full font-bold uppercase tracking-widest text-sm shadow-lg" > Habis < / span >
< / div >
) }
< div className = "absolute top-4 left-4" >
< span className = "bg-white/90 backdrop-blur px-4 py-1 rounded-full text-xs font-bold text-orange-700 shadow-sm uppercase tracking-wider" >
Best Seller
< / span >
< / div >
< / div >
< div className = "px-4 flex-grow" >
< h3 className = "text-2xl font-bold text-gray-900 mb-2 group-hover:text-orange-600 transition-colors" > { menu . nama_menu } < / h3 >
< p className = "text-gray-500 text-sm leading-relaxed mb-6 line-clamp-2" > { menu . deskripsi } < / p >
< / div >
< div className = "px-4 pb-4 mt-auto" >
< div className = "flex items-center justify-between" >
< div className = "flex flex-col" >
< span className = "text-gray-400 text-xs font-semibold uppercase tracking-wider" > Harga < / span >
< span className = "text-2xl font-black text-orange-600" >
Rp { Number ( menu . harga ) . toLocaleString ( 'id-ID' ) }
< / span >
< / div >
< BaseButton
label = "Pesan"
color = "warning"
disabled = { menu . status === 'habis' }
onClick = { ( ) = > handleOrderClick ( menu ) }
className = "rounded-2xl px-8 py-3 shadow-md shadow-orange-100 active:scale-95 transition-all"
icon = { mdiCart }
/ >
< / div >
< / div >
< / div >
) ) }
< / div >
) }
< / SectionMain >
{ /* Footer */ }
< footer className = "bg-gray-900 text-white py-20" >
< div className = "max-w-7xl mx-auto px-4 sm:px-6 lg:px-8" >
< div className = "grid grid-cols-1 md:grid-cols-4 gap-12 mb-16" >
< div className = "col-span-1 md:col-span-2" >
< div className = "flex items-center space-x-2 mb-6" >
< span className = "text-3xl" > 🥐 < / span >
< span className = "text-2xl font-bold text-white" > Croissant Delight < / span >
< / div >
< p className = "text-gray-400 max-w-sm mb-8" >
Menghadirkan kelezatan roti artisan Perancis ke rumah Anda dengan bahan terbaik dan proses yang higienis .
< / p >
< / div >
< div >
< h4 className = "text-lg font-bold mb-6" > Quick Links < / h4 >
< ul className = "space-y-4 text-gray-400" >
< li > < a href = "#" className = "hover:text-orange-500 transition-colors" > Home < / a > < / li >
< li > < a href = "#menu-section" className = "hover:text-orange-500 transition-colors" > Menu < / a > < / li >
< li > < a href = "#about" className = "hover:text-orange-500 transition-colors" > About Us < / a > < / li >
< / ul >
< / div >
< div >
< h4 className = "text-lg font-bold mb-6" > Follow Us < / h4 >
< div className = "flex space-x-4" >
< div className = "w-10 h-10 bg-gray-800 rounded-full flex items-center justify-center hover:bg-orange-600 transition-colors cursor-pointer" >
< span className = "text-xl" > 📸 < / span >
< / div >
< div className = "w-10 h-10 bg-gray-800 rounded-full flex items-center justify-center hover:bg-orange-600 transition-colors cursor-pointer" >
< span className = "text-xl" > 🐦 < / span >
< / div >
< div className = "w-10 h-10 bg-gray-800 rounded-full flex items-center justify-center hover:bg-orange-600 transition-colors cursor-pointer" >
< span className = "text-xl" > 📘 < / span >
< / div >
< / div >
< / div >
< / div >
< div className = "border-t border-gray-800 pt-8 flex flex-col md:flex-row justify-between items-center text-sm text-gray-500" >
< p > © 2026 Croissant Delight . Crafted with ❤ ️ for Croissant Lovers . < / p >
< div className = "flex space-x-6 mt-4 md:mt-0" >
< a href = "#" className = "hover:text-white" > Privacy Policy < / a >
< a href = "#" className = "hover:text-white" > Terms of Service < / a >
< / div >
< / div >
< / div >
< / footer >
{ /* Order Modal */ }
< CardBoxModal
title = { orderSuccess ? "" : ` Pesan ${ selectedProduct ? . nama_menu } ` }
buttonColor = "info"
buttonLabel = "Submit Pesanan"
isActive = { isOrderModalOpen }
onConfirm = { handleOrderSubmit }
onCancel = { ( ) = > setIsOrderModalOpen ( false ) }
isLoading = { isSubmitting }
hasFooter = { ! orderSuccess }
>
{ orderSuccess ? (
< div className = "text-center py-12 px-6" >
< div className = "w-24 h-24 bg-green-100 rounded-full flex items-center justify-center mx-auto mb-6 animate-bounce" >
< BaseIcon path = { mdiCheckDecagram } size = { 64 } className = "text-green-500" / >
< / div >
< h3 className = "text-3xl font-black text-gray-900 mb-4" > Pesanan Terkirim ! < / h3 >
< p className = "text-lg text-gray-600 leading-relaxed mb-8" >
Terima kasih < span className = "font-bold text-orange-600" > { orderData . nama_pemesan } < / span > . < br / >
Pesanan Anda sedang diproses dan akan segera diantar .
< / p >
< BaseButton
label = "Tutup"
color = "white"
onClick = { ( ) = > setIsOrderModalOpen ( false ) }
className = "rounded-xl px-12 py-3 border border-gray-200"
/ >
< / div >
) : (
< div className = "space-y-6 px-2" >
< div className = "bg-orange-50 -mx-6 -mt-6 p-6 mb-6 flex items-center gap-6 border-b border-orange-100" >
< div className = "w-24 h-24 rounded-2xl overflow-hidden shadow-md flex-shrink-0" >
< ImageField
image = { selectedProduct ? . foto }
className = "w-full h-full object-cover"
/ >
< / div >
< div >
< h4 className = "text-xl font-bold text-gray-900" > { selectedProduct ? . nama_menu } < / h4 >
< p className = "text-orange-600 font-bold" > Rp { Number ( selectedProduct ? . harga ) . toLocaleString ( 'id-ID' ) } / pcs < / p >
< / div >
< / div >
< FormField label = "Nama Pemesan" help = "Siapa yang memesan kelezatan ini?" >
< input
type = "text"
className = "w-full h-12 px-4 border border-gray-200 rounded-xl focus:outline-none focus:ring-2 focus:ring-orange-500 focus:border-transparent transition-all"
value = { orderData . nama_pemesan }
onChange = { ( e ) = > setOrderData ( { . . . orderData , nama_pemesan : e.target.value } ) }
placeholder = "Masukkan nama Anda"
required
/ >
< / FormField >
< div className = "grid grid-cols-2 gap-4" >
< FormField label = "Jumlah" help = "Minimal 1 pcs" >
< input
type = "number"
min = "1"
className = "w-full h-12 px-4 border border-gray-200 rounded-xl focus:outline-none focus:ring-2 focus:ring-orange-500 focus:border-transparent transition-all"
value = { orderData . quantity }
onChange = { ( e ) = > setOrderData ( { . . . orderData , quantity : Math.max ( 1 , parseInt ( e . target . value ) || 1 ) } ) }
/ >
< / FormField >
< FormField label = "Metode Bayar" >
< select
className = "w-full h-12 px-4 border border-gray-200 rounded-xl focus:outline-none focus:ring-2 focus:ring-orange-500 focus:border-transparent transition-all bg-white appearance-none"
value = { orderData . metode_pembayaran }
onChange = { ( e ) = > setOrderData ( { . . . orderData , metode_pembayaran : e.target.value } ) }
>
< option value = "tunai" > Cash ( Tunai ) < / option >
< option value = "qris" > E - Wallet ( QRIS ) < / option >
< / select >
< / FormField >
< / div >
{ orderData . metode_pembayaran === 'qris' && (
< div className = "bg-amber-50 p-6 rounded-3xl border border-amber-100 text-center animate-fadeIn" >
< p className = "text-sm font-bold mb-4 text-amber-800" > Scan QRIS Croissant Delight < / p >
< div className = "bg-white p-4 inline-block rounded-2xl shadow-sm" >
< img src = "https://api.qrserver.com/v1/create-qr-code/?size=150x150&data=CroissantDelightPayment" alt = "QRIS" className = "w-32 h-32" / >
< / div >
< p className = "text-xs mt-4 text-amber-600 font-medium" > Lakukan pembayaran sekarang dan simpan bukti bayarnya . < / p >
< / div >
) }
< div className = "bg-gray-50 -mx-6 -mb-6 p-6 mt-8 flex justify-between items-center" >
< div >
< p className = "text-gray-500 text-xs font-bold uppercase tracking-widest mb-1" > Total Pembayaran < / p >
< p className = "text-3xl font-black text-orange-600" >
Rp { ( ( selectedProduct ? . harga || 0 ) * orderData . quantity ) . toLocaleString ( 'id-ID' ) }
< / p >
< / div >
< / div >
< / div >
) }
< / CardBoxModal >
< style jsx global > { `
@keyframes float {
0 % , 100 % { transform : translateY ( 0 px ) ; }
50 % { transform : translateY ( - 10 px ) ; }
}
. animate - float {
animation : float 3 s ease - in - out infinite ;
}
. animate - fadeIn {
animation : fadeIn 0.5 s ease - out forwards ;
}
@keyframes fadeIn {
from { opacity : 0 ; transform : translateY ( 10 px ) ; }
to { opacity : 1 ; transform : translateY ( 0 ) ; }
}
` }</style>
< / div >
) ;
}
Starter . getLayout = function getLayout ( page : ReactElement ) {
LandingPage . getLayout = function getLayout ( page : ReactElement ) {
return < LayoutGuest > { page } < / LayoutGuest > ;
} ;
} ;