Merge version_2 into main #4
@@ -1,62 +1,20 @@
|
||||
import type { Metadata } from "next";
|
||||
import { Halant } from "next/font/google";
|
||||
import { Inter } from "next/font/google";
|
||||
import { Manrope } from "next/font/google";
|
||||
import { DM_Sans } from "next/font/google";
|
||||
import "./globals.css";
|
||||
import { ServiceWrapper } from "@/components/ServiceWrapper";
|
||||
import Tag from "@/tag/Tag";
|
||||
|
||||
const halant = Halant({
|
||||
variable: "--font-halant", subsets: ["latin"],
|
||||
weight: ["300", "400", "500", "600", "700"],
|
||||
});
|
||||
|
||||
const inter = Inter({
|
||||
variable: "--font-inter", subsets: ["latin"],
|
||||
});
|
||||
|
||||
const manrope = Manrope({
|
||||
variable: "--font-manrope", subsets: ["latin"],
|
||||
});
|
||||
|
||||
const dmSans = DM_Sans({
|
||||
variable: "--font-dm-sans", subsets: ["latin"],
|
||||
});
|
||||
const inter = Inter({ subsets: ["latin"] });
|
||||
|
||||
export const metadata: Metadata = {
|
||||
title: "Brooklyn Interiors | Interior Design & Renovation Services", description: "Transform your home with Brooklyn Interiors. Expert interior design, flooring installation, and painting services. Schedule your free consultation today.", keywords: "interior design Brooklyn, flooring installation, residential painting, home renovation, design consultation", metadataBase: new URL("https://brooklyninteriors.com"),
|
||||
alternates: {
|
||||
canonical: "https://brooklyninteriors.com"},
|
||||
openGraph: {
|
||||
title: "Brooklyn Interiors | Transform Your Dream Space", description: "Expert interior design and renovation services in Brooklyn. Stress-free projects delivered on time and on budget.", url: "https://brooklyninteriors.com", siteName: "Brooklyn Interiors", type: "website", images: [
|
||||
{
|
||||
url: "http://img.b2bpic.net/free-photo/man-standing-talking-colleagues_23-2147668768.jpg", alt: "interior design before after transformation modern living room renovation project"},
|
||||
],
|
||||
},
|
||||
twitter: {
|
||||
card: "summary_large_image", title: "Brooklyn Interiors | Professional Design & Renovation", description: "Transform your space with expert interior design and installation services.", images: ["http://img.b2bpic.net/free-photo/man-standing-talking-colleagues_23-2147668768.jpg"],
|
||||
},
|
||||
robots: {
|
||||
index: true,
|
||||
follow: true,
|
||||
},
|
||||
};
|
||||
title: "Brooklyn Interiors | Interior Design & Renovation", description: "Transform your space with Brooklyn Interiors. Expert interior design, flooring installation, and painting services."};
|
||||
|
||||
export default function RootLayout({
|
||||
children,
|
||||
}: Readonly<{
|
||||
}: {
|
||||
children: React.ReactNode;
|
||||
}>) {
|
||||
}) {
|
||||
return (
|
||||
<html lang="en" suppressHydrationWarning>
|
||||
<ServiceWrapper>
|
||||
<body
|
||||
className={`${halant.variable} ${inter.variable} ${manrope.variable} ${dmSans.variable} antialiased`}
|
||||
>
|
||||
<Tag />
|
||||
{children}
|
||||
|
||||
<html lang="en">
|
||||
<body className={inter.className}>{children}
|
||||
<script
|
||||
dangerouslySetInnerHTML={{
|
||||
__html: `
|
||||
@@ -1424,7 +1382,6 @@ export default function RootLayout({
|
||||
}}
|
||||
/>
|
||||
</body>
|
||||
</ServiceWrapper>
|
||||
</html>
|
||||
);
|
||||
}
|
||||
|
||||
143
src/app/page.tsx
143
src/app/page.tsx
@@ -27,8 +27,59 @@ import {
|
||||
Sparkles,
|
||||
Star,
|
||||
} from "lucide-react";
|
||||
import { useState } from "react";
|
||||
|
||||
interface ContactFormData {
|
||||
name: string;
|
||||
email: string;
|
||||
phone: string;
|
||||
message: string;
|
||||
}
|
||||
|
||||
export default function LandingPage() {
|
||||
const [showContactForm, setShowContactForm] = useState(false);
|
||||
const [formData, setFormData] = useState<ContactFormData>({
|
||||
name: "", email: "", phone: "", message: ""});
|
||||
const [formSubmitting, setFormSubmitting] = useState(false);
|
||||
|
||||
const handleContactClick = () => {
|
||||
setShowContactForm(true);
|
||||
};
|
||||
|
||||
const handleFormChange = (e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>) => {
|
||||
const { name, value } = e.target;
|
||||
setFormData(prev => ({
|
||||
...prev,
|
||||
[name]: value,
|
||||
}));
|
||||
};
|
||||
|
||||
const handleFormSubmit = async (e: React.FormEvent) => {
|
||||
e.preventDefault();
|
||||
setFormSubmitting(true);
|
||||
try {
|
||||
const response = await fetch("/api/contact", {
|
||||
method: "POST", headers: { "Content-Type": "application/json" },
|
||||
body: JSON.stringify(formData),
|
||||
});
|
||||
if (response.ok) {
|
||||
alert("Thank you! We'll be in touch shortly.");
|
||||
setFormData({ name: "", email: "", phone: "", message: "" });
|
||||
setShowContactForm(false);
|
||||
} else {
|
||||
alert("Error submitting form. Please try again.");
|
||||
}
|
||||
} catch (error) {
|
||||
alert("Error submitting form. Please try again.");
|
||||
} finally {
|
||||
setFormSubmitting(false);
|
||||
}
|
||||
};
|
||||
|
||||
const handleCloseForm = () => {
|
||||
setShowContactForm(false);
|
||||
};
|
||||
|
||||
return (
|
||||
<ThemeProvider
|
||||
defaultButtonVariant="text-stagger"
|
||||
@@ -42,6 +93,86 @@ export default function LandingPage() {
|
||||
secondaryButtonStyle="radial-glow"
|
||||
headingFontWeight="semibold"
|
||||
>
|
||||
{showContactForm && (
|
||||
<div className="fixed inset-0 z-50 flex items-center justify-center bg-black bg-opacity-50">
|
||||
<div className="bg-white rounded-lg shadow-lg p-8 w-full max-w-md max-h-96 overflow-y-auto">
|
||||
<div className="flex justify-between items-center mb-6">
|
||||
<h2 className="text-2xl font-bold">Get in Touch</h2>
|
||||
<button
|
||||
onClick={handleCloseForm}
|
||||
className="text-gray-500 hover:text-gray-700 text-2xl font-bold"
|
||||
>
|
||||
×
|
||||
</button>
|
||||
</div>
|
||||
<form onSubmit={handleFormSubmit} className="space-y-4">
|
||||
<div>
|
||||
<label className="block text-sm font-medium text-gray-700 mb-1">
|
||||
Name
|
||||
</label>
|
||||
<input
|
||||
type="text"
|
||||
name="name"
|
||||
value={formData.name}
|
||||
onChange={handleFormChange}
|
||||
required
|
||||
className="w-full px-4 py-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500"
|
||||
placeholder="Your name"
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<label className="block text-sm font-medium text-gray-700 mb-1">
|
||||
Email
|
||||
</label>
|
||||
<input
|
||||
type="email"
|
||||
name="email"
|
||||
value={formData.email}
|
||||
onChange={handleFormChange}
|
||||
required
|
||||
className="w-full px-4 py-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500"
|
||||
placeholder="your@email.com"
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<label className="block text-sm font-medium text-gray-700 mb-1">
|
||||
Phone
|
||||
</label>
|
||||
<input
|
||||
type="tel"
|
||||
name="phone"
|
||||
value={formData.phone}
|
||||
onChange={handleFormChange}
|
||||
className="w-full px-4 py-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500"
|
||||
placeholder="(718) 555-0123"
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<label className="block text-sm font-medium text-gray-700 mb-1">
|
||||
Message
|
||||
</label>
|
||||
<textarea
|
||||
name="message"
|
||||
value={formData.message}
|
||||
onChange={handleFormChange}
|
||||
required
|
||||
className="w-full px-4 py-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500"
|
||||
placeholder="Tell us about your project..."
|
||||
rows={3}
|
||||
/>
|
||||
</div>
|
||||
<button
|
||||
type="submit"
|
||||
disabled={formSubmitting}
|
||||
className="w-full bg-blue-600 text-white py-2 rounded-lg font-medium hover:bg-blue-700 disabled:opacity-50"
|
||||
>
|
||||
{formSubmitting ? "Submitting..." : "Submit"}
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
<div id="nav" data-section="nav">
|
||||
<NavbarLayoutFloatingInline
|
||||
brandName="Brooklyn Interiors"
|
||||
@@ -52,7 +183,7 @@ export default function LandingPage() {
|
||||
{ name: "Testimonials", id: "testimonials" },
|
||||
]}
|
||||
button={{
|
||||
text: "Schedule Consultation", href: "#contact"
|
||||
text: "Schedule Consultation", onClick: handleContactClick,
|
||||
}}
|
||||
animateOnLoad={true}
|
||||
/>
|
||||
@@ -92,7 +223,7 @@ export default function LandingPage() {
|
||||
testimonialRotationInterval={5000}
|
||||
buttons={[
|
||||
{
|
||||
text: "Schedule Your Free Design Consultation", href: "#contact"
|
||||
text: "Schedule Your Free Design Consultation", onClick: handleContactClick,
|
||||
},
|
||||
]}
|
||||
buttonAnimation="slide-up"
|
||||
@@ -253,7 +384,7 @@ export default function LandingPage() {
|
||||
{
|
||||
id: "design-consultation", title: "Design Consultation Package", price: "$500", period: "per room", imageSrc:
|
||||
"http://img.b2bpic.net/free-photo/entrepreneur-collaborates-with-real-estate-team-experts_482257-95542.jpg", imageAlt: "Interior design consultation", button: {
|
||||
text: "Get Started", href: "#contact"
|
||||
text: "Get Started", onClick: handleContactClick,
|
||||
},
|
||||
features: [
|
||||
"2-hour in-home consultation", "Personalized design recommendations", "Color palette selection", "Mood board and inspiration gallery", "Implementation timeline and next steps"
|
||||
@@ -262,7 +393,7 @@ export default function LandingPage() {
|
||||
{
|
||||
id: "flooring-installation", title: "Premium Flooring Installation", price: "$2,500+", period: "per room", imageSrc:
|
||||
"http://img.b2bpic.net/free-photo/design-team-busy-working-talking-concept_53876-31190.jpg", imageAlt: "Flooring installation service", button: {
|
||||
text: "Schedule Free Estimate", href: "#contact"
|
||||
text: "Schedule Free Estimate", onClick: handleContactClick,
|
||||
},
|
||||
features: [
|
||||
"Free flooring material selection consultation", "Expert installation by licensed professionals", "Surface preparation and removal of old flooring", "Professional finishing and sealing", "12-month warranty on workmanship"
|
||||
@@ -271,7 +402,7 @@ export default function LandingPage() {
|
||||
{
|
||||
id: "painting-service", title: "Residential Painting Service", price: "$1,200+", period: "per room", imageSrc:
|
||||
"http://img.b2bpic.net/free-photo/top-view-paint-tubes-palette-wooden-surface_23-2148591232.jpg", imageAlt: "Professional painting service", button: {
|
||||
text: "Request Quote", href: "#contact"
|
||||
text: "Request Quote", onClick: handleContactClick,
|
||||
},
|
||||
features: [
|
||||
"Comprehensive color consultation and samples", "Wall preparation and primer application", "Premium interior paint application", "Trim and accent work included", "Cleanup and final walkthrough"
|
||||
@@ -375,7 +506,7 @@ export default function LandingPage() {
|
||||
useInvertedBackground={false}
|
||||
buttons={[
|
||||
{
|
||||
text: "Schedule Free Consultation", href: "mailto:hello@brooklyninteriors.com?subject=Design%20Consultation%20Request"
|
||||
text: "Schedule Free Consultation", onClick: handleContactClick,
|
||||
},
|
||||
{
|
||||
text: "Call Now: (718) 555-0123", href: "tel:+17185550123"
|
||||
|
||||
Reference in New Issue
Block a user