Some checks failed
Build and Deploy / build (push) Has been cancelled
WARNING: This change breaks existing SEO URLs for Serbian locale. Changes: - Migrated from separate locale folders (src/app/en/, src/app/de/, etc.) to [locale] dynamic segments (src/app/[locale]/) - Serbian is now at /sr/ instead of / (root) - English at /en/, German at /de/, French at /fr/ - All components updated to generate locale-aware links - Root / now redirects to /sr (307 temporary redirect) SEO Impact: - Previously indexed Serbian URLs (/, /products, /about, /contact) will now return 404 or redirect to /sr/* URLs - This is a breaking change for SEO - Serbian pages should ideally remain at root (/) with only non-default locales getting prefix - Consider implementing 301 redirects from old URLs to maintain search engine rankings Technical Notes: - next-intl v4 with [locale] structure requires ALL locales to have the prefix (cannot have default locale at root) - Alternative approach would be separate folder structure per locale
182 lines
6.7 KiB
TypeScript
182 lines
6.7 KiB
TypeScript
"use client";
|
|
|
|
import { motion } from "framer-motion";
|
|
import { Star, ShoppingBag } from "lucide-react";
|
|
import Image from "next/image";
|
|
import Link from "next/link";
|
|
import { useLocale } from "next-intl";
|
|
import { useSaleorCheckoutStore } from "@/stores/saleorCheckoutStore";
|
|
import type { Product } from "@/types/saleor";
|
|
import { getProductPrice, getProductImage, formatPrice, parseDescription } from "@/lib/saleor";
|
|
|
|
interface NewHeroProps {
|
|
featuredProduct?: Product;
|
|
}
|
|
|
|
export default function NewHero({ featuredProduct }: NewHeroProps) {
|
|
const locale = useLocale();
|
|
const { addLine, openCart } = useSaleorCheckoutStore();
|
|
|
|
const handleAddToCart = async () => {
|
|
const variant = featuredProduct?.variants?.[0];
|
|
if (variant?.id) {
|
|
await addLine(variant.id, 1);
|
|
openCart();
|
|
}
|
|
};
|
|
|
|
const price = featuredProduct ? getProductPrice(featuredProduct) : "";
|
|
const image = featuredProduct ? getProductImage(featuredProduct) : "";
|
|
|
|
return (
|
|
<section className="relative h-screen min-h-[700px] flex flex-col overflow-hidden pt-10">
|
|
{/* Background Image */}
|
|
<div className="absolute inset-0 z-0">
|
|
<div className="absolute inset-0 bg-gradient-to-b from-[#E8F4F8]/30 to-white/80" />
|
|
<div className="absolute inset-0 bg-gradient-to-r from-[#E8F4F8]/50 via-transparent to-[#E8F4F8]/30" />
|
|
</div>
|
|
|
|
{/* Mobile Hero Text */}
|
|
<div className="relative z-10 flex flex-col justify-end items-center text-center p-6 pb-12 lg:hidden">
|
|
<motion.h1
|
|
initial={{ opacity: 0, y: 20 }}
|
|
animate={{ opacity: 1, y: 0 }}
|
|
transition={{ duration: 0.6 }}
|
|
className="font-serif italic text-3xl text-[#1A1A1A] leading-[1.15] tracking-tight"
|
|
>
|
|
Natural Oils,
|
|
<br />
|
|
Real Results
|
|
</motion.h1>
|
|
</div>
|
|
|
|
{/* Desktop Floating Product Card */}
|
|
<div className="hidden lg:block absolute left-10 xl:left-20 top-32 z-10">
|
|
<motion.div
|
|
initial={{ opacity: 0, x: -30 }}
|
|
animate={{ opacity: 1, x: 0 }}
|
|
transition={{ duration: 0.8, delay: 0.3 }}
|
|
className="bg-white/95 backdrop-blur-md w-[320px] xl:w-[360px] rounded-[4px] overflow-hidden shadow-lg"
|
|
>
|
|
{featuredProduct ? (
|
|
<>
|
|
{/* Product Image */}
|
|
<div className="relative aspect-square bg-[#E8F4F8]">
|
|
<Image
|
|
src={image}
|
|
alt={featuredProduct.name}
|
|
fill
|
|
className="object-cover"
|
|
priority
|
|
/>
|
|
</div>
|
|
|
|
<div className="p-5">
|
|
{/* Title & Rating */}
|
|
<div className="flex items-center justify-between mb-2">
|
|
<h3 className="text-lg font-medium text-[#1A1A1A]">
|
|
{featuredProduct.name}
|
|
</h3>
|
|
<div className="flex items-center gap-0.5 shrink-0">
|
|
{[...Array(5)].map((_, i) => (
|
|
<Star
|
|
key={i}
|
|
className="w-3.5 h-3.5 fill-amber-400 text-amber-400"
|
|
/>
|
|
))}
|
|
</div>
|
|
</div>
|
|
|
|
{/* Description */}
|
|
<p className="text-sm text-[#4A4A4A]/70 mt-1 line-clamp-2">
|
|
{parseDescription(featuredProduct.description).slice(0, 100) ||
|
|
"Premium natural oil for hair and skin care"}
|
|
</p>
|
|
|
|
{/* Tech Badge */}
|
|
<div className="mt-3 pt-3 border-t border-[#1A1A1A]/6">
|
|
<p className="text-xs font-medium text-[#1A1A1A] tracking-wide">
|
|
COLD-PRESSED TECHNOLOGY
|
|
</p>
|
|
<p className="text-xs text-[#4A4A4A]/60 mt-0.5 leading-relaxed">
|
|
Pure extraction method preserving all nutrients and benefits
|
|
</p>
|
|
</div>
|
|
|
|
{/* Price & CTA */}
|
|
<div className="flex items-center justify-between mt-4 pt-4 border-t border-[#1A1A1A]/6">
|
|
<div>
|
|
<span className="text-lg font-medium text-[#1A1A1A]">
|
|
{price}
|
|
</span>
|
|
<span className="text-xs text-[#4A4A4A]/60 ml-2">50ml</span>
|
|
</div>
|
|
<button
|
|
onClick={handleAddToCart}
|
|
className="inline-flex items-center gap-2 bg-[#1A1A1A] text-white px-4 py-2 text-sm font-medium hover:bg-[#1A1A1A]/90 transition-colors"
|
|
>
|
|
<ShoppingBag className="w-4 h-4" />
|
|
Add
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</>
|
|
) : (
|
|
<div className="p-8 text-center">
|
|
<p className="text-[#4A4A4A]/70">Loading featured product...</p>
|
|
</div>
|
|
)}
|
|
</motion.div>
|
|
</div>
|
|
|
|
{/* Right Side Content */}
|
|
<div className="hidden lg:flex flex-1 items-center justify-end pr-10 xl:pr-20">
|
|
<motion.div
|
|
initial={{ opacity: 0, y: 30 }}
|
|
animate={{ opacity: 1, y: 0 }}
|
|
transition={{ duration: 0.8, delay: 0.5 }}
|
|
className="max-w-xl text-right"
|
|
>
|
|
<span className="inline-block text-xs tracking-[0.3em] text-[#6B7280] mb-6">
|
|
PREMIUM NATURAL OILS
|
|
</span>
|
|
|
|
<h1 className="font-serif italic text-5xl xl:text-6xl text-[#1A1A1A] tracking-tight leading-[1.1] mb-6">
|
|
ManoonOils
|
|
</h1>
|
|
|
|
<p className="text-xl text-[#4A4A4A] font-light mb-8 leading-relaxed">
|
|
Discover our premium collection of natural oils for hair and skin
|
|
care. Handmade with love using only the finest ingredients.
|
|
</p>
|
|
|
|
<div className="flex gap-4 justify-end">
|
|
<Link
|
|
href={`/${locale}/products`}
|
|
className="inline-block bg-[#1A1A1A] text-white px-8 py-4 text-sm tracking-wide hover:bg-[#1A1A1A]/90 transition-colors"
|
|
>
|
|
Shop Collection
|
|
</Link>
|
|
<Link
|
|
href={`/${locale}/about`}
|
|
className="inline-block border border-[#1A1A1A] text-[#1A1A1A] px-8 py-4 text-sm tracking-wide hover:bg-[#1A1A1A] hover:text-white transition-colors"
|
|
>
|
|
Our Story
|
|
</Link>
|
|
</div>
|
|
</motion.div>
|
|
</div>
|
|
|
|
{/* Mobile CTA */}
|
|
<div className="lg:hidden relative z-10 px-6 pb-12">
|
|
<Link
|
|
href={`/${locale}/products`}
|
|
className="block w-full bg-[#1A1A1A] text-white text-center py-4 text-sm tracking-wide"
|
|
>
|
|
Shop Now
|
|
</Link>
|
|
</div>
|
|
</section>
|
|
);
|
|
}
|