Merge version_1 into main #1
@@ -6,24 +6,17 @@ import { ServiceWrapper } from "@/components/ServiceWrapper";
|
||||
import Tag from "@/tag/Tag";
|
||||
|
||||
const notoSans = Noto_Sans({
|
||||
variable: "--font-noto-sans",
|
||||
subsets: ["latin"],
|
||||
variable: "--font-noto-sans", subsets: ["latin"],
|
||||
});
|
||||
|
||||
const inter = Inter({
|
||||
variable: "--font-inter",
|
||||
subsets: ["latin"],
|
||||
variable: "--font-inter", subsets: ["latin"],
|
||||
});
|
||||
|
||||
export const metadata: Metadata = {
|
||||
title: "McLaren Labs | Growth Consulting for Startups",
|
||||
description: "Growth partner for startups ready to scale. Strategy, systems, and results. We operate in the shadows so you can shine in the light.",
|
||||
keywords: ["growth consulting", "startup scaling", "growth strategy", "founder advisory", "startup growth partner"],
|
||||
title: "McLaren Labs | Growth Consulting for Startups", description: "Growth partner for startups ready to scale. Strategy, systems, and results. We operate in the shadows so you can shine in the light.", keywords: ["growth consulting", "startup scaling", "growth strategy", "founder advisory", "startup growth partner"],
|
||||
openGraph: {
|
||||
title: "McLaren Labs | Growth Consulting",
|
||||
description: "Growth partner for startups ready to scale.",
|
||||
siteName: "McLaren Labs",
|
||||
type: "website"
|
||||
title: "McLaren Labs | Growth Consulting", description: "Growth partner for startups ready to scale.", siteName: "McLaren Labs", type: "website"
|
||||
},
|
||||
robots: {
|
||||
index: true,
|
||||
|
||||
@@ -73,34 +73,16 @@ export default function HomePage() {
|
||||
tag="Case Studies"
|
||||
products={[
|
||||
{
|
||||
id: "1",
|
||||
brand: "Health Tech",
|
||||
name: "1.2M+ Downloads",
|
||||
price: "$74K → $3.5M ARR",
|
||||
rating: 5,
|
||||
reviewCount: "12 months",
|
||||
imageSrc: "https://img.b2bpic.net/free-vector/interface-goals-habits-tracking-application_23-2148632020.jpg",
|
||||
imageAlt: "mobile app health growth chart success"
|
||||
id: "1", brand: "Health Tech", name: "1.2M+ Downloads", price: "$74K → $3.5M ARR", rating: 5,
|
||||
reviewCount: "12 months", imageSrc: "https://img.b2bpic.net/free-vector/interface-goals-habits-tracking-application_23-2148632020.jpg", imageAlt: "mobile app health growth chart success"
|
||||
},
|
||||
{
|
||||
id: "2",
|
||||
brand: "SaaS Platform",
|
||||
name: "500% Revenue Growth",
|
||||
price: "$150K → $900K MRR",
|
||||
rating: 5,
|
||||
reviewCount: "18 months",
|
||||
imageSrc: "https://img.b2bpic.net/free-photo/business-leader-trader-searching-new-investment-solution_482257-116895.jpg",
|
||||
imageAlt: "saas dashboard analytics data software"
|
||||
id: "2", brand: "SaaS Platform", name: "500% Revenue Growth", price: "$150K → $900K MRR", rating: 5,
|
||||
reviewCount: "18 months", imageSrc: "https://img.b2bpic.net/free-photo/business-leader-trader-searching-new-investment-solution_482257-116895.jpg", imageAlt: "saas dashboard analytics data software"
|
||||
},
|
||||
{
|
||||
id: "3",
|
||||
brand: "Marketplace",
|
||||
name: "10x User Acquisition",
|
||||
price: "$2M → $20M GMV",
|
||||
rating: 5,
|
||||
reviewCount: "24 months",
|
||||
imageSrc: "https://img.b2bpic.net/free-photo/teammates-working-late-office_23-2148991369.jpg",
|
||||
imageAlt: "startup growth team collaboration scaling business"
|
||||
id: "3", brand: "Marketplace", name: "10x User Acquisition", price: "$2M → $20M GMV", rating: 5,
|
||||
reviewCount: "24 months", imageSrc: "https://img.b2bpic.net/free-photo/teammates-working-late-office_23-2148991369.jpg", imageAlt: "startup growth team collaboration scaling business"
|
||||
}
|
||||
]}
|
||||
gridVariant="three-columns-all-equal-width"
|
||||
@@ -133,23 +115,20 @@ export default function HomePage() {
|
||||
<FooterBaseReveal
|
||||
columns={[
|
||||
{
|
||||
title: "Company",
|
||||
items: [
|
||||
title: "Company", items: [
|
||||
{ label: "About", href: "about" },
|
||||
{ label: "Work", href: "case-studies" },
|
||||
{ label: "Contact", href: "contact" }
|
||||
]
|
||||
},
|
||||
{
|
||||
title: "Legal",
|
||||
items: [
|
||||
title: "Legal", items: [
|
||||
{ label: "Privacy Policy", href: "https://example.com/privacy" },
|
||||
{ label: "Terms of Service", href: "https://example.com/terms" }
|
||||
]
|
||||
},
|
||||
{
|
||||
title: "Connect",
|
||||
items: [
|
||||
title: "Connect", items: [
|
||||
{ label: "Twitter", href: "https://twitter.com" },
|
||||
{ label: "LinkedIn", href: "https://linkedin.com" }
|
||||
]
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
"use client";
|
||||
|
||||
import { use, useCallback } from "react";
|
||||
import { use, useCallback, useState } from "react";
|
||||
import { useRouter } from "next/navigation";
|
||||
import ReactLenis from "lenis/react";
|
||||
import { ThemeProvider } from "@/providers/themeProvider/ThemeProvider";
|
||||
@@ -19,6 +19,7 @@ interface ProductPageProps {
|
||||
export default function ProductPage({ params }: ProductPageProps) {
|
||||
const { id } = use(params);
|
||||
const router = useRouter();
|
||||
const [cartOpen, setCartOpen] = useState(false);
|
||||
|
||||
const {
|
||||
product,
|
||||
@@ -33,8 +34,8 @@ export default function ProductPage({ params }: ProductPageProps) {
|
||||
|
||||
const {
|
||||
items: cartItems,
|
||||
isOpen: cartOpen,
|
||||
setIsOpen: setCartOpen,
|
||||
isOpen: isCartOpen,
|
||||
setIsOpen: setIsCartOpen,
|
||||
addItem,
|
||||
updateQuantity,
|
||||
removeItem,
|
||||
@@ -236,17 +237,27 @@ export default function ProductPage({ params }: ProductPageProps) {
|
||||
logoHref="#"
|
||||
/>
|
||||
</div>
|
||||
<div id="productCatalog" data-section="productCatalog">
|
||||
<ProductCatalog
|
||||
layout="page"
|
||||
products={products}
|
||||
searchValue={search}
|
||||
onSearchChange={setSearch}
|
||||
searchPlaceholder="Search products..."
|
||||
filters={filters}
|
||||
emptyMessage="No products found"
|
||||
<div id="productDetail" data-section="productDetail">
|
||||
<ProductDetailCard
|
||||
product={product}
|
||||
images={images}
|
||||
meta={meta}
|
||||
variants={variants}
|
||||
quantityVariant={quantityVariant}
|
||||
onAddToCart={handleAddToCart}
|
||||
onBuyNow={handleBuyNow}
|
||||
/>
|
||||
</div>
|
||||
<ProductCart
|
||||
isOpen={isCartOpen}
|
||||
onClose={() => setIsCartOpen(false)}
|
||||
items={cartItems}
|
||||
onUpdateQuantity={updateQuantity}
|
||||
onRemoveItem={removeItem}
|
||||
total={cartTotal}
|
||||
onCheckout={handleCheckout}
|
||||
isLoading={isCheckoutLoading}
|
||||
/>
|
||||
<div id="footer" data-section="footer">
|
||||
<FooterBaseReveal
|
||||
columns={[
|
||||
@@ -261,7 +272,7 @@ export default function ProductPage({ params }: ProductPageProps) {
|
||||
title: "Legal", items: [
|
||||
{ label: "Privacy Policy", href: "https://example.com/privacy" },
|
||||
{ label: "Terms of Service", href: "https://example.com/terms" }
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
title: "Connect", items: [
|
||||
|
||||
@@ -6,6 +6,7 @@ import NavbarLayoutFloatingOverlay from '@/components/navbar/NavbarLayoutFloatin
|
||||
import ProductCatalog from "@/components/ecommerce/productCatalog/ProductCatalog";
|
||||
import FooterBaseReveal from '@/components/sections/footer/FooterBaseReveal';
|
||||
import { useProductCatalog } from "@/hooks/useProductCatalog";
|
||||
import { useState } from "react";
|
||||
|
||||
export default function ShopPage() {
|
||||
const {
|
||||
@@ -15,6 +16,8 @@ export default function ShopPage() {
|
||||
setSearch,
|
||||
filters,
|
||||
} = useProductCatalog({ basePath: "/shop" });
|
||||
|
||||
const [cartOpen, setCartOpen] = useState(false);
|
||||
|
||||
if (isLoading) {
|
||||
return (
|
||||
|
||||
Reference in New Issue
Block a user