23 Commits

Author SHA1 Message Date
c88c45d030 Merge version_3 into main
Merge version_3 into main
2026-02-20 13:42:58 +00:00
c2254c2faf Update src/app/shop/page.tsx 2026-02-20 13:42:54 +00:00
2777466057 Update src/app/shop/[id]/page.tsx 2026-02-20 13:42:53 +00:00
3e39766798 Update src/app/page.tsx 2026-02-20 13:42:52 +00:00
12614bf6f7 Update src/app/layout.tsx 2026-02-20 13:42:52 +00:00
ed01a00d27 Update src/app/blog/page.tsx 2026-02-20 13:42:51 +00:00
28b1073b5d Merge version_3 into main
Merge version_3 into main
2026-02-20 13:40:15 +00:00
dad36c5d2d Update src/app/shop/page.tsx 2026-02-20 13:40:11 +00:00
47dc645476 Update src/app/shop/[id]/page.tsx 2026-02-20 13:40:11 +00:00
a28cc0a9b1 Update src/app/page.tsx 2026-02-20 13:40:10 +00:00
5db6ada320 Update src/app/layout.tsx 2026-02-20 13:40:09 +00:00
92627b54c0 Update src/app/blog/page.tsx 2026-02-20 13:40:08 +00:00
b617b9ae06 Merge version_2 into main
Merge version_2 into main
2026-02-20 13:24:56 +00:00
cca580672d Update src/app/page.tsx 2026-02-20 13:24:51 +00:00
d3b64f42c1 Update src/app/layout.tsx 2026-02-20 13:24:50 +00:00
56b620f36d Merge version_2 into main
Merge version_2 into main
2026-02-20 13:17:57 +00:00
f32df0f2bd Update src/app/styles/variables.css 2026-02-20 13:17:53 +00:00
82fe096a9a Update src/app/shop/page.tsx 2026-02-20 13:17:53 +00:00
99b2f058ff Update src/app/shop/[id]/page.tsx 2026-02-20 13:17:52 +00:00
3dbef719d5 Update src/app/page.tsx 2026-02-20 13:17:51 +00:00
6743f20e66 Update src/app/layout.tsx 2026-02-20 13:17:51 +00:00
c01e32dda3 Update src/app/blog/page.tsx 2026-02-20 13:17:49 +00:00
4f70bed237 Merge version_1 into main
Merge version_1 into main
2026-02-20 13:13:25 +00:00
6 changed files with 214 additions and 279 deletions

View File

@@ -1,12 +1,19 @@
"use client";
import ReactLenis from "lenis/react";
import { ThemeProvider } from "@/providers/themeProvider/ThemeProvider";
import { useBlogPosts } from "@/hooks/useBlogPosts";
import NavbarStyleApple from '@/components/navbar/NavbarStyleApple/NavbarStyleApple';
import FooterMedia from '@/components/sections/footer/FooterMedia';
import BlogCardThree from '@/components/sections/blog/BlogCardThree';
import BlogCardTwo from '@/components/sections/blog/BlogCardTwo';
const navItems = [
{ name: "Home", id: "/" },
{ name: "Products", id: "/#products" },
{ name: "About", id: "/#about" },
{ name: "Testimonials", id: "/#testimonials" },
{ name: "Contact", id: "/#contact" },
];
export default function BlogPage() {
const { posts, isLoading } = useBlogPosts();
@@ -24,35 +31,34 @@ export default function BlogPage() {
secondaryButtonStyle="solid"
headingFontWeight="light"
>
<ReactLenis root>
<div id="nav" data-section="nav">
<NavbarStyleApple
brandName="Persik"
navItems={[
{ name: "Home", id: "/" },
{ name: "Shop", id: "#products" },
{ name: "About", id: "#about" },
{ name: "Testimonials", id: "#testimonials" },
{ name: "FAQ", id: "#faq" },
{ name: "Contact", id: "#contact" },
]}
navItems={navItems}
/>
</div>
<main>
{isLoading ? (
<div className="w-content-width mx-auto py-20 text-center">
<div className="w-full mx-auto py-40 text-center">
<p className="text-foreground">Loading posts...</p>
</div>
) : (
<BlogCardThree
blogs={posts}
title="Featured Articles"
description="Explore our latest insights"
animationType="slide-up"
textboxLayout="default"
useInvertedBackground={false}
carouselMode="buttons"
/>
<div id="blog-posts" data-section="blog-posts">
<BlogCardTwo
blogs={posts}
title="From Our Blog"
description="Explore our latest floral tips, stories, and insights."
animationType="slide-up"
textboxLayout="default"
useInvertedBackground={false}
carouselMode="buttons"
/>
</div>
)}
</main>
<div id="footer" data-section="footer">
<FooterMedia
imageSrc="https://img.b2bpic.net/free-photo/woman-holds-festive-flower-arrangement-with-bright-chrysanthemum-flowers_169016-51483.jpg?_wi=2"
imageAlt="Soft focus background image of various flowers"
@@ -61,28 +67,27 @@ export default function BlogPage() {
columns={[
{
title: "Shop", items: [
{ label: "Bouquets", href: "#products" },
{ label: "Arrangements", href: "#products" },
{ label: "Gifts", href: "#products" },
{ label: "Bouquets", href: "/shop" },
{ label: "Arrangements", href: "/shop" },
{ label: "Gifts", href: "/shop" },
],
},
{
title: "About Us", items: [
{ label: "Our Story", href: "#about" },
{ label: "Testimonials", href: "#testimonials" },
{ label: "FAQ", href: "#faq" },
{ label: "Our Story", href: "/#about" },
{ label: "Testimonials", href: "/#testimonials" },
],
},
{
title: "Support", items: [
{ label: "Contact", href: "#contact" },
{ label: "Contact", href: "/#contact" },
{ label: "Delivery Info", href: "https://example.com/delivery" },
{ label: "Privacy Policy", href: "https://example.com/privacy" },
],
},
]}
/>
</ReactLenis>
</div>
</ThemeProvider>
);
}
}

View File

@@ -1,8 +1,6 @@
import type { Metadata } from "next";
import { Nunito_Sans } from "next/font/google";
import "./globals.css";
import { ServiceWrapper } from "@/components/ServiceWrapper";
import Tag from "@/tag/Tag";
const nunitoSans = Nunito_Sans({
variable: "--font-nunito-sans", subsets: ["latin"],
@@ -13,11 +11,13 @@ export const metadata: Metadata = {
openGraph: {
title: "Persik Flowers - Fresh Flowers for Every Occasion", description: "Discover exquisite bouquets and arrangements from Persik. Your local flower shop for all occasions, offering fresh flowers and expert floral design.", url: "https://www.persikflowers.com", siteName: "Persik", images: [
{
url: "https://img.b2bpic.net/free-photo/flowers-bouquet-dining-table_1339-1210.jpg", alt: "Beautiful bouquet of fresh flowers"},
url: "https://webuild-dev.s3.eu-north-1.amazonaws.com/users/user_35vmIsFKiMtTSUSBP7nWGRgR0We/tmp/panda-with-flowers-realistic-1771593889092-2a64eb03.png", alt: "Beautiful bouquet of fresh flowers"
}
],
type: "website"},
type: "website"
},
twitter: {
card: "summary_large_image", title: "Persik Flowers - Fresh Flowers for Every Occasion", description: "Discover exquisite bouquets and arrangements from Persik. Your local flower shop for all occasions, offering fresh flowers and expert floral design.", images: ["https://img.b2bpic.net/free-photo/flowers-bouquet-dining-table_1339-1210.jpg"],
card: "summary_large_image", title: "Persik Flowers - Fresh Flowers for Every Occasion", description: "Discover exquisite bouquets and arrangements from Persik. Your local flower shop for all occasions, offering fresh flowers and expert floral design.", images: ["https://webuild-dev.s3.eu-north-1.amazonaws.com/users/user_35vmIsFKiMtTSUSBP7nWGRgR0We/tmp/panda-with-flowers-realistic-1771593889092-2a64eb03.png"],
},
robots: {
index: true,
@@ -32,13 +32,9 @@ export default function RootLayout({
}>) {
return (
<html lang="en" suppressHydrationWarning>
<ServiceWrapper>
<body
className={`${nunitoSans.variable} antialiased`}
>
<Tag />
{children}
<body className={`${nunitoSans.variable} antialiased`}>
{children}
<script
dangerouslySetInnerHTML={{
__html: `
@@ -1406,7 +1402,6 @@ export default function RootLayout({
}}
/>
</body>
</ServiceWrapper>
</html>
);
}

View File

@@ -1,14 +1,13 @@
"use client";
import { ThemeProvider } from "@/providers/themeProvider/ThemeProvider";
import { Award, Flower, Heart } from "lucide-react";
import { Award, Flower, Heart, Phone } from "lucide-react";
import NavbarStyleApple from '@/components/navbar/NavbarStyleApple/NavbarStyleApple';
import HeroBillboard from '@/components/sections/hero/HeroBillboard';
import ProductCardFour from '@/components/sections/product/ProductCardFour';
import AboutMetric from '@/components/sections/about/AboutMetric';
import TestimonialCardSix from '@/components/sections/testimonial/TestimonialCardSix';
import FaqSplitText from '@/components/sections/faq/FaqSplitText';
import ContactSplitForm from '@/components/sections/contact/ContactSplitForm';
import ContactFaq from '@/components/sections/contact/ContactFaq';
import FooterMedia from '@/components/sections/footer/FooterMedia';
export default function LandingPage() {
@@ -29,11 +28,10 @@ export default function LandingPage() {
<NavbarStyleApple
brandName="Persik"
navItems={[
{ name: "Home", id: "#hero" },
{ name: "Shop", id: "#products" },
{ name: "Home", id: "/" },
{ name: "Products", id: "#products" },
{ name: "About", id: "#about" },
{ name: "Testimonials", id: "#testimonials" },
{ name: "FAQ", id: "#faq" },
{ name: "Contact", id: "#contact" },
]}
/>
@@ -47,7 +45,7 @@ export default function LandingPage() {
{ text: "Shop Now", href: "#products" },
{ text: "Learn More", href: "#about" },
]}
imageSrc="https://img.b2bpic.net/free-photo/flowers-bouquet-dining-table_1339-1210.jpg"
imageSrc="https://webuild-dev.s3.eu-north-1.amazonaws.com/users/user_35vmIsFKiMtTSUSBP7nWGRgR0We/tmp/panda-with-flowers-realistic-1771593889092-2a64eb03.png"
imageAlt="Beautiful bouquet of fresh flowers with pink and peach tones"
mediaAnimation="slide-up"
tag="Your Local Florist"
@@ -98,36 +96,20 @@ export default function LandingPage() {
useInvertedBackground={false}
/>
</div>
<div id="faq" data-section="faq">
<FaqSplitText
sideTitle="Frequently Asked Questions"
sideDescription="Find quick answers to common questions about our flowers, delivery, and services."
<div id="contact" data-section="contact">
<ContactFaq
ctaTitle="Get in Touch with Persik"
ctaDescription="Have a question or a special request? We'd love to hear from you. Send us a message and we'll get back to you shortly."
ctaButton={{ text: "Send Message", href: "#contact" }}
ctaIcon={Phone}
faqs={[
{ id: "1", title: "What are your delivery options?", content: "We offer same-day delivery for orders placed before 2 PM. Standard delivery is available nationwide. Please check our delivery policy for details." },
{ id: "2", title: "Can I customize a bouquet?", content: "Absolutely! We love creating bespoke arrangements. Contact us directly to discuss your specific preferences and occasion." },
{ id: "3", title: "How do I care for my flowers?", content: "Each bouquet comes with a care card. Generally, trim stems, change water daily, and keep away from direct sunlight and heat sources." },
{ id: "4", title: "Do you offer corporate services?", content: "Yes, we provide floral services for corporate events, office decor, and client gifting. Reach out to our team for a tailored proposal." },
]}
faqsAnimation="slide-up"
textPosition="left"
useInvertedBackground={false}
/>
</div>
<div id="contact" data-section="contact">
<ContactSplitForm
title="Get in Touch with Persik"
description="Have a question or a special request? We'd love to hear from you. Send us a message and we'll get back to you shortly."
inputs={[
{ name: "name", type: "text", placeholder: "Your Name", required: true },
{ name: "email", type: "email", placeholder: "Your Email", required: true },
{ name: "phone", type: "tel", placeholder: "Your Phone Number (Optional)" },
]}
textarea={{ name: "message", placeholder: "Tell us about your floral needs or inquiry...", rows: 5, required: true }}
buttonText="Send Message"
imageSrc="https://img.b2bpic.net/free-photo/flowers-floral-shop-different-types_1303-15615.jpg"
imageAlt="Beautiful flowers in a vase on a wooden table, in a cozy flower shop setting"
mediaAnimation="slide-up"
mediaPosition="right"
animationType="slide-up"
useInvertedBackground={false}
/>
</div>
@@ -138,12 +120,12 @@ export default function LandingPage() {
logoText="Persik Flowers"
copyrightText="© 2024 Persik | All rights reserved"
columns={[
{ title: "Shop", items: [{ label: "Bouquets", href: "#products" }, { label: "Arrangements", href: "#products" }, { label: "Gifts", href: "#products" }] },
{ title: "About Us", items: [{ label: "Our Story", href: "#about" }, { label: "Testimonials", href: "#testimonials" }, { label: "FAQ", href: "#faq" }] },
{ title: "Support", items: [{ label: "Contact", href: "#contact" }, { label: "Delivery Info", href: "https://example.com/delivery" }, { label: "Privacy Policy", href: "https://example.com/privacy" }] },
{ title: "Shop", items: [{ label: "Bouquets", href: "/shop" }, { label: "Arrangements", href: "/shop" }, { label: "Gifts", href: "/shop" }] },
{ title: "About Us", items: [{ label: "Our Story", href: "/#about" }, { label: "Testimonials", href: "/#testimonials" }] },
{ title: "Support", items: [{ label: "Contact", href: "/#contact" }, { label: "Delivery Info", href: "https://example.com/delivery" }, { label: "Privacy Policy", href: "https://example.com/privacy" }] },
]}
/>
</div>
</ThemeProvider>
);
}
}

View File

@@ -2,11 +2,10 @@
import React, { use, useCallback } from "react";
import { useRouter } from "next/navigation";
import ReactLenis from "lenis/react";
import { ThemeProvider } from "@/providers/themeProvider/ThemeProvider";
import NavbarStyleApple from "@/components/navbar/NavbarStyleApple/NavbarStyleApple";
import FooterMedia from '@/components/sections/footer/FooterMedia';
import ProductDetailCard from "@/components/ecommerce/productDetail/ProductDetailCard";
import FeatureCardTwentyOne from "@/components/sections/feature/FeatureCardTwentyOne";
import ProductCart from "@/components/ecommerce/cart/ProductCart";
import { useProductDetail } from "@/hooks/useProductDetail";
import { useCart } from "@/hooks/useCart";
@@ -16,6 +15,14 @@ interface ProductPageProps {
params: Promise<{ id: string }>;
}
const navItems = [
{ name: "Home", id: "/" },
{ name: "Products", id: "/shop" },
{ name: "About", id: "/#about" },
{ name: "Testimonials", id: "/#testimonials" },
{ name: "Contact", id: "/#contact" },
];
export default function ProductPage({ params }: ProductPageProps) {
const { id } = use(params);
const router = useRouter();
@@ -25,8 +32,6 @@ export default function ProductPage({ params }: ProductPageProps) {
isLoading,
images,
meta,
variants,
quantityVariant,
selectedQuantity,
createCartItem,
} = useProductDetail(id);
@@ -48,8 +53,9 @@ export default function ProductPage({ params }: ProductPageProps) {
const item = createCartItem();
if (item) {
addItem(item);
setCartOpen(true);
}
}, [createCartItem, addItem]);
}, [createCartItem, addItem, setCartOpen]);
const handleBuyNow = useCallback(() => {
if (product) {
@@ -66,16 +72,17 @@ export default function ProductPage({ params }: ProductPageProps) {
await checkout(getCheckoutItems(), { successUrl: currentUrl.toString() });
}, [cartItems, checkout, getCheckoutItems]);
const cartCount = cartItems.length;
const navbarProps = {
brandName: "Persik", navItems: [{ name: "Home", id: "/" }, { name: "Shop", id: "/shop" }],
button: { text: "Cart", onClick: () => setCartOpen(true) },
brandName: "Persik", navItems: navItems,
button: { text: `Cart (${cartCount})`, onClick: () => setCartOpen(true) },
mobileNavContent: (
<div className="flex flex-col gap-2 mt-4">
<button
onClick={() => setCartOpen(true)}
className="w-full text-left p-2 rounded-md hover:bg-muted/50"
>
Cart
Cart ({cartCount})
</button>
</div>
)
@@ -83,77 +90,60 @@ export default function ProductPage({ params }: ProductPageProps) {
const footerProps = {
imageSrc: "https://img.b2bpic.net/free-photo/woman-holds-festive-flower-arrangement-with-bright-chrysanthemum-flowers_169016-51483.jpg?_wi=4", imageAlt: "Soft focus background image of various flowers", logoText: "Persik Flowers", copyrightText: "© 2024 Persik | All rights reserved", columns: [
{ title: "Shop", items: [{ label: "Bouquets", href: "#products" }, { label: "Arrangements", href: "#products" }, { label: "Gifts", href: "#products" }] },
{ title: "About Us", items: [{ label: "Our Story", href: "#about" }, { label: "Testimonials", href: "#testimonials" }, { label: "FAQ", href: "#faq" }] },
{ title: "Support", items: [{ label: "Contact", href: "#contact" }, { label: "Delivery Info", href: "https://example.com/delivery" }, { label: "Privacy Policy", href: "https://example.com/privacy" }] }
{ title: "Shop", items: [{ label: "Bouquets", href: "/shop" }, { label: "Arrangements", href: "/shop" }, { label: "Gifts", href: "/shop" }] },
{ title: "About Us", items: [{ label: "Our Story", href: "/#about" }, { label: "Testimonials", href: "/#testimonials" }] },
{ title: "Support", items: [{ label: "Contact", href: "/#contact" }, { label: "Delivery Info", href: "https://example.com/delivery" }, { label: "Privacy Policy", href: "https://example.com/privacy" }] }
]
};
if (isLoading) {
return (
<ThemeProvider
defaultButtonVariant="elastic-effect"
defaultTextAnimation="reveal-blur"
borderRadius="soft"
contentWidth="smallMedium"
sizing="mediumSizeLargeTitles"
background="none"
cardStyle="gradient-bordered"
primaryButtonStyle="diagonal-gradient"
secondaryButtonStyle="solid"
headingFontWeight="light"
>
<ReactLenis root>
<div id="navbar" data-section="navbar">
<NavbarStyleApple {...navbarProps} />
</div>
<main className="min-h-screen flex items-center justify-center pt-20">
<p className="text-foreground">Loading product...</p>
</main>
<div id="footer" data-section="footer">
<FooterMedia {...footerProps} />
</div>
</ReactLenis>
</ThemeProvider>
);
}
const renderContent = () => {
if (isLoading) {
return (
<main className="min-h-screen flex items-center justify-center pt-20">
<p className="text-foreground">Loading product...</p>
</main>
);
}
if (!product) {
return (
<main className="min-h-screen flex items-center justify-center pt-20">
<div className="text-center">
<p className="text-foreground mb-4">Product not found</p>
<button
onClick={() => router.push("/shop")}
className="primary-button px-6 py-2 rounded-theme"
>
Back to Shop
</button>
</div>
</main>
);
}
if (!product) {
return (
<ThemeProvider
defaultButtonVariant="elastic-effect"
defaultTextAnimation="reveal-blur"
borderRadius="soft"
contentWidth="smallMedium"
sizing="mediumSizeLargeTitles"
background="none"
cardStyle="gradient-bordered"
primaryButtonStyle="diagonal-gradient"
secondaryButtonStyle="solid"
headingFontWeight="light"
>
<ReactLenis root>
<div id="navbar" data-section="navbar">
<NavbarStyleApple {...navbarProps} />
</div>
<main className="min-h-screen flex items-center justify-center pt-20">
<div className="text-center">
<p className="text-foreground mb-4">Product not found</p>
<button
onClick={() => router.push("/shop")}
className="primary-button px-6 py-2 rounded-theme"
>
Back to Shop
</button>
</div>
</main>
<div id="footer" data-section="footer">
<FooterMedia {...footerProps} />
</div>
</ReactLenis>
</ThemeProvider>
<div id="product-detail" data-section="product-detail">
<FeatureCardTwentyOne
title={product.name}
description={product.description}
imageSrc={images[0]?.src || '/placeholders/placeholder1.webp'}
imageAlt={images[0]?.alt || product.name}
mediaPosition="left"
useInvertedBackground={false}
mediaAnimation="slide-up"
accordionItems={[
{ id: 'price', title: 'Price', content: product.price },
...(meta.sku ? [{ id: 'sku', title: 'SKU', content: meta.sku }] : []),
...(product.rating ? [{ id: 'rating', title: 'Rating', content: `${product.rating}/5` }] : []),
]}
buttons={[
{ text: "Add To Cart", onClick: handleAddToCart },
{ text: "Buy Now", onClick: handleBuyNow },
]}
/>
</div>
);
}
};
return (
<ThemeProvider
@@ -168,50 +158,26 @@ export default function ProductPage({ params }: ProductPageProps) {
secondaryButtonStyle="solid"
headingFontWeight="light"
>
<ReactLenis root>
<div id="navbar" data-section="navbar">
<NavbarStyleApple {...navbarProps} />
</div>
<div id="product-detail-card" data-section="product-detail-card">
<ProductDetailCard
layout="page"
name={product.name}
price={product.price}
salePrice={meta.salePrice}
rating={product.rating || 0}
description={product.description}
images={images}
variants={variants.length > 0 ? variants : undefined}
quantity={quantityVariant}
ribbon={meta.ribbon}
inventoryStatus={meta.inventoryStatus}
inventoryQuantity={meta.inventoryQuantity}
sku={meta.sku}
buttons={[
{ text: "Add To Cart", onClick: handleAddToCart },
{ text: "Buy Now", onClick: handleBuyNow },
]}
/>
</div>
<div id="product-cart" data-section="product-cart">
<ProductCart
isOpen={cartOpen}
onClose={() => setCartOpen(false)}
items={cartItems}
onQuantityChange={updateQuantity}
onRemove={removeItem}
total={`$${cartTotal}`}
buttons={[
{
text: isCheckoutLoading ? "Processing..." : "Check Out", onClick: handleCheckout,
},
]}
/>
</div>
<div id="footer" data-section="footer">
<FooterMedia {...footerProps} />
</div>
</ReactLenis>
<div id="nav" data-section="nav">
<NavbarStyleApple {...navbarProps} />
</div>
{renderContent()}
<ProductCart
isOpen={cartOpen}
onClose={() => setCartOpen(false)}
items={cartItems}
onQuantityChange={updateQuantity}
onRemove={removeItem}
total={`$${cartTotal}`}
buttons={[
{
text: isCheckoutLoading ? "Processing..." : "Check Out", onClick: handleCheckout,
},
]}
/>
<div id="footer" data-section="footer">
<FooterMedia {...footerProps} />
</div>
</ThemeProvider>
);
}

View File

@@ -1,23 +1,29 @@
"use client";
import React, { useCallback } from "react";
import ReactLenis from "lenis/react";
import { useRouter } from 'next/navigation';
import { ThemeProvider } from "@/providers/themeProvider/ThemeProvider";
import NavbarStyleApple from '@/components/navbar/NavbarStyleApple/NavbarStyleApple';
import FooterMedia from '@/components/sections/footer/FooterMedia';
import ProductCatalog from "@/components/ecommerce/productCatalog/ProductCatalog";
import ProductCardOne from "@/components/sections/product/ProductCardOne";
import ProductCart from "@/components/ecommerce/cart/ProductCart";
import { useProductCatalog } from "@/hooks/useProductCatalog";
import { useCart } from "@/hooks/useCart";
import { useCheckout } from "@/hooks/useCheckout";
const navItems = [
{ name: "Home", id: "/" },
{ name: "Products", id: "/shop" },
{ name: "About", id: "/#about" },
{ name: "Testimonials", id: "/#testimonials" },
{ name: "Contact", id: "/#contact" },
];
export default function ShopPage() {
const router = useRouter();
const {
products,
isLoading,
search,
setSearch,
filters,
} = useProductCatalog({ basePath: "/shop" });
const {
@@ -41,16 +47,17 @@ export default function ShopPage() {
await checkout(getCheckoutItems(), { successUrl: currentUrl.toString() });
}, [cartItems, checkout, getCheckoutItems]);
const cartCount = cartItems.length;
const navbarProps = {
brandName: "Persik", navItems: [{ name: "Home", id: "/" }, { name: "Shop", id: "/shop" }],
button: { text: "Cart", onClick: () => setCartOpen(true) },
brandName: "Persik", navItems: navItems,
button: { text: `Cart (${cartCount})`, onClick: () => setCartOpen(true) },
mobileNavContent: (
<div className="flex flex-col gap-2 mt-4">
<button
onClick={() => setCartOpen(true)}
className="w-full text-left p-2 rounded-md hover:bg-muted/50"
>
Cart
Cart ({cartCount})
</button>
</div>
)
@@ -58,41 +65,12 @@ export default function ShopPage() {
const footerProps = {
imageSrc: "https://img.b2bpic.net/free-photo/woman-holds-festive-flower-arrangement-with-bright-chrysanthemum-flowers_169016-51483.jpg?_wi=3", imageAlt: "Soft focus background image of various flowers", logoText: "Persik Flowers", copyrightText: "© 2024 Persik | All rights reserved", columns: [
{ title: "Shop", items: [{ label: "Bouquets", href: "#products" }, { label: "Arrangements", href: "#products" }, { label: "Gifts", href: "#products" }] },
{ title: "About Us", items: [{ label: "Our Story", href: "#about" }, { label: "Testimonials", href: "#testimonials" }, { label: "FAQ", href: "#faq" }] },
{ title: "Support", items: [{ label: "Contact", href: "#contact" }, { label: "Delivery Info", href: "https://example.com/delivery" }, { label: "Privacy Policy", href: "https://example.com/privacy" }] }
{ title: "Shop", items: [{ label: "Bouquets", href: "/shop" }, { label: "Arrangements", href: "/shop" }, { label: "Gifts", href: "/shop" }] },
{ title: "About Us", items: [{ label: "Our Story", href: "/#about" }, { label: "Testimonials", href: "/#testimonials" }] },
{ title: "Support", items: [{ label: "Contact", href: "/#contact" }, { label: "Delivery Info", href: "https://example.com/delivery" }, { label: "Privacy Policy", href: "https://example.com/privacy" }] }
]
};
if (isLoading) {
return (
<ThemeProvider
defaultButtonVariant="elastic-effect"
defaultTextAnimation="reveal-blur"
borderRadius="soft"
contentWidth="smallMedium"
sizing="mediumSizeLargeTitles"
background="none"
cardStyle="gradient-bordered"
primaryButtonStyle="diagonal-gradient"
secondaryButtonStyle="solid"
headingFontWeight="light"
>
<ReactLenis root>
<div id="navbar" data-section="navbar">
<NavbarStyleApple {...navbarProps} />
</div>
<main className="min-h-screen flex items-center justify-center pt-20">
<p className="text-foreground">Loading products...</p>
</main>
<div id="footer" data-section="footer">
<FooterMedia {...footerProps} />
</div>
</ReactLenis>
</ThemeProvider>
);
}
return (
<ThemeProvider
defaultButtonVariant="elastic-effect"
@@ -106,40 +84,49 @@ export default function ShopPage() {
secondaryButtonStyle="solid"
headingFontWeight="light"
>
<ReactLenis root>
<div id="navbar" data-section="navbar">
<NavbarStyleApple {...navbarProps} />
</div>
<div id="nav" data-section="nav">
<NavbarStyleApple {...navbarProps} />
</div>
{isLoading ? (
<main className="min-h-screen flex items-center justify-center pt-20">
<p className="text-foreground">Loading products...</p>
</main>
) : (
<div id="product-catalog" data-section="product-catalog">
<ProductCatalog
layout="page"
products={products}
searchValue={search}
onSearchChange={setSearch}
searchPlaceholder="Search products..."
filters={filters}
emptyMessage="No products found"
<ProductCardOne
title="Our Products"
description="Browse our collection of beautiful flowers."
products={products.map((p: any) => ({
id: p.id,
name: p.name,
price: p.price,
imageSrc: p.images?.[0]?.src || '/placeholders/placeholder1.webp',
imageAlt: p.images?.[0]?.alt || p.name,
onProductClick: () => router.push(`/shop/${p.id}`),
}))}
gridVariant="four-items-2x2-equal-grid"
animationType="slide-up"
textboxLayout="default"
useInvertedBackground={false}
/>
</div>
<div id="product-cart" data-section="product-cart">
<ProductCart
isOpen={cartOpen}
onClose={() => setCartOpen(false)}
items={cartItems}
onQuantityChange={updateQuantity}
onRemove={removeItem}
total={`$${cartTotal}`}
buttons={[
{
text: isCheckoutLoading ? "Processing..." : "Check Out", onClick: handleCheckout,
},
]}
/>
</div>
<div id="footer" data-section="footer">
<FooterMedia {...footerProps} />
</div>
</ReactLenis>
)}
<ProductCart
isOpen={cartOpen}
onClose={() => setCartOpen(false)}
items={cartItems}
onQuantityChange={updateQuantity}
onRemove={removeItem}
total={`$${cartTotal}`}
buttons={[
{
text: isCheckoutLoading ? "Processing..." : "Check Out", onClick: handleCheckout,
},
]}
/>
<div id="footer" data-section="footer">
<FooterMedia {...footerProps} />
</div>
</ThemeProvider>
);
}
}

View File

@@ -2,21 +2,21 @@
/* Base units */
/* --vw is set by ThemeProvider */
/* --background: #fffafa;;
--card: #fff7f7;;
--foreground: #1a0000;;
--primary-cta: #e63946;;
/* --background: #f5f5f5;;
--card: #ffffff;;
--foreground: #1c1c1c;;
--primary-cta: #159c49;;
--secondary-cta: #ffffff;;
--accent: #f5c4c7;;
--background-accent: #f09199;; */
--accent: #6139e6;;
--background-accent: #a8e8ba;; */
--background: #fffafa;;
--card: #fff7f7;;
--foreground: #1a0000;;
--primary-cta: #e63946;;
--background: #f5f5f5;;
--card: #ffffff;;
--foreground: #1c1c1c;;
--primary-cta: #159c49;;
--secondary-cta: #ffffff;;
--accent: #f5c4c7;;
--background-accent: #f09199;;
--accent: #6139e6;;
--background-accent: #a8e8ba;;
/* text sizing - set by ThemeProvider */
/* --text-2xs: clamp(0.465rem, 0.62vw, 0.62rem);