Compare commits
6 Commits
193b4da576
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
| d0aad0b313 | |||
| 2128824c2f | |||
| b1345e6d4f | |||
| 576e6fcf0b | |||
| a3e0f4b29f | |||
| 7aa82f337c |
@@ -7,9 +7,15 @@ services:
|
|||||||
- "3040:3000" # Kannst du später sogar löschen, wenn es nur noch über Caddy laufen soll
|
- "3040:3000" # Kannst du später sogar löschen, wenn es nur noch über Caddy laufen soll
|
||||||
environment:
|
environment:
|
||||||
- NODE_ENV=production
|
- NODE_ENV=production
|
||||||
|
- SES_SMTP_HOST=${SES_SMTP_HOST:-email-smtp.us-east-2.amazonaws.com}
|
||||||
|
- SES_SMTP_PORT=${SES_SMTP_PORT:-587}
|
||||||
|
- SES_SMTP_USER=${SES_SMTP_USER}
|
||||||
|
- SES_SMTP_PASS=${SES_SMTP_PASS}
|
||||||
|
- SES_FROM_EMAIL=${SES_FROM_EMAIL:-website@buddelectric.net}
|
||||||
|
- SES_TO_EMAIL=${SES_TO_EMAIL:-buddelectric@grandecom.net}
|
||||||
networks:
|
networks:
|
||||||
- bizmatch # <-- NEU: Container ins selbe Netz wie Caddy hängen
|
- bizmatch # <-- NEU: Container ins selbe Netz wie Caddy hängen
|
||||||
|
|
||||||
networks: # <-- NEU: Netzwerk deklarieren
|
networks: # <-- NEU: Netzwerk deklarieren
|
||||||
bizmatch:
|
bizmatch:
|
||||||
external: true
|
external: true
|
||||||
|
|||||||
21
package-lock.json
generated
21
package-lock.json
generated
@@ -10,12 +10,14 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"lucide-react": "^0.563.0",
|
"lucide-react": "^0.563.0",
|
||||||
"next": "16.1.6",
|
"next": "16.1.6",
|
||||||
|
"nodemailer": "^9.0.1",
|
||||||
"react": "19.2.3",
|
"react": "19.2.3",
|
||||||
"react-dom": "19.2.3"
|
"react-dom": "19.2.3"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@tailwindcss/postcss": "^4",
|
"@tailwindcss/postcss": "^4",
|
||||||
"@types/node": "^20",
|
"@types/node": "^20",
|
||||||
|
"@types/nodemailer": "^8.0.1",
|
||||||
"@types/react": "^19",
|
"@types/react": "^19",
|
||||||
"@types/react-dom": "^19",
|
"@types/react-dom": "^19",
|
||||||
"eslint": "^9",
|
"eslint": "^9",
|
||||||
@@ -1556,6 +1558,16 @@
|
|||||||
"undici-types": "~6.21.0"
|
"undici-types": "~6.21.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@types/nodemailer": {
|
||||||
|
"version": "8.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/nodemailer/-/nodemailer-8.0.1.tgz",
|
||||||
|
"integrity": "sha512-PxpaInm8V1JQDd4j0ds5HfvWQk8JupS1C0Picb96QJsrrRDjBH+DlK7L4ZdNSqNULhiZRQHc40nLVShaGxXAMw==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@types/node": "*"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@types/react": {
|
"node_modules/@types/react": {
|
||||||
"version": "19.2.13",
|
"version": "19.2.13",
|
||||||
"resolved": "https://registry.npmjs.org/@types/react/-/react-19.2.13.tgz",
|
"resolved": "https://registry.npmjs.org/@types/react/-/react-19.2.13.tgz",
|
||||||
@@ -5046,6 +5058,15 @@
|
|||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
|
"node_modules/nodemailer": {
|
||||||
|
"version": "9.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/nodemailer/-/nodemailer-9.0.1.tgz",
|
||||||
|
"integrity": "sha512-Gwv8SQewT616ZM/URn0H54b8PWo/Wum7md3EW2aWy1lO27+WZCX+Xyak3J+NlmHUjDh5ME+uesJUDRbR3Ye8Bw==",
|
||||||
|
"license": "MIT-0",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=6.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/object-assign": {
|
"node_modules/object-assign": {
|
||||||
"version": "4.1.1",
|
"version": "4.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
|
||||||
|
|||||||
@@ -11,12 +11,14 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"lucide-react": "^0.563.0",
|
"lucide-react": "^0.563.0",
|
||||||
"next": "16.1.6",
|
"next": "16.1.6",
|
||||||
|
"nodemailer": "^9.0.1",
|
||||||
"react": "19.2.3",
|
"react": "19.2.3",
|
||||||
"react-dom": "19.2.3"
|
"react-dom": "19.2.3"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@tailwindcss/postcss": "^4",
|
"@tailwindcss/postcss": "^4",
|
||||||
"@types/node": "^20",
|
"@types/node": "^20",
|
||||||
|
"@types/nodemailer": "^8.0.1",
|
||||||
"@types/react": "^19",
|
"@types/react": "^19",
|
||||||
"@types/react-dom": "^19",
|
"@types/react-dom": "^19",
|
||||||
"eslint": "^9",
|
"eslint": "^9",
|
||||||
|
|||||||
BIN
public/images/newspaper.webp
Normal file
BIN
public/images/newspaper.webp
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 254 KiB |
@@ -1,7 +1,8 @@
|
|||||||
import { Shield, CheckCircle2, Award, Clock } from "lucide-react";
|
import { Shield, Award, Clock } from "lucide-react";
|
||||||
import Link from "next/link";
|
import Link from "next/link";
|
||||||
import Image from "next/image";
|
import Image from "next/image";
|
||||||
import { Metadata } from "next";
|
import { Metadata } from "next";
|
||||||
|
import NewspaperClipping from "@/components/NewspaperClipping";
|
||||||
|
|
||||||
export const metadata: Metadata = {
|
export const metadata: Metadata = {
|
||||||
title: "About Budd Electric Co. | Family-Owned Since 1969",
|
title: "About Budd Electric Co. | Family-Owned Since 1969",
|
||||||
@@ -37,18 +38,8 @@ export default function AboutUs() {
|
|||||||
<div className="mx-auto max-w-7xl px-6 lg:px-8">
|
<div className="mx-auto max-w-7xl px-6 lg:px-8">
|
||||||
<div className="grid lg:grid-cols-2 gap-16 items-center">
|
<div className="grid lg:grid-cols-2 gap-16 items-center">
|
||||||
<div className="relative">
|
<div className="relative">
|
||||||
<div className="aspect-[4/3] rounded-lg overflow-hidden bg-gray-100 shadow-xl border-l-8 border-[color:var(--brand)]">
|
<NewspaperClipping />
|
||||||
<Image
|
</div>
|
||||||
src="/images/residential.png"
|
|
||||||
alt="Budd Electric professional electrician team working on residential electrical services"
|
|
||||||
fill
|
|
||||||
sizes="(max-width: 1024px) 100vw, 50vw"
|
|
||||||
className="object-cover"
|
|
||||||
loading="lazy"
|
|
||||||
quality={65}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div>
|
<div>
|
||||||
<h2 className="text-sm font-bold tracking-[0.2em] text-[color:var(--brand)] uppercase mb-3">Who We Are</h2>
|
<h2 className="text-sm font-bold tracking-[0.2em] text-[color:var(--brand)] uppercase mb-3">Who We Are</h2>
|
||||||
<h3 className="text-3xl md:text-4xl font-bold text-[color:var(--ink)] font-display mb-6">Three Generations of Excellence</h3>
|
<h3 className="text-3xl md:text-4xl font-bold text-[color:var(--ink)] font-display mb-6">Three Generations of Excellence</h3>
|
||||||
@@ -65,13 +56,13 @@ export default function AboutUs() {
|
|||||||
<span className="text-4xl font-bold text-[color:var(--brand)]">1969</span>
|
<span className="text-4xl font-bold text-[color:var(--brand)]">1969</span>
|
||||||
<span className="text-sm font-bold uppercase tracking-wider text-gray-400">Established</span>
|
<span className="text-sm font-bold uppercase tracking-wider text-gray-400">Established</span>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex flex-col gap-2">
|
<div className="flex flex-col gap-2">
|
||||||
<span className="text-4xl font-bold text-[color:var(--brand)]">3rd Gen</span>
|
<span className="text-4xl font-bold text-[color:var(--brand)]">3rd Gen</span>
|
||||||
<span className="text-sm font-bold uppercase tracking-wider text-gray-400">Master Electricians</span>
|
<span className="text-sm font-bold uppercase tracking-wider text-gray-400">Master Electricians</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
|
|||||||
79
src/app/api/contact/route.ts
Normal file
79
src/app/api/contact/route.ts
Normal file
@@ -0,0 +1,79 @@
|
|||||||
|
import { NextRequest, NextResponse } from "next/server";
|
||||||
|
import nodemailer from "nodemailer";
|
||||||
|
|
||||||
|
export async function POST(request: NextRequest) {
|
||||||
|
try {
|
||||||
|
const body = await request.json();
|
||||||
|
const { firstName, lastName, email, phone, serviceType, message } = body;
|
||||||
|
|
||||||
|
if (!firstName || typeof firstName !== "string" || firstName.trim().length === 0) {
|
||||||
|
return NextResponse.json({ error: "First name is required." }, { status: 400 });
|
||||||
|
}
|
||||||
|
if (!lastName || typeof lastName !== "string" || lastName.trim().length === 0) {
|
||||||
|
return NextResponse.json({ error: "Last name is required." }, { status: 400 });
|
||||||
|
}
|
||||||
|
if (!email || typeof email !== "string" || !/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email)) {
|
||||||
|
return NextResponse.json({ error: "A valid email address is required." }, { status: 400 });
|
||||||
|
}
|
||||||
|
if (!phone || typeof phone !== "string" || phone.trim().length === 0) {
|
||||||
|
return NextResponse.json({ error: "Phone number is required." }, { status: 400 });
|
||||||
|
}
|
||||||
|
if (!serviceType || typeof serviceType !== "string" || serviceType.trim().length === 0) {
|
||||||
|
return NextResponse.json({ error: "Please select a service type." }, { status: 400 });
|
||||||
|
}
|
||||||
|
if (!message || typeof message !== "string" || message.trim().length === 0) {
|
||||||
|
return NextResponse.json({ error: "Message is required." }, { status: 400 });
|
||||||
|
}
|
||||||
|
|
||||||
|
const smtpHost = process.env.SES_SMTP_HOST || "email-smtp.us-east-2.amazonaws.com";
|
||||||
|
const smtpPort = parseInt(process.env.SES_SMTP_PORT || "587", 10);
|
||||||
|
const smtpUser = process.env.SES_SMTP_USER;
|
||||||
|
const smtpPass = process.env.SES_SMTP_PASS;
|
||||||
|
const fromEmail = process.env.SES_FROM_EMAIL || "website@buddelectric.net";
|
||||||
|
const toEmail = process.env.SES_TO_EMAIL || "buddelectric@grandecom.net";
|
||||||
|
|
||||||
|
if (!smtpUser || !smtpPass) {
|
||||||
|
return NextResponse.json({ error: "Email service is not configured." }, { status: 500 });
|
||||||
|
}
|
||||||
|
|
||||||
|
const transporter = nodemailer.createTransport({
|
||||||
|
host: smtpHost,
|
||||||
|
port: smtpPort,
|
||||||
|
secure: false,
|
||||||
|
auth: {
|
||||||
|
user: smtpUser,
|
||||||
|
pass: smtpPass,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const serviceTypeLabels: Record<string, string> = {
|
||||||
|
residential: "Residential Service",
|
||||||
|
commercial: "Commercial Project",
|
||||||
|
generator: "Generator Quote",
|
||||||
|
other: "Other",
|
||||||
|
};
|
||||||
|
|
||||||
|
const htmlBody = `
|
||||||
|
<h2 style="color:#1e293b;">New Contact Form Submission</h2>
|
||||||
|
<table style="border-collapse:collapse;width:100%;max-width:600px;">
|
||||||
|
<tr><td style="padding:8px;border-bottom:1px solid #e2e8f0;font-weight:bold;">Name</td><td style="padding:8px;border-bottom:1px solid #e2e8f0;">${firstName} ${lastName}</td></tr>
|
||||||
|
<tr><td style="padding:8px;border-bottom:1px solid #e2e8f0;font-weight:bold;">Email</td><td style="padding:8px;border-bottom:1px solid #e2e8f0;">${email}</td></tr>
|
||||||
|
<tr><td style="padding:8px;border-bottom:1px solid #e2e8f0;font-weight:bold;">Phone</td><td style="padding:8px;border-bottom:1px solid #e2e8f0;">${phone}</td></tr>
|
||||||
|
<tr><td style="padding:8px;border-bottom:1px solid #e2e8f0;font-weight:bold;">Service Type</td><td style="padding:8px;border-bottom:1px solid #e2e8f0;">${serviceTypeLabels[serviceType] || serviceType}</td></tr>
|
||||||
|
<tr><td style="padding:8px;font-weight:bold;">Message</td><td style="padding:8px;">${message}</td></tr>
|
||||||
|
</table>
|
||||||
|
`;
|
||||||
|
|
||||||
|
await transporter.sendMail({
|
||||||
|
from: fromEmail,
|
||||||
|
to: toEmail,
|
||||||
|
replyTo: email,
|
||||||
|
subject: `New Contact Form Submission from ${firstName} ${lastName}`,
|
||||||
|
html: htmlBody,
|
||||||
|
});
|
||||||
|
|
||||||
|
return NextResponse.json({ success: true }, { status: 200 });
|
||||||
|
} catch {
|
||||||
|
return NextResponse.json({ error: "Failed to send your message. Please try again or call us directly." }, { status: 500 });
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
import { MapPin, Phone, Mail, Clock } from "lucide-react";
|
import { MapPin, Phone, Mail, Clock } from "lucide-react";
|
||||||
import { Metadata } from "next";
|
import { Metadata } from "next";
|
||||||
import Image from "next/image";
|
import Image from "next/image";
|
||||||
|
import ContactForm from "@/components/ContactForm";
|
||||||
|
|
||||||
export const metadata: Metadata = {
|
export const metadata: Metadata = {
|
||||||
title: "Contact Budd Electric Co. | Corpus Christi Electrician",
|
title: "Contact Budd Electric Co. | Corpus Christi Electrician",
|
||||||
@@ -26,7 +27,7 @@ export default function Contact() {
|
|||||||
<div className="mx-auto max-w-7xl px-6 lg:px-8 relative z-10 text-center">
|
<div className="mx-auto max-w-7xl px-6 lg:px-8 relative z-10 text-center">
|
||||||
<h1 className="text-4xl md:text-6xl font-bold text-white font-display mb-6">Contact Us</h1>
|
<h1 className="text-4xl md:text-6xl font-bold text-white font-display mb-6">Contact Us</h1>
|
||||||
<p className="text-xl text-gray-400 max-w-2xl mx-auto">
|
<p className="text-xl text-gray-400 max-w-2xl mx-auto">
|
||||||
Get in touch for a free quote or schedule a service call today.
|
Get in touch or schedule a service call today.
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
@@ -56,7 +57,6 @@ export default function Contact() {
|
|||||||
<div>
|
<div>
|
||||||
<h4 className="font-bold text-lg text-[color:var(--ink)]">Call Us</h4>
|
<h4 className="font-bold text-lg text-[color:var(--ink)]">Call Us</h4>
|
||||||
<p className="text-[color:var(--muted)] text-xl font-bold text-[color:var(--brand)]">(361) 855-2255</p>
|
<p className="text-[color:var(--muted)] text-xl font-bold text-[color:var(--brand)]">(361) 855-2255</p>
|
||||||
<p className="text-sm text-gray-400">24/7 Emergency Support Available</p>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -76,7 +76,7 @@ export default function Contact() {
|
|||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<h4 className="font-bold text-lg text-[color:var(--ink)]">Business Hours</h4>
|
<h4 className="font-bold text-lg text-[color:var(--ink)]">Business Hours</h4>
|
||||||
<p className="text-[color:var(--muted)]">Monday - Friday: 8:00 AM - 5:00 PM<br />Saturday & Sunday: Emergency Only</p>
|
<p className="text-[color:var(--muted)]">Monday - Friday: 8:00 AM - 5:00 PM<br />Saturday & Sunday: Closed</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -99,41 +99,7 @@ export default function Contact() {
|
|||||||
{/* FORM */}
|
{/* FORM */}
|
||||||
<div className="bg-white p-10 rounded shadow-2xl border-t-8 border-[color:var(--brand)]">
|
<div className="bg-white p-10 rounded shadow-2xl border-t-8 border-[color:var(--brand)]">
|
||||||
<h3 className="text-2xl font-bold font-display text-[color:var(--ink)] mb-6">Send us a Message</h3>
|
<h3 className="text-2xl font-bold font-display text-[color:var(--ink)] mb-6">Send us a Message</h3>
|
||||||
<form className="space-y-6">
|
<ContactForm />
|
||||||
<div className="grid grid-cols-2 gap-6">
|
|
||||||
<div className="space-y-2">
|
|
||||||
<label htmlFor="firstName" className="text-sm font-bold text-gray-700 uppercase tracking-wide">First Name</label>
|
|
||||||
<input id="firstName" name="firstName" type="text" required className="w-full bg-gray-50 border border-gray-200 p-3 rounded focus:outline-none focus:border-[color:var(--brand)] focus:ring-1 focus:ring-[color:var(--brand)]" />
|
|
||||||
</div>
|
|
||||||
<div className="space-y-2">
|
|
||||||
<label htmlFor="lastName" className="text-sm font-bold text-gray-700 uppercase tracking-wide">Last Name</label>
|
|
||||||
<input id="lastName" name="lastName" type="text" required className="w-full bg-gray-50 border border-gray-200 p-3 rounded focus:outline-none focus:border-[color:var(--brand)] focus:ring-1 focus:ring-[color:var(--brand)]" />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div className="space-y-2">
|
|
||||||
<label htmlFor="email" className="text-sm font-bold text-gray-700 uppercase tracking-wide">Email</label>
|
|
||||||
<input id="email" name="email" type="email" required className="w-full bg-gray-50 border border-gray-200 p-3 rounded focus:outline-none focus:border-[color:var(--brand)] focus:ring-1 focus:ring-[color:var(--brand)]" />
|
|
||||||
</div>
|
|
||||||
<div className="space-y-2">
|
|
||||||
<label htmlFor="phone" className="text-sm font-bold text-gray-700 uppercase tracking-wide">Phone</label>
|
|
||||||
<input id="phone" name="phone" type="tel" required className="w-full bg-gray-50 border border-gray-200 p-3 rounded focus:outline-none focus:border-[color:var(--brand)] focus:ring-1 focus:ring-[color:var(--brand)]" />
|
|
||||||
</div>
|
|
||||||
<div className="space-y-2">
|
|
||||||
<label htmlFor="serviceType" className="text-sm font-bold text-gray-700 uppercase tracking-wide">Service Type</label>
|
|
||||||
<select id="serviceType" name="serviceType" required className="w-full bg-gray-50 border border-gray-200 p-3 rounded focus:outline-none focus:border-[color:var(--brand)] focus:ring-1 focus:ring-[color:var(--brand)]">
|
|
||||||
<option value="">Select a service type</option>
|
|
||||||
<option value="residential">Residential Service</option>
|
|
||||||
<option value="commercial">Commercial Project</option>
|
|
||||||
<option value="generator">Generator Quote</option>
|
|
||||||
<option value="other">Other</option>
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
<div className="space-y-2">
|
|
||||||
<label htmlFor="message" className="text-sm font-bold text-gray-700 uppercase tracking-wide">Message</label>
|
|
||||||
<textarea id="message" name="message" rows={4} required className="w-full bg-gray-50 border border-gray-200 p-3 rounded focus:outline-none focus:border-[color:var(--brand)] focus:ring-1 focus:ring-[color:var(--brand)]"></textarea>
|
|
||||||
</div>
|
|
||||||
<button type="submit" className="w-full bg-[color:var(--brand)] text-white font-bold uppercase tracking-widest py-4 rounded hover:bg-[color:var(--brand-strong)] transition shadow-lg">Send Message</button>
|
|
||||||
</form>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
import { Home, Phone, Zap, Factory } from "lucide-react";
|
import { Home, Zap, Building2 } from "lucide-react";
|
||||||
import Link from "next/link";
|
import Link from "next/link";
|
||||||
import Image from "next/image";
|
import Image from "next/image";
|
||||||
import { ArrowRight } from "lucide-react";
|
import { ArrowRight } from "lucide-react";
|
||||||
import { Metadata } from "next";
|
import { Metadata } from "next";
|
||||||
|
|
||||||
export const metadata: Metadata = {
|
export const metadata: Metadata = {
|
||||||
title: "Electrical Services Corpus Christi | Residential & Commercial",
|
title: "Electrical Services Corpus Christi | Commercial & Residential",
|
||||||
description: "Professional residential, commercial, and industrial electrical services in Corpus Christi, TX. Licensed electricians for all your electrical needs. Call (361) 855-2255.",
|
description: "Professional commercial and residential electrical services in Corpus Christi, TX. Licensed electricians for all your electrical needs. Call (361) 855-2255.",
|
||||||
};
|
};
|
||||||
|
|
||||||
export default function Services() {
|
export default function Services() {
|
||||||
@@ -28,7 +28,7 @@ export default function Services() {
|
|||||||
<div className="mx-auto max-w-7xl px-6 lg:px-8 relative z-10 text-center">
|
<div className="mx-auto max-w-7xl px-6 lg:px-8 relative z-10 text-center">
|
||||||
<h1 className="text-4xl md:text-6xl font-bold text-white font-display mb-6">Electrical Services</h1>
|
<h1 className="text-4xl md:text-6xl font-bold text-white font-display mb-6">Electrical Services</h1>
|
||||||
<p className="text-xl text-gray-400 max-w-2xl mx-auto">
|
<p className="text-xl text-gray-400 max-w-2xl mx-auto">
|
||||||
Comprehensive solutions for every need. Residential, Commercial, and Industrial.
|
Comprehensive solutions for every need. Commercial and Residential electrical services.
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
@@ -36,18 +36,18 @@ export default function Services() {
|
|||||||
{/* SERVICE LIST */}
|
{/* SERVICE LIST */}
|
||||||
<section className="py-24">
|
<section className="py-24">
|
||||||
<div className="mx-auto max-w-7xl px-6 lg:px-8 space-y-24">
|
<div className="mx-auto max-w-7xl px-6 lg:px-8 space-y-24">
|
||||||
{/* RESIDENTIAL */}
|
{/* COMMERCIAL */}
|
||||||
<div id="residential" className="grid lg:grid-cols-2 gap-16 items-center">
|
<div id="commercial" className="grid lg:grid-cols-2 gap-16 items-center scroll-mt-36">
|
||||||
<div className="order-2 lg:order-1">
|
<div className="order-2 lg:order-1">
|
||||||
<div className="w-14 h-14 bg-red-50 text-[color:var(--brand)] rounded flex items-center justify-center mb-6">
|
<div className="w-14 h-14 bg-red-50 text-[color:var(--brand)] rounded flex items-center justify-center mb-6">
|
||||||
<Home size={32} />
|
<Building2 size={32} />
|
||||||
</div>
|
</div>
|
||||||
<h2 className="text-3xl font-bold text-[color:var(--ink)] font-display mb-6">Residential Services</h2>
|
<h2 className="text-3xl font-bold text-[color:var(--ink)] font-display mb-6">Commercial Electrical Services</h2>
|
||||||
<p className="text-[color:var(--muted)] text-lg mb-8 leading-relaxed">
|
<p className="text-[color:var(--muted)] text-lg mb-8 leading-relaxed">
|
||||||
Your home is your sanctuary. We ensure it's powered safely and efficiently. From simple outlet repairs to full-home rewiring, no job is too small or too complex.
|
Serving South Texas for over 50 Years our team has experience, knowledge, skill and expertise in wiring new or existing Office Buildings, Strip Centers, Dental Offices and Medical Facilities as well as making repairs to existing installations.
|
||||||
</p>
|
</p>
|
||||||
<ul className="grid grid-cols-1 sm:grid-cols-2 gap-4">
|
<ul className="grid grid-cols-1 sm:grid-cols-2 gap-4">
|
||||||
{["Service Upgrades", "Safety Inspections", "Lighting Installation", "Ceiling Fans", "Outlet Repair", "Panel Replacement"].map((item, i) => (
|
{["Commercial New Construction and Renovations", "Lighting and Outlet Repairs", "Electrical System Upgrades", "Automated Lighting Controls", "Backup Generator Installations"].map((item, i) => (
|
||||||
<li key={i} className="flex items-center gap-3 text-gray-700 font-medium">
|
<li key={i} className="flex items-center gap-3 text-gray-700 font-medium">
|
||||||
<span className="w-2 h-2 bg-[color:var(--brand)] rounded-full"></span>
|
<span className="w-2 h-2 bg-[color:var(--brand)] rounded-full"></span>
|
||||||
{item}
|
{item}
|
||||||
@@ -56,62 +56,62 @@ export default function Services() {
|
|||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
<div className="order-1 lg:order-2 rounded-lg overflow-hidden shadow-xl aspect-[4/3] bg-gray-100 relative">
|
<div className="order-1 lg:order-2 rounded-lg overflow-hidden shadow-xl aspect-[4/3] bg-gray-100 relative">
|
||||||
<Image
|
<Image
|
||||||
src="/images/residential.png"
|
src="/images/commercial.png"
|
||||||
alt="Professional residential electrical wiring and home electrical services"
|
alt="Commercial electrical wiring and service upgrades"
|
||||||
fill
|
fill
|
||||||
sizes="(max-width: 1024px) 100vw, 50vw"
|
sizes="(max-width: 1024px) 100vw, 50vw"
|
||||||
quality={65}
|
quality={65}
|
||||||
loading="lazy"
|
loading="lazy"
|
||||||
className="object-cover"
|
className="object-cover"
|
||||||
/>
|
/>
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{/* COMMERCIAL */}
|
|
||||||
<div id="commercial" className="grid lg:grid-cols-2 gap-16 items-center">
|
|
||||||
<div className="rounded-lg overflow-hidden shadow-xl aspect-[4/3] bg-gray-100 relative">
|
|
||||||
<Image
|
|
||||||
src="/images/commercial.png"
|
|
||||||
alt="Commercial and industrial electrical wiring and services"
|
|
||||||
fill
|
|
||||||
sizes="(max-width: 1024px) 100vw, 50vw"
|
|
||||||
quality={65}
|
|
||||||
loading="lazy"
|
|
||||||
className="object-cover"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<div className="w-14 h-14 bg-red-50 text-[color:var(--brand)] rounded flex items-center justify-center mb-6">
|
|
||||||
<Factory size={32} />
|
|
||||||
</div>
|
|
||||||
<h2 className="text-3xl font-bold text-[color:var(--ink)] font-display mb-6">Commercial & Industrial</h2>
|
|
||||||
<p className="text-[color:var(--muted)] text-lg mb-8 leading-relaxed">
|
|
||||||
Keep your business running smoothly with our expert commercial services. We handle everything from new construction build-outs to ongoing maintenance contracts.
|
|
||||||
</p>
|
|
||||||
<ul className="grid grid-cols-1 sm:grid-cols-2 gap-4">
|
|
||||||
{["New Construction Wiring", "Tenant Build-outs", "Parking Lot Lighting", "Emergency Lighting", "Data Cabling", "Troubleshooting"].map((item, i) => (
|
|
||||||
<li key={i} className="flex items-center gap-3 text-gray-700 font-medium">
|
|
||||||
<span className="w-2 h-2 bg-[color:var(--brand)] rounded-full"></span>
|
|
||||||
{item}
|
|
||||||
</li>
|
|
||||||
))}
|
|
||||||
</ul>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* GENERATORS */}
|
{/* GENERATORS */}
|
||||||
<div id="generator" className="grid lg:grid-cols-2 gap-16 items-center">
|
<div id="generator" className="grid lg:grid-cols-2 gap-16 items-center scroll-mt-36">
|
||||||
<div className="order-2 lg:order-1">
|
<div className="rounded-lg overflow-hidden shadow-xl aspect-[4/3] bg-gray-100 relative">
|
||||||
|
<Image
|
||||||
|
src="/images/generator.png"
|
||||||
|
alt="Kohler whole-home standby generator installation and service"
|
||||||
|
fill
|
||||||
|
sizes="(max-width: 1024px) 100vw, 50vw"
|
||||||
|
quality={65}
|
||||||
|
loading="lazy"
|
||||||
|
className="object-cover"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
<div className="w-14 h-14 bg-red-50 text-[color:var(--brand)] rounded flex items-center justify-center mb-6">
|
<div className="w-14 h-14 bg-red-50 text-[color:var(--brand)] rounded flex items-center justify-center mb-6">
|
||||||
<Zap size={32} />
|
<Zap size={32} />
|
||||||
</div>
|
</div>
|
||||||
<h2 className="text-3xl font-bold text-[color:var(--ink)] font-display mb-6">Kohler Generators</h2>
|
<h2 className="text-3xl font-bold text-[color:var(--ink)] font-display mb-6">Kohler Generators</h2>
|
||||||
<p className="text-[color:var(--muted)] text-lg mb-8 leading-relaxed">
|
<p className="text-[color:var(--muted)] text-lg mb-8 leading-relaxed">
|
||||||
Don't be left in the dark during a storm. As an authorized Kohler dealer, we sell, install, and service standby generators to keep your power on when the grid goes down.
|
Don't be left in the dark during a storm. As an authorized Kohler Dealer we sell, install, and service standby generators to keep your power on when the grid goes down.
|
||||||
</p>
|
</p>
|
||||||
<ul className="grid grid-cols-1 sm:grid-cols-2 gap-4">
|
<ul className="grid grid-cols-1 sm:grid-cols-2 gap-4">
|
||||||
{["Sales & Consultation", "Professional Installation", "Maintenance Plans", "Warranty Service", "Transfer Switch Install"].map((item, i) => (
|
{["Sales & Consultation", "Turnkey Installation", "Maintenance Plans", "Warranty Service", "Troubleshooting/Repairs"].map((item, i) => (
|
||||||
|
<li key={i} className="flex items-center gap-3 text-gray-700 font-medium">
|
||||||
|
<span className="w-2 h-2 bg-[color:var(--brand)] rounded-full"></span>
|
||||||
|
{item}
|
||||||
|
</li>
|
||||||
|
))}
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* RESIDENTIAL */}
|
||||||
|
<div id="residential" className="grid lg:grid-cols-2 gap-16 items-center scroll-mt-36">
|
||||||
|
<div className="order-2 lg:order-1">
|
||||||
|
<div className="w-14 h-14 bg-red-50 text-[color:var(--brand)] rounded flex items-center justify-center mb-6">
|
||||||
|
<Home size={32} />
|
||||||
|
</div>
|
||||||
|
<h2 className="text-3xl font-bold text-[color:var(--ink)] font-display mb-6">Residential Electrical Services</h2>
|
||||||
|
<p className="text-[color:var(--muted)] text-lg mb-8 leading-relaxed">
|
||||||
|
Your home is your sanctuary. We ensure it is powered safely and efficiently. From simple repairs to wiring a large custom home, no job is too small or too complex.
|
||||||
|
</p>
|
||||||
|
<ul className="grid grid-cols-1 sm:grid-cols-2 gap-4">
|
||||||
|
{["Electrical Service Upgrades", "Lighting and Ceiling Fan Installation", "Outlet Repair and Installation", "Automated Lighting Controls", "Backup Generators", "Panel Replacement"].map((item, i) => (
|
||||||
<li key={i} className="flex items-center gap-3 text-gray-700 font-medium">
|
<li key={i} className="flex items-center gap-3 text-gray-700 font-medium">
|
||||||
<span className="w-2 h-2 bg-[color:var(--brand)] rounded-full"></span>
|
<span className="w-2 h-2 bg-[color:var(--brand)] rounded-full"></span>
|
||||||
{item}
|
{item}
|
||||||
@@ -120,19 +120,19 @@ export default function Services() {
|
|||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
<div className="order-1 lg:order-2 rounded-lg overflow-hidden shadow-xl aspect-[4/3] bg-gray-100 relative">
|
<div className="order-1 lg:order-2 rounded-lg overflow-hidden shadow-xl aspect-[4/3] bg-gray-100 relative">
|
||||||
<Image
|
<Image
|
||||||
src="/images/generator.png"
|
src="/images/residential.png"
|
||||||
alt="Kohler whole-home standby generator installation and service"
|
alt="Professional residential electrical wiring and home electrical services"
|
||||||
fill
|
fill
|
||||||
sizes="(max-width: 1024px) 100vw, 50vw"
|
sizes="(max-width: 1024px) 100vw, 50vw"
|
||||||
quality={65}
|
quality={65}
|
||||||
loading="lazy"
|
loading="lazy"
|
||||||
className="object-cover"
|
className="object-cover"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
{/* CTA */}
|
{/* CTA */}
|
||||||
<section className="bg-[color:var(--bg-dark)] py-20 border-t border-white/10">
|
<section className="bg-[color:var(--bg-dark)] py-20 border-t border-white/10">
|
||||||
@@ -140,7 +140,7 @@ export default function Services() {
|
|||||||
<h2 className="text-3xl font-bold text-white font-display mb-6">Need a custom solution?</h2>
|
<h2 className="text-3xl font-bold text-white font-display mb-6">Need a custom solution?</h2>
|
||||||
<p className="text-gray-400 mb-8 max-w-2xl mx-auto">If you don't see the specific service you need listed, give us a call. We likely handle it.</p>
|
<p className="text-gray-400 mb-8 max-w-2xl mx-auto">If you don't see the specific service you need listed, give us a call. We likely handle it.</p>
|
||||||
<Link href="/contact-us" className="inline-flex items-center gap-3 bg-[color:var(--brand)] text-white px-8 py-4 font-bold uppercase tracking-widest hover:bg-[color:var(--brand-strong)] transition rounded shadow-lg shadow-red-900/20">
|
<Link href="/contact-us" className="inline-flex items-center gap-3 bg-[color:var(--brand)] text-white px-8 py-4 font-bold uppercase tracking-widest hover:bg-[color:var(--brand-strong)] transition rounded shadow-lg shadow-red-900/20">
|
||||||
Get a Free Quote <ArrowRight size={20} />
|
Contact Us Today <ArrowRight size={20} />
|
||||||
</Link>
|
</Link>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import Link from "next/link";
|
import Link from "next/link";
|
||||||
import Image from "next/image";
|
import Image from "next/image";
|
||||||
import { ArrowRight, Zap, Shield, Home as HomeIcon, Factory, HardHat, CheckCircle2, Star, Clock, MapPin, Phone } from "lucide-react";
|
import { ArrowRight, Zap, Shield, Home as HomeIcon, Building2, CheckCircle2, Star, Clock, MapPin, Phone } from "lucide-react";
|
||||||
import ReviewCarousel from "@/components/ReviewCarousel";
|
import ReviewCarousel from "@/components/ReviewCarousel";
|
||||||
import HeroCarousel from "@/components/HeroCarousel";
|
import HeroCarousel from "@/components/HeroCarousel";
|
||||||
import FAQSection from "@/components/FAQSection";
|
import FAQSection from "@/components/FAQSection";
|
||||||
@@ -56,16 +56,12 @@ export default function Home() {
|
|||||||
</Link>
|
</Link>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="mt-12 mb-16 flex flex-wrap items-center gap-4 md:gap-8 text-sm font-medium text-gray-400">
|
<div className="mt-12 mb-16 flex flex-wrap items-center gap-4 md:gap-8 text-sm font-medium text-gray-400">
|
||||||
<div className="flex items-center gap-2">
|
<div className="flex items-center gap-2">
|
||||||
<CheckCircle2 className="text-[color:var(--brand)]" size={18} />
|
<CheckCircle2 className="text-[color:var(--brand)]" size={18} />
|
||||||
<span>Licensed & Insured</span>
|
<span>Licensed & Insured</span>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex items-center gap-2">
|
</div>
|
||||||
<CheckCircle2 className="text-[color:var(--brand)]" size={18} />
|
|
||||||
<span>24/7 Emergency Support</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="relative hidden lg:block">
|
<div className="relative hidden lg:block">
|
||||||
@@ -94,31 +90,31 @@ export default function Home() {
|
|||||||
<div className="w-14 h-14 bg-white text-[color:var(--brand)] rounded flex items-center justify-center mb-6 shadow-sm border border-gray-100 group-hover:scale-110 transition">
|
<div className="w-14 h-14 bg-white text-[color:var(--brand)] rounded flex items-center justify-center mb-6 shadow-sm border border-gray-100 group-hover:scale-110 transition">
|
||||||
<HomeIcon size={28} />
|
<HomeIcon size={28} />
|
||||||
</div>
|
</div>
|
||||||
<h3 className="text-xl font-bold text-[color:var(--ink)] mb-3 font-display">Residential</h3>
|
<h3 className="text-xl font-bold text-[color:var(--ink)] mb-3 font-display">Residential Electrical Services</h3>
|
||||||
<p className="text-gray-500 mb-6 line-clamp-3">
|
<p className="text-gray-500 mb-6">
|
||||||
Complete home electrical services including safety inspections, repairs, lighting, and fan installations.
|
Complete home electrical services from Outlet Installations or Repairs, Light Fixture/ Ceiling Fan Installations to wiring a new Custom Home.
|
||||||
</p>
|
</p>
|
||||||
<Link href="/electrical-services" className="text-[color:var(--brand)] font-bold uppercase text-xs tracking-widest hover:underline" aria-label="Learn more about Residential services">Residential Services</Link>
|
<Link href="/electrical-services#residential" className="text-[color:var(--brand)] font-bold uppercase text-xs tracking-widest hover:underline" aria-label="Learn more about Residential services">Residential Services</Link>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Card 2 */}
|
{/* Card 2 */}
|
||||||
<div className="group bg-[color:var(--bg-dark)] text-white rounded-lg overflow-hidden shadow-2xl hover:shadow-[0_25px_50px_-12px_rgba(0,0,0,0.5)] transition duration-300 relative transform md:-translate-y-4">
|
<div className="group bg-[color:var(--bg-dark)] text-white rounded-lg overflow-hidden shadow-2xl hover:shadow-[0_25px_50px_-12px_rgba(0,0,0,0.5)] transition duration-300 relative transform md:-translate-y-4">
|
||||||
<div className="h-2 bg-[color:var(--brand)] w-0 group-hover:w-full transition-all duration-500"></div>
|
<div className="h-2 bg-[color:var(--brand)] w-0 group-hover:w-full transition-all duration-500"></div>
|
||||||
<div className="absolute top-0 right-0 p-4 opacity-10">
|
<div className="absolute top-0 right-0 p-4 opacity-10">
|
||||||
<Zap size={100} />
|
<Zap size={100} />
|
||||||
</div>
|
</div>
|
||||||
<div className="p-8 relative z-10">
|
<div className="p-8 relative z-10">
|
||||||
<div className="w-14 h-14 bg-[color:var(--brand)] text-white rounded flex items-center justify-center mb-6 shadow-lg group-hover:scale-110 transition">
|
<div className="w-14 h-14 bg-[color:var(--brand)] text-white rounded flex items-center justify-center mb-6 shadow-lg group-hover:scale-110 transition">
|
||||||
<Factory size={28} />
|
<Building2 size={28} />
|
||||||
</div>
|
</div>
|
||||||
<h3 className="text-xl font-bold text-white mb-3 font-display">Commercial</h3>
|
<h3 className="text-xl font-bold text-white mb-3 font-display">Commercial Electrical Services</h3>
|
||||||
<p className="text-gray-400 mb-6">
|
<p className="text-gray-400 mb-6">
|
||||||
Reliable power for your business. New construction, maintenance, and industrial-grade solutions.
|
Complete electrical service for your business from electrical repairs, lighting upgrades, energy compliant lighting controls, to complete electrical system installations for new Commercial Buildings.
|
||||||
</p>
|
</p>
|
||||||
<Link href="/electrical-services" className="text-white font-bold uppercase text-xs tracking-widest hover:text-[color:var(--brand)] transition" aria-label="Learn more about Commercial services">Commercial Services</Link>
|
<Link href="/electrical-services#commercial" className="text-white font-bold uppercase text-xs tracking-widest hover:text-[color:var(--brand)] transition" aria-label="Learn more about Commercial services">Commercial Services</Link>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Card 3 */}
|
{/* Card 3 */}
|
||||||
<div className="group bg-gray-50 border border-gray-100 rounded-lg overflow-hidden hover:shadow-2xl transition duration-300 relative">
|
<div className="group bg-gray-50 border border-gray-100 rounded-lg overflow-hidden hover:shadow-2xl transition duration-300 relative">
|
||||||
@@ -127,11 +123,11 @@ export default function Home() {
|
|||||||
<div className="w-14 h-14 bg-white text-[color:var(--brand)] rounded flex items-center justify-center mb-6 shadow-sm border border-gray-100 group-hover:scale-110 transition">
|
<div className="w-14 h-14 bg-white text-[color:var(--brand)] rounded flex items-center justify-center mb-6 shadow-sm border border-gray-100 group-hover:scale-110 transition">
|
||||||
<Zap size={28} />
|
<Zap size={28} />
|
||||||
</div>
|
</div>
|
||||||
<h3 className="text-xl font-bold text-[color:var(--ink)] mb-3 font-display">Generators</h3>
|
<h3 className="text-xl font-bold text-[color:var(--ink)] mb-3 font-display">Kohler Generators</h3>
|
||||||
<p className="text-gray-500 mb-6 line-clamp-3">
|
<p className="text-gray-500 mb-6">
|
||||||
Authorized Kohler dealer. Keep your lights on when the grid goes down with standby power.
|
Authorized Kohler Sales, Installation, and Service Dealer. Keep your lights on when the grid goes down with a new backup Kohler Generator.
|
||||||
</p>
|
</p>
|
||||||
<Link href="/electrical-services" className="text-[color:var(--brand)] font-bold uppercase text-xs tracking-widest hover:underline" aria-label="Learn more about Generator services">Generator Services</Link>
|
<Link href="/electrical-services#generator" className="text-[color:var(--brand)] font-bold uppercase text-xs tracking-widest hover:underline" aria-label="Learn more about Kohler Generator services">Kohler Generator Services</Link>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
79
src/app/privacy-policy/page.tsx
Normal file
79
src/app/privacy-policy/page.tsx
Normal file
@@ -0,0 +1,79 @@
|
|||||||
|
import { Metadata } from "next";
|
||||||
|
import Image from "next/image";
|
||||||
|
|
||||||
|
export const metadata: Metadata = {
|
||||||
|
title: "Privacy Policy | Budd Electric Co.",
|
||||||
|
description: "Privacy policy for Budd Electric Co., a family-owned electrical contractor in Corpus Christi, TX. Learn how we collect, use, and protect your information.",
|
||||||
|
};
|
||||||
|
|
||||||
|
export default function PrivacyPolicy() {
|
||||||
|
return (
|
||||||
|
<div className="bg-[color:var(--bg)]">
|
||||||
|
{/* PAGE HERO */}
|
||||||
|
<section className="bg-[color:var(--bg-dark)] py-20 relative overflow-hidden -mt-20 pt-44">
|
||||||
|
<div className="absolute inset-0 opacity-10">
|
||||||
|
<Image
|
||||||
|
src="/images/hero-bg.png"
|
||||||
|
alt=""
|
||||||
|
fill
|
||||||
|
priority
|
||||||
|
quality={40}
|
||||||
|
sizes="100vw"
|
||||||
|
className="object-cover object-center"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div className="mx-auto max-w-7xl px-6 lg:px-8 relative z-10 text-center">
|
||||||
|
<h1 className="text-4xl md:text-6xl font-bold text-white font-display mb-6">Privacy Policy</h1>
|
||||||
|
<p className="text-xl text-gray-400 max-w-2xl mx-auto">
|
||||||
|
Last updated: June 23, 2026
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
{/* CONTENT */}
|
||||||
|
<section className="py-24">
|
||||||
|
<div className="mx-auto max-w-3xl px-6 lg:px-8">
|
||||||
|
<div className="prose prose-lg max-w-none text-[color:var(--muted)] space-y-8">
|
||||||
|
<p>
|
||||||
|
Budd Electric Co. (“we,” “us,” or “our”) respects your privacy. This policy explains what information we collect through our website, how we use it, and your choices.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<h2 className="text-2xl font-bold text-[color:var(--ink)] font-display mt-12">Information We Collect</h2>
|
||||||
|
<p>
|
||||||
|
We collect the information you voluntarily provide through our contact form, such as your name, email address, phone number, selected service type, and any message details. We may also collect basic technical information automatically, such as your browser type and general usage data, to help us operate and improve the site.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<h2 className="text-2xl font-bold text-[color:var(--ink)] font-display mt-12">How We Use Your Information</h2>
|
||||||
|
<p>
|
||||||
|
We use the information you submit solely to respond to your inquiries, provide quotes, schedule service, and communicate with you about our electrical services. We do not sell or rent your personal information to third parties.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<h2 className="text-2xl font-bold text-[color:var(--ink)] font-display mt-12">Sharing of Information</h2>
|
||||||
|
<p>
|
||||||
|
We may share information only with trusted service providers who help us operate our website and email communications (for example, our email delivery provider), and only as needed to provide those services. We may disclose information if required by law.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<h2 className="text-2xl font-bold text-[color:var(--ink)] font-display mt-12">Data Retention</h2>
|
||||||
|
<p>
|
||||||
|
We retain contact submissions only as long as necessary to respond to your request and for our normal business records.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<h2 className="text-2xl font-bold text-[color:var(--ink)] font-display mt-12">Your Choices</h2>
|
||||||
|
<p>
|
||||||
|
You may contact us at any time to ask what information we hold about you or to request that we delete it.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<h2 className="text-2xl font-bold text-[color:var(--ink)] font-display mt-12">Contact Us</h2>
|
||||||
|
<p>
|
||||||
|
If you have any questions about this Privacy Policy, contact us at <a href="mailto:buddelectric@grandecom.net" className="text-[color:var(--brand)] hover:underline">buddelectric@grandecom.net</a> or <a href="tel:+13618552255" className="text-[color:var(--brand)] hover:underline">(361) 855-2255</a>.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p className="italic text-sm text-gray-400 mt-12 border-t border-gray-200 pt-8">
|
||||||
|
This policy is provided for general informational purposes and does not constitute legal advice. Budd Electric Co. recommends reviewing it with a qualified attorney.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
79
src/app/terms-of-service/page.tsx
Normal file
79
src/app/terms-of-service/page.tsx
Normal file
@@ -0,0 +1,79 @@
|
|||||||
|
import { Metadata } from "next";
|
||||||
|
import Image from "next/image";
|
||||||
|
|
||||||
|
export const metadata: Metadata = {
|
||||||
|
title: "Terms of Service | Budd Electric Co.",
|
||||||
|
description: "Terms of service for the Budd Electric Co. website. Family-owned electrical contractor in Corpus Christi, TX since 1969.",
|
||||||
|
};
|
||||||
|
|
||||||
|
export default function TermsOfService() {
|
||||||
|
return (
|
||||||
|
<div className="bg-[color:var(--bg)]">
|
||||||
|
{/* PAGE HERO */}
|
||||||
|
<section className="bg-[color:var(--bg-dark)] py-20 relative overflow-hidden -mt-20 pt-44">
|
||||||
|
<div className="absolute inset-0 opacity-10">
|
||||||
|
<Image
|
||||||
|
src="/images/hero-bg.png"
|
||||||
|
alt=""
|
||||||
|
fill
|
||||||
|
priority
|
||||||
|
quality={40}
|
||||||
|
sizes="100vw"
|
||||||
|
className="object-cover object-center"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div className="mx-auto max-w-7xl px-6 lg:px-8 relative z-10 text-center">
|
||||||
|
<h1 className="text-4xl md:text-6xl font-bold text-white font-display mb-6">Terms of Service</h1>
|
||||||
|
<p className="text-xl text-gray-400 max-w-2xl mx-auto">
|
||||||
|
Last updated: June 23, 2026
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
{/* CONTENT */}
|
||||||
|
<section className="py-24">
|
||||||
|
<div className="mx-auto max-w-3xl px-6 lg:px-8">
|
||||||
|
<div className="prose prose-lg max-w-none text-[color:var(--muted)] space-y-8">
|
||||||
|
<p>
|
||||||
|
These Terms of Service (“Terms”) govern your use of the Budd Electric Co. website. By accessing or using this site, you agree to these Terms.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<h2 className="text-2xl font-bold text-[color:var(--ink)] font-display mt-12">Use of the Website</h2>
|
||||||
|
<p>
|
||||||
|
This website is provided for informational purposes to learn about Budd Electric Co.’s electrical services and to contact us. You agree to use the site only for lawful purposes.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<h2 className="text-2xl font-bold text-[color:var(--ink)] font-display mt-12">No Guarantee of Service</h2>
|
||||||
|
<p>
|
||||||
|
Submitting a contact form or request does not create a binding agreement for services. All electrical work is subject to a separate written estimate and agreement. Pricing, availability, and scheduling are confirmed directly with our team.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<h2 className="text-2xl font-bold text-[color:var(--ink)] font-display mt-12">Intellectual Property</h2>
|
||||||
|
<p>
|
||||||
|
All content on this website, including text, logos, and images, is the property of Budd Electric Co. or its licensors and may not be reproduced without permission.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<h2 className="text-2xl font-bold text-[color:var(--ink)] font-display mt-12">Disclaimer of Warranties</h2>
|
||||||
|
<p>
|
||||||
|
This website is provided “as is” without warranties of any kind. We do not guarantee that the site will be uninterrupted or error-free.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<h2 className="text-2xl font-bold text-[color:var(--ink)] font-display mt-12">Limitation of Liability</h2>
|
||||||
|
<p>
|
||||||
|
Budd Electric Co. is not liable for any indirect or incidental damages arising from your use of this website.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<h2 className="text-2xl font-bold text-[color:var(--ink)] font-display mt-12">Contact</h2>
|
||||||
|
<p>
|
||||||
|
Questions about these Terms can be directed to <a href="mailto:buddelectric@grandecom.net" className="text-[color:var(--brand)] hover:underline">buddelectric@grandecom.net</a> or <a href="tel:+13618552255" className="text-[color:var(--brand)] hover:underline">(361) 855-2255</a>.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p className="italic text-sm text-gray-400 mt-12 border-t border-gray-200 pt-8">
|
||||||
|
These Terms are provided for general informational purposes and do not constitute legal advice. Budd Electric Co. recommends reviewing them with a qualified attorney.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
95
src/components/ContactForm.tsx
Normal file
95
src/components/ContactForm.tsx
Normal file
@@ -0,0 +1,95 @@
|
|||||||
|
"use client";
|
||||||
|
|
||||||
|
import { useState } from "react";
|
||||||
|
|
||||||
|
export default function ContactForm() {
|
||||||
|
const [formData, setFormData] = useState({
|
||||||
|
firstName: "",
|
||||||
|
lastName: "",
|
||||||
|
email: "",
|
||||||
|
phone: "",
|
||||||
|
serviceType: "",
|
||||||
|
message: "",
|
||||||
|
});
|
||||||
|
const [status, setStatus] = useState<"idle" | "loading" | "success" | "error">("idle");
|
||||||
|
const [statusMessage, setStatusMessage] = useState("");
|
||||||
|
|
||||||
|
const handleChange = (e: React.ChangeEvent<HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement>) => {
|
||||||
|
setFormData((prev) => ({ ...prev, [e.target.name]: e.target.value }));
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleSubmit = async (e: React.FormEvent) => {
|
||||||
|
e.preventDefault();
|
||||||
|
setStatus("loading");
|
||||||
|
setStatusMessage("");
|
||||||
|
|
||||||
|
try {
|
||||||
|
const res = await fetch("/api/contact", {
|
||||||
|
method: "POST",
|
||||||
|
headers: { "Content-Type": "application/json" },
|
||||||
|
body: JSON.stringify(formData),
|
||||||
|
});
|
||||||
|
const data = await res.json();
|
||||||
|
|
||||||
|
if (res.ok) {
|
||||||
|
setStatus("success");
|
||||||
|
setStatusMessage("Thank you! Your message has been sent. We'll get back to you shortly.");
|
||||||
|
setFormData({ firstName: "", lastName: "", email: "", phone: "", serviceType: "", message: "" });
|
||||||
|
} else {
|
||||||
|
setStatus("error");
|
||||||
|
setStatusMessage(data.error || "Something went wrong. Please try again.");
|
||||||
|
}
|
||||||
|
} catch {
|
||||||
|
setStatus("error");
|
||||||
|
setStatusMessage("Network error. Please check your connection and try again.");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<form className="space-y-6" onSubmit={handleSubmit}>
|
||||||
|
<div className="grid grid-cols-2 gap-6">
|
||||||
|
<div className="space-y-2">
|
||||||
|
<label htmlFor="firstName" className="text-sm font-bold text-gray-700 uppercase tracking-wide">First Name</label>
|
||||||
|
<input id="firstName" name="firstName" type="text" required value={formData.firstName} onChange={handleChange} className="w-full bg-gray-50 border border-gray-200 p-3 rounded focus:outline-none focus:border-[color:var(--brand)] focus:ring-1 focus:ring-[color:var(--brand)]" />
|
||||||
|
</div>
|
||||||
|
<div className="space-y-2">
|
||||||
|
<label htmlFor="lastName" className="text-sm font-bold text-gray-700 uppercase tracking-wide">Last Name</label>
|
||||||
|
<input id="lastName" name="lastName" type="text" required value={formData.lastName} onChange={handleChange} className="w-full bg-gray-50 border border-gray-200 p-3 rounded focus:outline-none focus:border-[color:var(--brand)] focus:ring-1 focus:ring-[color:var(--brand)]" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="space-y-2">
|
||||||
|
<label htmlFor="email" className="text-sm font-bold text-gray-700 uppercase tracking-wide">Email</label>
|
||||||
|
<input id="email" name="email" type="email" required value={formData.email} onChange={handleChange} className="w-full bg-gray-50 border border-gray-200 p-3 rounded focus:outline-none focus:border-[color:var(--brand)] focus:ring-1 focus:ring-[color:var(--brand)]" />
|
||||||
|
</div>
|
||||||
|
<div className="space-y-2">
|
||||||
|
<label htmlFor="phone" className="text-sm font-bold text-gray-700 uppercase tracking-wide">Phone</label>
|
||||||
|
<input id="phone" name="phone" type="tel" required value={formData.phone} onChange={handleChange} className="w-full bg-gray-50 border border-gray-200 p-3 rounded focus:outline-none focus:border-[color:var(--brand)] focus:ring-1 focus:ring-[color:var(--brand)]" />
|
||||||
|
</div>
|
||||||
|
<div className="space-y-2">
|
||||||
|
<label htmlFor="serviceType" className="text-sm font-bold text-gray-700 uppercase tracking-wide">Service Type</label>
|
||||||
|
<select id="serviceType" name="serviceType" required value={formData.serviceType} onChange={handleChange} className="w-full bg-gray-50 border border-gray-200 p-3 rounded focus:outline-none focus:border-[color:var(--brand)] focus:ring-1 focus:ring-[color:var(--brand)]">
|
||||||
|
<option value="">Select a service type</option>
|
||||||
|
<option value="commercial">Commercial Project</option>
|
||||||
|
<option value="residential">Residential Project</option>
|
||||||
|
<option value="generator">Generator Inquiry</option>
|
||||||
|
<option value="other">Other</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div className="space-y-2">
|
||||||
|
<label htmlFor="message" className="text-sm font-bold text-gray-700 uppercase tracking-wide">Message</label>
|
||||||
|
<textarea id="message" name="message" rows={4} required value={formData.message} onChange={handleChange} className="w-full bg-gray-50 border border-gray-200 p-3 rounded focus:outline-none focus:border-[color:var(--brand)] focus:ring-1 focus:ring-[color:var(--brand)]"></textarea>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{status === "success" && (
|
||||||
|
<div className="p-3 bg-green-50 border border-green-200 rounded text-green-700 text-sm">{statusMessage}</div>
|
||||||
|
)}
|
||||||
|
{status === "error" && (
|
||||||
|
<div className="p-3 bg-red-50 border border-red-200 rounded text-red-700 text-sm">{statusMessage}</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
<button type="submit" disabled={status === "loading"} className="w-full bg-[color:var(--brand)] text-white font-bold uppercase tracking-widest py-4 rounded hover:bg-[color:var(--brand-strong)] transition shadow-lg disabled:opacity-50 disabled:cursor-not-allowed">
|
||||||
|
{status === "loading" ? "Sending..." : "Send Message"}
|
||||||
|
</button>
|
||||||
|
</form>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -219,8 +219,8 @@ export default function Footer() {
|
|||||||
<div className="border-t border-white/5 pt-8 flex flex-col md:flex-row justify-between items-center text-gray-500 text-xs uppercase tracking-wider">
|
<div className="border-t border-white/5 pt-8 flex flex-col md:flex-row justify-between items-center text-gray-500 text-xs uppercase tracking-wider">
|
||||||
<p>© {new Date().getFullYear()} Budd Electric Co. TECL #17007</p>
|
<p>© {new Date().getFullYear()} Budd Electric Co. TECL #17007</p>
|
||||||
<div className="flex gap-6 mt-4 md:mt-0">
|
<div className="flex gap-6 mt-4 md:mt-0">
|
||||||
<Link href="https://www.thryv.com/client-privacy-policy/" target="_blank" rel="noopener noreferrer" className="hover:text-white transition-colors">Privacy Policy</Link>
|
<Link href="/privacy-policy" className="hover:text-white transition-colors">Privacy Policy</Link>
|
||||||
<Link href="https://www.thryv.com/client-terms-of-use/" target="_blank" rel="noopener noreferrer" className="hover:text-white transition-colors">Terms of Service</Link>
|
<Link href="/terms-of-service" className="hover:text-white transition-colors">Terms of Service</Link>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ export default function Header() {
|
|||||||
href="/contact-us"
|
href="/contact-us"
|
||||||
className="hidden lg:flex items-center gap-2 rounded bg-[color:var(--brand)] px-5 py-2.5 text-sm font-bold text-white shadow-lg shadow-red-900/20 transition hover:bg-[color:var(--brand-strong)] uppercase tracking-wider"
|
className="hidden lg:flex items-center gap-2 rounded bg-[color:var(--brand)] px-5 py-2.5 text-sm font-bold text-white shadow-lg shadow-red-900/20 transition hover:bg-[color:var(--brand-strong)] uppercase tracking-wider"
|
||||||
>
|
>
|
||||||
Free Quote
|
Contact Us
|
||||||
<ArrowRight size={14} strokeWidth={3} />
|
<ArrowRight size={14} strokeWidth={3} />
|
||||||
</Link>
|
</Link>
|
||||||
<button
|
<button
|
||||||
@@ -117,7 +117,7 @@ export default function Header() {
|
|||||||
onClick={() => setMobileMenuOpen(false)}
|
onClick={() => setMobileMenuOpen(false)}
|
||||||
className="flex items-center justify-center gap-2 rounded bg-[color:var(--brand)] px-7 py-4 text-sm font-bold text-white shadow-lg shadow-red-900/20 transition hover:bg-[color:var(--brand-strong)] hover:shadow-red-900/40 uppercase tracking-wider w-full"
|
className="flex items-center justify-center gap-2 rounded bg-[color:var(--brand)] px-7 py-4 text-sm font-bold text-white shadow-lg shadow-red-900/20 transition hover:bg-[color:var(--brand-strong)] hover:shadow-red-900/40 uppercase tracking-wider w-full"
|
||||||
>
|
>
|
||||||
Get a Quote
|
Contact Us
|
||||||
<ArrowRight size={16} strokeWidth={3} />
|
<ArrowRight size={16} strokeWidth={3} />
|
||||||
</Link>
|
</Link>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
74
src/components/NewspaperClipping.tsx
Normal file
74
src/components/NewspaperClipping.tsx
Normal file
@@ -0,0 +1,74 @@
|
|||||||
|
"use client";
|
||||||
|
|
||||||
|
import { useState, useEffect, useCallback } from "react";
|
||||||
|
import Image from "next/image";
|
||||||
|
import { X } from "lucide-react";
|
||||||
|
|
||||||
|
export default function NewspaperClipping() {
|
||||||
|
const [open, setOpen] = useState(false);
|
||||||
|
|
||||||
|
const close = useCallback(() => setOpen(false), []);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (!open) return;
|
||||||
|
const handleKey = (e: KeyboardEvent) => {
|
||||||
|
if (e.key === "Escape") close();
|
||||||
|
};
|
||||||
|
document.addEventListener("keydown", handleKey);
|
||||||
|
document.body.style.overflow = "hidden";
|
||||||
|
return () => {
|
||||||
|
document.removeEventListener("keydown", handleKey);
|
||||||
|
document.body.style.overflow = "";
|
||||||
|
};
|
||||||
|
}, [open, close]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<div
|
||||||
|
className="aspect-[4/3] rounded-lg overflow-hidden bg-gray-100 shadow-xl border-l-8 border-[color:var(--brand)] cursor-pointer group relative"
|
||||||
|
onClick={() => setOpen(true)}
|
||||||
|
>
|
||||||
|
<Image
|
||||||
|
src="/images/newspaper.webp"
|
||||||
|
alt="Budd Electric Co. featured in the local newspaper"
|
||||||
|
fill
|
||||||
|
sizes="(max-width: 1024px) 100vw, 50vw"
|
||||||
|
className="object-contain p-3 group-hover:scale-105 transition-transform duration-300"
|
||||||
|
loading="lazy"
|
||||||
|
/>
|
||||||
|
<div className="absolute inset-0 bg-black/0 group-hover:bg-black/10 transition-colors flex items-center justify-center">
|
||||||
|
<span className="text-white text-sm font-bold opacity-0 group-hover:opacity-100 transition-opacity bg-black/60 px-4 py-2 rounded">Click to enlarge</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<p className="mt-3 text-center text-sm text-gray-400 italic">Featured in the local press</p>
|
||||||
|
|
||||||
|
{open && (
|
||||||
|
<div
|
||||||
|
className="fixed inset-0 z-50 bg-black/85 flex items-center justify-center p-4 md:p-8"
|
||||||
|
onClick={close}
|
||||||
|
>
|
||||||
|
<button
|
||||||
|
onClick={close}
|
||||||
|
className="absolute top-4 right-4 text-white/80 hover:text-white transition-colors z-10"
|
||||||
|
aria-label="Close"
|
||||||
|
>
|
||||||
|
<X size={36} strokeWidth={2} />
|
||||||
|
</button>
|
||||||
|
<div
|
||||||
|
className="relative max-w-5xl w-full max-h-[90vh]"
|
||||||
|
onClick={(e) => e.stopPropagation()}
|
||||||
|
>
|
||||||
|
<Image
|
||||||
|
src="/images/newspaper.webp"
|
||||||
|
alt="Budd Electric Co. featured in the local newspaper"
|
||||||
|
width={1600}
|
||||||
|
height={1200}
|
||||||
|
className="object-contain w-full h-full max-h-[90vh]"
|
||||||
|
unoptimized
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user