Merge version_1 into main #2

Merged
bender merged 4 commits from version_1 into main 2026-02-21 00:15:12 +00:00
4 changed files with 61 additions and 46 deletions

View File

@@ -9,6 +9,15 @@ import { useBlogPosts } from "@/hooks/useBlogPosts";
export default function BlogPage() {
const { posts, isLoading } = useBlogPosts();
const navItems = [
{ name: "Home", id: "/" },
{ name: "Fence Types", id: "/#services" },
{ name: "Gallery", id: "/#gallery" },
{ name: "Reviews", id: "/#reviews" },
{ name: "FAQs", id: "/#faq" },
{ name: "Contact", id: "/#contact" },
];
return (
<ThemeProvider
defaultButtonVariant="shift-hover"
@@ -25,14 +34,7 @@ export default function BlogPage() {
<ReactLenis root>
<div id="nav" data-section="nav">
<NavbarStyleApple
navItems={[
{ name: "Home", id: "/" },
{ name: "Fence Types", id: "services" },
{ name: "Gallery", id: "gallery" },
{ name: "Reviews", id: "reviews" },
{ name: "FAQs", id: "faq" },
{ name: "Contact", id: "contact" },
]}
navItems={navItems}
brandName="Uptown Fence"
/>
</div>

View File

@@ -71,7 +71,7 @@ export default function LandingPage() {
speed={30}
tag="Uptown Fence Difference"
textboxLayout="default"
tagAnimation="entrance-slide"
tagAnimation="slide-up"
containerClassName="max-w-screen-xl mx-auto px-4 sm:px-6 lg:px-8"
textBoxTitleClassName="font-playfair-display text-4xl md:text-5xl lg:text-6xl text-center"
textBoxDescriptionClassName="font-inter text-center max-w-2xl mx-auto"
@@ -86,22 +86,22 @@ export default function LandingPage() {
products={[
{
id: "privacy-fences", brand: "Uptown Fence", name: "Privacy Fences (6'+)", price: "", rating: 5,
reviewCount: "★★★★★", imageSrc: "https://img.b2bpic.net/free-photo/wooden-trellis-overgrown-with-greenery-selective-focus-herbal-foliage-with-green-white-leaves-garden-trellis-background-screensaver-nature-banner_166373-2862.jpg?_wi=1", imageAlt: "Modern 6-foot privacy fence"},
reviewCount: "★★★★★", imageSrc: "https://img.b2bpic.net/free-photo/wooden-trellis-overgrown-with-greenery-selective-focus-herbal-foliage-with-green-white-leaves-garden-trellis-background-screensaver-nature-banner_166373-2862.jpg", imageAlt: "Modern 6-foot privacy fence"},
{
id: "chain-link-upgrades", brand: "Uptown Fence", name: "Chain Link Upgrades", price: "", rating: 5,
reviewCount: "★★★★★", imageSrc: "https://img.b2bpic.net/free-photo/runway-stadium_1417-1666.jpg", imageAlt: "Upgraded chain link fence"},
{
id: "gates-access", brand: "Uptown Fence", name: "Gates & Access", price: "", rating: 5,
reviewCount: "★★★★★", imageSrc: "https://img.b2bpic.net/free-photo/exterior-modern-residential-building_637285-1921.jpg?_wi=1", imageAlt: "Custom fence gate"},
reviewCount: "★★★★★", imageSrc: "https://img.b2bpic.net/free-photo/exterior-modern-residential-building_637285-1921.jpg", imageAlt: "Custom fence gate"},
{
id: "repairs-replacements", brand: "Uptown Fence", name: "Repairs & Replacements", price: "", rating: 5,
reviewCount: "★★★★★", imageSrc: "https://img.b2bpic.net/free-photo/man-protective-gloves-is-painting-wooden-fence-bright-summer-day_613910-17104.jpg", imageAlt: "Fence repair work"},
{
id: "hoa-associations", brand: "Uptown Fence", name: "HOA / Condo Associations", price: "", rating: 5,
reviewCount: "★★★★★", imageSrc: "https://img.b2bpic.net/free-photo/modern-wooden-fence-lush-green-hedge-garden-landscape_626616-510.jpg?_wi=1", imageAlt: "HOA fence installation"},
reviewCount: "★★★★★", imageSrc: "https://img.b2bpic.net/free-photo/modern-wooden-fence-lush-green-hedge-garden-landscape_626616-510.jpg", imageAlt: "HOA fence installation"},
{
id: "neighbor-sharing", brand: "Uptown Fence", name: "Neighbor-Sharing Projects", price: "", rating: 5,
reviewCount: "★★★★★", imageSrc: "https://img.b2bpic.net/free-photo/modern-wooden-fence-lush-green-hedge-garden-landscape_626616-510.jpg?_wi=2", imageAlt: "Shared fence project"},
reviewCount: "★★★★★", imageSrc: "https://img.b2bpic.net/free-photo/modern-wooden-fence-lush-green-hedge-garden-landscape_626616-510.jpg", imageAlt: "Shared fence project"},
]}
gridVariant="three-columns-all-equal-width"
animationType="slide-up"
@@ -127,7 +127,7 @@ export default function LandingPage() {
]}
useInvertedBackground={false}
buttons={[{ text: "Get a Free Estimate", href: "#contact" }]}
buttonAnimation="shift-hover"
buttonAnimation="slide-up"
containerClassName="max-w-screen-xl mx-auto px-4 sm:px-6 lg:px-8"
headingClassName="font-playfair-display text-4xl md:text-5xl lg:text-6xl"
buttonClassName="px-8 py-4"
@@ -141,23 +141,23 @@ export default function LandingPage() {
features={[
{
id: 1,
title: "Request an estimate", description: "Tell us your goals + timeline, and well get the ball rolling quickly.", phoneOne: { imageSrc: "https://img.b2bpic.net/free-vector/pack-flat-business-elements_23-2147555719.jpg?_wi=1", imageAlt: "Estimate request illustration" },
phoneTwo: { imageSrc: "https://img.b2bpic.net/free-vector/pack-flat-business-elements_23-2147555719.jpg?_wi=2", imageAlt: "Estimate request illustration" },
title: "Request an estimate", description: "Tell us your goals + timeline, and well get the ball rolling quickly.", phoneOne: { imageSrc: "https://img.b2bpic.net/free-vector/pack-flat-business-elements_23-2147555719.jpg", imageAlt: "Estimate request illustration" },
phoneTwo: { imageSrc: "https://img.b2bpic.net/free-vector/pack-flat-business-elements_23-2147555719.jpg", imageAlt: "Estimate request illustration" },
},
{
id: 2,
title: "On-site plan", description: "Measurements, options, and a clear, transparent quote with no hidden fees.", phoneOne: { imageSrc: "https://img.b2bpic.net/free-vector/flat-construction-landing-page_23-2148192933.jpg?_wi=1", imageAlt: "On-site plan illustration" },
phoneTwo: { imageSrc: "https://img.b2bpic.net/free-vector/flat-construction-landing-page_23-2148192933.jpg?_wi=2", imageAlt: "On-site plan illustration" },
title: "On-site plan", description: "Measurements, options, and a clear, transparent quote with no hidden fees.", phoneOne: { imageSrc: "https://img.b2bpic.net/free-vector/flat-construction-landing-page_23-2148192933.jpg", imageAlt: "On-site plan illustration" },
phoneTwo: { imageSrc: "https://img.b2bpic.net/free-vector/flat-construction-landing-page_23-2148192933.jpg", imageAlt: "On-site plan illustration" },
},
{
id: 3,
title: "Build day(s)", description: "Efficient installation with regular updates and minimal disruption to your property.", phoneOne: { imageSrc: "https://img.b2bpic.net/free-photo/full-shot-man-spraying-powder-paint_23-2149714280.jpg?_wi=1", imageAlt: "Build day illustration" },
phoneTwo: { imageSrc: "https://img.b2bpic.net/free-photo/full-shot-man-spraying-powder-paint_23-2149714280.jpg?_wi=2", imageAlt: "Build day illustration" },
title: "Build day(s)", description: "Efficient installation with regular updates and minimal disruption to your property.", phoneOne: { imageSrc: "https://img.b2bpic.net/free-photo/full-shot-man-spraying-powder-paint_23-2149714280.jpg", imageAlt: "Build day illustration" },
phoneTwo: { imageSrc: "https://img.b2bpic.net/free-photo/full-shot-man-spraying-powder-paint_23-2149714280.jpg", imageAlt: "Build day illustration" },
},
{
id: 4,
title: "Final walkthrough", description: "Details checked, site cleaned, ensuring everything is done right to your satisfaction.", phoneOne: { imageSrc: "https://img.b2bpic.net/free-vector/family-volunteers-planting-trees_74855-2387.jpg?_wi=1", imageAlt: "Final walkthrough illustration" },
phoneTwo: { imageSrc: "https://img.b2bpic.net/free-vector/family-volunteers-planting-trees_74855-2387.jpg?_wi=2", imageAlt: "Final walkthrough illustration" },
title: "Final walkthrough", description: "Details checked, site cleaned, ensuring everything is done right to your satisfaction.", phoneOne: { imageSrc: "https://img.b2bpic.net/free-vector/family-volunteers-planting-trees_74855-2387.jpg", imageAlt: "Final walkthrough illustration" },
phoneTwo: { imageSrc: "https://img.b2bpic.net/free-vector/family-volunteers-planting-trees_74855-2387.jpg", imageAlt: "Final walkthrough illustration" },
},
]}
showStepNumbers={true}
@@ -180,10 +180,10 @@ export default function LandingPage() {
{ id: "gallery-1", brand: "Uptown Fence", name: "Privacy Fence Detail", price: "", rating: 5, reviewCount: "Gallery", imageSrc: "https://img.b2bpic.net/free-photo/photo-wood-texture-pattern_58702-15951.jpg", imageAlt: "Detail of a newly installed privacy fence" },
{ id: "gallery-2", brand: "Uptown Fence", name: "Custom Gate Hardware", price: "", rating: 5, reviewCount: "Gallery", imageSrc: "https://img.b2bpic.net/free-photo/closeup-shot-metal-lock-wooden-door_181624-15663.jpg", imageAlt: "Close-up of custom gate hardware" },
{ id: "gallery-3", brand: "Uptown Fence", name: "Seamless Corner Joint", price: "", rating: 5, reviewCount: "Gallery", imageSrc: "https://img.b2bpic.net/free-photo/green-ivy-leaves-sprouting-from-wooden-old-garden-fence-old-wooden-planks-red-brick-walls-covered-with-green-leaves-natural-background-texture_166373-1636.jpg", imageAlt: "Perfectly constructed fence corner" },
{ id: "gallery-4", brand: "Uptown Fence", name: "Modern Backyard Fence", price: "", rating: 5, reviewCount: "Gallery", imageSrc: "https://img.b2bpic.net/free-photo/modern-wooden-fence-lush-green-hedge-garden-landscape_626616-510.jpg?_wi=3", imageAlt: "Wide shot of a modern backyard fence" },
{ id: "gallery-4", brand: "Uptown Fence", name: "Modern Backyard Fence", price: "", rating: 5, reviewCount: "Gallery", imageSrc: "https://img.b2bpic.net/free-photo/modern-wooden-fence-lush-green-hedge-garden-landscape_626616-510.jpg", imageAlt: "Wide shot of a modern backyard fence" },
{ id: "gallery-5", brand: "Uptown Fence", name: "Chain Link (Before)", price: "", rating: 5, reviewCount: "Gallery", imageSrc: "https://img.b2bpic.net/free-photo/photo-chain-stone_58702-13289.jpg", imageAlt: "Before photo of old chain link fence" },
{ id: "gallery-6", brand: "Uptown Fence", name: "Privacy Upgrade (After)", price: "", rating: 5, reviewCount: "Gallery", imageSrc: "https://img.b2bpic.net/free-photo/wooden-trellis-overgrown-with-greenery-selective-focus-herbal-foliage-with-green-white-leaves-garden-trellis-background-screensaver-nature-banner_166373-2862.jpg?_wi=2", imageAlt: "After photo of chain link to privacy fence upgrade" },
{ id: "gallery-7", brand: "Uptown Fence", name: "Residential Gate Entrance", price: "", rating: 5, reviewCount: "Gallery", imageSrc: "https://img.b2bpic.net/free-photo/exterior-modern-residential-building_637285-1921.jpg?_wi=2", imageAlt: "Grand residential gate entrance" },
{ id: "gallery-6", brand: "Uptown Fence", name: "Privacy Upgrade (After)", price: "", rating: 5, reviewCount: "Gallery", imageSrc: "https://img.b2bpic.net/free-photo/wooden-trellis-overgrown-with-greenery-selective-focus-herbal-foliage-with-green-white-leaves-garden-trellis-background-screensaver-nature-banner_166373-2862.jpg", imageAlt: "After photo of chain link to privacy fence upgrade" },
{ id: "gallery-7", brand: "Uptown Fence", name: "Residential Gate Entrance", price: "", rating: 5, reviewCount: "Gallery", imageSrc: "https://img.b2bpic.net/free-photo/exterior-modern-residential-building_637285-1921.jpg", imageAlt: "Grand residential gate entrance" },
{ id: "gallery-8", brand: "Uptown Fence", name: "Clean Job Site", price: "", rating: 5, reviewCount: "Gallery", imageSrc: "https://img.b2bpic.net/free-photo/male-gardener-guiding-her-friend-water-plant-with-hose_23-2148165202.jpg", imageAlt: "Clean and organized fence job site" },
{ id: "gallery-9", brand: "Uptown Fence", name: "Decorative Post Caps", price: "", rating: 5, reviewCount: "Gallery", imageSrc: "https://img.b2bpic.net/free-photo/shiny-color-beautiful-part-modern_1328-185.jpg", imageAlt: "Detail of modern fence post caps" },
{ id: "gallery-10", brand: "Uptown Fence", name: "Long Straight Runs", price: "", rating: 5, reviewCount: "Gallery", imageSrc: "https://img.b2bpic.net/free-photo/field-green-grass-with-wooden-posts-shape-pyramid_181624-19390.jpg", imageAlt: "Long, perfectly straight fence line" }
@@ -210,12 +210,12 @@ export default function LandingPage() {
title="Neighbors Dont Just Like Uptown Fence—They Recommend It."
description=""
testimonials={[
{ id: "1", name: "Sarah Johnson", role: "Homeowner", testimonial: "Professional, hardworking, amazing work. Our new fence is beyond expectations.", imageSrc: "https://img.b2bpic.net/free-vector/modern-quotes-template-line-style_1017-27410.jpg?_wi=1", imageAlt: "Quote icon" },
{ id: "2", name: "Michael Chen", role: "Resident", testimonial: "Every request was heard and delivered. Kyle truly cares about the details.", imageSrc: "https://img.b2bpic.net/free-vector/modern-quotes-template-line-style_1017-27410.jpg?_wi=2", imageAlt: "Quote icon" },
{ id: "3", name: "Emily Rodriguez", role: "Property Manager", testimonial: "Upfront, honest, communicated every step. The process was seamless and stress-free.", imageSrc: "https://img.b2bpic.net/free-vector/modern-quotes-template-line-style_1017-27410.jpg?_wi=3", imageAlt: "Quote icon" },
{ id: "4", name: "David Kim", role: "Homeowner", testimonial: "Fair pricing and phenomenal job. Couldn't be happier with the results.", imageSrc: "https://img.b2bpic.net/free-vector/modern-quotes-template-line-style_1017-27410.jpg?_wi=4", imageAlt: "Quote icon" },
{ id: "5", name: "Jessica Lee", role: "Client", testimonial: "Impeccable attention to detail. The fence looks absolutely stunning and solid.", imageSrc: "https://img.b2bpic.net/free-vector/modern-quotes-template-line-style_1017-27410.jpg?_wi=5", imageAlt: "Quote icon" },
{ id: "6", name: "Chris White", role: "Resident", testimonial: "Finished in two days—looks amazing. The speed and quality were impressive.", imageSrc: "https://img.b2bpic.net/free-vector/modern-quotes-template-line-style_1017-27410.jpg?_wi=6", imageAlt: "Quote icon" },
{ id: "1", name: "Sarah Johnson", role: "Homeowner", testimonial: "Professional, hardworking, amazing work. Our new fence is beyond expectations.", imageSrc: "https://img.b2bpic.net/free-vector/modern-quotes-template-line-style_1017-27410.jpg", imageAlt: "Quote icon" },
{ id: "2", name: "Michael Chen", role: "Resident", testimonial: "Every request was heard and delivered. Kyle truly cares about the details.", imageSrc: "https://img.b2bpic.net/free-vector/modern-quotes-template-line-style_1017-27410.jpg", imageAlt: "Quote icon" },
{ id: "3", name: "Emily Rodriguez", role: "Property Manager", testimonial: "Upfront, honest, communicated every step. The process was seamless and stress-free.", imageSrc: "https://img.b2bpic.net/free-vector/modern-quotes-template-line-style_1017-27410.jpg", imageAlt: "Quote icon" },
{ id: "4", name: "David Kim", role: "Homeowner", testimonial: "Fair pricing and phenomenal job. Couldn't be happier with the results.", imageSrc: "https://img.b2bpic.net/free-vector/modern-quotes-template-line-style_1017-27410.jpg", imageAlt: "Quote icon" },
{ id: "5", name: "Jessica Lee", role: "Client", testimonial: "Impeccable attention to detail. The fence looks absolutely stunning and solid.", imageSrc: "https://img.b2bpic.net/free-vector/modern-quotes-template-line-style_1017-27410.jpg", imageAlt: "Quote icon" },
{ id: "6", name: "Chris White", role: "Resident", testimonial: "Finished in two days—looks amazing. The speed and quality were impressive.", imageSrc: "https://img.b2bpic.net/free-vector/modern-quotes-template-line-style_1017-27410.jpg", imageAlt: "Quote icon" },
]}
animationType="slide-up"
useInvertedBackground={false}

View File

@@ -51,6 +51,15 @@ function ProductPageContent({ params }: ProductPageProps) {
const { buyNow, checkout, isLoading: isCheckoutLoading } = useCheckout();
const navItems = [
{ name: "Home", id: "/" },
{ name: "Fence Types", id: "/#services" },
{ name: "Gallery", id: "/#gallery" },
{ name: "Reviews", id: "/#reviews" },
{ name: "FAQs", id: "/#faq" },
{ name: "Contact", id: "/#contact" },
];
const handleAddToCart = useCallback(() => {
const item = createCartItem();
if (item) {
@@ -88,11 +97,10 @@ function ProductPageContent({ params }: ProductPageProps) {
headingFontWeight="extrabold"
>
<ReactLenis root>
<div id="navbar" data-section="navbar">
<div id="nav" data-section="nav">
<NavbarStyleApple
navItems={[{ "name": "Home", "id": "/" }, { "name": "Fence Types", "id": "services" }, { "name": "Gallery", "id": "gallery" }, { "name": "Reviews", "id": "reviews" }, { "name": "FAQs", "id": "faq" }, { "name": "Contact", "id": "contact" }, { "name": "Shop", "id": "/shop" }]}
navItems={navItems}
brandName="Uptown Fence"
button={{ text: "Cart", onClick: () => setCartOpen(true) }}
/>
</div>
<div id="loading-state" data-section="loading-state">
@@ -120,11 +128,10 @@ function ProductPageContent({ params }: ProductPageProps) {
headingFontWeight="extrabold"
>
<ReactLenis root>
<div id="navbar" data-section="navbar">
<div id="nav" data-section="nav">
<NavbarStyleApple
navItems={[{ "name": "Home", "id": "/" }, { "name": "Fence Types", "id": "services" }, { "name": "Gallery", "id": "gallery" }, { "name": "Reviews", "id": "reviews" }, { "name": "FAQs", "id": "faq" }, { "name": "Contact", "id": "contact" }, { "name": "Shop", "id": "/shop" }]}
navItems={navItems}
brandName="Uptown Fence"
button={{ text: "Cart", onClick: () => setCartOpen(true) }}
/>
</div>
<div id="not-found-state" data-section="not-found-state">
@@ -159,11 +166,10 @@ function ProductPageContent({ params }: ProductPageProps) {
headingFontWeight="extrabold"
>
<ReactLenis root>
<div id="navbar" data-section="navbar">
<div id="nav" data-section="nav">
<NavbarStyleApple
navItems={[{ "name": "Home", "id": "/" }, { "name": "Fence Types", "id": "services" }, { "name": "Gallery", "id": "gallery" }, { "name": "Reviews", "id": "reviews" }, { "name": "FAQs", "id": "faq" }, { "name": "Contact", "id": "contact" }, { "name": "Shop", "id": "/shop" }]}
navItems={navItems}
brandName="Uptown Fence"
button={{ text: "Cart", onClick: () => setCartOpen(true) }}
/>
</div>
<div id="product-detail-card" data-section="product-detail-card">

View File

@@ -18,6 +18,15 @@ export default function ShopPage() {
const { setIsOpen: setCartOpen } = useCart();
const navItems = [
{ name: "Home", id: "/" },
{ name: "Fence Types", id: "/#services" },
{ name: "Gallery", id: "/#gallery" },
{ name: "Reviews", id: "/#reviews" },
{ name: "FAQs", id: "/#faq" },
{ name: "Contact", id: "/#contact" },
];
if (isLoading) {
return (
<ThemeProvider
@@ -33,11 +42,10 @@ export default function ShopPage() {
headingFontWeight="extrabold"
>
<ReactLenis root>
<div id="navbar" data-section="navbar">
<div id="nav" data-section="nav">
<NavbarStyleApple
navItems={[{ "name": "Home", "id": "/" }, { "name": "Fence Types", "id": "services" }, { "name": "Gallery", "id": "gallery" }, { "name": "Reviews", "id": "reviews" }, { "name": "FAQs", "id": "faq" }, { "name": "Contact", "id": "contact" }, { "name": "Shop", "id": "/shop" }]}
navItems={navItems}
brandName="Uptown Fence"
button={{ text: "Cart", onClick: () => setCartOpen(true) }}
/>
</div>
<div id="loading-state" data-section="loading-state">
@@ -64,11 +72,10 @@ export default function ShopPage() {
headingFontWeight="extrabold"
>
<ReactLenis root>
<div id="navbar" data-section="navbar">
<div id="nav" data-section="nav">
<NavbarStyleApple
navItems={[{ "name": "Home", "id": "/" }, { "name": "Fence Types", "id": "services" }, { "name": "Gallery", "id": "gallery" }, { "name": "Reviews", "id": "reviews" }, { "name": "FAQs", "id": "faq" }, { "name": "Contact", "id": "contact" }, { "name": "Shop", "id": "/shop" }]}
navItems={navItems}
brandName="Uptown Fence"
button={{ text: "Cart", onClick: () => setCartOpen(true) }}
/>
</div>
<div id="product-catalog" data-section="product-catalog">