inner pages updated
@ -1,63 +1,93 @@
|
|||||||
|
"use client";
|
||||||
|
|
||||||
import Link from 'next/link';
|
import Link from 'next/link';
|
||||||
import Image from 'next/image';
|
import Image from 'next/image';
|
||||||
|
import { useState, useEffect } from 'react';
|
||||||
|
|
||||||
export default function AboutPage() {
|
export default function AboutPage() {
|
||||||
|
const [testIndex, setTestIndex] = useState(0);
|
||||||
|
const [openFaq, setOpenFaq] = useState<number | null>(null);
|
||||||
|
|
||||||
|
const testimonials = [
|
||||||
|
{ quote: "VG Fence consistently delivers high-quality materials on time. Their contractor pricing allows me to stay competitive, and their inventory is unmatched.", author: "Mark S.", role: "Local Fence Contractor" },
|
||||||
|
{ quote: "Their galvanized and black finish railings are top-notch. It's rare to find a supplier that combines durability with such an aesthetic appeal.", author: "Sarah L.", role: "Property Manager" },
|
||||||
|
{ quote: "The team at VG Fence is incredibly knowledgeable. They helped us select the right ornamental fencing for our latest residential development.", author: "David K.", role: "Construction Manager" }
|
||||||
|
];
|
||||||
|
|
||||||
|
const nextTestimonial = () => setTestIndex((prev) => (prev + 1) % testimonials.length);
|
||||||
|
const prevTestimonial = () => setTestIndex((prev) => (prev - 1 + testimonials.length) % testimonials.length);
|
||||||
|
|
||||||
|
const faqs = [
|
||||||
|
{ question: "Do you offer contractor pricing?", answer: "Yes! We provide dedicated contractor accounts with specialized pricing. You need to create an account and verify your business details to unlock these rates." },
|
||||||
|
{ question: "Do you offer installation services?", answer: "While our primary focus is supplying high-quality materials, we do provide installation support for select projects based on their size and scope." },
|
||||||
|
{ question: "Where are your materials sourced from?", answer: "We source professional-grade materials focused on durability, specifically suited for Canada's diverse climate, including robust galvanized and black finish options." },
|
||||||
|
{ question: "Do you offer delivery across Ontario?", answer: "Yes, we provide reliable delivery services across Ontario for both residential and commercial projects. Delivery times depend on the order size and location." },
|
||||||
|
{ question: "Can I order custom gate sizes?", answer: "Absolutely. We specialize in custom gate fabrication. You can provide us with your specific dimensions and requirements, and we will manufacture them to fit your project perfectly." },
|
||||||
|
];
|
||||||
|
|
||||||
|
// Auto-slide effect
|
||||||
|
useEffect(() => {
|
||||||
|
const interval = setInterval(() => {
|
||||||
|
nextTestimonial();
|
||||||
|
}, 5000); // Change slide every 5 seconds
|
||||||
|
|
||||||
|
return () => clearInterval(interval);
|
||||||
|
}, [testIndex]); // Reset timer when index changes (manual navigation)
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div style={{ minHeight: '100vh', background: 'var(--white)' }}>
|
<div className="about-page-wrapper">
|
||||||
{/* Inner Banner */}
|
{/* Inner Banner */}
|
||||||
<section className="hero" style={{ minHeight: '350px', display: 'flex', alignItems: 'center', paddingTop: '130px' }}>
|
<section className="inner-banner fade-up">
|
||||||
<div className="hero-pattern"></div>
|
<div className="inner-banner-content">
|
||||||
<div className="hero-left" style={{ padding: '0', width: '100%' }}>
|
<h1 className="section-h2">Your Trusted <span>Fencing</span> Partner</h1>
|
||||||
<div className="hero-eyebrow">About VG Fence</div>
|
<div className="banner-breadcrumb" style={{ marginTop: '30px', marginBottom: '0' }}>
|
||||||
<h1 className="hero-h1" style={{ marginBottom: '16px' }}>Your Trusted <em>Fencing</em> Partner.</h1>
|
<Link href="/">
|
||||||
<p className="hero-sub" style={{ maxWidth: '600px', marginBottom: '0' }}>
|
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><path d="m3 9 9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z"/><polyline points="9 22 9 12 15 12 15 22"/></svg>
|
||||||
Ontario's dedicated supplier for professional-grade fencing and railing materials.
|
Home
|
||||||
Reliability built with every post and panel.
|
</Link>
|
||||||
</p>
|
<span className="separator">/</span>
|
||||||
|
<span>About Us</span>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
{/* Our Story Section */}
|
{/* Our Story Section */}
|
||||||
<section className="section">
|
<section className="about-section section">
|
||||||
<div className="container" style={{ maxWidth: '1200px', margin: '0 auto', padding: '0 20px' }}>
|
<div className="container about-story-container">
|
||||||
<div style={{ display: 'grid', gridTemplateColumns: '1.2fr 1fr', gap: '80px', alignItems: 'center' }} className="about-layout">
|
<div className="about-story-layout">
|
||||||
<div>
|
<div>
|
||||||
<div className="section-eyebrow">Our Story</div>
|
<div className="section-eyebrow">Our Story</div>
|
||||||
<h2 className="section-h2" style={{ marginBottom: '32px' }}>A Reputation Built on <span>Reliability.</span></h2>
|
<h2 className="section-h2 about-story-h2">Your Trusted <span>Fencing </span>Partner</h2>
|
||||||
<div style={{ fontSize: '17px', color: 'var(--gray-600)', lineHeight: 1.8, display: 'flex', flexDirection: 'column', gap: '20px' }}>
|
<div className="about-story-text">
|
||||||
<p>
|
<p>
|
||||||
At VG Fence, we are dedicated to providing high-quality fencing and railing materials to contractors,
|
At VG Fence, we are dedicated to providing high-quality fencing and railing materials to contractors, property managers, event organizers, and homeowners. With years of experience in the industry, we have built a reputation as a reliable supplier for both commercial and residential projects.
|
||||||
property managers, event organizers, and homeowners. With years of experience in the industry,
|
|
||||||
we have built a reputation as a reliable supplier for both commercial and residential projects.
|
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
We stock and supply a comprehensive range of fence products, including chain link fences,
|
We stock and supply a comprehensive range of fence products, including chain link fences, temporary fencing, ornamental fences, wood fence hardware, gates, railings, deck products, and privacy screens. All our materials are available in galvanized and black finishes, ensuring durability and long-lasting performance.
|
||||||
temporary fencing, ornamental fences, wood fence hardware, gates, railings, deck products,
|
|
||||||
and privacy screens.
|
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
All our materials are available in galvanized and black finishes, ensuring durability
|
While our focus is primarily on material supply, we also provide installation support for select projects, based on size and scope.
|
||||||
and long-lasting performance in Canada's diverse climate.
|
|
||||||
</p>
|
|
||||||
<p style={{ fontStyle: 'italic', color: 'var(--gray-500)', fontSize: '15px' }}>
|
|
||||||
While our focus is primarily on material supply, we also provide installation support for
|
|
||||||
select projects, based on size and scope.
|
|
||||||
</p>
|
</p>
|
||||||
|
<div style={{ marginTop: '40px' }}>
|
||||||
|
<Link href="/products" className="btn-primary">Learn More</Link>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div style={{ position: 'relative' }}>
|
<div className="about-image-column">
|
||||||
<div style={{ position: 'relative', width: '100%', height: '500px', borderRadius: '20px', overflow: 'hidden', boxShadow: '0 30px 60px rgba(0,0,0,.1)' }}>
|
<div className="about-image-wrapper">
|
||||||
<Image
|
<Image
|
||||||
src="/placeholder.jpg"
|
src="/assets/about-fencing.png"
|
||||||
alt="Quality Fencing"
|
alt="Quality modern fencing in a beautiful garden"
|
||||||
fill
|
fill
|
||||||
style={{ objectFit: 'cover' }}
|
className="about-image-cover"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div style={{ position: 'absolute', bottom: '-30px', left: '-30px', background: 'var(--navy)', padding: '32px', borderRadius: '12px', color: 'var(--white)', maxWidth: '280px', zIndex: 2 }}>
|
<div className="floating-card about-floating-card" style={{ padding: '30px', maxWidth: '450px' }}>
|
||||||
<div style={{ fontSize: '40px', fontWeight: 800, color: 'var(--orange)', marginBottom: '8px', fontFamily: 'var(--font-display)' }}>100%</div>
|
<div className="section-eyebrow" style={{ color: 'var(--orange)', marginBottom: '12px' }}>Our Mission</div>
|
||||||
<div style={{ fontSize: '13px', fontWeight: 600, textTransform: 'uppercase', letterSpacing: '.1em', lineHeight: 1.4 }}>Professional Grade Materials In Stock</div>
|
<div className="about-floating-card-text" style={{ fontSize: '15px', lineHeight: '1.6', fontWeight: '500' }}>
|
||||||
|
To supply premium fencing and railing materials that combine quality, durability, and convenience, helping every project — large or small — succeed.
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -65,78 +95,84 @@ export default function AboutPage() {
|
|||||||
</section>
|
</section>
|
||||||
|
|
||||||
{/* Mission Section */}
|
{/* Mission Section */}
|
||||||
<section className="section" style={{ background: 'var(--cream)' }}>
|
{/* <section className="section about-mission-section">
|
||||||
<div className="container" style={{ maxWidth: '800px', margin: '0 auto', padding: '0 20px', textAlign: 'center' }}>
|
<div className="container about-mission-container">
|
||||||
<div className="section-eyebrow" style={{ margin: '0 auto 16px', justifyContent: 'center' }}>Our Mission</div>
|
<div className="section-eyebrow about-mission-eyebrow">Our Mission</div>
|
||||||
<h2 className="section-h2" style={{ marginBottom: '32px' }}>Empowering <span>Success.</span></h2>
|
<h2 className="section-h2 about-mission-h2">Empowering <span>Success.</span></h2>
|
||||||
<div style={{ background: 'var(--white)', padding: '64px 15px', borderRadius: '20px', boxShadow: '0 10px 30px rgba(0,0,0,.03)' }}>
|
<div className="about-mission-card">
|
||||||
<p style={{ fontSize: '24px', color: 'var(--navy)', lineHeight: 1.6, fontWeight: 500, fontFamily: 'var(--font-body)' }}>
|
<p className="about-mission-text">
|
||||||
"To supply premium fencing and railing materials that combine quality, durability, and convenience,
|
"To supply premium fencing and railing materials that combine quality, durability, and convenience,
|
||||||
helping every project — large or small — succeed."
|
helping every project — large or small — succeed."
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section> */}
|
||||||
|
|
||||||
{/* Testimonial Section */}
|
{/* Testimonial Section (Slider) */}
|
||||||
<section className="section testimonials-section">
|
<section className="section testimonials-section">
|
||||||
<div className="container" style={{ maxWidth: '1200px', margin: '0 auto', padding: '0 20px', textAlign: 'center' }}>
|
<div className="container about-testimonial-container">
|
||||||
<div className="section-eyebrow" style={{ margin: '0 auto 16px', justifyContent: 'center' }}>Testimonials</div>
|
<div className="section-eyebrow about-testimonial-eyebrow">Testimonials</div>
|
||||||
<h2 className="section-h2" style={{ color: 'var(--white)' }}>What Our Partners <span>Say.</span></h2>
|
<h2 className="section-h2 about-testimonial-h2">What Our Partners <span>Say.</span></h2>
|
||||||
|
|
||||||
<div className="testimonials-grid">
|
<div className="testimonials-slider">
|
||||||
<div className="testimonial-card">
|
<div className="slider-inner" style={{ transform: `translateX(-${testIndex * 100}%)` }}>
|
||||||
<div className="testimonial-quote">"VG Fence consistently delivers high-quality materials on time. Their contractor pricing allows me to stay competitive, and their inventory is unmatched."</div>
|
{testimonials.map((test, idx) => (
|
||||||
<div className="testimonial-author">Mark S.</div>
|
<div className="slide" key={idx}>
|
||||||
<div className="testimonial-role">Local Fence Contractor</div>
|
<div className="testimonial-card about-testimonial-card-inner">
|
||||||
|
<div className="testimonial-quote about-testimonial-quote">{test.quote}</div>
|
||||||
|
<div className="testimonial-author about-testimonial-author">{test.author}</div>
|
||||||
|
<div className="testimonial-role about-testimonial-role">{test.role}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
</div>
|
</div>
|
||||||
<div className="testimonial-card">
|
<div className="slider-controls">
|
||||||
<div className="testimonial-quote">"Their galvanized and black finish railings are top-notch. It's rare to find a supplier that combines durability with such an aesthetic appeal."</div>
|
<button className="slider-btn" onClick={prevTestimonial}>←</button>
|
||||||
<div className="testimonial-author">Sarah L.</div>
|
<button className="slider-btn" onClick={nextTestimonial}>→</button>
|
||||||
<div className="testimonial-role">Property Manager</div>
|
|
||||||
</div>
|
|
||||||
<div className="testimonial-card">
|
|
||||||
<div className="testimonial-quote">"The team at VG Fence is incredibly knowledgeable. They helped us select the right ornamental fencing for our latest residential development."</div>
|
|
||||||
<div className="testimonial-author">David K.</div>
|
|
||||||
<div className="testimonial-role">Construction Manager</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
{/* FAQ Section */}
|
{/* FAQ Section (Accordion) */}
|
||||||
<section className="section faq-section">
|
<section className="section faq-section">
|
||||||
<div className="container" style={{ maxWidth: '1200px', margin: '0 auto', padding: '0 20px', textAlign: 'center' }}>
|
<div className="container about-faq-container">
|
||||||
<div className="section-eyebrow" style={{ margin: '0 auto 16px', justifyContent: 'center' }}>FAQ</div>
|
<div className="section-eyebrow about-faq-eyebrow">FAQ</div>
|
||||||
<h2 className="section-h2">Frequently Asked <span>Questions.</span></h2>
|
<h2 className="section-h2 about-faq-h2">Frequently Asked <span>Questions.</span></h2>
|
||||||
|
|
||||||
<div className="faq-list" style={{ textAlign: 'left' }}>
|
<div className="faq-accordion">
|
||||||
<div className="faq-item">
|
{faqs.map((faq, idx) => (
|
||||||
<div className="faq-question">Do you offer contractor pricing?</div>
|
<div className="faq-item" key={idx}>
|
||||||
<div className="faq-answer">Yes! We provide dedicated contractor accounts with specialized pricing. You need to create an account and verify your business details to unlock these rates.</div>
|
<div
|
||||||
</div>
|
className="faq-header"
|
||||||
<div className="faq-item">
|
onClick={() => setOpenFaq(openFaq === idx ? null : idx)}
|
||||||
<div className="faq-question">Do you offer installation services?</div>
|
>
|
||||||
<div className="faq-answer">While our primary focus is supplying high-quality materials, we do provide installation support for select projects based on their size and scope.</div>
|
<div className="faq-question">{faq.question}</div>
|
||||||
</div>
|
<div className={`faq-icon ${openFaq === idx ? 'open' : ''}`}>
|
||||||
<div className="faq-item">
|
▾
|
||||||
<div className="faq-question">Where are your materials sourced from?</div>
|
</div>
|
||||||
<div className="faq-answer">We source professional-grade materials focused on durability, specifically suited for Canada's diverse climate, including robust galvanized and black finish options.</div>
|
</div>
|
||||||
</div>
|
<div className={`faq-answer-collapse ${openFaq === idx ? 'open' : ''}`}>
|
||||||
|
<div className="faq-answer-inner">
|
||||||
|
{faq.answer}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
{/* CTA Section */}
|
{/* CTA Section */}
|
||||||
<section className="cta-section section-padding" style={{ textAlign: 'center', background: 'var(--navy)', color: 'var(--white)' }}>
|
{/* <section className="cta-section section-padding about-cta-section">
|
||||||
<h2 className="cta-h2">Ready to <span>Build?</span></h2>
|
<h2 className="cta-h2">Ready to <span>Build?</span></h2>
|
||||||
<p className="cta-sub" style={{ opacity: .7 }}>Explore Ontario's most reliable inventory of fencing products.</p>
|
<p className="cta-sub about-cta-sub">Explore Ontario's most reliable inventory of fencing products.</p>
|
||||||
<div className="cta-btns">
|
<div className="cta-btns">
|
||||||
<Link href="/products" className="btn-primary">View Full Catalog</Link>
|
<Link href="/products" className="btn-primary">View Full Catalog</Link>
|
||||||
<Link href="/contact" className="btn-white-outline">Contact Us</Link>
|
<Link href="/contact" className="btn-white-outline">Contact Us</Link>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section> */}
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
117
app/blog/[slug]/page.tsx
Normal file
@ -0,0 +1,117 @@
|
|||||||
|
import Image from "next/image";
|
||||||
|
import Link from "next/link";
|
||||||
|
import { notFound } from "next/navigation";
|
||||||
|
import { blogs } from "@/data/blogs";
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
params: Promise<{ slug: string }>;
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function generateStaticParams() {
|
||||||
|
return blogs.map((blog) => ({
|
||||||
|
slug: blog.slug,
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function generateMetadata({ params }: Props) {
|
||||||
|
const { slug } = await params;
|
||||||
|
const blog = blogs.find((b) => b.slug === slug);
|
||||||
|
if (!blog) return { title: "Blog Not Found" };
|
||||||
|
|
||||||
|
return {
|
||||||
|
title: `${blog.title} | VG Fence Products`,
|
||||||
|
description: blog.excerpt,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export default async function BlogDetailPage({ params }: Props) {
|
||||||
|
const { slug } = await params;
|
||||||
|
const blog = blogs.find((b) => b.slug === slug);
|
||||||
|
|
||||||
|
if (!blog) {
|
||||||
|
notFound();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Split content into paragraphs to insert images in between
|
||||||
|
const paragraphs = blog.content.split('\n\n');
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="blog-detail-page">
|
||||||
|
{/* ── INNER BANNER ── */}
|
||||||
|
<section className="detail-banner fade-up">
|
||||||
|
<div className="detail-banner-content">
|
||||||
|
<h1 className="detail-title">{blog.title}</h1>
|
||||||
|
<div className="banner-breadcrumb" style={{ marginTop: '30px', marginBottom: '0' }}>
|
||||||
|
<Link href="/">
|
||||||
|
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><path d="m3 9 9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z"/><polyline points="9 22 9 12 15 12 15 22"/></svg>
|
||||||
|
Home
|
||||||
|
</Link>
|
||||||
|
<span className="separator">/</span>
|
||||||
|
<Link href="/blog">Blog</Link>
|
||||||
|
<span className="separator">/</span>
|
||||||
|
<span>{blog.title}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
{/* ── CONTENT SECTION ── */}
|
||||||
|
<section className="section detail-content-section">
|
||||||
|
<div className="detail-container">
|
||||||
|
{/* Big Image */}
|
||||||
|
<div className="big-image-wrap">
|
||||||
|
<Image
|
||||||
|
src={blog.image}
|
||||||
|
alt={blog.title}
|
||||||
|
width={1200}
|
||||||
|
height={600}
|
||||||
|
className="big-image"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="detail-body">
|
||||||
|
{/* First couple of paragraphs */}
|
||||||
|
{paragraphs.slice(0, Math.min(2, paragraphs.length)).map((p, i) => (
|
||||||
|
<p key={i}>{p}</p>
|
||||||
|
))}
|
||||||
|
|
||||||
|
{/* 2 Small Images (Left and Right) */}
|
||||||
|
<div className="split-images">
|
||||||
|
<div className="small-image-wrap">
|
||||||
|
<Image
|
||||||
|
src="/assets/about-fencing.png"
|
||||||
|
alt="Feature 1"
|
||||||
|
width={500}
|
||||||
|
height={350}
|
||||||
|
className="small-image"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div className="small-image-wrap">
|
||||||
|
<Image
|
||||||
|
src="/assets/manufacturing-hero.png"
|
||||||
|
alt="Feature 2"
|
||||||
|
width={500}
|
||||||
|
height={350}
|
||||||
|
className="small-image"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Remaining paragraphs */}
|
||||||
|
{paragraphs.slice(2).map((p, i) => (
|
||||||
|
<p key={i}>{p}</p>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Bottom Button */}
|
||||||
|
<div className="detail-footer" style={{ marginTop: '60px', textAlign: 'center' }}>
|
||||||
|
<Link href="/blog" className="back-link" style={{ marginBottom: 0 }}>
|
||||||
|
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5" strokeLinecap="round" strokeLinejoin="round"><line x1="19" y1="12" x2="5" y2="12"></line><polyline points="12 19 5 12 12 5"></polyline></svg>
|
||||||
|
Back to Blog
|
||||||
|
</Link>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
57
app/blog/page.tsx
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
import Link from "next/link";
|
||||||
|
import Image from "next/image";
|
||||||
|
import { blogs } from "@/data/blogs";
|
||||||
|
|
||||||
|
export const metadata = {
|
||||||
|
title: "Blog | VG Fence Products",
|
||||||
|
description: "Read our latest articles about fencing installation, maintenance, and product choices.",
|
||||||
|
};
|
||||||
|
|
||||||
|
export default function BlogPage() {
|
||||||
|
return (
|
||||||
|
<div className="blog-index-page">
|
||||||
|
{/* ── INNER BANNER ── */}
|
||||||
|
<section className="inner-banner fade-up">
|
||||||
|
<div className="inner-banner-content">
|
||||||
|
<h1 className="section-h2">Our <span>Blog</span></h1>
|
||||||
|
<div className="banner-breadcrumb" style={{ marginTop: '30px', marginBottom: '0' }}>
|
||||||
|
<Link href="/">
|
||||||
|
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><path d="m3 9 9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z"/><polyline points="9 22 9 12 15 12 15 22"/></svg>
|
||||||
|
Home
|
||||||
|
</Link>
|
||||||
|
<span className="separator">/</span>
|
||||||
|
<span>Blog</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
{/* ── BLOG GRID ── */}
|
||||||
|
<section className="blog-grid-section">
|
||||||
|
<div className="blog-grid">
|
||||||
|
{blogs.map((blog) => (
|
||||||
|
<Link href={`/blog/${blog.slug}`} key={blog.id} className="blog-card post-card">
|
||||||
|
<div className="blog-card-img">
|
||||||
|
<Image
|
||||||
|
src={blog.image}
|
||||||
|
alt={blog.title}
|
||||||
|
fill
|
||||||
|
style={{ objectFit: 'cover' }}
|
||||||
|
/>
|
||||||
|
<div className="blog-card-category">{blog.category}</div>
|
||||||
|
</div>
|
||||||
|
<div className="blog-card-body">
|
||||||
|
<div className="blog-card-date">{blog.date}</div>
|
||||||
|
<h3 className="blog-card-title">{blog.title}</h3>
|
||||||
|
<p className="blog-card-excerpt">{blog.excerpt}</p>
|
||||||
|
<div className="blog-card-footer">
|
||||||
|
<span className="read-more">Read Article <i className="arrow-icon">→</i></span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</Link>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
@ -1,19 +1,22 @@
|
|||||||
|
import Link from 'next/link';
|
||||||
import Navbar from '@/components/Navbar';
|
import Navbar from '@/components/Navbar';
|
||||||
import Footer from '@/components/Footer';
|
import Footer from '@/components/Footer';
|
||||||
|
|
||||||
export default function ContactPage() {
|
export default function ContactPage() {
|
||||||
return (
|
return (
|
||||||
<div style={{ minHeight: '100vh', background: 'var(--cream)' }}>
|
<div style={{ background: 'var(--cream)' }}>
|
||||||
{/* Inner Banner */}
|
{/* Inner Banner */}
|
||||||
<section className="hero" style={{ minHeight: '350px', display: 'flex', alignItems: 'center', paddingTop: '130px' }}>
|
<section className="inner-banner fade-up">
|
||||||
<div className="hero-pattern"></div>
|
<div className="inner-banner-content">
|
||||||
<div className="hero-left" style={{ padding: '0', width: '100%' }}>
|
<h1 className="section-h2">How to <span>Contact</span> Us</h1>
|
||||||
<div className="hero-eyebrow">Get in Touch</div>
|
<div className="banner-breadcrumb" style={{ marginTop: '30px', marginBottom: '0' }}>
|
||||||
<h1 className="hero-h1" style={{ marginBottom: '16px' }}>How to <em>contact</em> us.</h1>
|
<Link href="/">
|
||||||
<p className="hero-sub" style={{ maxWidth: '600px', marginBottom: '0' }}>
|
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><path d="m3 9 9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z"/><polyline points="9 22 9 12 15 12 15 22"/></svg>
|
||||||
If you’ve got questions or ideas you would like to share, send a message.
|
Home
|
||||||
For anything more specific, please use one of our addresses.
|
</Link>
|
||||||
</p>
|
<span className="separator">/</span>
|
||||||
|
<span>Contact</span>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
|
|||||||
1313
app/globals.css
@ -20,7 +20,7 @@ export const metadata: Metadata = {
|
|||||||
title: "VG Fence Products — Ontario's B2B Fence Supply Partner",
|
title: "VG Fence Products — Ontario's B2B Fence Supply Partner",
|
||||||
description: "Supplying contractors, builders, and property managers across Ontario with chain link, ornamental, composite, glass railing, and stain products.",
|
description: "Supplying contractors, builders, and property managers across Ontario with chain link, ornamental, composite, glass railing, and stain products.",
|
||||||
icons: {
|
icons: {
|
||||||
icon: "/favicon.png",
|
icon: "/assets/favicon.webp",
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -56,10 +56,25 @@ export default function LoginPage() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="auth-page">
|
<div className="login-page-wrapper">
|
||||||
<div className="auth-card">
|
{/* ── INNER BANNER ── */}
|
||||||
<h1 className="auth-title"><span>Login</span></h1>
|
{/* <section className="inner-banner fade-up">
|
||||||
<p className="auth-sub">Access your pricing and order history.</p>
|
<div className="inner-banner-content">
|
||||||
|
<h1 className="section-h2">Customer <span>Login</span></h1>
|
||||||
|
<div className="banner-breadcrumb" style={{ marginTop: '30px', marginBottom: '0' }}>
|
||||||
|
<Link href="/">
|
||||||
|
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><path d="m3 9 9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z"/><polyline points="9 22 9 12 15 12 15 22"/></svg>
|
||||||
|
Home
|
||||||
|
</Link>
|
||||||
|
<span className="separator">/</span>
|
||||||
|
<span>Login</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section> */}
|
||||||
|
|
||||||
|
<div className="auth-page section">
|
||||||
|
<div className="auth-card">
|
||||||
|
<h2 className="auth-title" style={{ fontSize: '28px', marginBottom: '32px' }}>Access Your <span>Account</span></h2>
|
||||||
|
|
||||||
{err && <div style={{ color: 'red', marginBottom: '10px', fontSize: '14px', background: 'rgba(255,0,0,0.1)', padding: '8px', borderRadius: '4px' }}>{err}</div>}
|
{err && <div style={{ color: 'red', marginBottom: '10px', fontSize: '14px', background: 'rgba(255,0,0,0.1)', padding: '8px', borderRadius: '4px' }}>{err}</div>}
|
||||||
{msg && <div style={{ color: 'green', marginBottom: '10px', fontSize: '14px', background: 'rgba(0,255,0,0.1)', padding: '8px', borderRadius: '4px' }}>{msg}</div>}
|
{msg && <div style={{ color: 'green', marginBottom: '10px', fontSize: '14px', background: 'rgba(0,255,0,0.1)', padding: '8px', borderRadius: '4px' }}>{msg}</div>}
|
||||||
@ -105,5 +120,6 @@ export default function LoginPage() {
|
|||||||
</div> */}
|
</div> */}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
145
app/manufacturing/page.tsx
Normal file
@ -0,0 +1,145 @@
|
|||||||
|
"use client";
|
||||||
|
|
||||||
|
import Link from 'next/link';
|
||||||
|
import Image from 'next/image';
|
||||||
|
|
||||||
|
export default function ManufacturingPage() {
|
||||||
|
return (
|
||||||
|
<div className="about-page-wrapper">
|
||||||
|
{/* Inner Banner */}
|
||||||
|
<section className="inner-banner fade-up">
|
||||||
|
<div className="inner-banner-content">
|
||||||
|
<h1 className="section-h2">Job <span>Order</span> Manufacturing</h1>
|
||||||
|
<div className="banner-breadcrumb" style={{ marginTop: '30px', marginBottom: '0' }}>
|
||||||
|
<Link href="/">
|
||||||
|
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><path d="m3 9 9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z"/><polyline points="9 22 9 12 15 12 15 22"/></svg>
|
||||||
|
Home
|
||||||
|
</Link>
|
||||||
|
<span className="separator">/</span>
|
||||||
|
<span>Manufacturing</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
{/* Intro Section */}
|
||||||
|
<section className="about-section section">
|
||||||
|
<div className="container about-story-container">
|
||||||
|
<div className="about-story-layout">
|
||||||
|
<div>
|
||||||
|
<div className="section-eyebrow">Our Capabilities</div>
|
||||||
|
<h2 className="section-h2 about-story-h2">Bulk & Job Order <span>Manufacturing</span></h2>
|
||||||
|
<div className="about-story-text">
|
||||||
|
<p>
|
||||||
|
VG Fence specializes in bulk and job order manufacturing for contractors, developers, and businesses.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
From residential and commercial gates to brackets or custom metal components, we handle production from start to finish — ensuring high-quality, durable products delivered on time.
|
||||||
|
</p>
|
||||||
|
<div style={{ marginTop: '40px' }}>
|
||||||
|
<Link href="/contact" className="btn-primary">
|
||||||
|
Get a custom quote today for your next project →
|
||||||
|
</Link>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="about-image-column">
|
||||||
|
<div className="about-image-wrapper">
|
||||||
|
<Image
|
||||||
|
src="/assets/manufacturing-hero.png"
|
||||||
|
alt="Industrial metal fabrication and manufacturing"
|
||||||
|
fill
|
||||||
|
className="about-image-cover"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div className="floating-card about-floating-card">
|
||||||
|
<div className="about-floating-card-100">Fence Solutions</div>
|
||||||
|
{/* <div className="about-floating-card-text">Fence Solutions</div> */}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
{/* Services Grid */}
|
||||||
|
<section className="section" style={{ background: 'var(--gray-100)' }}>
|
||||||
|
<div className="container">
|
||||||
|
<div style={{ textAlign: 'center', marginBottom: '80px' }}>
|
||||||
|
<div className="section-eyebrow" style={{ justifyContent: 'center' }}>What We Build</div>
|
||||||
|
<h2 className="section-h2">Specialized <span>Production.</span></h2>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="mfg-grid">
|
||||||
|
{/* Gates */}
|
||||||
|
<div className="mfg-card">
|
||||||
|
<div style={{ padding: '12px', background: 'rgba(221,107,32,0.1)', borderRadius: '12px', width: '48px', height: '48px', display: 'flex', alignItems: 'center', justifyContent: 'center', marginBottom: '24px' }}>
|
||||||
|
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="var(--orange)" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><rect x="3" y="3" width="18" height="18" rx="2"/><path d="M12 3v18"/><path d="M3 12h18"/></svg>
|
||||||
|
</div>
|
||||||
|
<h3 className="section-h2">Residential & <span>Commercial Gates</span></h3>
|
||||||
|
<ul className="service-list">
|
||||||
|
<li>Sliding, swing, and decorative gates</li>
|
||||||
|
<li>Custom sizes and finishes</li>
|
||||||
|
<li>Galvanized or powder-coated for durability</li>
|
||||||
|
<li>Factory-fabricated for precise fit and fast installation</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Components */}
|
||||||
|
<div className="mfg-card">
|
||||||
|
<div style={{ padding: '12px', background: 'rgba(221,107,32,0.1)', borderRadius: '12px', width: '48px', height: '48px', display: 'flex', alignItems: 'center', justifyContent: 'center', marginBottom: '24px' }}>
|
||||||
|
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="var(--orange)" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><path d="M21 16V8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73l7 4a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16z"/><polyline points="3.27 6.96 12 12.01 20.73 6.96"/><line x1="12" y1="22.08" x2="12" y2="12"/></svg>
|
||||||
|
</div>
|
||||||
|
<h3 className="section-h2">Brackets, Rails & <span>Metal Components</span></h3>
|
||||||
|
<ul className="service-list">
|
||||||
|
<li>Fence brackets, mounting hardware, rail supports</li>
|
||||||
|
<li>Custom metal components for all types of projects</li>
|
||||||
|
<li>Bulk manufacturing for contractors and developers</li>
|
||||||
|
<li>High-quality steel with consistent dimensions</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Bulk Orders */}
|
||||||
|
<div className="mfg-card">
|
||||||
|
<div style={{ padding: '12px', background: 'rgba(221,107,32,0.1)', borderRadius: '12px', width: '48px', height: '48px', display: 'flex', alignItems: 'center', justifyContent: 'center', marginBottom: '24px' }}>
|
||||||
|
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="var(--orange)" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><path d="M3 9h18v10a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V9Z"/><path d="m3 9 2.45-4.91A2 2 0 0 1 7.24 3h9.52a2 2 0 0 1 1.79 1.09L21 9"/><path d="M12 3v6"/></svg>
|
||||||
|
</div>
|
||||||
|
<h3 className="section-h2">Bulk & <span>Job Orders</span></h3>
|
||||||
|
<ul className="service-list">
|
||||||
|
<li>Large-scale production for commercial or municipal projects</li>
|
||||||
|
<li>Pre-assembled material bundles for faster execution</li>
|
||||||
|
<li>Optional customization for dimensions and finishes</li>
|
||||||
|
<li>Competitive pricing for bulk quantities</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Fabrication */}
|
||||||
|
<div className="mfg-card">
|
||||||
|
<div style={{ padding: '12px', background: 'rgba(221,107,32,0.1)', borderRadius: '12px', width: '48px', height: '48px', display: 'flex', alignItems: 'center', justifyContent: 'center', marginBottom: '24px' }}>
|
||||||
|
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="var(--orange)" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><path d="M14.7 6.3a1 1 0 0 0 0 1.4l1.6 1.6a1 1 0 0 0 1.4 0l3.77-3.77a6 6 0 0 1-7.94 7.94l-6.91 6.91a2.12 2.12 0 0 1-3-3l6.91-6.91a6 6 0 0 1 7.94-7.94l-3.76 3.76Z"/></svg>
|
||||||
|
</div>
|
||||||
|
<h3 className="section-h2">Full Fabrication <span>Works</span></h3>
|
||||||
|
<ul className="service-list">
|
||||||
|
<li>Cutting, bending, welding, and finishing</li>
|
||||||
|
<li>Custom fabrication for any size requirement</li>
|
||||||
|
<li>Assistance with finishing touches for panels and accessories</li>
|
||||||
|
<li>Ensures every product meets durability standards</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
{/* CTA Section */}
|
||||||
|
<section className="cta-section section-padding about-cta-section">
|
||||||
|
<h2 className="cta-h2">Get Your <span>Custom Quote</span> Today</h2>
|
||||||
|
<p className="cta-sub about-cta-sub" style={{ fontSize: '20px', marginBottom: '32px' }}>
|
||||||
|
Fill out our job order & fabrication request form or call <strong style={{ color: 'var(--orange)' }}>226-888-7999</strong> to discuss your bulk and custom fabrication needs.
|
||||||
|
</p>
|
||||||
|
<div className="cta-btns">
|
||||||
|
<Link href="/contact" className="btn-primary">Contact Us Now</Link>
|
||||||
|
<a href="tel:2268887999" className="btn-white-outline">Call Us Today</a>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
@ -24,17 +24,36 @@ export default async function ProductDetailPage({
|
|||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="product-detail-page" style={{ minHeight: '100vh', paddingTop: '144px', paddingBottom: '96px', background: 'var(--white)' }}>
|
<div className="product-detail-page">
|
||||||
<div style={{ maxWidth: '1200px', margin: '0 auto', padding: '0 48px' }}>
|
{/* ── INNER BANNER ── */}
|
||||||
<Link href="/products" style={{ display: 'inline-flex', alignItems: 'center', gap: '8px', marginBottom: '48px', color: 'var(--gray-600)', textDecoration: 'none', fontSize: '14px', fontWeight: 600 }}>
|
<section className="detail-banner fade-up">
|
||||||
← Back to Catalog
|
<div className="detail-banner-content">
|
||||||
|
<h1 className="detail-title">{product.name}</h1>
|
||||||
|
<div className="banner-breadcrumb" style={{ marginTop: '30px', marginBottom: '0' }}>
|
||||||
|
<Link href="/">
|
||||||
|
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><path d="m3 9 9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z"/><polyline points="9 22 9 12 15 12 15 22"/></svg>
|
||||||
|
Home
|
||||||
|
</Link>
|
||||||
|
<span className="separator">/</span>
|
||||||
|
<Link href="/products">Products</Link>
|
||||||
|
<span className="separator">/</span>
|
||||||
|
<span>{product.name}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<div className="section">
|
||||||
|
<div className="container">
|
||||||
|
<Link href="/products" className="back-link">
|
||||||
|
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5" strokeLinecap="round" strokeLinejoin="round"><line x1="19" y1="12" x2="5" y2="12"></line><polyline points="12 19 5 12 12 5"></polyline></svg>
|
||||||
|
Back to Catalog
|
||||||
</Link>
|
</Link>
|
||||||
|
|
||||||
<div style={{ display: 'grid', gridTemplateColumns: '1.2fr 1fr', gap: '80px', alignItems: 'start' }}>
|
<div className="detail-grid">
|
||||||
{/* Left: Image */}
|
{/* Left: Image */}
|
||||||
<div style={{ position: 'relative', width: '100%', height: '600px', borderRadius: '12px', overflow: 'hidden', boxShadow: '0 20px 40px rgba(0,0,0,0.05)', background: '#f5f5f5' }}>
|
<div className="detail-image-column">
|
||||||
<Image
|
<Image
|
||||||
src="/placeholder.jpg"
|
src="/assets/manufacturing-hero.png"
|
||||||
alt={product!.name}
|
alt={product!.name}
|
||||||
fill
|
fill
|
||||||
style={{ objectFit: 'cover' }}
|
style={{ objectFit: 'cover' }}
|
||||||
@ -43,7 +62,7 @@ export default async function ProductDetailPage({
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Right: Info */}
|
{/* Right: Info */}
|
||||||
<div style={{ paddingTop: '20px' }}>
|
<div className="detail-info-column">
|
||||||
<div className="section-eyebrow" style={{ marginBottom: '16px' }}>{product!.category}</div>
|
<div className="section-eyebrow" style={{ marginBottom: '16px' }}>{product!.category}</div>
|
||||||
<h1 className="section-h2" style={{ fontSize: '48px', marginBottom: '24px', lineHeight: 1.1 }}>{product!.name}</h1>
|
<h1 className="section-h2" style={{ fontSize: '48px', marginBottom: '24px', lineHeight: 1.1 }}>{product!.name}</h1>
|
||||||
|
|
||||||
@ -70,7 +89,7 @@ export default async function ProductDetailPage({
|
|||||||
</div> */}
|
</div> */}
|
||||||
|
|
||||||
<div style={{ marginTop: '56px' }}>
|
<div style={{ marginTop: '56px' }}>
|
||||||
<Link href="/#quote" className="btn-primary" style={{ width: '100%', textAlign: 'center', padding: '20px' }}>
|
<Link href="/contact" className="btn-primary" style={{ width: '100%', textAlign: 'center', padding: '20px' }}>
|
||||||
Contact for Quote & Specs →
|
Contact for Quote & Specs →
|
||||||
</Link>
|
</Link>
|
||||||
{/* <p style={{ textAlign: 'center', fontSize: '13px', color: 'var(--gray-400)', marginTop: '16px' }}>
|
{/* <p style={{ textAlign: 'center', fontSize: '13px', color: 'var(--gray-400)', marginTop: '16px' }}>
|
||||||
@ -81,5 +100,6 @@ export default async function ProductDetailPage({
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -13,32 +13,33 @@ export default function ProductsPage() {
|
|||||||
const indexOfFirstProduct = indexOfLastProduct - productsPerPage;
|
const indexOfFirstProduct = indexOfLastProduct - productsPerPage;
|
||||||
const currentProducts = products.slice(indexOfFirstProduct, indexOfLastProduct);
|
const currentProducts = products.slice(indexOfFirstProduct, indexOfLastProduct);
|
||||||
const totalPages = Math.ceil(products.length / productsPerPage);
|
const totalPages = Math.ceil(products.length / productsPerPage);
|
||||||
|
|
||||||
const paginate = (pageNumber: number) => setCurrentPage(pageNumber);
|
const paginate = (pageNumber: number) => setCurrentPage(pageNumber);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div style={{ minHeight: '100vh' }}>
|
<div style={{ minHeight: '100vh' }}>
|
||||||
{/* Inner Banner */}
|
{/* Inner Banner */}
|
||||||
<section className="hero" style={{ minHeight: '400px', display: 'flex', alignItems: 'center', paddingTop: '130px' }}>
|
<section className="inner-banner fade-up">
|
||||||
<div className="hero-pattern"></div>
|
<div className="inner-banner-content">
|
||||||
<div className="hero-left" style={{ padding: '0', width: '100%' }}>
|
<h1 className="section-h2">Our <span>Product</span> Catalog</h1>
|
||||||
<div className="hero-eyebrow" style={{ marginLeft: '0px' }}>Full Inventory</div>
|
<div className="banner-breadcrumb" style={{ marginTop: '30px', marginBottom: '0' }}>
|
||||||
<h1 className="hero-h1" style={{ marginBottom: '16px' }}>Our <em>Product</em> Catalog.</h1>
|
<Link href="/">
|
||||||
<p className="hero-sub" style={{ maxWidth: '600px', marginBottom: '0' }}>
|
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><path d="m3 9 9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z"/><polyline points="9 22 9 12 15 12 15 22"/></svg>
|
||||||
Explore our complete range of professional-grade fence supply products.
|
Home
|
||||||
High stocks and contractor pricing for same-day delivery across Ontario.
|
</Link>
|
||||||
</p>
|
<span className="separator">/</span>
|
||||||
|
<span>Products</span>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
{/* Grid Content */}
|
{/* Grid Content */}
|
||||||
<section className="products-section">
|
<section className="products-section section">
|
||||||
<div className="products-grid">
|
<div className="products-grid product-page">
|
||||||
{currentProducts.map((product) => (
|
{currentProducts.map((product) => (
|
||||||
<div key={product.slug} className="product-card" style={{ display: 'flex', flexDirection: 'column', height: '100%', textDecoration: 'none' }}>
|
<div key={product.slug} className="product-card" style={{ display: 'flex', flexDirection: 'column', height: '100%', textDecoration: 'none' }}>
|
||||||
<div style={{ position: 'relative', width: '100%', height: '240px', borderRadius: '8px', overflow: 'hidden', marginBottom: '20px', background: 'var(--gray-100)' }}>
|
<div style={{ position: 'relative', width: '100%', height: '240px', borderRadius: '8px', overflow: 'hidden', marginBottom: '20px', background: 'var(--gray-100)' }}>
|
||||||
<Image
|
<Image
|
||||||
src="/placeholder.jpg"
|
src="/assets/about-fencing.png"
|
||||||
alt={product.name}
|
alt={product.name}
|
||||||
fill
|
fill
|
||||||
style={{ objectFit: 'cover' }}
|
style={{ objectFit: 'cover' }}
|
||||||
|
|||||||
189
app/rentals/page.tsx
Normal file
@ -0,0 +1,189 @@
|
|||||||
|
import Link from "next/link";
|
||||||
|
import Image from "next/image";
|
||||||
|
|
||||||
|
export const metadata = {
|
||||||
|
title: "Fence Rentals | VG Fence Products",
|
||||||
|
description: "Temporary fence rentals for construction sites, events, and security perimeters. Flexible rental terms and quick delivery.",
|
||||||
|
};
|
||||||
|
|
||||||
|
export default function RentalsPage() {
|
||||||
|
const products = [
|
||||||
|
{ name: "Temporary Fence Panels", desc: "Durable and easy to assemble", img: "/assets/temp-fence-panel.png" },
|
||||||
|
{ name: "Temporary Fence Gates", desc: "Single or double swing gates", img: "/assets/about-fencing.png" },
|
||||||
|
{ name: "Fence Wheels", desc: "Smooth movement for gate panels", img: "/assets/manufacturing-hero.png" },
|
||||||
|
{ name: "Wind Bracing", desc: "Prevent fence panels from tipping", img: "/assets/about-fencing.png" },
|
||||||
|
{ name: "Fence Bases", desc: "Concrete, rubber, or plastic bases for stability", img: "/assets/manufacturing-hero.png" },
|
||||||
|
{ name: "Fence Clamps & Accessories", desc: "Secure connections for panels", img: "/assets/about-fencing.png" },
|
||||||
|
{ name: "Sandbags / Ballast", desc: "Extra stability for windy or busy areas", img: "/assets/manufacturing-hero.png" },
|
||||||
|
{ name: "Debris & Safety Netting", desc: "Optional add-ons for construction sites", img: "/assets/about-fencing.png" },
|
||||||
|
];
|
||||||
|
|
||||||
|
const applications = [
|
||||||
|
{ id: 1, title: "Construction Sites", desc: "Keep workers and equipment secure" },
|
||||||
|
{ id: 2, title: "Events and Festivals", desc: "Crowd control and perimeter fencing" },
|
||||||
|
{ id: 3, title: "Sports and Film Production", desc: "Temporary barriers for staff and public safety" },
|
||||||
|
{ id: 4, title: "Short-Term and Long-Term Projects", desc: "Flexible rental periods" },
|
||||||
|
];
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="rentals-page">
|
||||||
|
{/* ── INNER BANNER ── */}
|
||||||
|
<section className="inner-banner fade-up">
|
||||||
|
<div className="inner-banner-content">
|
||||||
|
<h1 className="section-h2">Fence <span>Rentals</span></h1>
|
||||||
|
<div className="banner-breadcrumb" style={{ marginTop: '30px', marginBottom: '0' }}>
|
||||||
|
<Link href="/">
|
||||||
|
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><path d="m3 9 9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z"/><polyline points="9 22 9 12 15 12 15 22"/></svg>
|
||||||
|
Home
|
||||||
|
</Link>
|
||||||
|
<span className="separator">/</span>
|
||||||
|
<span>Rentals</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
{/* ── INTRO SECTION (REDESIGNED) ── */}
|
||||||
|
<section className="section rental-intro">
|
||||||
|
<div className="container">
|
||||||
|
<div className="about-story-layout" style={{ alignItems: 'center' }}>
|
||||||
|
<div className="about-story-text" style={{ textAlign: 'left' }}>
|
||||||
|
<div className="section-eyebrow">FENCE RENTALS</div>
|
||||||
|
<h2 className="section-h2" style={{ fontSize: '48px', lineHeight: '1.1', marginBottom: '30px' }}>
|
||||||
|
Temporary Fence Rentals for <span>Construction, Events, and Security</span>
|
||||||
|
</h2>
|
||||||
|
<p style={{ fontSize: '16px', color: 'var(--gray-600)', lineHeight: '1.8', marginBottom: '24px' }}>
|
||||||
|
VG Fence provides high-quality temporary fencing solutions for contractors, event organizers, and property managers. Our rentals are flexible, reliable, and designed to secure construction sites, public events, and temporary perimeters.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<div style={{ display: 'flex', alignItems: 'center', gap: '15px', padding: '15px 20px', background: 'rgba(232,87,42,0.05)', borderLeft: '4px solid var(--orange)', borderRadius: '4px', marginBottom: '32px' }}>
|
||||||
|
{/* <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="var(--orange)" strokeWidth="2.5" strokeLinecap="round" strokeLinejoin="round"><circle cx="12" cy="12" r="10"/><line x1="12" y1="16" x2="12" y2="12"/><line x1="12" y1="8" x2="12.01" y2="8"/></svg> */}
|
||||||
|
<span style={{ fontSize: '15px', fontWeight: 700, color: 'var(--navy)' }}>Installation support for temporary fences is available for select projects</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* <div className="progress-container">
|
||||||
|
<div className="circular-progress">
|
||||||
|
<span className="progress-value">85%</span>
|
||||||
|
</div>
|
||||||
|
<div className="progress-info">
|
||||||
|
<h4>Satisfied Customer</h4>
|
||||||
|
<p>Reliable support for contractors and event managers across Ontario projects.</p>
|
||||||
|
</div>
|
||||||
|
</div> */}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="about-image-column">
|
||||||
|
<div className="about-image-wrapper" style={{ padding: '15px', background: 'var(--white)', boxShadow: '0 30px 60px rgba(0,0,0,0.1)', borderRadius: '4px' }}>
|
||||||
|
<Image
|
||||||
|
src="/assets/about-fencing.png"
|
||||||
|
alt="Industrial fencing installation experts"
|
||||||
|
fill
|
||||||
|
style={{ objectFit: 'cover', borderRadius: '2px' }}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
{/* ── PRODUCTS SECTION ── */}
|
||||||
|
<section className="section rental-products" style={{ background: 'var(--gray-100)' }}>
|
||||||
|
<div className="container">
|
||||||
|
<div style={{ textAlign: 'center', marginBottom: '60px' }}>
|
||||||
|
<div className="section-eyebrow" style={{ justifyContent: 'center' }}>Equipment List</div>
|
||||||
|
<h2 className="section-h2">Products & Equipment <span>Available</span></h2>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="rental-grid">
|
||||||
|
{products.map((p, i) => (
|
||||||
|
<div key={i} className="rental-item-card">
|
||||||
|
<div className="rental-item-img">
|
||||||
|
<Image src={p.img} alt={p.name} fill style={{ objectFit: 'cover' }} />
|
||||||
|
</div>
|
||||||
|
<div className="rental-item-body">
|
||||||
|
<h3 className="rental-item-name">{p.name}</h3>
|
||||||
|
<p className="rental-item-desc">{p.desc}</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
{/* ── APPLICATIONS SECTION ── */}
|
||||||
|
<section className="section rental-apps">
|
||||||
|
<div className="container">
|
||||||
|
<div style={{ textAlign: 'center', marginBottom: '60px' }}>
|
||||||
|
<div className="section-eyebrow" style={{ justifyContent: 'center' }}>Tailored Solutions</div>
|
||||||
|
<h2 className="section-h2">Applications</h2>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="app-grid">
|
||||||
|
{applications.map((app) => (
|
||||||
|
<div key={app.id} className="app-card">
|
||||||
|
<div className="app-num">{app.id}</div>
|
||||||
|
<div className="app-content">
|
||||||
|
<h3 className="app-title">{app.title}</h3>
|
||||||
|
<p className="app-desc">{app.desc}</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
{/* ── WHY CHOOSE SECTION (IMAGE + TIMELINE) ── */}
|
||||||
|
<section className="rental-why-section fade-up">
|
||||||
|
<div className="rental-why-img">
|
||||||
|
<Image
|
||||||
|
src="/assets/fence-rentals-hero.png"
|
||||||
|
alt="VG Fence Temporary Fencing"
|
||||||
|
fill
|
||||||
|
style={{ objectFit: 'cover' }}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div className="rental-why-content">
|
||||||
|
<h2 className="rental-why-title">Why Choose VG Fence Rentals</h2>
|
||||||
|
|
||||||
|
<ul className="rental-timeline">
|
||||||
|
<li className="rental-timeline-item">
|
||||||
|
<div className="timeline-icon">
|
||||||
|
<svg width="28" height="28" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><path d="M12 2v20"/><path d="m5 15 7-7 7 7"/></svg>
|
||||||
|
</div>
|
||||||
|
<div className="timeline-text">Flexible rental terms (daily, weekly, monthly)</div>
|
||||||
|
</li>
|
||||||
|
<li className="rental-timeline-item">
|
||||||
|
<div className="timeline-icon">
|
||||||
|
<svg width="28" height="28" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><path d="M14 9V5a3 3 0 0 0-3-3l-4 9v11h11.28a2 2 0 0 0 2-1.7L22 14v-2a2 2 0 0 0-2-2h-6Z"/><path d="M7 22H4a2 2 0 0 1-2-2v-7a2 2 0 0 1 2-2h3"/></svg>
|
||||||
|
</div>
|
||||||
|
<div className="timeline-text">Durable and professional-grade materials</div>
|
||||||
|
</li>
|
||||||
|
<li className="rental-timeline-item">
|
||||||
|
<div className="timeline-icon">
|
||||||
|
<svg width="28" height="28" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><rect x="1" y="3" width="15" height="13"/><polyline points="16 8 20 8 23 11 23 16 16 16 16 8"/><circle cx="5.5" cy="18.5" r="2.5"/><circle cx="18.5" cy="18.5" r="2.5"/></svg>
|
||||||
|
</div>
|
||||||
|
<div className="timeline-text">Quick delivery & setup support available</div>
|
||||||
|
</li>
|
||||||
|
<li className="rental-timeline-item">
|
||||||
|
<div className="timeline-icon">
|
||||||
|
<svg width="28" height="28" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><polygon points="12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26 12 2"/></svg>
|
||||||
|
</div>
|
||||||
|
<div className="timeline-text">Galvanized or black finishes</div>
|
||||||
|
</li>
|
||||||
|
<li className="rental-timeline-item">
|
||||||
|
<div className="timeline-icon">
|
||||||
|
<svg width="28" height="28" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><path d="M22 11.08V12a10 10 0 1 1-5.93-9.14"/><polyline points="22 4 12 14.01 9 11.01"/></svg>
|
||||||
|
</div>
|
||||||
|
<div className="timeline-text">Reliable support for contractors and event managers</div>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<div style={{ marginTop: '60px', borderTop: '1px solid rgba(255,255,255,0.1)', paddingTop: '40px' }}>
|
||||||
|
<h2 className="section-h2" style={{ color: 'var(--white)', fontSize: '32px', marginBottom: '30px' }}>Secure Your <span>Temporary Fencing</span> Today</h2>
|
||||||
|
<Link href="/contact" className="btn-primary">Request a Quote</Link>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
@ -6,7 +6,7 @@ export default function Footer() {
|
|||||||
<div className="footer-top">
|
<div className="footer-top">
|
||||||
<div>
|
<div>
|
||||||
<div className="footer-brand-name">
|
<div className="footer-brand-name">
|
||||||
<img src="/vg-fence.png" alt="VG Fence Products" style={{ height: '32px', width: 'auto', marginLeft: '-15px' }} />
|
<img src="/assets/vg-fence.png" alt="VG Fence Products" style={{ height: '32px', width: 'auto', marginLeft: '-15px' }} />
|
||||||
</div>
|
</div>
|
||||||
<div className="footer-tagline">Ontario's B2B fence supply partner — KWC & beyond</div>
|
<div className="footer-tagline">Ontario's B2B fence supply partner — KWC & beyond</div>
|
||||||
<div className="footer-territory">📍 Serving 250km radius from Kitchener-Waterloo</div>
|
<div className="footer-territory">📍 Serving 250km radius from Kitchener-Waterloo</div>
|
||||||
@ -31,6 +31,7 @@ export default function Footer() {
|
|||||||
<div>
|
<div>
|
||||||
<div className="footer-col-title">Services</div>
|
<div className="footer-col-title">Services</div>
|
||||||
<ul className="footer-links">
|
<ul className="footer-links">
|
||||||
|
<li><Link href="/manufacturing">Custom Manufacturing</Link></li>
|
||||||
<li><Link href="/#services">2D drawing services</Link></li>
|
<li><Link href="/#services">2D drawing services</Link></li>
|
||||||
<li><Link href="/#services">Wood staining</Link></li>
|
<li><Link href="/#services">Wood staining</Link></li>
|
||||||
<li><Link href="/#services">Site services</Link></li>
|
<li><Link href="/#services">Site services</Link></li>
|
||||||
|
|||||||
@ -1,18 +1,44 @@
|
|||||||
|
"use client";
|
||||||
|
|
||||||
|
import { useState } from 'react';
|
||||||
import Link from 'next/link';
|
import Link from 'next/link';
|
||||||
|
|
||||||
export default function Navbar() {
|
export default function Navbar() {
|
||||||
|
const [isOpen, setIsOpen] = useState(false);
|
||||||
|
|
||||||
|
const toggleMenu = () => setIsOpen(!isOpen);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<nav>
|
<nav className={isOpen ? "nav-active" : ""}>
|
||||||
<Link href="/" className="nav-logo">
|
<Link href="/" className="nav-logo">
|
||||||
<img src="/vg-fence.png" alt="VG Fence Products" style={{ height: '40px', width: 'auto' }} />
|
<img src="/assets/vg-fence.png" alt="VG Fence Products" style={{ height: '40px', width: 'auto' }} />
|
||||||
</Link>
|
</Link>
|
||||||
<ul className="nav-links">
|
|
||||||
<li><Link href="/">Home</Link></li>
|
{/* Hamburger Menu Toggle */}
|
||||||
<li><Link href="/about">About</Link></li>
|
<button className="menu-toggle" onClick={toggleMenu} aria-label="Toggle Menu">
|
||||||
<li><Link href="/products">Products</Link></li>
|
<div className={isOpen ? "hamburger active" : "hamburger"}>
|
||||||
<li><Link href="/contact">Contact</Link></li>
|
<span></span>
|
||||||
|
<span></span>
|
||||||
|
<span></span>
|
||||||
|
</div>
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<ul className={isOpen ? "nav-links active" : "nav-links"}>
|
||||||
|
<li><Link href="/" onClick={() => setIsOpen(false)}>Home</Link></li>
|
||||||
|
<li><Link href="/about" onClick={() => setIsOpen(false)}>About</Link></li>
|
||||||
|
<li><Link href="/products" onClick={() => setIsOpen(false)}>Products</Link></li>
|
||||||
|
<li><Link href="/manufacturing" onClick={() => setIsOpen(false)}>Manufacturing</Link></li>
|
||||||
|
<li><Link href="/rentals" onClick={() => setIsOpen(false)}>Rentals</Link></li>
|
||||||
|
<li><Link href="/blog" onClick={() => setIsOpen(false)}>Blog</Link></li>
|
||||||
|
<li><Link href="/contact" onClick={() => setIsOpen(false)}>Contact</Link></li>
|
||||||
|
<li className="mobile-cta-li">
|
||||||
|
<Link href="/login" className="nav-cta" onClick={() => setIsOpen(false)} style={{ width: '100%', justifyContent: 'center' }}>
|
||||||
|
Login
|
||||||
|
</Link>
|
||||||
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
<Link href="/login" className="nav-cta" style={{ display: 'flex', alignItems: 'center', gap: '8px' }}>
|
|
||||||
|
<Link href="/login" className="nav-cta desktop-cta">
|
||||||
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><path d="M20 21v-2a4 4 0 0 0-4-4H8a4 4 0 0 0-4 4v2"/><circle cx="12" cy="7" r="4"/></svg>
|
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><path d="M20 21v-2a4 4 0 0 0-4-4H8a4 4 0 0 0-4 4v2"/><circle cx="12" cy="7" r="4"/></svg>
|
||||||
Login
|
Login
|
||||||
</Link>
|
</Link>
|
||||||
|
|||||||
124
data/blogs.ts
Normal file
@ -0,0 +1,124 @@
|
|||||||
|
export interface BlogPost {
|
||||||
|
id: number;
|
||||||
|
title: string;
|
||||||
|
slug: string;
|
||||||
|
excerpt: string;
|
||||||
|
content: string;
|
||||||
|
date: string;
|
||||||
|
image: string;
|
||||||
|
author: string;
|
||||||
|
category: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const blogs: BlogPost[] = [
|
||||||
|
{
|
||||||
|
id: 1,
|
||||||
|
title: "How to Install a Decorative Ornamental Fence",
|
||||||
|
slug: "how-to-install-decorative-ornamental-fence",
|
||||||
|
excerpt: "Ornamental fences add elegance and security. Learn how to install them correctly for durability and visual appeal.",
|
||||||
|
content: "Ornamental fences add elegance and security to both residential and commercial properties. Installing them correctly ensures durability and visual appeal. \n\nBegin by measuring your property line and marking post locations. Standard spacing depends on panel size but is usually between 6–8 feet. Dig post holes deep enough for stability and set posts in concrete for permanent installations.\n\nAttach rails to posts using brackets and mounting hardware supplied by your fence provider. Secure panels to rails using screws or fasteners. For gates, ensure the frame is reinforced, hinges are properly aligned, and latches are installed at a comfortable height. \n\nCheck that the fence is level and aligned along the entire property line. Finishing touches such as post caps or decorative finials protect the fence and enhance aesthetics. Proper installation will result in a fence that is both functional and visually striking for years.",
|
||||||
|
date: "May 10, 2024",
|
||||||
|
image: "/assets/about-fencing.png",
|
||||||
|
author: "VG Fence Expert",
|
||||||
|
category: "Installation"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 2,
|
||||||
|
title: "Benefits of Aluminum Railing Systems",
|
||||||
|
slug: "benefits-of-aluminum-railing-systems",
|
||||||
|
excerpt: "Aluminum railings are durable, lightweight, and low maintenance. Discover why they are perfect for decks and balconies.",
|
||||||
|
content: "Aluminum railing systems are a popular choice for decks, balconies, and commercial spaces due to their durability, lightweight design, and low maintenance. Unlike wood, aluminum does not warp, rot, or require frequent painting. \n\nAluminum railings can be powder-coated in various colors, including black, for a modern aesthetic. Panels are often pre-assembled, making installation fast and efficient. Posts and mounting brackets are designed to meet safety standards while supporting structural integrity.\n\nThese systems are suitable for residential and commercial applications, including rooftop terraces, staircases, and public walkways. The combination of aesthetic appeal and long-lasting performance makes aluminum railings a cost-effective solution for high-end and practical projects.",
|
||||||
|
date: "May 12, 2024",
|
||||||
|
image: "/assets/manufacturing-hero.png",
|
||||||
|
author: "VG Fence Expert",
|
||||||
|
category: "Railings"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 3,
|
||||||
|
title: "Choosing the Right Wood Fence Hardware",
|
||||||
|
slug: "choosing-the-right-wood-fence-hardware",
|
||||||
|
excerpt: "Selecting the right hardware for your wood fence is essential for durability and proper functionality.",
|
||||||
|
content: "Selecting the right hardware for your wood fence is essential for durability and proper functionality. Start with hinges: heavy-duty hinges are recommended for larger gates, while decorative hinges add aesthetic appeal without compromising strength. \n\nLatches and locks should be selected based on security needs. For residential yards, a simple latch may suffice, while commercial or high-traffic areas may require keyed locks or combination mechanisms.\n\nBrackets and mounting hardware secure rails to posts and help maintain alignment. Using galvanized or powder-coated components increases resistance to weathering and corrosion. Proper installation ensures gates operate smoothly and reduces maintenance needs. \n\nFinally, consider post caps and finials. While they add style, they also protect posts from water damage and extend the life of your fence.",
|
||||||
|
date: "May 15, 2024",
|
||||||
|
image: "/assets/about-fencing.png",
|
||||||
|
author: "VG Fence Expert",
|
||||||
|
category: "Hardware"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 4,
|
||||||
|
title: "How to Maintain Your Chain Link Fence",
|
||||||
|
slug: "how-to-maintain-your-chain-link-fence",
|
||||||
|
excerpt: "Proper maintenance of chain link fences ensures long-term durability and security. Follow these simple tips.",
|
||||||
|
content: "Proper maintenance of chain link fences ensures long-term durability and security. Regular inspections help identify problems like loose ties, bent posts, or rust. \n\nCleaning is simple: rinse with water to remove debris, and use mild soap for stubborn stains. For galvanized fences, check for corrosion or damage, particularly around gates and corners. Black vinyl-coated fences require less frequent treatment but still benefit from periodic inspection.\n\nTighten loose tension bars, bands, and rail connections as needed. Replace damaged posts or fabric promptly to prevent further issues. Applying a protective coating on exposed metal surfaces can also help extend the fence’s lifespan. \n\nRoutine maintenance ensures safety, keeps your property secure, and preserves the fence’s appearance for years to come.",
|
||||||
|
date: "May 18, 2024",
|
||||||
|
image: "/assets/manufacturing-hero.png",
|
||||||
|
author: "VG Fence Expert",
|
||||||
|
category: "Maintenance"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 5,
|
||||||
|
title: "Temporary Fence Rental Tips for Events and Construction Sites",
|
||||||
|
slug: "temporary-fence-rental-tips-for-events-and-construction-sites",
|
||||||
|
excerpt: "Everything you need to know about renting temporary fencing for your next project or event.",
|
||||||
|
content: "Temporary fencing is a reliable solution for managing crowd control, site safety, and project perimeters. Whether you’re renting for a construction site or a public event, understanding the key elements ensures safe and efficient usage. \n\nStart with proper planning: determine your site layout, entry points, and the number of panels needed. Panels are typically modular and come in standardized sizes, making installation straightforward. Gate access should be strategically placed for staff or emergency access.\n\nBases can be concrete, rubber, or plastic depending on the terrain, and accessories like clamps, wind bracing, or ballast increase stability, especially in windy conditions. Renting from a supplier that maintains clean, high-quality equipment reduces the risk of damage or accidents. \n\nFinally, consider rental duration. Short-term events may only need a few days, while construction sites might require weeks or months. Flexible rental terms and reliable delivery ensure the fencing is both cost-effective and efficient.",
|
||||||
|
date: "May 20, 2024",
|
||||||
|
image: "/assets/about-fencing.png",
|
||||||
|
author: "VG Fence Expert",
|
||||||
|
category: "Rental"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 6,
|
||||||
|
title: "DIY Wood Fence Installation Tips",
|
||||||
|
slug: "diy-wood-fence-installation-tips",
|
||||||
|
excerpt: "Installing a wood fence yourself can be a rewarding project if you plan carefully and select the right materials.",
|
||||||
|
content: "Installing a wood fence yourself can be a rewarding project if you plan carefully and select the right materials. Start by measuring your yard and marking post locations. Standard spacing between posts is usually 6–8 feet. \n\nNext, choose the right posts and hardware. Heavy-duty hinges, latches, and brackets ensure gates operate smoothly and the fence remains durable. Use pressure-treated wood to resist rot and weather damage.\n\nWhen digging post holes, ensure proper depth (generally 1/3 of the post height) and use gravel or concrete for stability. Attach rails and panels with screws or bolts, keeping everything level and aligned. For gates, reinforce frames and include drop rods or locks as needed. \n\nFinally, finish with stain or paint to protect the wood and enhance aesthetics. Following these steps ensures a strong, long-lasting fence.",
|
||||||
|
date: "May 22, 2024",
|
||||||
|
image: "/assets/manufacturing-hero.png",
|
||||||
|
author: "VG Fence Expert",
|
||||||
|
category: "DIY"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 7,
|
||||||
|
title: "Glass Railings vs Aluminum Railings: Which Should You Choose?",
|
||||||
|
slug: "glass-railings-vs-aluminum-railings-which-should-you-choose",
|
||||||
|
excerpt: "Choosing between glass and aluminum railings depends on your project’s aesthetic and functional requirements.",
|
||||||
|
content: "Choosing between glass and aluminum railings depends on your project’s aesthetic, safety, and functional requirements. \n\nGlass railings offer modern, transparent designs ideal for decks, balconies, or areas where unobstructed views are desired. Tempered glass panels provide safety while maintaining an open feel. Installation requires spigots, base shoes, and clamps to secure panels effectively. \n\nAluminum railings are lightweight, durable, and low-maintenance. They are ideal for residential and commercial decks, staircases, and balcony applications. Aluminum railings can be powder-coated in black or other colors for style and corrosion resistance.\n\nBoth railing systems are designed to meet safety codes and enhance property aesthetics. Your choice will depend on visual preference, budget, and installation requirements.",
|
||||||
|
date: "May 25, 2024",
|
||||||
|
image: "/assets/about-fencing.png",
|
||||||
|
author: "VG Fence Expert",
|
||||||
|
category: "Comparison"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 8,
|
||||||
|
title: "Commercial Temporary Fence Rentals: What You Need to Know",
|
||||||
|
slug: "commercial-temporary-fence-rentals-what-you-need-to-know",
|
||||||
|
excerpt: "Temporary fencing is a flexible solution for managing commercial construction sites and event perimeters.",
|
||||||
|
content: "Temporary fencing is a flexible and efficient solution for managing commercial construction sites, event perimeters, and secured areas. Renting temporary fences provides cost savings, easy installation, and scalability for different project sizes. \n\nAvailable products include panels, gates, bases, and accessories such as clamps and wheels. Bases can be concrete, rubber, or plastic depending on the site conditions. Wind bracing and ballast options increase stability for exposed locations.\n\nTemporary fence rentals are ideal for construction sites needing quick setup, public events requiring crowd control, or film productions with temporary perimeter needs. Rental durations are flexible, ranging from a single day to several months. \n\nSelecting a rental provider with high-quality materials and reliable delivery ensures safety and compliance with local regulations.",
|
||||||
|
date: "May 28, 2024",
|
||||||
|
image: "/assets/manufacturing-hero.png",
|
||||||
|
author: "VG Fence Expert",
|
||||||
|
category: "Rental"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 9,
|
||||||
|
title: "Top 5 Benefits of Privacy Fencing for Homeowners",
|
||||||
|
slug: "top-5-benefits-of-privacy-fencing-for-homeowners",
|
||||||
|
excerpt: "Privacy fencing offers homeowners a combination of security, aesthetics, and peace of mind.",
|
||||||
|
content: "Privacy fencing offers homeowners a combination of security, aesthetics, and peace of mind. Black PVC or aluminum slats can be inserted into chain link fences to provide visual screening while allowing airflow. \n\nSome key benefits include: \n\n1. Enhanced Security: Privacy fences make it harder for intruders to access your property. \n2. Noise Reduction: Denser fencing helps reduce noise from streets or neighboring properties. \n3. Visual Screening: Keeps your yard private while maintaining a clean look. \n4. Wind Protection: Reduces wind exposure for gardens or outdoor living spaces. \n5. Property Value: Well-designed privacy fencing can improve the overall appeal of your home.\n\nInstalling privacy fencing is straightforward and complements both new and existing chain link or wood fences. High-quality materials ensure the fence lasts for many years with minimal maintenance.",
|
||||||
|
date: "May 30, 2024",
|
||||||
|
image: "/assets/about-fencing.png",
|
||||||
|
author: "VG Fence Expert",
|
||||||
|
category: "Privacy"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 10,
|
||||||
|
title: "How to Choose the Right Chain Link Fence for Your Property",
|
||||||
|
slug: "how-to-choose-the-right-chain-link-fence-for-your-property",
|
||||||
|
excerpt: "Chain link fences are versatile solutions for residential and commercial sites. Learn how to choose the right one.",
|
||||||
|
content: "Chain link fences are one of the most versatile fencing solutions available, ideal for both residential yards and large commercial sites. Choosing the right chain link fence depends on several key factors: height, mesh size, post type, and finish. \n\nFor residential use, a smaller mesh size and a black vinyl coating can provide both security and aesthetic appeal. For commercial or industrial projects, galvanized finishes are often preferred due to their durability and resistance to corrosion. \n\nFence height is another consideration. Standard residential fences typically range from 3 to 6 feet, while commercial fences may exceed 8 feet to meet security requirements. Posts play a critical role in stability, with terminal posts used at corners, gates, and ends for added support. Accessories like tension bars, braces, and rail ends ensure the fence remains secure and long-lasting. \n\nBy evaluating your property needs, site conditions, and aesthetic preferences, you can choose a chain link fence that balances durability, functionality, and style.",
|
||||||
|
date: "June 2, 2024",
|
||||||
|
image: "/assets/manufacturing-hero.png",
|
||||||
|
author: "VG Fence Expert",
|
||||||
|
category: "Chain Link"
|
||||||
|
}
|
||||||
|
];
|
||||||
@ -1,7 +1,11 @@
|
|||||||
import type { NextConfig } from "next";
|
import type { NextConfig } from "next";
|
||||||
|
|
||||||
const nextConfig: NextConfig = {
|
const nextConfig: NextConfig = {
|
||||||
/* config options here */
|
output: 'export',
|
||||||
|
trailingSlash: true,
|
||||||
|
images: {
|
||||||
|
unoptimized: true,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
export default nextConfig;
|
export default nextConfig;
|
||||||
|
|||||||
BIN
public/assets/about-fencing.png
Normal file
|
After Width: | Height: | Size: 1.0 MiB |
|
Before Width: | Height: | Size: 20 KiB After Width: | Height: | Size: 20 KiB |
BIN
public/assets/favicon.webp
Normal file
|
After Width: | Height: | Size: 1.6 KiB |
BIN
public/assets/fence-rentals-hero.png
Normal file
|
After Width: | Height: | Size: 1.1 MiB |
|
Before Width: | Height: | Size: 391 B After Width: | Height: | Size: 391 B |
|
Before Width: | Height: | Size: 1.0 KiB After Width: | Height: | Size: 1.0 KiB |
BIN
public/assets/manufacturing-hero.png
Normal file
|
After Width: | Height: | Size: 947 KiB |
|
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 1.3 KiB |
BIN
public/assets/temp-fence-panel.png
Normal file
|
After Width: | Height: | Size: 558 KiB |
|
Before Width: | Height: | Size: 128 B After Width: | Height: | Size: 128 B |
|
Before Width: | Height: | Size: 5.6 KiB After Width: | Height: | Size: 5.6 KiB |
|
Before Width: | Height: | Size: 385 B After Width: | Height: | Size: 385 B |