Performance improvements and Dockerfile update

This commit is contained in:
2026-04-19 09:48:53 +00:00
parent 31f88749f9
commit e94dec0036
17 changed files with 315 additions and 295 deletions

View File

@ -1,5 +1,5 @@
import { useState, useEffect, useRef } from "react";
import { motion, AnimatePresence } from "framer-motion";
import { m, AnimatePresence } from "framer-motion";
import { Image } from "@unpic/react";
const banners = [
@ -95,7 +95,7 @@ export default function BannerSlider() {
{/* Banner Images with Premium Animations */}
<AnimatePresence initial={false} custom={direction} mode="popLayout">
<motion.div
<m.div
key={`${currentIndex}-${direction}`}
custom={direction}
variants={slideVariants}
@ -130,13 +130,13 @@ export default function BannerSlider() {
{/* Premium overlay with gradient */}
<div className="absolute inset-0 bg-gradient-to-t from-black/20 via-transparent to-transparent" />
</motion.div>
</m.div>
</AnimatePresence>
{/* Premium Shop Now Button */}
{currentIndex === 0 && (
<div className="absolute bottom-16 md:bottom-20 left-1/2 transform -translate-x-1/2 z-10">
<motion.a
<m.a
href="https://shop.mozimo.in/"
target="_blank"
rel="noopener noreferrer"
@ -159,7 +159,7 @@ export default function BannerSlider() {
}}
>
<span className="relative z-10">Shop Now</span>
</motion.a>
</m.a>
</div>
)}
@ -167,7 +167,7 @@ export default function BannerSlider() {
<AnimatePresence>
{showArrows && (
<>
<motion.button
<m.button
initial={{ opacity: 0, x: -20 }}
animate={{ opacity: 1, x: 0 }}
exit={{ opacity: 0, x: -20 }}
@ -191,9 +191,9 @@ export default function BannerSlider() {
d="M15 19l-7-7 7-7"
/>
</svg>
</motion.button>
</m.button>
<motion.button
<m.button
initial={{ opacity: 0, x: 20 }}
animate={{ opacity: 1, x: 0 }}
exit={{ opacity: 0, x: 20 }}
@ -217,14 +217,14 @@ export default function BannerSlider() {
d="M9 5l7 7-7 7"
/>
</svg>
</motion.button>
</m.button>
</>
)}
</AnimatePresence>
{/* Mobile Navigation Arrows */}
<div className="md:hidden absolute inset-x-0 top-1/2 transform -translate-y-1/2 z-20 flex justify-between items-center px-4">
<motion.button
<m.button
onClick={goToPrevious}
className="glass text-white p-3 rounded-full backdrop-blur-sm transition-all duration-300 border border-white/20 hover:border-white/40 shadow-premium"
whileHover={{ scale: 1.1, rotate: -5 }}
@ -244,9 +244,9 @@ export default function BannerSlider() {
d="M15 19l-7-7 7-7"
/>
</svg>
</motion.button>
</m.button>
<motion.button
<m.button
onClick={goToNext}
className="glass text-white p-3 rounded-full backdrop-blur-sm transition-all duration-300 border border-white/20 hover:border-white/40 shadow-premium"
whileHover={{ scale: 1.1, rotate: 5 }}
@ -266,13 +266,13 @@ export default function BannerSlider() {
d="M9 5l7 7-7 7"
/>
</svg>
</motion.button>
</m.button>
</div>
{/* Premium Dots Indicator */}
<div className="absolute bottom-6 md:bottom-8 left-1/2 transform -translate-x-1/2 z-20 hidden md:flex space-x-2 md:space-x-3">
{banners.map((_, index) => (
<motion.button
<m.button
key={index}
onClick={() => goToSlide(index)}
className={`w-2 h-2 md:w-3 md:h-3 rounded-full transition-all duration-300 ${
@ -289,7 +289,7 @@ export default function BannerSlider() {
{/* Premium Progress Bar */}
<div className="absolute bottom-0 left-0 right-0 h-1 bg-white/10 z-20">
<motion.div
<m.div
className="h-full bg-gradient-to-r from-[#8B4513] to-[#DAA520]"
initial={{ width: 0 }}
animate={{ width: "100%" }}

View File

@ -1,4 +1,4 @@
import { motion } from "framer-motion";
import { m } from "framer-motion";
import { Image } from "@unpic/react";
export default function DesktopFooter() {
@ -11,7 +11,7 @@ export default function DesktopFooter() {
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-8 md:py-12 grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-8 relative z-10">
{/* Column 1: Brand Identity */}
<motion.div
<m.div
className="space-y-4 sm:col-span-2 lg:col-span-1"
initial={{ opacity: 0, y: 20 }}
whileInView={{ opacity: 1, y: 0 }}
@ -41,10 +41,10 @@ export default function DesktopFooter() {
India&apos;s Premier European style bean-to-bar chocolate
experience.
</p>
</motion.div>
</m.div>
{/* Column 2: Get in touch */}
<motion.div
<m.div
className="space-y-4"
initial={{ opacity: 0, y: 20 }}
whileInView={{ opacity: 1, y: 0 }}
@ -73,7 +73,7 @@ export default function DesktopFooter() {
fontFamily: "Renner*",
}}
>
<motion.div
<m.div
className="flex items-center space-x-2"
initial={{ opacity: 0, x: -10 }}
whileInView={{ opacity: 1, x: 0 }}
@ -89,8 +89,8 @@ export default function DesktopFooter() {
<path d="M2 3a1 1 0 011-1h2.153a1 1 0 01.986.836l.74 4.435a1 1 0 01-.54 1.06l-1.548.773a11.037 11.037 0 006.105 6.105l.774-1.548a1 1 0 011.059-.54l4.435.74a1 1 0 01.836.986V17a1 1 0 01-1 1h-2C7.82 18 2 12.18 2 5V3z" />
</svg>
<span className="text-xs md:text-sm">0172-4045414</span>
</motion.div>
<motion.div
</m.div>
<m.div
className="flex items-start space-x-2"
initial={{ opacity: 0, x: -10 }}
whileInView={{ opacity: 1, x: 0 }}
@ -112,12 +112,12 @@ export default function DesktopFooter() {
<span className="text-xs md:text-sm">
SCO 8, Inner Market, 9-D, Sector 9, Chandigarh, 160009
</span>
</motion.div>
</m.div>
</div>
</motion.div>
</m.div>
{/* Column 3: Know more */}
<motion.div
<m.div
className="space-y-4"
initial={{ opacity: 0, y: 20 }}
whileInView={{ opacity: 1, y: 0 }}
@ -152,7 +152,7 @@ export default function DesktopFooter() {
"Terms & Conditions",
"Shipping Policy",
].map((link, index) => (
<motion.li
<m.li
key={link}
initial={{ opacity: 0, x: -10 }}
whileInView={{ opacity: 1, x: 0 }}
@ -166,13 +166,13 @@ export default function DesktopFooter() {
{link}
<span className="absolute bottom-0 left-0 w-0 h-0.5 bg-gradient-to-r from-[#8B4513] to-[#DAA520] transition-all duration-300 group-hover:w-full"></span>
</a>
</motion.li>
</m.li>
))}
</ul>
</motion.div>
</m.div>
{/* Column 4: FAQ, Store, Ordering, Social Media */}
<motion.div
<m.div
className="space-y-4 sm:col-span-2 lg:col-span-1"
initial={{ opacity: 0, y: 20 }}
whileInView={{ opacity: 1, y: 0 }}
@ -191,7 +191,7 @@ export default function DesktopFooter() {
}}
>
{["FAQ", "Locate our store", "Bulk Ordering"].map((link, index) => (
<motion.div
<m.div
key={link}
initial={{ opacity: 0, x: -10 }}
whileInView={{ opacity: 1, x: 0 }}
@ -205,7 +205,7 @@ export default function DesktopFooter() {
{link}
<span className="absolute bottom-0 left-0 w-0 h-0.5 bg-gradient-to-r from-[#8B4513] to-[#DAA520] transition-all duration-300 group-hover:w-full"></span>
</a>
</motion.div>
</m.div>
))}
</div>
@ -225,7 +225,7 @@ export default function DesktopFooter() {
</h3>
<div className="flex space-x-3 md:space-x-4">
{/* Facebook */}
<motion.a
<m.a
href="https://www.facebook.com/share/16vPmvcQV7/?mibextid=wwXIfr"
target="_blank"
rel="noopener noreferrer"
@ -245,9 +245,9 @@ export default function DesktopFooter() {
>
<path d="M22.675 0h-21.35C.595 0 0 .592 0 1.326v21.348C0 23.408.595 24 1.325 24h11.495v-9.294H9.692v-3.622h3.128V8.413c0-3.1 1.893-4.788 4.659-4.788 1.325 0 2.463.099 2.797.143v3.24l-1.918.001c-1.504 0-1.797.715-1.797 1.763v2.313h3.587l-.467 3.622h-3.12V24h6.116C23.406 24 24 23.408 24 22.674V1.326C24 .592 23.406 0 22.675 0" />
</svg>
</motion.a>
</m.a>
{/* Instagram */}
<motion.a
<m.a
href="https://www.instagram.com/mozimo.choc?igsh=bTVzbGo0enV3b3Jn"
target="_blank"
rel="noopener noreferrer"
@ -267,9 +267,9 @@ export default function DesktopFooter() {
>
<path d="M12 2.163c3.204 0 3.584.012 4.85.07 1.366.062 2.633.334 3.608 1.308.974.974 1.246 2.241 1.308 3.608.058 1.266.069 1.646.069 4.85s-.012 3.584-.07 4.85c-.062 1.366-.334 2.633-1.308 3.608-.974.974-2.241 1.246-3.608 1.308-1.266.058-1.646.069-4.85.069s-3.584-.012-4.85-.07c-1.366-.062-2.633-.334-3.608-1.308-.974-.974-1.246-2.241-1.308-3.608C2.175 15.647 2.163 15.267 2.163 12s.012-3.584.07-4.85c.062-1.366.334-2.633 1.308-3.608C4.515 2.567 5.782 2.295 7.148 2.233 8.414 2.175 8.794 2.163 12 2.163zm0-2.163C8.741 0 8.332.012 7.052.07 5.771.128 4.659.334 3.678 1.315c-.98.98-1.187 2.092-1.245 3.373C2.012 5.668 2 6.077 2 12c0 5.923.012 6.332.07 7.612.058 1.281.265 2.393 1.245 3.373.98.98 2.092 1.187 3.373 1.245C8.332 23.988 8.741 24 12 24s3.668-.012 4.948-.07c1.281-.058 2.393-.265 3.373-1.245.98-.98 1.187-2.092 1.245-3.373.058-1.28.07-1.689.07-7.612 0-5.923-.012-6.332-.07-7.612-.058-1.281-.265-2.393-1.245-3.373-.98-.98-2.092-1.187-3.373-1.245C15.668.012 15.259 0 12 0zm0 5.838a6.162 6.162 0 1 0 0 12.324 6.162 6.162 0 0 0 0-12.324zm0 10.162a3.999 3.999 0 1 1 0-7.998 3.999 3.999 0 0 1 0 7.998zm6.406-11.845a1.44 1.44 0 1 0 0 2.88 1.44 1.44 0 0 0 0-2.88z" />
</svg>
</motion.a>
</m.a>
{/* YouTube */}
<motion.a
<m.a
href="https://www.youtube.com/@MozimoChocolates"
target="_blank"
rel="noopener noreferrer"
@ -289,9 +289,9 @@ export default function DesktopFooter() {
>
<path d="M23.498 6.186a2.994 2.994 0 0 0-2.107-2.117C19.163 3.5 12 3.5 12 3.5s-7.163 0-9.391.569A2.994 2.994 0 0 0 .502 6.186C0 8.413 0 12 0 12s0 3.587.502 5.814a2.994 2.994 0 0 0 2.107 2.117C4.837 20.5 12 20.5 12 20.5s7.163 0 9.391-.569a2.994 2.994 0 0 0 2.107-2.117C24 15.587 24 12 24 12s0-3.587-.502-5.814zM9.545 15.568V8.432l6.545 3.568-6.545 3.568z" />
</svg>
</motion.a>
</m.a>
{/* LinkedIn */}
<motion.a
<m.a
href="https://www.linkedin.com/company/mozimochocolates/"
target="_blank"
rel="noopener noreferrer"
@ -311,14 +311,14 @@ export default function DesktopFooter() {
>
<path d="M19 0h-14c-2.761 0-5 2.239-5 5v14c0 2.761 2.239 5 5 5h14c2.761 0 5-2.239 5-5v-14c0-2.761-2.239-5-5-5zm-11 19h-3v-10h3v10zm-1.5-11.268c-.966 0-1.75-.784-1.75-1.75s.784-1.75 1.75-1.75 1.75.784 1.75 1.75-.784 1.75-1.75 1.75zm15.5 11.268h-3v-5.604c0-1.337-.025-3.063-1.868-3.063-1.868 0-2.154 1.459-2.154 2.967v5.7h-3v-10h2.881v1.367h.041c.401-.761 1.381-1.563 2.841-1.563 3.039 0 3.6 2.001 3.6 4.601v5.595z" />
</svg>
</motion.a>
</m.a>
</div>
</div>
</motion.div>
</m.div>
</div>
{/* Bottom Bar */}
<motion.div
<m.div
className="border-t border-[#e5e5e5] mt-6 md:mt-8 pt-6 md:pt-8 text-center text-sm font-renner relative z-10"
style={{
fontWeight: 300,
@ -335,7 +335,7 @@ export default function DesktopFooter() {
<p className="text-xs md:text-sm">
&copy; 2024 Mozimo. All rights reserved.
</p>
</motion.div>
</m.div>
</footer>
);
}

View File

@ -1,4 +1,4 @@
import { motion, AnimatePresence } from "framer-motion";
import { m, AnimatePresence, useScroll, useMotionValueEvent } from "framer-motion";
import { Image } from "@unpic/react";
import { useState, useEffect } from "react";
import { useLocation } from "@tanstack/react-router";
@ -8,15 +8,11 @@ export default function Header() {
const [isMobileMenuOpen, setIsMobileMenuOpen] = useState(false);
const pathname = useLocation({ select: (loc) => loc.pathname });
useEffect(() => {
const handleScroll = () => {
const scrollPosition = window.scrollY;
setIsScrolled(scrollPosition > 100);
};
const { scrollY } = useScroll();
window.addEventListener("scroll", handleScroll);
return () => window.removeEventListener("scroll", handleScroll);
}, []);
useMotionValueEvent(scrollY, "change", (latest: number) => {
setIsScrolled(latest > 100);
});
// Close mobile menu when clicking outside
useEffect(() => {
@ -59,7 +55,7 @@ export default function Header() {
return (
<>
{/* Mobile Header - Only visible on mobile */}
<motion.header
<m.header
className="fixed top-0 z-[60] w-full md:hidden p-1 "
initial={false}
animate={{
@ -78,7 +74,7 @@ export default function Header() {
<nav className="relative bg-white border border-white/20 shadow-premium w-full h-full flex items-center px-4 rounded-[15px]">
{/* Left: Hamburger Menu */}
<div className="absolute left-4 top-1/2 -translate-y-1/2">
<motion.button
<m.button
className="hamburger-button p-2 text-gray-800 hover:text-[#8B4513] transition-all duration-300 relative min-w-[40px] min-h-[40px] flex items-center justify-center rounded-full hover:bg-white/20 backdrop-blur-sm"
whileHover={{ scale: 1.1 }}
whileTap={{ scale: 0.95 }}
@ -86,20 +82,20 @@ export default function Header() {
aria-label="Toggle mobile menu"
>
<div className="w-6 h-6 flex flex-col justify-center items-center">
<motion.span
<m.span
className="w-6 h-0.5 bg-current block transition-all duration-300"
animate={{
rotate: isMobileMenuOpen ? 45 : 0,
y: isMobileMenuOpen ? 6 : 0,
}}
/>
<motion.span
<m.span
className="w-6 h-0.5 bg-current block mt-1 transition-all duration-300"
animate={{
opacity: isMobileMenuOpen ? 0 : 1,
}}
/>
<motion.span
<m.span
className="w-6 h-0.5 bg-current block mt-1 transition-all duration-300"
animate={{
rotate: isMobileMenuOpen ? -45 : 0,
@ -107,18 +103,18 @@ export default function Header() {
}}
/>
</div>
</motion.button>
</m.button>
</div>
{/* Center: Logo */}
<div className="absolute left-1/2 transform -translate-x-1/2">
<motion.div
<m.div
className="flex items-center justify-center"
initial={{ opacity: 0, y: -20 }}
animate={{ opacity: 1, y: 0 }}
transition={{ duration: 0.6 }}
>
<motion.div
<m.div
className="relative"
animate={{
width: isScrolled ? 40 : 60, // shrink on scroll
@ -137,13 +133,13 @@ export default function Header() {
layout="fullWidth"
className="w-full h-full object-contain drop-shadow-lg"
/>
</motion.div>
</motion.div>
</m.div>
</m.div>
</div>
{/* Right: Action Buttons */}
<div className="absolute right-4 top-1/2 -translate-y-1/2 flex items-center gap-1">
<motion.button
<m.button
className="p-2"
whileHover={{ scale: 1.05 }}
whileTap={{ scale: 0.95 }}
@ -162,9 +158,9 @@ export default function Header() {
d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z"
/>
</svg>
</motion.button>
</m.button>
<motion.button
<m.button
className="p-2"
whileHover={{ scale: 1.05 }}
whileTap={{ scale: 0.95 }}
@ -183,9 +179,9 @@ export default function Header() {
d="M16 11V7a4 4 0 00-8 0v4M5 9h14l1 12H4L5 9z"
/>
</svg>
</motion.button>
</m.button>
<motion.button
<m.button
className="p-2"
whileHover={{ scale: 1.05 }}
whileTap={{ scale: 0.95 }}
@ -204,13 +200,13 @@ export default function Header() {
d="M16 7a4 4 0 11-8 0 4 4 0 018 0zM12 14a7 7 0 00-7 7h14a7 7 0 00-7-7z"
/>
</svg>
</motion.button>
</m.button>
</div>
</nav>
</motion.header>
</m.header>
{/* Desktop Header - Only visible on desktop */}
<motion.header
<m.header
className="fixed top-0 z-50 hidden md:block "
initial={false}
animate={{
@ -234,7 +230,7 @@ export default function Header() {
<div className="flex justify-between items-center w-full px-20">
{/* Left Navigation */}
<div className="flex items-center space-x-16">
<motion.a
<m.a
href={pathname === "/about" ? "/" : "/about"}
className="text-gray-800 hover:text-[#8B4513] transition-all duration-300 font-renner relative group"
style={{
@ -248,8 +244,8 @@ export default function Header() {
>
{pathname === "/about" ? "Home" : "About us"}
<span className="absolute bottom-0 left-0 w-0 h-0.5 bg-gradient-to-r from-[#8B4513] to-[#DAA520] transition-all duration-300 group-hover:w-full"></span>
</motion.a>
<motion.a
</m.a>
<m.a
href="https://shop.mozimo.in/"
target="_blank"
rel="noopener noreferrer"
@ -265,11 +261,11 @@ export default function Header() {
>
Shop
<span className="absolute bottom-0 left-0 w-0 h-0.5 bg-gradient-to-r from-[#8B4513] to-[#DAA520] transition-all duration-300 group-hover:w-full"></span>
</motion.a>
</m.a>
</div>
{/* Center Logo */}
<motion.div
<m.div
className="relative"
animate={{
width: isScrolled ? 75 : 96, // shrink logo when scrolled
@ -289,12 +285,12 @@ export default function Header() {
layout="fullWidth"
className="w-full h-full object-contain drop-shadow-lg"
/>
</motion.div>
</m.div>
{/* Right Icons */}
<div className="flex items-center space-x-8">
{/* More Dropdown */}
<motion.button
<m.button
className="flex items-center space-x-1 text-gray-800 hover:text-[#8B4513] transition-all duration-300 font-renner relative group"
style={{
fontWeight: 300,
@ -307,7 +303,7 @@ export default function Header() {
aria-label="More options"
>
<span>More</span>
<motion.svg
<m.svg
className="w-4 h-4"
fill="none"
stroke="currentColor"
@ -322,10 +318,10 @@ export default function Header() {
strokeWidth={2}
d="M19 9l-7 7-7-7"
/>
</motion.svg>
</motion.button>
</m.svg>
</m.button>
<motion.button
<m.button
className="p-3 text-gray-800 hover:text-[#8B4513] transition-all duration-300 relative min-w-[40px] min-h-[40px] flex items-center justify-center rounded-full hover:bg-white/20 backdrop-blur-sm"
whileHover={{ scale: 1.1, rotate: 5 }}
whileTap={{ scale: 0.95 }}
@ -344,8 +340,8 @@ export default function Header() {
d="M16 7a4 4 0 11-8 0 4 4 0 018 0zM12 14a7 7 0 00-7 7h14a7 7 0 00-7-7z"
/>
</svg>
</motion.button>
<motion.button
</m.button>
<m.button
className="p-3 text-gray-800 hover:text-[#8B4513] transition-all duration-300 relative min-w-[40px] min-h-[40px] flex items-center justify-center rounded-full hover:bg-white/20 backdrop-blur-sm"
whileHover={{ scale: 1.1, rotate: -5 }}
whileTap={{ scale: 0.95 }}
@ -364,8 +360,8 @@ export default function Header() {
d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z"
/>
</svg>
</motion.button>
<motion.button
</m.button>
<m.button
className="p-3 text-gray-800 hover:text-[#8B4513] transition-all duration-300 relative min-w-[40px] min-h-[40px] flex items-center justify-center rounded-full hover:bg-white/20 backdrop-blur-sm"
whileHover={{ scale: 1.1, y: -2 }}
whileTap={{ scale: 0.95 }}
@ -384,23 +380,23 @@ export default function Header() {
d="M16 11V7a4 4 0 00-8 0v4M5 9h14l1 12H4L5 9z"
/>
</svg>
</motion.button>
</m.button>
</div>
</div>
</nav>
</motion.header>
</m.header>
{/* Mobile Menu Overlay - Only visible on mobile */}
<AnimatePresence>
{isMobileMenuOpen && (
<motion.div
<m.div
className="mobile-menu fixed inset-0 z-50 bg-black/50 backdrop-blur-sm md:hidden"
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
exit={{ opacity: 0 }}
transition={{ duration: 0.3 }}
>
<motion.div
<m.div
className="absolute top-[72px] left-0 right-0 bg-white/95 backdrop-blur-md border-t border-white/20 shadow-premium"
initial={{ opacity: 0, y: -20 }}
animate={{ opacity: 1, y: 0 }}
@ -410,7 +406,7 @@ export default function Header() {
<div className="px-6 py-8 space-y-6">
{/* Mobile Navigation Links */}
<div className="space-y-4">
<motion.a
<m.a
href={pathname === "/about" ? "/" : "/about"}
className="block text-lg font-renner text-gray-800 hover:text-[#8B4513] transition-all duration-300 py-3 border-b border-gray-100"
style={{
@ -424,8 +420,8 @@ export default function Header() {
whileHover={{ x: 10 }}
>
{pathname === "/about" ? "Home" : "About us"}
</motion.a>
<motion.a
</m.a>
<m.a
href="https://shop.mozimo.in/"
target="_blank"
rel="noopener noreferrer"
@ -441,8 +437,8 @@ export default function Header() {
whileHover={{ x: 10 }}
>
Shop
</motion.a>
<motion.a
</m.a>
<m.a
href="#categories"
className="block text-lg font-renner text-gray-800 hover:text-[#8B4513] transition-all duration-300 py-3 border-b border-gray-100"
style={{
@ -456,11 +452,11 @@ export default function Header() {
whileHover={{ x: 10 }}
>
Categories
</motion.a>
</m.a>
</div>
</div>
</motion.div>
</motion.div>
</m.div>
</m.div>
)}
</AnimatePresence>
</>

View File

@ -1,4 +1,4 @@
import { motion } from "framer-motion";
import { m } from "framer-motion";
import { Image } from "@unpic/react";
export default function MobileFooter() {
@ -11,7 +11,7 @@ export default function MobileFooter() {
<div className="px-4 py-8 flex flex-col gap-8 relative z-10">
{/* Logo at top */}
<motion.div
<m.div
className="flex"
initial={{ opacity: 0, y: 20 }}
whileInView={{ opacity: 1, y: 0 }}
@ -26,12 +26,12 @@ export default function MobileFooter() {
height={80}
layout="fixed"
/>
</motion.div>
</m.div>
{/* Two column layout */}
<div className="grid grid-cols-2 gap-6">
{/* Left Column - Contact Info */}
<motion.div
<m.div
className="space-y-4"
initial={{ opacity: 0, x: -10 }}
whileInView={{ opacity: 1, x: 0 }}
@ -60,7 +60,7 @@ export default function MobileFooter() {
fontFamily: "Renner*",
}}
>
<motion.div
<m.div
className="flex items-center space-x-2"
initial={{ opacity: 0, x: -10 }}
whileInView={{ opacity: 1, x: 0 }}
@ -76,8 +76,8 @@ export default function MobileFooter() {
<path d="M2 3a1 1 0 011-1h2.153a1 1 0 01.986.836l.74 4.435a1 1 0 01-.54 1.06l-1.548.773a11.037 11.037 0 006.105 6.105l.774-1.548a1 1 0 011.059-.54l4.435.74a1 1 0 01.836.986V17a1 1 0 01-1 1h-2C7.82 18 2 12.18 2 5V3z" />
</svg>
<span className="text-xs md:text-sm">0172-4045414</span>
</motion.div>
<motion.div
</m.div>
<m.div
className="flex items-start space-x-2"
initial={{ opacity: 0, x: -10 }}
whileInView={{ opacity: 1, x: 0 }}
@ -99,7 +99,7 @@ export default function MobileFooter() {
<span className="text-xs md:text-sm">
SCO 8, Inner Market, 9-D, Sector 9, Chandigarh, 160009
</span>
</motion.div>
</m.div>
</div>
{/* Find Us On */}
@ -118,7 +118,7 @@ export default function MobileFooter() {
</h3>
<div className="flex">
{/* Social icons with original animations */}
<motion.a
<m.a
href="https://www.facebook.com/share/16vPmvcQV7/?mibextid=wwXIfr"
target="_blank"
rel="noopener noreferrer"
@ -138,8 +138,8 @@ export default function MobileFooter() {
>
<path d="M22.675 0h-21.35C.595 0 0 .592 0 1.326v21.348C0 23.408.595 24 1.325 24h11.495v-9.294H9.692v-3.622h3.128V8.413c0-3.1 1.893-4.788 4.659-4.788 1.325 0 2.463.099 2.797.143v3.24l-1.918.001c-1.504 0-1.797.715-1.797 1.763v2.313h3.587l-.467 3.622h-3.12V24h6.116C23.406 24 24 23.408 24 22.674V1.326C24 .592 23.406 0 22.675 0" />
</svg>
</motion.a>
<motion.a
</m.a>
<m.a
href="https://www.instagram.com/mozimo.choc?igsh=bTVzbGo0enV3b3Jn"
target="_blank"
rel="noopener noreferrer"
@ -159,8 +159,8 @@ export default function MobileFooter() {
>
<path d="M12 2.163c3.204 0 3.584.012 4.85.07 1.366.062 2.633.334 3.608 1.308.974.974 1.246 2.241 1.308 3.608.058 1.266.069 1.646.069 4.85s-.012 3.584-.07 4.85c-.062 1.366-.334 2.633-1.308 3.608-.974.974-2.241 1.246-3.608 1.308-1.266.058-1.646.069-4.85.069s-3.584-.012-4.85-.07c-1.366-.062-2.633-.334-3.608-1.308-.974-.974-1.246-2.241-1.308-3.608C2.175 15.647 2.163 15.267 2.163 12s.012-3.584.07-4.85c.062-1.366.334-2.633 1.308-3.608C4.515 2.567 5.782 2.295 7.148 2.233 8.414 2.175 8.794 2.163 12 2.163zm0-2.163C8.741 0 8.332.012 7.052.07 5.771.128 4.659.334 3.678 1.315c-.98.98-1.187 2.092-1.245 3.373C2.012 5.668 2 6.077 2 12c0 5.923.012 6.332.07 7.612.058 1.281.265 2.393 1.245 3.373.98.98 2.092 1.187 3.373 1.245C8.332 23.988 8.741 24 12 24s3.668-.012 4.948-.07c1.281-.058 2.393-.265 3.373-1.245.98-.98 1.187-2.092 1.245-3.373.058-1.28.07-1.689.07-7.612 0-5.923-.012-6.332-.07-7.612-.058-1.281-.265-2.393-1.245-3.373-.98-.98-2.092-1.187-3.373-1.245C15.668.012 15.259 0 12 0zm0 5.838a6.162 6.162 0 1 0 0 12.324 6.162 6.162 0 0 0 0-12.324zm0 10.162a3.999 3.999 0 1 1 0-7.998 3.999 3.999 0 0 1 0 7.998zm6.406-11.845a1.44 1.44 0 1 0 0 2.88 1.44 1.44 0 0 0 0-2.88z" />
</svg>
</motion.a>
<motion.a
</m.a>
<m.a
href="https://www.youtube.com/@MozimoChocolates"
target="_blank"
rel="noopener noreferrer"
@ -180,8 +180,8 @@ export default function MobileFooter() {
>
<path d="M23.498 6.186a2.994 2.994 0 0 0-2.107-2.117C19.163 3.5 12 3.5 12 3.5s-7.163 0-9.391.569A2.994 2.994 0 0 0 .502 6.186C0 8.413 0 12 0 12s0 3.587.502 5.814a2.994 2.994 0 0 0 2.107 2.117C4.837 20.5 12 20.5 12 20.5s7.163 0 9.391-.569a2.994 2.994 0 0 0 2.107-2.117C24 15.587 24 12 24 12s0-3.587-.502-5.814zM9.545 15.568V8.432l6.545 3.568-6.545 3.568z" />
</svg>
</motion.a>
<motion.a
</m.a>
<m.a
href="https://www.linkedin.com/company/mozimochocolates/"
target="_blank"
rel="noopener noreferrer"
@ -201,14 +201,14 @@ export default function MobileFooter() {
>
<path d="M19 0h-14c-2.761 0-5 2.239-5 5v14c0 2.761 2.239 5 5 5h14c2.761 0 5-2.239 5-5v-14c0-2.761-2.239-5-5-5zm-11 19h-3v-10h3v10zm-1.5-11.268c-.966 0-1.75-.784-1.75-1.75s.784-1.75 1.75-1.75 1.75.784 1.75 1.75-.784 1.75-1.75 1.75zm15.5 11.268h-3v-5.604c0-1.337-.025-3.063-1.868-3.063-1.868 0-2.154 1.459-2.154 2.967v5.7h-3v-10h2.881v1.367h.041c.401-.761 1.381-1.563 2.841-1.563 3.039 0 3.6 2.001 3.6 4.601v5.595z" />
</svg>
</motion.a>
</m.a>
{/* Other social icons... */}
</div>
</div>
</motion.div>
</m.div>
{/* Right Column - Know more and other links */}
<motion.div
<m.div
className="space-y-4"
initial={{ opacity: 0, x: 10 }}
whileInView={{ opacity: 1, x: 0 }}
@ -247,7 +247,7 @@ export default function MobileFooter() {
"Locate our store",
"Bulk Ordering",
].map((link, index) => (
<motion.li
<m.li
key={link}
initial={{ opacity: 0, x: -10 }}
whileInView={{ opacity: 1, x: 0 }}
@ -261,15 +261,15 @@ export default function MobileFooter() {
{link}
<span className="absolute bottom-0 left-0 w-0 h-0.5 bg-gradient-to-r from-[#8B4513] to-[#DAA520] transition-all duration-300 group-hover:w-full"></span>
</a>
</motion.li>
</m.li>
))}
</ul>
</div>
</motion.div>
</m.div>
</div>
{/* Copyright - original styling preserved */}
<motion.div
<m.div
className="border-t border-[#e5e5e5] mt-6 md:mt-8 pt-6 md:pt-8 text-center text-sm font-renner relative z-10"
style={{
fontWeight: 300,
@ -286,7 +286,7 @@ export default function MobileFooter() {
<p className="text-xs md:text-sm">
&copy; 2024 Mozimo. All rights reserved.
</p>
</motion.div>
</m.div>
</div>
</footer>
);

View File

@ -1,5 +1,5 @@
import { useState, useCallback, useMemo, useEffect } from "react";
import { LazyMotion, domAnimation, m } from "framer-motion";
import { m } from "framer-motion";
import Section from "@/components/Section";
import { Image } from "@unpic/react";
@ -94,7 +94,7 @@ import { Image } from "@unpic/react";
return (
<Section background="white" id="categories">
<LazyMotion features={domAnimation}>
<div className="grid grid-cols-1 lg:grid-cols-2 gap-0 items-stretch min-h-[400px] md:min-h-[500px]">
{/* Left */}
<div className="flex flex-col justify-center h-full bg-white px-4 md:px-8 py-6 md:py-12 order-2 lg:order-1">
@ -123,7 +123,7 @@ import { Image } from "@unpic/react";
</div>
</div>
</div>
</LazyMotion>
</Section>
);
}

View File

@ -1,6 +1,6 @@
'use client';
import { motion } from 'framer-motion';
import { m } from 'framer-motion';
import { ReactNode } from 'react';
interface SectionProps {
@ -35,7 +35,7 @@ export default function Section({
return (
<section id={id} className={classes}>
<motion.div
<m.div
initial={{ opacity: 0, y: 60 }}
whileInView={{ opacity: 1, y: 0 }}
transition={{
@ -50,7 +50,7 @@ export default function Section({
<div className="absolute top-0 left-1/2 transform -translate-x-1/2 w-16 md:w-24 h-1 bg-gradient-to-r from-transparent via-[#8B4513]/30 to-transparent opacity-0 hover:opacity-100 transition-opacity duration-500" />
{children}
</motion.div>
</m.div>
</section>
);
}

View File

@ -1,5 +1,5 @@
import { useEffect, useRef } from "react";
import { motion } from "framer-motion";
import { m } from "framer-motion";
import { Image } from "@unpic/react";
import Section from "./Section";
import { useInstagram } from "@/hooks/useInstagram";
@ -60,7 +60,7 @@ export default function SocialMedia() {
return (
<Section background="cream" padding="md">
<motion.div
<m.div
initial="initial"
whileInView="animate"
viewport={{ once: true, margin: "-50px" }}
@ -79,7 +79,7 @@ export default function SocialMedia() {
>
Follow us on Instagram
</h2>
</motion.div>
</m.div>
<div
ref={scrollRef}
@ -88,7 +88,7 @@ export default function SocialMedia() {
{loading ? (
<>
{[1, 2, 3].map((i) => (
<motion.div
<m.div
key={i}
className="bg-white rounded-lg shadow-premium h-64 md:h-96 skeleton snap-start w-[calc(80vw-1rem)] flex-shrink-0 sm:w-auto"
initial={{ opacity: 0, y: 20 }}
@ -101,7 +101,7 @@ export default function SocialMedia() {
) : error ? (
isTokenExpired ? (
<div className="col-span-full text-center py-12 sm:col-span-2 lg:col-span-3">
<motion.div
<m.div
initial={{ opacity: 0, y: 20 }}
whileInView={{ opacity: 1, y: 0 }}
transition={{ duration: 0.6 }}
@ -121,12 +121,12 @@ export default function SocialMedia() {
<div className="text-sm text-gray-500">
In the meantime, follow us @mozimo_chocolate
</div>
</motion.div>
</m.div>
</div>
) : (
<>
{/* Left Block - Chocolate Spread Jar */}
<motion.div
<m.div
initial="initial"
whileInView="animate"
viewport={{ once: true, margin: "-50px" }}
@ -135,7 +135,7 @@ export default function SocialMedia() {
whileHover={{ scale: 1.02 }}
>
<div className="relative h-64 md:h-96 bg-gradient-to-br from-amber-50 to-orange-50 flex items-center justify-center">
<motion.div
<m.div
className="text-center"
whileHover={{ scale: 1.05 }}
transition={{ duration: 0.3 }}
@ -151,12 +151,12 @@ export default function SocialMedia() {
SINGLE ORIGIN HAZELNUT SPREAD 45%
</div>
</div>
</motion.div>
</m.div>
</div>
</motion.div>
</m.div>
{/* Middle Block - Magazine Article */}
<motion.div
<m.div
initial="initial"
whileInView="animate"
viewport={{ once: true, margin: "-50px" }}
@ -191,10 +191,10 @@ export default function SocialMedia() {
</p>
</div>
</div>
</motion.div>
</m.div>
{/* Right Block - World Chocolate Day */}
<motion.div
<m.div
initial="initial"
whileInView="animate"
viewport={{ once: true, margin: "-50px" }}
@ -218,12 +218,12 @@ export default function SocialMedia() {
</p>
</div>
</div>
</motion.div>
</m.div>
</>
)
) : (
posts?.slice(0, 3).map((post, index) => (
<motion.div
<m.div
key={post.id}
initial="initial"
whileInView="animate"
@ -273,7 +273,7 @@ export default function SocialMedia() {
</div>
</div>
</a>
</motion.div>
</m.div>
))
)}
</div>