14 Commits

Author SHA1 Message Date
3ee5a3cfba Merge version_8 into main
Merge version_8 into main
2026-02-26 13:16:30 +00:00
4f96977d28 Bob AI: Add infinite 360-degree spin animation to the hero image tha 2026-02-26 13:15:49 +00:00
2e27f3fdf9 Merge version_7 into main
Merge version_7 into main
2026-02-26 13:14:18 +00:00
e3e977c0ce Bob AI: Add infinite continuous spinning animation to the hero image 2026-02-26 13:13:37 +00:00
5f0303afed Merge version_5 into main
Merge version_5 into main
2026-02-26 13:10:23 +00:00
973b38f7a0 Bob AI: Replace the flip animation on hover with a continuous infini 2026-02-26 13:09:42 +00:00
9a3a179ad4 Merge version_4 into main
Merge version_4 into main
2026-02-26 13:07:54 +00:00
2745a435fb Bob AI: Change the hero image flip animation direction from Y-axis ( 2026-02-26 13:07:14 +00:00
174847fd3e Update src/app/layout.tsx 2026-02-26 13:06:58 +00:00
b1bfb8dacf Merge version_3 into main
Merge version_3 into main
2026-02-26 13:05:50 +00:00
e9df669943 Bob AI: Add a flip animation effect to the hero image on hover using 2026-02-26 13:05:09 +00:00
3f01f55a30 Merge version_2 into main
Merge version_2 into main
2026-02-26 13:02:57 +00:00
576fa3574e Bob AI: Replace the current NavbarStyleCentered navbar with a differ 2026-02-26 13:02:16 +00:00
a85a6847ae Merge version_1 into main
Merge version_1 into main
2026-02-26 13:00:42 +00:00
3 changed files with 1439 additions and 49 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -10,6 +10,7 @@ import TestimonialCardFive from '@/components/sections/testimonial/TestimonialCa
import ContactSplitForm from '@/components/sections/contact/ContactSplitForm';
import FooterBaseCard from '@/components/sections/footer/FooterBaseCard';
import { Sparkles } from "lucide-react";
import NavbarStyleApple from "@/components/navbar/NavbarStyleApple/NavbarStyleApple";
export default function LandingPage() {
return (
@@ -26,7 +27,7 @@ export default function LandingPage() {
headingFontWeight="bold"
>
<div id="nav" data-section="nav">
<NavbarStyleCentered
<NavbarStyleApple
navItems={[{name: 'Hero', id: 'hero-section'}, {name: 'About', id: 'about-section'}, {name: 'Feature', id: 'features-section'}, {name: 'Product', id: 'products-section'}, {name: 'Testimonial', id: 'testimonials-section'}, {name: 'Contact', id: 'contact-section'}]}
button={{text: 'Order Now', href: '#products-section'}}
brandName="WarmCrust Bakery"

View File

@@ -6,6 +6,7 @@ import HeroBackgrounds, { type HeroBackgroundVariantProps } from "@/components/b
import LogoMarquee, { type MarqueeItem } from "@/components/shared/LogoMarquee";
import { cls } from "@/lib/utils";
import { useButtonAnimation } from "@/components/hooks/useButtonAnimation";
import { useState } from "react";
import type { LucideIcon } from "lucide-react";
import type { ButtonConfig, ButtonAnimationType } from "@/types/button";
import type { Avatar } from "@/components/shared/AvatarGroup";
@@ -61,7 +62,7 @@ interface HeroBillboardProps {
buttonTextClassName?: string;
mediaWrapperClassName?: string;
imageClassName?: string;
marqueeClassName?: string;
marqueeClassName?: string;
marqueeItemClassName?: string;
marqueeCardClassName?: string;
marqueeImageClassName?: string;
@@ -70,45 +71,46 @@ interface HeroBillboardProps {
}
const HeroBillboard = ({
title,
description,
background,
tag,
tagIcon,
tagAnimation,
buttons,
buttonAnimation,
avatars,
avatarText,
imageSrc,
videoSrc,
imageAlt = "",
videoAriaLabel = "Hero video",
mediaAnimation = "none",
marqueeItems,
marqueeSpeed = 30,
showMarqueeCard = true,
ariaLabel = "Hero section",
className = "",
containerClassName = "",
textBoxClassName = "",
titleClassName = "",
descriptionClassName = "",
tagClassName = "",
avatarGroupClassName = "",
buttonContainerClassName = "",
buttonClassName = "",
buttonTextClassName = "",
mediaWrapperClassName = "",
imageClassName = "",
marqueeClassName = "",
marqueeItemClassName = "",
marqueeCardClassName = "",
marqueeImageClassName = "",
marqueeTextClassName = "",
marqueeIconClassName = "",
title,
description,
background,
tag,
tagIcon,
tagAnimation,
buttons,
buttonAnimation,
avatars,
avatarText,
imageSrc,
videoSrc,
imageAlt = "",
videoAriaLabel = "Hero video",
mediaAnimation = "none",
marqueeItems,
marqueeSpeed = 30,
showMarqueeCard = true,
ariaLabel = "Hero section",
className = "",
containerClassName = "",
textBoxClassName = "",
titleClassName = "",
descriptionClassName = "",
tagClassName = "",
avatarGroupClassName = "",
buttonContainerClassName = "",
buttonClassName = "",
buttonTextClassName = "",
mediaWrapperClassName = "",
imageClassName = "",
marqueeClassName = "",
marqueeItemClassName = "",
marqueeCardClassName = "",
marqueeImageClassName = "",
marqueeTextClassName = "",
marqueeIconClassName = "",
}: HeroBillboardProps) => {
const { containerRef: mediaContainerRef } = useButtonAnimation({ animationType: mediaAnimation });
const { containerRef: mediaContainerRef } = useButtonAnimation({ animationType: mediaAnimation });
const [isHovering, setIsHovering] = useState(false);
return (
<section
@@ -139,15 +141,35 @@ const HeroBillboard = ({
center={true}
/>
<div className="flex flex-col gap-6" >
<div ref={mediaContainerRef} className={cls("w-full overflow-hidden rounded-theme-capped card p-4", mediaWrapperClassName)}>
<MediaContent
imageSrc={imageSrc}
videoSrc={videoSrc}
imageAlt={imageAlt}
videoAriaLabel={videoAriaLabel}
imageClassName={cls("z-1 aspect-square md:aspect-video", imageClassName)}
/>
</div>
<div
ref={mediaContainerRef}
className={cls("w-full overflow-hidden rounded-theme-capped card p-4 [perspective:1000px]", mediaWrapperClassName)}
onMouseEnter={() => setIsHovering(true)}
onMouseLeave={() => setIsHovering(false)}
>
<style>{`
@keyframes infiniteSpin {
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
}
.spin-on-hover {
animation: infiniteSpin 8s linear infinite;
}
`}</style>
<div className={cls("w-full h-full [transform-style:preserve-3d]", isHovering && "spin-on-hover")}>
<MediaContent
imageSrc={imageSrc}
videoSrc={videoSrc}
imageAlt={imageAlt}
videoAriaLabel={videoAriaLabel}
imageClassName={cls("z-1 aspect-square md:aspect-video", imageClassName)}
/>
</div>
</div>
{marqueeItems && marqueeItems.length > 0 && (
<LogoMarquee
items={marqueeItems}