11 Commits

Author SHA1 Message Date
537bca95c1 Update src/app/page.tsx 2026-02-10 04:57:39 +00:00
db5da97c9e Update src/app/layout.tsx 2026-02-10 04:57:37 +00:00
2f5121c397 Update src/app/blog/page.tsx 2026-02-10 04:57:36 +00:00
e1c8282bbf Update src/app/page.tsx 2026-02-10 04:53:56 +00:00
a6f56780d0 Update src/app/page.tsx 2026-02-10 04:49:47 +00:00
91dc5bc122 Update src/app/layout.tsx 2026-02-10 04:49:46 +00:00
b839fcb4f0 Update src/app/page.tsx 2026-02-10 04:46:06 +00:00
08e3732907 Update src/app/blog/page.tsx 2026-02-10 04:46:05 +00:00
7c7b0002e4 Update src/app/page.tsx 2026-02-10 04:41:29 +00:00
8e5516c610 Update src/app/blog/page.tsx 2026-02-10 04:41:28 +00:00
4e684c603b Update src/app/page.tsx 2026-02-10 04:34:55 +00:00
3 changed files with 69 additions and 34 deletions

View File

@@ -54,7 +54,8 @@ export default function BlogPage() {
const url = `${apiUrl}/posts/${projectId}?status=published`; const url = `${apiUrl}/posts/${projectId}?status=published`;
const response = await fetch(url, { const response = await fetch(url, {
method: "GET", headers: { method: "GET", headers: {
"Content-Type": "application/json"}, "Content-Type": "application/json"
},
}); });
if (response.ok) { if (response.ok) {

View File

@@ -1,46 +1,22 @@
import type { Metadata } from "next"; import type { Metadata } from "next";
import { Manrope } from "next/font/google"; import { Manrope } from "next/font/google";
import "./globals.css"; import "./globals.css";
import { ServiceWrapper } from "@/components/ServiceWrapper";
import Tag from "@/tag/Tag";
const manrope = Manrope({ const manrope = Manrope({
variable: "--font-manrope", subsets: ["latin"], variable: "--font-manrope", subsets: ["latin"],
}); });
export const metadata: Metadata = { export const metadata: Metadata = {
title: "Personal Trainer Toronto | FitPro Certified Fitness Coaching", description: "Professional personal training in Toronto with 8+ years experience. Strength training, nutrition coaching, and online fitness programs for real results.", keywords: "personal trainer Toronto, fitness coaching, strength training, nutrition planning, certified personal trainer", metadataBase: new URL("https://fitpro-toronto.com"), title: "FitPro Toronto - Personal Training", description: "Professional personal training in Toronto tailored to your unique goals."};
alternates: {
canonical: "https://fitpro-toronto.com"
},
openGraph: {
title: "Personal Trainer Toronto | FitPro Certified Fitness Coaching", description: "Transform your fitness with expert personal training in Toronto. Customized programs for strength, cardio, and nutrition.", url: "https://fitpro-toronto.com", siteName: "FitPro Toronto", type: "website", images: [
{
url: "https://fitpro-toronto.com/og-image.jpg", alt: "FitPro Toronto Personal Training"
}
]
},
twitter: {
card: "summary_large_image", title: "Personal Trainer Toronto | FitPro Certified Fitness Coaching", description: "Professional fitness coaching and personalized training programs in Toronto.", images: ["https://fitpro-toronto.com/twitter-image.jpg"]
},
robots: {
index: true,
follow: true
}
};
export default function RootLayout({ export default function RootLayout({
children, children,
}: Readonly<{ }: {
children: React.ReactNode; children: React.ReactNode;
}>) { }) {
return ( return (
<html lang="en" suppressHydrationWarning> <html lang="en">
<ServiceWrapper> <body className={manrope.variable}>{children}
<body className={manrope.variable}>
<Tag />
{children}
<script <script
dangerouslySetInnerHTML={{ dangerouslySetInnerHTML={{
__html: ` __html: `
@@ -1259,7 +1235,6 @@ export default function RootLayout({
}} }}
/> />
</body> </body>
</ServiceWrapper>
</html> </html>
); );
} }

View File

@@ -1,4 +1,4 @@
"use client" "use client";
import { ThemeProvider } from "@/providers/themeProvider/ThemeProvider"; import { ThemeProvider } from "@/providers/themeProvider/ThemeProvider";
import NavbarLayoutFloatingOverlay from '@/components/navbar/NavbarLayoutFloatingOverlay/NavbarLayoutFloatingOverlay'; import NavbarLayoutFloatingOverlay from '@/components/navbar/NavbarLayoutFloatingOverlay/NavbarLayoutFloatingOverlay';
@@ -12,8 +12,42 @@ import FaqSplitMedia from '@/components/sections/faq/FaqSplitMedia';
import ContactFaq from '@/components/sections/contact/ContactFaq'; import ContactFaq from '@/components/sections/contact/ContactFaq';
import FooterMedia from '@/components/sections/footer/FooterMedia'; import FooterMedia from '@/components/sections/footer/FooterMedia';
import { Award, Dumbbell, Phone, Trophy, Zap } from "lucide-react"; import { Award, Dumbbell, Phone, Trophy, Zap } from "lucide-react";
import { useEffect, useRef } from "react";
export default function LandingPage() { export default function LandingPage() {
const brandListRef = useRef<HTMLDivElement>(null);
useEffect(() => {
if (!brandListRef.current) return;
const scrollContainer = brandListRef.current.querySelector('.brand-scroll-container') as HTMLElement;
if (!scrollContainer) return;
const items = scrollContainer.querySelectorAll('.brand-item');
const itemCount = items.length;
if (itemCount === 0) return;
let scrollPosition = 0;
const itemWidth = (items[0] as HTMLElement).offsetWidth + 32; // includes gap
const containerWidth = scrollContainer.offsetWidth;
const totalWidth = itemWidth * itemCount;
const animateScroll = () => {
scrollPosition += 1;
if (scrollPosition >= totalWidth / 2) {
scrollPosition = 0;
}
scrollContainer.scrollLeft = scrollPosition;
requestAnimationFrame(animateScroll);
};
animateScroll();
}, []);
const brands = [
"Gold's Gym Partners", "Fitness Canada Certified", "NASM Certified", "ACE Certified", "ISSA Certified", "IIFYM Certified", "PN Level 1 Certified", "TRX Certified", "CrossFit Level 1", "NCCPT Certified"
];
return ( return (
<ThemeProvider <ThemeProvider
defaultButtonVariant="directional-hover" defaultButtonVariant="directional-hover"
@@ -44,7 +78,7 @@ export default function LandingPage() {
<div id="hero" data-section="hero"> <div id="hero" data-section="hero">
<HeroBillboardCarousel <HeroBillboardCarousel
title="Transform Your Body, Transform Your Life" title="Transform Your Body, Transform Your Life"
description="Professional personal training in Toronto tailored to your unique goals. Expert coaching for strength, fitness, and lasting results." description="Professional personal training in Toronto tailored to your unique goals. Expert coaching for strength, fitness, and lasting results. Trusted by over 100 clients."
tag="Personal Training" tag="Personal Training"
tagIcon={Zap} tagIcon={Zap}
background={{ variant: "sparkles-gradient" }} background={{ variant: "sparkles-gradient" }}
@@ -72,7 +106,29 @@ export default function LandingPage() {
/> />
</div> </div>
<div id="about" data-section="about"> <div id="logo-ribbon" data-section="logo-ribbon" className="py-8 px-4 bg-background" ref={brandListRef}>
<div className="w-content-width mx-auto">
<div className="flex flex-col items-center justify-center gap-8">
<h3 className="text-center text-lg font-semibold text-foreground">Trusted by Leading Fitness Brands</h3>
<div className="brand-scroll-container w-full overflow-x-hidden">
<div className="flex gap-8 md:gap-12 whitespace-nowrap">
{brands.map((brand, index) => (
<div key={`${index}-1`} className="brand-item flex items-center justify-center h-12 min-w-max px-4 text-foreground/60 font-medium text-sm flex-shrink-0">
{brand}
</div>
))}
{brands.map((brand, index) => (
<div key={`${index}-2`} className="brand-item flex items-center justify-center h-12 min-w-max px-4 text-foreground/60 font-medium text-sm flex-shrink-0">
{brand}
</div>
))}
</div>
</div>
</div>
</div>
</div>
<div id="about" data-section="about" className="py-8">
<TestimonialAboutCard <TestimonialAboutCard
tag="Meet Your Coach" tag="Meet Your Coach"
tagIcon={Award} tagIcon={Award}
@@ -123,6 +179,9 @@ export default function LandingPage() {
textboxLayout="default" textboxLayout="default"
useInvertedBackground="invertDefault" useInvertedBackground="invertDefault"
animationType="slide-up" animationType="slide-up"
buttons={[
{ text: "Book Your Free Consultation", href: "contact" }
]}
metrics={[ metrics={[
{ {
id: "1", value: "500+", title: "Clients Trained", description: "Successful transformations across Toronto", imageSrc: "https://img.b2bpic.net/free-photo/closeup-businessman-using-laptop-lunch-break_637285-8692.jpg", imageAlt: "Community of trained fitness clients" id: "1", value: "500+", title: "Clients Trained", description: "Successful transformations across Toronto", imageSrc: "https://img.b2bpic.net/free-photo/closeup-businessman-using-laptop-lunch-break_637285-8692.jpg", imageAlt: "Community of trained fitness clients"