Compare commits
55 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 5f6dcacc6e | |||
| 252e3182aa | |||
| f7820690ad | |||
| ef397ae2ff | |||
| 90f7b1c37f | |||
| f143e629cb | |||
| 1d5eb0daa5 | |||
| 1481d8893b | |||
| aaa87ce578 | |||
| 18065969f5 | |||
| e98c8c5d5f | |||
| 175ae4498f | |||
| 50df1b89f7 | |||
| 371275a0d2 | |||
| 2147f00101 | |||
| c6827bc6d0 | |||
| fc457c0111 | |||
| 4139dce37d | |||
| 1e0131b52a | |||
| 5cccffb965 | |||
| 1475426aa2 | |||
| 77cb47421f | |||
| 94d17eaf5c | |||
| 84a9b6cced | |||
| a3b72f5294 | |||
| 1820e0dc1e | |||
| dc66382035 | |||
| 0eefa55441 | |||
| a6aee2f71c | |||
| 1ae8fd9c0d | |||
| 63b2abab97 | |||
| cc9fc90796 | |||
| 177b11fff0 | |||
| 314e5a2155 | |||
| d68596f792 | |||
| fd99c4098d | |||
| cafccc2bb9 | |||
| aed9b2b98b | |||
| 0de718b267 | |||
| f79ca3bf25 | |||
| 2a475c3569 | |||
| b3b369f9a3 | |||
| 524ef9d2ce | |||
| 8270ed02f9 | |||
| a3f3535ec4 | |||
| 6dc81c2d06 | |||
| 1c1a14a2f9 | |||
| eeef14991b | |||
| 59d92bb9fb | |||
| 5ddfd5cd4c | |||
| 9b2b897371 | |||
| e177fba23a | |||
| d57373f1c4 | |||
| 2a7607af45 | |||
| e68a449496 |
147
src/app/admin/page.tsx
Normal file
147
src/app/admin/page.tsx
Normal file
@@ -0,0 +1,147 @@
|
||||
"use client";
|
||||
|
||||
import { ThemeProvider } from "@/components/theme/ThemeProvider";
|
||||
import NavbarLayoutFloatingInline from "@/components/navbar/NavbarLayoutFloatingInline";
|
||||
import { ReactLenis } from "lenis/react";
|
||||
|
||||
interface Request {
|
||||
id: string;
|
||||
clientName: string;
|
||||
address: string;
|
||||
issueType: string;
|
||||
membershipPlan: string;
|
||||
status: "pending" | "in-progress" | "completed" | "cancelled";
|
||||
}
|
||||
|
||||
const mockRequests: Request[] = [
|
||||
{
|
||||
id: "REQ-001", clientName: "John Smith", address: "123 Main St, Springfield, IL 62701", issueType: "Plumbing", membershipPlan: "Premium", status: "in-progress"},
|
||||
{
|
||||
id: "REQ-002", clientName: "Sarah Johnson", address: "456 Oak Ave, Chicago, IL 60601", issueType: "HVAC", membershipPlan: "Standard", status: "pending"},
|
||||
{
|
||||
id: "REQ-003", clientName: "Michael Chen", address: "789 Elm Rd, Naperville, IL 60540", issueType: "Electrical", membershipPlan: "Premium", status: "completed"},
|
||||
{
|
||||
id: "REQ-004", clientName: "Emma Davis", address: "321 Pine St, Evanston, IL 60201", issueType: "Roofing", membershipPlan: "Basic", status: "pending"},
|
||||
{
|
||||
id: "REQ-005", clientName: "Robert Wilson", address: "654 Maple Dr, Aurora, IL 60505", issueType: "Plumbing", membershipPlan: "Standard", status: "completed"},
|
||||
];
|
||||
|
||||
const getStatusColor = (status: string) => {
|
||||
switch (status) {
|
||||
case "completed":
|
||||
return "bg-green-100 text-green-800";
|
||||
case "in-progress":
|
||||
return "bg-blue-100 text-blue-800";
|
||||
case "pending":
|
||||
return "bg-yellow-100 text-yellow-800";
|
||||
case "cancelled":
|
||||
return "bg-red-100 text-red-800";
|
||||
default:
|
||||
return "bg-gray-100 text-gray-800";
|
||||
}
|
||||
};
|
||||
|
||||
export default function AdminDashboard() {
|
||||
return (
|
||||
<ThemeProvider
|
||||
defaultButtonVariant="hover-magnetic"
|
||||
defaultTextAnimation="entrance-slide"
|
||||
borderRadius="rounded"
|
||||
contentWidth="medium"
|
||||
sizing="medium"
|
||||
background="none"
|
||||
cardStyle="solid"
|
||||
primaryButtonStyle="gradient"
|
||||
secondaryButtonStyle="solid"
|
||||
headingFontWeight="semibold"
|
||||
>
|
||||
<ReactLenis root>
|
||||
<NavbarLayoutFloatingInline
|
||||
navItems={[
|
||||
{ name: "Home", id: "/" },
|
||||
{ name: "Dashboard", id: "/admin" },
|
||||
{ name: "Settings", id: "#settings" },
|
||||
{ name: "Support", id: "#support" },
|
||||
]}
|
||||
brandName="OW HomeShield"
|
||||
button={{
|
||||
text: "Logout", onClick: () => {
|
||||
console.log("Logout clicked");
|
||||
},
|
||||
}}
|
||||
animateOnLoad={true}
|
||||
/>
|
||||
<div id="admin-dashboard" data-section="admin-dashboard" className="min-h-screen bg-background pt-32 pb-16 px-4 sm:px-6 lg:px-8">
|
||||
<div className="max-w-7xl mx-auto">
|
||||
{/* Header */}
|
||||
<div className="mb-8">
|
||||
<h1 className="text-4xl font-bold text-foreground mb-2">Admin Dashboard</h1>
|
||||
<p className="text-foreground/60">Manage customer requests and track service status</p>
|
||||
</div>
|
||||
|
||||
{/* Table Container */}
|
||||
<div className="rounded-lg border border-card bg-card overflow-hidden shadow-sm">
|
||||
<div className="overflow-x-auto">
|
||||
<table className="w-full">
|
||||
<thead>
|
||||
<tr className="border-b border-background bg-background/50">
|
||||
<th className="px-6 py-4 text-left text-sm font-semibold text-foreground">Request ID</th>
|
||||
<th className="px-6 py-4 text-left text-sm font-semibold text-foreground">Client Name</th>
|
||||
<th className="px-6 py-4 text-left text-sm font-semibold text-foreground">Address</th>
|
||||
<th className="px-6 py-4 text-left text-sm font-semibold text-foreground">Issue Type</th>
|
||||
<th className="px-6 py-4 text-left text-sm font-semibold text-foreground">Membership Plan</th>
|
||||
<th className="px-6 py-4 text-left text-sm font-semibold text-foreground">Status</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{mockRequests.map((request, index) => (
|
||||
<tr
|
||||
key={request.id}
|
||||
className={`border-b border-background ${index % 2 === 0 ? "bg-white" : "bg-background/30"} hover:bg-background/50 transition-colors`}
|
||||
>
|
||||
<td className="px-6 py-4 text-sm text-foreground font-medium">{request.id}</td>
|
||||
<td className="px-6 py-4 text-sm text-foreground">{request.clientName}</td>
|
||||
<td className="px-6 py-4 text-sm text-foreground/80">{request.address}</td>
|
||||
<td className="px-6 py-4 text-sm text-foreground">{request.issueType}</td>
|
||||
<td className="px-6 py-4 text-sm text-foreground">
|
||||
<span className="inline-flex items-center px-3 py-1 rounded-full text-xs font-medium bg-primary-cta/10 text-primary-cta">
|
||||
{request.membershipPlan}
|
||||
</span>
|
||||
</td>
|
||||
<td className="px-6 py-4 text-sm">
|
||||
<span className={`inline-flex items-center px-3 py-1 rounded-full text-xs font-medium ${getStatusColor(request.status)}`}>
|
||||
{request.status.charAt(0).toUpperCase() + request.status.slice(1)}
|
||||
</span>
|
||||
</td>
|
||||
</tr>
|
||||
))}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Summary Stats */}
|
||||
<div className="mt-8 grid grid-cols-1 md:grid-cols-4 gap-4">
|
||||
<div className="bg-card rounded-lg border border-background p-6">
|
||||
<p className="text-sm text-foreground/60 mb-2">Total Requests</p>
|
||||
<p className="text-3xl font-bold text-foreground">{mockRequests.length}</p>
|
||||
</div>
|
||||
<div className="bg-card rounded-lg border border-background p-6">
|
||||
<p className="text-sm text-foreground/60 mb-2">Pending</p>
|
||||
<p className="text-3xl font-bold text-yellow-600">{mockRequests.filter(r => r.status === "pending").length}</p>
|
||||
</div>
|
||||
<div className="bg-card rounded-lg border border-background p-6">
|
||||
<p className="text-sm text-foreground/60 mb-2">In Progress</p>
|
||||
<p className="text-3xl font-bold text-blue-600">{mockRequests.filter(r => r.status === "in-progress").length}</p>
|
||||
</div>
|
||||
<div className="bg-card rounded-lg border border-background p-6">
|
||||
<p className="text-sm text-foreground/60 mb-2">Completed</p>
|
||||
<p className="text-3xl font-bold text-green-600">{mockRequests.filter(r => r.status === "completed").length}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</ReactLenis>
|
||||
</ThemeProvider>
|
||||
);
|
||||
}
|
||||
@@ -1,252 +1,258 @@
|
||||
"use client";
|
||||
|
||||
import { ThemeProvider } from "@/providers/themeProvider/ThemeProvider";
|
||||
import NavbarLayoutFloatingOverlay from "@/components/navbar/NavbarLayoutFloatingOverlay/NavbarLayoutFloatingOverlay";
|
||||
import HeroBillboard from "@/components/sections/hero/HeroBillboard";
|
||||
import TextSplitAbout from "@/components/sections/about/TextSplitAbout";
|
||||
import FeatureCardOne from "@/components/sections/feature/FeatureCardOne";
|
||||
import { ThemeProvider } from "@/components/theme/ThemeProvider";
|
||||
import NavbarStyleFullscreen from "@/components/navbar/NavbarStyleFullscreen/NavbarStyleFullscreen";
|
||||
import HeroBillboardTestimonial from "@/components/sections/hero/HeroBillboardTestimonial";
|
||||
import MediaAbout from "@/components/sections/about/MediaAbout";
|
||||
import FeatureCardTwelve from "@/components/sections/feature/FeatureCardTwelve";
|
||||
import ProductCardFour from "@/components/sections/product/ProductCardFour";
|
||||
import PricingCardThree from "@/components/sections/pricing/PricingCardThree";
|
||||
import PricingCardTwo from "@/components/sections/pricing/PricingCardTwo";
|
||||
import TestimonialCardTwo from "@/components/sections/testimonial/TestimonialCardTwo";
|
||||
import PricingCardNine from "@/components/sections/pricing/PricingCardNine";
|
||||
import { PricingCardTwo } from "@/components/sections/pricing/PricingCardTwo";
|
||||
import TestimonialCardSix from "@/components/sections/testimonial/TestimonialCardSix";
|
||||
import ContactSplit from "@/components/sections/contact/ContactSplit";
|
||||
import FooterBase from "@/components/sections/footer/FooterBase";
|
||||
import FooterCard from "@/components/sections/footer/FooterCard";
|
||||
import { Phone, Mail, MapPin, Sparkles } from "lucide-react";
|
||||
import FooterBaseCard from "@/components/sections/footer/FooterBaseCard";
|
||||
import FooterSimple from "@/components/sections/footer/FooterSimple";
|
||||
import { Mail, Phone, MapPin } from "lucide-react";
|
||||
|
||||
export default function ContactPage() {
|
||||
const navItems = [
|
||||
{ name: "Home", id: "/" },
|
||||
{ name: "Contact", id: "/contact" },
|
||||
];
|
||||
|
||||
return (
|
||||
<ThemeProvider
|
||||
defaultButtonVariant="hover-bubble"
|
||||
defaultButtonVariant="hover-magnetic"
|
||||
defaultTextAnimation="entrance-slide"
|
||||
borderRadius="rounded"
|
||||
contentWidth="small"
|
||||
sizing="largeSmallSizeLargeTitles"
|
||||
background="circleGradient"
|
||||
cardStyle="inset"
|
||||
primaryButtonStyle="radial-glow"
|
||||
secondaryButtonStyle="layered"
|
||||
headingFontWeight="medium"
|
||||
contentWidth="medium"
|
||||
sizing="medium"
|
||||
background="none"
|
||||
cardStyle="solid"
|
||||
primaryButtonStyle="gradient"
|
||||
secondaryButtonStyle="glass"
|
||||
headingFontWeight="bold"
|
||||
>
|
||||
<div id="nav" data-section="nav">
|
||||
<NavbarLayoutFloatingOverlay
|
||||
brandName="OW HomeShield Inc."
|
||||
navItems={[
|
||||
{ name: "Home", id: "/" },
|
||||
{ name: "Contact", id: "/contact" },
|
||||
{ name: "About", id: "#about" },
|
||||
{ name: "Pricing", id: "#pricing" }
|
||||
]}
|
||||
button={{
|
||||
text: "Call Now: 226-224-3573", href: "tel:226-224-3573"
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
<NavbarStyleFullscreen
|
||||
navItems={navItems}
|
||||
brandName="OW HomeShield"
|
||||
bottomLeftText="Available 24/7"
|
||||
bottomRightText="support@owhomeshield.com"
|
||||
/>
|
||||
|
||||
<div id="hero" data-section="hero">
|
||||
<HeroBillboard
|
||||
<HeroBillboardTestimonial
|
||||
title="Get in Touch with OW HomeShield"
|
||||
description="Have questions about our membership plans or need immediate service? We're here to help. Contact our team today."
|
||||
description="We're here to help with all your home maintenance and repair needs. Contact us today for a consultation or to learn more about our membership plans."
|
||||
tag="Contact Us"
|
||||
tagAnimation="slide-up"
|
||||
background={{ variant: "plain" }}
|
||||
buttons={[
|
||||
{ text: "Call Now", href: "tel:226-224-3573" },
|
||||
{ text: "Email Us", href: "mailto:info@owhomeshield.com" }
|
||||
background={{ variant: "glowing-orb" }}
|
||||
imageSrc="/hero-contact.jpg"
|
||||
imageAlt="Contact OW HomeShield"
|
||||
mediaAnimation="slide-up"
|
||||
testimonials={[
|
||||
{
|
||||
name: "John Miller", handle: "Homeowner", testimonial:
|
||||
"OW HomeShield's support team responded within minutes. Professional and courteous service!", rating: 5,
|
||||
imageSrc: "/avatar1.jpg"},
|
||||
]}
|
||||
buttons={[
|
||||
{ text: "Call Now", href: "tel:1-800-123-4567" },
|
||||
{ text: "Schedule Service", href: "#contact-form" },
|
||||
]}
|
||||
buttonAnimation="slide-up"
|
||||
imageSrc="http://img.b2bpic.net/free-photo/high-angle-young-man-taking-break_23-2148384545.jpg"
|
||||
imageAlt="Contact support team"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div id="about" data-section="about">
|
||||
<TextSplitAbout
|
||||
title="Why Contact OW HomeShield?"
|
||||
description="Our dedicated team is ready to assist you with any questions about our services, membership plans, or to schedule urgent repairs. We pride ourselves on fast response times and professional service."
|
||||
imageSrc="http://img.b2bpic.net/free-photo/medium-shot-smiley-woman-home_23-2149412549.jpg"
|
||||
imageAlt="Happy homeowner"
|
||||
features={[
|
||||
{ title: "Fast Response", description: "Get assistance within hours", videoSrc: "" },
|
||||
{ title: "Expert Team", description: "Licensed and certified professionals", videoSrc: "" },
|
||||
{ title: "24/7 Available", description: "Emergency support anytime", videoSrc: "" }
|
||||
]}
|
||||
animationType="blur-reveal"
|
||||
<MediaAbout
|
||||
title="Why Choose OW HomeShield?"
|
||||
description="Over 20 years of trusted service. Our team of licensed technicians is dedicated to keeping your home in top condition with professional maintenance and rapid emergency response."
|
||||
tag="Our Expertise"
|
||||
imageSrc="/about-contact.jpg"
|
||||
imageAlt="OW HomeShield team"
|
||||
useInvertedBackground={false}
|
||||
buttons={[
|
||||
{ text: "Learn More", href: "#features" },
|
||||
{ text: "View Plans", href: "#pricing" },
|
||||
]}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div id="features" data-section="features">
|
||||
<FeatureCardOne
|
||||
title="Our Service Offerings"
|
||||
description="Comprehensive home maintenance and repair services designed for your needs"
|
||||
<FeatureCardTwelve
|
||||
title="Our Services"
|
||||
description="Comprehensive home maintenance solutions tailored to your needs"
|
||||
tag="What We Offer"
|
||||
features={[
|
||||
{
|
||||
id: "maintenance", label: "Maintenance", title: "Regular Home Maintenance Plans", items: [
|
||||
"Monthly inspections", "HVAC system checks", "Plumbing assessments", "Electrical safety reviews"],
|
||||
buttons: [{ text: "Learn More", href: "#" }],
|
||||
},
|
||||
{
|
||||
id: "emergency", label: "Emergency", title: "24/7 Emergency Repair Service", items: [
|
||||
"Rapid response times", "Emergency hotline", "Licensed technicians", "Same-day service available"],
|
||||
buttons: [{ text: "Get Help", href: "#" }],
|
||||
},
|
||||
]}
|
||||
animationType="slide-up"
|
||||
textboxLayout="default"
|
||||
useInvertedBackground={false}
|
||||
features={[
|
||||
{
|
||||
title: "Emergency Repairs", description: "24/7 emergency service for urgent home repairs"
|
||||
},
|
||||
{
|
||||
title: "Consultation", description: "Free consultation to assess your home maintenance needs"
|
||||
},
|
||||
{
|
||||
title: "Local Service", description: "Serving your community with professional local technicians"
|
||||
}
|
||||
]}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div id="products" data-section="products">
|
||||
<ProductCardFour
|
||||
title="Featured Services"
|
||||
description="Explore our most popular home maintenance and repair services"
|
||||
title="Service Packages"
|
||||
description="Choose from our selection of professional home maintenance services"
|
||||
tag="Available Services"
|
||||
products={[
|
||||
{
|
||||
id: "1", name: "HVAC Maintenance", price: "$150", variant: "Quarterly Service", imageSrc: "/service1.jpg", imageAlt: "HVAC Service"},
|
||||
{
|
||||
id: "2", name: "Plumbing Inspection", price: "$120", variant: "Annual Check", imageSrc: "/service2.jpg", imageAlt: "Plumbing Service"},
|
||||
{
|
||||
id: "3", name: "Electrical Safety", price: "$180", variant: "Comprehensive Review", imageSrc: "/service3.jpg", imageAlt: "Electrical Service"},
|
||||
{
|
||||
id: "4", name: "Roofing Inspection", price: "$200", variant: "Professional Assessment", imageSrc: "/service4.jpg", imageAlt: "Roofing Service"},
|
||||
]}
|
||||
gridVariant="uniform-all-items-equal"
|
||||
animationType="slide-up"
|
||||
textboxLayout="default"
|
||||
useInvertedBackground={false}
|
||||
gridVariant="four-items-2x2-equal-grid"
|
||||
products={[
|
||||
{
|
||||
id: "1", name: "Plumbing Repairs", description: "Expert plumbing solutions", imageSrc: "http://img.b2bpic.net/free-vector/protect-against-cyber-attacks-infographic_23-2148534111.jpg", imageAlt: "Plumbing service", price: "$99", variant: "standard"
|
||||
},
|
||||
{
|
||||
id: "2", name: "Electrical Work", description: "Safe electrical installations", imageSrc: "http://img.b2bpic.net/free-vector/flat-labor-day-labels-collection_23-2149037530.jpg", imageAlt: "Electrical service", price: "$129", variant: "standard"
|
||||
},
|
||||
{
|
||||
id: "3", name: "Home Inspections", description: "Thorough home assessments", imageSrc: "http://img.b2bpic.net/free-vector/bank-service-concept-labels-template_23-2150487023.jpg", imageAlt: "Home inspection", price: "$149", variant: "standard"
|
||||
},
|
||||
{
|
||||
id: "4", name: "Preventative Maintenance", description: "Regular maintenance plans", imageSrc: "http://img.b2bpic.net/free-photo/cheerful-pretty-businesswoman-near-business-plan-showing-it_171337-8559.jpg", imageAlt: "Maintenance service", price: "$79", variant: "standard"
|
||||
}
|
||||
]}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div id="pricing" data-section="pricing">
|
||||
<PricingCardThree
|
||||
title="Membership Pricing"
|
||||
description="Choose the perfect plan for your home protection needs"
|
||||
<PricingCardNine
|
||||
title="Membership Plans"
|
||||
description="Choose the perfect plan for your home maintenance needs"
|
||||
tag="Pricing"
|
||||
plans={[
|
||||
{
|
||||
id: "basic", title: "Basic", price: "$49", period: "/month", imageSrc: "/pricing-basic.jpg", imageAlt: "Basic Plan", button: { text: "Get Started", href: "#contact-form" },
|
||||
features: [
|
||||
"Monthly inspection", "Priority support", "10% service discount"],
|
||||
},
|
||||
{
|
||||
id: "premium", title: "Premium", price: "$99", period: "/month", imageSrc: "/pricing-premium.jpg", imageAlt: "Premium Plan", button: { text: "Get Started", href: "#contact-form" },
|
||||
features: [
|
||||
"Quarterly inspections", "24/7 emergency support", "20% service discount", "Free diagnostics"],
|
||||
},
|
||||
]}
|
||||
animationType="slide-up"
|
||||
textboxLayout="default"
|
||||
useInvertedBackground={false}
|
||||
plans={[
|
||||
{
|
||||
id: "silver", name: "Basic plan", badge: "Basic", price: "$44/mo", buttons: [
|
||||
{ text: "Get Started", href: "tel:226-224-3573" },
|
||||
{ text: "Learn More", href: "#" }
|
||||
],
|
||||
features: ["1 service visit/month", "Minor repairs", "10% discount"]
|
||||
},
|
||||
{
|
||||
id: "gold", name: "Business plan", badge: "Popular", badgeIcon: Sparkles,
|
||||
price: "$59/mo", buttons: [
|
||||
{ text: "Get Started", href: "tel:226-224-3573" },
|
||||
{ text: "Learn More", href: "#" }
|
||||
],
|
||||
features: ["2 service visits/month", "Priority booking", "15% discount"]
|
||||
},
|
||||
{
|
||||
id: "platinum", name: "Premium plan", badge: "Premium", price: "$84/mo", buttons: [
|
||||
{ text: "Get Started", href: "tel:226-224-3573" },
|
||||
{ text: "Learn More", href: "#" }
|
||||
],
|
||||
features: ["Unlimited visits", "24/7 support", "20% discount"]
|
||||
}
|
||||
]}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div id="pricing2" data-section="pricing2">
|
||||
<div id="pricing-cards" data-section="pricing-cards">
|
||||
<PricingCardTwo
|
||||
title="Additional Services"
|
||||
description="Specialized services available for your home"
|
||||
title="Annual Membership"
|
||||
description="Save more with annual commitment"
|
||||
tag="Best Value"
|
||||
plans={[
|
||||
{
|
||||
id: "annual-basic", title: "Annual Basic", price: "$499", period: "/year", description: "Save $89 annually", button: { text: "Subscribe", href: "#contact-form" },
|
||||
features: [
|
||||
"Monthly inspections", "Priority support", "10% discount on services"],
|
||||
highlighted: false,
|
||||
},
|
||||
{
|
||||
id: "annual-premium", title: "Annual Premium", price: "$999", period: "/year", description: "Save $189 annually", button: { text: "Subscribe", href: "#contact-form" },
|
||||
features: [
|
||||
"Quarterly inspections", "24/7 emergency support", "20% discount on services", "Free annual diagnostics"],
|
||||
highlighted: true,
|
||||
},
|
||||
]}
|
||||
animationType="slide-up"
|
||||
textboxLayout="default"
|
||||
useInvertedBackground={false}
|
||||
plans={[
|
||||
{
|
||||
id: "annual", price: "$299/year", subtitle: "Annual Check-up", badge: "Value", buttons: [
|
||||
{ text: "Book Now", href: "tel:226-224-3573" }
|
||||
],
|
||||
features: ["Full system check", "Detailed report", "Recommendations"]
|
||||
},
|
||||
{
|
||||
id: "emergency", price: "$149", subtitle: "Emergency Service", badge: "Priority", buttons: [
|
||||
{ text: "Call Now", href: "tel:226-224-3573" }
|
||||
],
|
||||
features: ["24/7 availability", "Fast response", "Professional service"]
|
||||
}
|
||||
]}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div id="testimonials" data-section="testimonials">
|
||||
<TestimonialCardTwo
|
||||
title="What Our Clients Say"
|
||||
description="Real feedback from satisfied homeowners"
|
||||
animationType="slide-up"
|
||||
textboxLayout="default"
|
||||
useInvertedBackground={false}
|
||||
<TestimonialCardSix
|
||||
testimonials={[
|
||||
{
|
||||
id: "1", name: "Sarah Johnson", role: "Homeowner", testimonial: "OW HomeShield has been incredible. Their team is professional, reliable, and always responsive to our needs.", imageSrc: "http://img.b2bpic.net/free-photo/cheerful-excited-businesswoman-blue-blouse-showing-thumb-up_1262-14826.jpg", imageAlt: "Sarah Johnson"
|
||||
},
|
||||
id: "1", name: "Sarah Johnson", handle: "Homeowner, Portland", testimonial:
|
||||
"OW HomeShield has been a lifesaver! Their technicians are professional and the service is always on time. Highly recommend!", imageSrc: "/avatar-sarah.jpg", imageAlt: "Sarah Johnson"},
|
||||
{
|
||||
id: "2", name: "Michael Chen", role: "Property Manager", testimonial: "We trust OW HomeShield to maintain our properties. Their attention to detail and quick response times are unmatched.", imageSrc: "http://img.b2bpic.net/free-photo/young-businessman-happy-expression_1194-1644.jpg", imageAlt: "Michael Chen"
|
||||
}
|
||||
id: "2", name: "Michael Chen", handle: "Property Manager, Seattle", testimonial:
|
||||
"Managing multiple properties is much easier with OW HomeShield handling maintenance. Reliable and cost-effective!", imageSrc: "/avatar-michael.jpg", imageAlt: "Michael Chen"},
|
||||
{
|
||||
id: "3", name: "Emma Davis", handle: "Homeowner, Vancouver", testimonial:
|
||||
"The 24/7 emergency support is incredible. When our heating went out in winter, they were there within an hour.", imageSrc: "/avatar-emma.jpg", imageAlt: "Emma Davis"},
|
||||
{
|
||||
id: "4", name: "James Wilson", handle: "Real Estate Agent, Bellevue", testimonial:
|
||||
"I recommend OW HomeShield to all my clients. Their membership plans provide excellent value and peace of mind.", imageSrc: "/avatar-james.jpg", imageAlt: "James Wilson"},
|
||||
{
|
||||
id: "5", name: "Lisa Anderson", handle: "Homeowner, Tacoma", testimonial:
|
||||
"Prevention is better than cure, and OW HomeShield's maintenance plans keep my home running smoothly year-round.", imageSrc: "/avatar-lisa.jpg", imageAlt: "Lisa Anderson"},
|
||||
{
|
||||
id: "6", name: "Robert Martinez", handle: "Property Owner, Olympia", testimonial:
|
||||
"Outstanding customer service and quality workmanship. OW HomeShield is the only choice for home maintenance in the region.", imageSrc: "/avatar-robert.jpg", imageAlt: "Robert Martinez"},
|
||||
]}
|
||||
title="What Our Customers Say"
|
||||
description="Trusted by thousands of homeowners across the Pacific Northwest"
|
||||
textboxLayout="default"
|
||||
useInvertedBackground={false}
|
||||
animationType="slide-up"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div id="contact-form" data-section="contact-form">
|
||||
<ContactSplit
|
||||
tag="Contact Us"
|
||||
title="Contact Our Team"
|
||||
description="Fill out the form below and we'll get back to you as soon as possible. For emergencies, please call us directly."
|
||||
background={{ variant: "plain" }}
|
||||
tag="Get in Touch"
|
||||
title="Ready to protect your home?"
|
||||
description="Sign up for OW HomeShield today and get professional maintenance and repair support. Our team is ready to help you maintain your property and handle any emergency that comes up."
|
||||
tagIcon={Mail}
|
||||
background={{ variant: "sparkles-gradient" }}
|
||||
useInvertedBackground={false}
|
||||
imageSrc="http://img.b2bpic.net/free-photo/medium-shot-smiley-woman-home_23-2149412549.jpg"
|
||||
imageAlt="Contact our team"
|
||||
inputPlaceholder="Your email address"
|
||||
buttonText="Send Message"
|
||||
termsText="We'll respond within 24 hours. For emergencies, call 226-224-3573."
|
||||
imageSrc="/contact-split.jpg"
|
||||
imageAlt="OW HomeShield team"
|
||||
mediaAnimation="slide-up"
|
||||
onSubmit={(email) => console.log('Contact form submitted:', email)}
|
||||
mediaPosition="right"
|
||||
inputPlaceholder="Enter your email"
|
||||
buttonText="Get Started"
|
||||
termsText="We respect your privacy. Unsubscribe at any time."
|
||||
onSubmit={(email) => console.log("Email submitted:", email)}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div id="footer" data-section="footer">
|
||||
<FooterBase
|
||||
copyrightText="© 2025 OW HomeShield Inc. All rights reserved."
|
||||
<FooterBaseCard
|
||||
logoText="OW HomeShield"
|
||||
columns={[
|
||||
{
|
||||
title: "Company", items: [
|
||||
{ label: "Home", href: "/" },
|
||||
{ label: "Contact", href: "/contact" },
|
||||
{ label: "About", href: "#about" }
|
||||
]
|
||||
title: "Product", items: [
|
||||
{ label: "Membership Plans", href: "#pricing" },
|
||||
{ label: "Services", href: "#services" },
|
||||
{ label: "Pricing", href: "#pricing" },
|
||||
],
|
||||
},
|
||||
{
|
||||
title: "Services", items: [
|
||||
{ label: "Repairs", href: "#services" },
|
||||
{ label: "Maintenance", href: "#services" },
|
||||
{ label: "Inspections", href: "#services" }
|
||||
]
|
||||
title: "Company", items: [
|
||||
{ label: "About Us", href: "#about" },
|
||||
{ label: "Contact", href: "#contact-form" },
|
||||
{ label: "Blog", href: "#blog" },
|
||||
],
|
||||
},
|
||||
{
|
||||
title: "Support", items: [
|
||||
{ label: "Emergency", href: "tel:226-224-3573" },
|
||||
{ label: "24/7 Hotline", href: "tel:1-800-123-4567" },
|
||||
{ label: "Emergency Service", href: "tel:1-800-123-4567" },
|
||||
{ label: "FAQ", href: "#faq" },
|
||||
{ label: "Contact", href: "#contact" }
|
||||
]
|
||||
}
|
||||
],
|
||||
},
|
||||
]}
|
||||
copyrightText="© 2025 OW HomeShield. All rights reserved."
|
||||
onPrivacyClick={() => console.log("Privacy clicked")}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div id="footer-simple" data-section="footer-simple">
|
||||
<FooterCard
|
||||
copyrightText="© 2025 OW HomeShield Inc. All rights reserved."
|
||||
<FooterSimple
|
||||
text="© 2025 OW HomeShield. Professional home maintenance and repair services."
|
||||
/>
|
||||
</div>
|
||||
</ThemeProvider>
|
||||
|
||||
286
src/app/dashboard/page.tsx
Normal file
286
src/app/dashboard/page.tsx
Normal file
@@ -0,0 +1,286 @@
|
||||
"use client";
|
||||
|
||||
import { ThemeProvider } from "@/providers/themeProvider/ThemeProvider";
|
||||
import NavbarStyleFullscreen from "@/components/navbar/NavbarStyleFullscreen/NavbarStyleFullscreen";
|
||||
import { useState, useMemo } from "react";
|
||||
import { Search, Filter, ChevronUp, ChevronDown } from "lucide-react";
|
||||
|
||||
const navItems = [
|
||||
{ name: "Home", id: "/" },
|
||||
{ name: "Membership", id: "/membership" },
|
||||
{ name: "Services", id: "#services" },
|
||||
{ name: "Dashboard", id: "/dashboard" },
|
||||
];
|
||||
|
||||
interface ServiceRequest {
|
||||
requestId: string;
|
||||
clientName: string;
|
||||
address: string;
|
||||
issueType: string;
|
||||
membershipPlan: string;
|
||||
status: "pending" | "in-progress" | "completed" | "cancelled";
|
||||
date: string;
|
||||
}
|
||||
|
||||
const mockRequests: ServiceRequest[] = [
|
||||
{
|
||||
requestId: "SR-001", clientName: "John Smith", address: "123 Oak Avenue, Springfield", issueType: "Plumbing", membershipPlan: "Premium", status: "completed", date: "2025-01-15"},
|
||||
{
|
||||
requestId: "SR-002", clientName: "Sarah Johnson", address: "456 Elm Street, Shelbyville", issueType: "HVAC", membershipPlan: "Standard", status: "in-progress", date: "2025-01-18"},
|
||||
{
|
||||
requestId: "SR-003", clientName: "Michael Davis", address: "789 Maple Drive, Capital City", issueType: "Electrical", membershipPlan: "Elite", status: "pending", date: "2025-01-20"},
|
||||
{
|
||||
requestId: "SR-004", clientName: "Emily Wilson", address: "321 Pine Road, Shelbyville", issueType: "Roofing", membershipPlan: "Basic", status: "completed", date: "2025-01-10"},
|
||||
{
|
||||
requestId: "SR-005", clientName: "David Brown", address: "654 Cedar Lane, Springfield", issueType: "General Maintenance", membershipPlan: "Premium", status: "in-progress", date: "2025-01-19"},
|
||||
{
|
||||
requestId: "SR-006", clientName: "Jessica Martinez", address: "987 Birch Court, Capital City", issueType: "Emergency Repair", membershipPlan: "Elite", status: "pending", date: "2025-01-20"},
|
||||
];
|
||||
|
||||
type SortField = "requestId" | "clientName" | "address" | "issueType" | "membershipPlan" | "status" | "date";
|
||||
type SortOrder = "asc" | "desc";
|
||||
|
||||
const getStatusColor = (
|
||||
status: "pending" | "in-progress" | "completed" | "cancelled"
|
||||
): string => {
|
||||
switch (status) {
|
||||
case "pending":
|
||||
return "bg-yellow-100 text-yellow-800";
|
||||
case "in-progress":
|
||||
return "bg-blue-100 text-blue-800";
|
||||
case "completed":
|
||||
return "bg-green-100 text-green-800";
|
||||
case "cancelled":
|
||||
return "bg-red-100 text-red-800";
|
||||
default:
|
||||
return "bg-gray-100 text-gray-800";
|
||||
}
|
||||
};
|
||||
|
||||
export default function DashboardPage() {
|
||||
const [searchQuery, setSearchQuery] = useState("");
|
||||
const [sortField, setSortField] = useState<SortField>("date");
|
||||
const [sortOrder, setSortOrder] = useState<SortOrder>("desc");
|
||||
const [statusFilter, setStatusFilter] = useState<string>("all");
|
||||
|
||||
const filteredAndSortedRequests = useMemo(() => {
|
||||
let filtered = mockRequests;
|
||||
|
||||
// Search filter
|
||||
if (searchQuery) {
|
||||
const query = searchQuery.toLowerCase();
|
||||
filtered = filtered.filter(
|
||||
(req) =>
|
||||
req.requestId.toLowerCase().includes(query) ||
|
||||
req.clientName.toLowerCase().includes(query) ||
|
||||
req.address.toLowerCase().includes(query)
|
||||
);
|
||||
}
|
||||
|
||||
// Status filter
|
||||
if (statusFilter !== "all") {
|
||||
filtered = filtered.filter((req) => req.status === statusFilter);
|
||||
}
|
||||
|
||||
// Sort
|
||||
filtered.sort((a, b) => {
|
||||
const aVal = a[sortField] || "";
|
||||
const bVal = b[sortField] || "";
|
||||
|
||||
if (aVal < bVal) return sortOrder === "asc" ? -1 : 1;
|
||||
if (aVal > bVal) return sortOrder === "asc" ? 1 : -1;
|
||||
return 0;
|
||||
});
|
||||
|
||||
return filtered;
|
||||
}, [searchQuery, sortField, sortOrder, statusFilter]);
|
||||
|
||||
const toggleSort = (field: SortField) => {
|
||||
if (sortField === field) {
|
||||
setSortOrder(sortOrder === "asc" ? "desc" : "asc");
|
||||
} else {
|
||||
setSortField(field);
|
||||
setSortOrder("asc");
|
||||
}
|
||||
};
|
||||
|
||||
const SortIcon = ({ field }: { field: SortField }) => {
|
||||
if (sortField !== field) return null;
|
||||
return sortOrder === "asc" ? (
|
||||
<ChevronUp className="w-4 h-4 inline ml-1" />
|
||||
) : (
|
||||
<ChevronDown className="w-4 h-4 inline ml-1" />
|
||||
);
|
||||
};
|
||||
|
||||
return (
|
||||
<ThemeProvider
|
||||
defaultButtonVariant="hover-magnetic"
|
||||
defaultTextAnimation="entrance-slide"
|
||||
borderRadius="rounded"
|
||||
contentWidth="medium"
|
||||
sizing="medium"
|
||||
background="circleGradient"
|
||||
cardStyle="glass-elevated"
|
||||
primaryButtonStyle="gradient"
|
||||
secondaryButtonStyle="glass"
|
||||
headingFontWeight="bold"
|
||||
>
|
||||
<NavbarStyleFullscreen
|
||||
navItems={navItems}
|
||||
brandName="OW HomeShield"
|
||||
bottomLeftText="24/7 Support"
|
||||
bottomRightText="support@owhomeshield.com"
|
||||
/>
|
||||
|
||||
<div className="min-h-screen pt-20 pb-20 px-4">
|
||||
<div className="max-w-7xl mx-auto">
|
||||
<h1 className="text-4xl font-bold mb-4">Service Requests Dashboard</h1>
|
||||
<p className="text-foreground/70 mb-8">
|
||||
Manage and track all service requests from clients.
|
||||
</p>
|
||||
|
||||
{/* Filters and Search */}
|
||||
<div className="bg-card rounded-lg p-6 border border-foreground/10 mb-6">
|
||||
<div className="grid grid-cols-1 md:grid-cols-3 gap-4">
|
||||
{/* Search */}
|
||||
<div className="relative">
|
||||
<Search className="absolute left-3 top-3 w-5 h-5 text-foreground/40" />
|
||||
<input
|
||||
type="text"
|
||||
placeholder="Search by ID, name, or address..."
|
||||
value={searchQuery}
|
||||
onChange={(e) => setSearchQuery(e.target.value)}
|
||||
className="w-full pl-10 pr-4 py-2 border border-foreground/20 rounded-lg bg-background focus:outline-none focus:border-primary-cta"
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* Status Filter */}
|
||||
<div className="flex items-center gap-2">
|
||||
<Filter className="w-5 h-5 text-foreground/40" />
|
||||
<select
|
||||
value={statusFilter}
|
||||
onChange={(e) => setStatusFilter(e.target.value)}
|
||||
className="w-full px-4 py-2 border border-foreground/20 rounded-lg bg-background focus:outline-none focus:border-primary-cta"
|
||||
>
|
||||
<option value="all">All Statuses</option>
|
||||
<option value="pending">Pending</option>
|
||||
<option value="in-progress">In Progress</option>
|
||||
<option value="completed">Completed</option>
|
||||
<option value="cancelled">Cancelled</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
{/* Results Count */}
|
||||
<div className="flex items-center justify-end">
|
||||
<span className="text-sm text-foreground/70">
|
||||
{filteredAndSortedRequests.length} requests
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Table */}
|
||||
<div className="bg-card rounded-lg border border-foreground/10 overflow-x-auto">
|
||||
<table className="w-full">
|
||||
<thead>
|
||||
<tr className="border-b border-foreground/10 bg-background/50">
|
||||
<th className="px-6 py-4 text-left">
|
||||
<button
|
||||
onClick={() => toggleSort("requestId")}
|
||||
className="font-semibold text-sm hover:text-primary-cta transition-colors flex items-center"
|
||||
>
|
||||
Request ID
|
||||
<SortIcon field="requestId" />
|
||||
</button>
|
||||
</th>
|
||||
<th className="px-6 py-4 text-left">
|
||||
<button
|
||||
onClick={() => toggleSort("clientName")}
|
||||
className="font-semibold text-sm hover:text-primary-cta transition-colors flex items-center"
|
||||
>
|
||||
Client Name
|
||||
<SortIcon field="clientName" />
|
||||
</button>
|
||||
</th>
|
||||
<th className="px-6 py-4 text-left">
|
||||
<button
|
||||
onClick={() => toggleSort("address")}
|
||||
className="font-semibold text-sm hover:text-primary-cta transition-colors flex items-center"
|
||||
>
|
||||
Address
|
||||
<SortIcon field="address" />
|
||||
</button>
|
||||
</th>
|
||||
<th className="px-6 py-4 text-left">
|
||||
<button
|
||||
onClick={() => toggleSort("issueType")}
|
||||
className="font-semibold text-sm hover:text-primary-cta transition-colors flex items-center"
|
||||
>
|
||||
Issue Type
|
||||
<SortIcon field="issueType" />
|
||||
</button>
|
||||
</th>
|
||||
<th className="px-6 py-4 text-left">
|
||||
<button
|
||||
onClick={() => toggleSort("membershipPlan")}
|
||||
className="font-semibold text-sm hover:text-primary-cta transition-colors flex items-center"
|
||||
>
|
||||
Membership Plan
|
||||
<SortIcon field="membershipPlan" />
|
||||
</button>
|
||||
</th>
|
||||
<th className="px-6 py-4 text-left">
|
||||
<button
|
||||
onClick={() => toggleSort("status")}
|
||||
className="font-semibold text-sm hover:text-primary-cta transition-colors flex items-center"
|
||||
>
|
||||
Status
|
||||
<SortIcon field="status" />
|
||||
</button>
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{filteredAndSortedRequests.length > 0 ? (
|
||||
filteredAndSortedRequests.map((request) => (
|
||||
<tr
|
||||
key={request.requestId}
|
||||
className="border-b border-foreground/10 hover:bg-background/50 transition-colors"
|
||||
>
|
||||
<td className="px-6 py-4 text-sm font-medium">
|
||||
{request.requestId}
|
||||
</td>
|
||||
<td className="px-6 py-4 text-sm">{request.clientName}</td>
|
||||
<td className="px-6 py-4 text-sm text-foreground/80">
|
||||
{request.address}
|
||||
</td>
|
||||
<td className="px-6 py-4 text-sm">{request.issueType}</td>
|
||||
<td className="px-6 py-4 text-sm">{request.membershipPlan}</td>
|
||||
<td className="px-6 py-4 text-sm">
|
||||
<span
|
||||
className={`px-3 py-1 rounded-full text-xs font-medium ${
|
||||
getStatusColor(request.status)
|
||||
}`}
|
||||
>
|
||||
{request.status.charAt(0).toUpperCase() +
|
||||
request.status.slice(1).replace("-", " ")}
|
||||
</span>
|
||||
</td>
|
||||
</tr>
|
||||
))
|
||||
) : (
|
||||
<tr>
|
||||
<td colSpan={6} className="px-6 py-12 text-center text-foreground/50">
|
||||
No service requests found.
|
||||
</td>
|
||||
</tr>
|
||||
)}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</ThemeProvider>
|
||||
);
|
||||
}
|
||||
254
src/app/membership/page.tsx
Normal file
254
src/app/membership/page.tsx
Normal file
@@ -0,0 +1,254 @@
|
||||
"use client";
|
||||
|
||||
import { ThemeProvider } from "@/providers/themeProvider/ThemeProvider";
|
||||
import NavbarStyleFullscreen from "@/components/navbar/NavbarStyleFullscreen/NavbarStyleFullscreen";
|
||||
import { useState } from "react";
|
||||
import { Upload } from "lucide-react";
|
||||
|
||||
const navItems = [
|
||||
{ name: "Home", id: "/" },
|
||||
{ name: "Membership", id: "/membership" },
|
||||
{ name: "Services", id: "#services" },
|
||||
{ name: "Dashboard", id: "/dashboard" },
|
||||
];
|
||||
|
||||
interface MembershipFormData {
|
||||
fullName: string;
|
||||
phone: string;
|
||||
email: string;
|
||||
homeAddress: string;
|
||||
propertyType: string;
|
||||
serviceDescription: string;
|
||||
photoFile: File | null;
|
||||
}
|
||||
|
||||
export default function MembershipPage() {
|
||||
const [formData, setFormData] = useState<MembershipFormData>({
|
||||
fullName: "", phone: "", email: "", homeAddress: "", propertyType: "", serviceDescription: "", photoFile: null,
|
||||
});
|
||||
|
||||
const [submitted, setSubmitted] = useState(false);
|
||||
|
||||
const handleInputChange = (
|
||||
e: React.ChangeEvent<
|
||||
HTMLInputElement | HTMLTextAreaElement | HTMLSelectElement
|
||||
>
|
||||
) => {
|
||||
const { name, value } = e.target;
|
||||
setFormData((prev) => ({
|
||||
...prev,
|
||||
[name]: value,
|
||||
}));
|
||||
};
|
||||
|
||||
const handleFileChange = (e: React.ChangeEvent<HTMLInputElement>) => {
|
||||
if (e.target.files && e.target.files[0]) {
|
||||
setFormData((prev) => ({
|
||||
...prev,
|
||||
photoFile: e.target.files![0],
|
||||
}));
|
||||
}
|
||||
};
|
||||
|
||||
const handleSubmit = (e: React.FormEvent) => {
|
||||
e.preventDefault();
|
||||
console.log("Form submitted:", formData);
|
||||
setSubmitted(true);
|
||||
setTimeout(() => {
|
||||
setFormData({
|
||||
fullName: "", phone: "", email: "", homeAddress: "", propertyType: "", serviceDescription: "", photoFile: null,
|
||||
});
|
||||
setSubmitted(false);
|
||||
}, 3000);
|
||||
};
|
||||
|
||||
return (
|
||||
<ThemeProvider
|
||||
defaultButtonVariant="hover-magnetic"
|
||||
defaultTextAnimation="entrance-slide"
|
||||
borderRadius="rounded"
|
||||
contentWidth="medium"
|
||||
sizing="medium"
|
||||
background="circleGradient"
|
||||
cardStyle="glass-elevated"
|
||||
primaryButtonStyle="gradient"
|
||||
secondaryButtonStyle="glass"
|
||||
headingFontWeight="bold"
|
||||
>
|
||||
<NavbarStyleFullscreen
|
||||
navItems={navItems}
|
||||
brandName="OW HomeShield"
|
||||
bottomLeftText="24/7 Support"
|
||||
bottomRightText="support@owhomeshield.com"
|
||||
/>
|
||||
|
||||
<div className="min-h-screen pt-20 pb-20 px-4">
|
||||
<div className="max-w-2xl mx-auto">
|
||||
<h1 className="text-4xl font-bold mb-4 text-center">
|
||||
New Member Signup
|
||||
</h1>
|
||||
<p className="text-center text-foreground/70 mb-12">
|
||||
Join OW HomeShield and get professional home maintenance and repair
|
||||
services.
|
||||
</p>
|
||||
|
||||
<div className="bg-card rounded-lg p-8 border border-foreground/10">
|
||||
{submitted ? (
|
||||
<div className="text-center py-12">
|
||||
<div className="text-5xl mb-4">✓</div>
|
||||
<h2 className="text-2xl font-bold mb-2">
|
||||
Thank you for signing up!
|
||||
</h2>
|
||||
<p className="text-foreground/70">
|
||||
We'll review your information and contact you shortly.
|
||||
</p>
|
||||
</div>
|
||||
) : (
|
||||
<form onSubmit={handleSubmit} className="space-y-6">
|
||||
{/* Full Name */}
|
||||
<div>
|
||||
<label className="block text-sm font-medium mb-2">
|
||||
Full Name *
|
||||
</label>
|
||||
<input
|
||||
type="text"
|
||||
name="fullName"
|
||||
value={formData.fullName}
|
||||
onChange={handleInputChange}
|
||||
required
|
||||
className="w-full px-4 py-2 border border-foreground/20 rounded-lg bg-background focus:outline-none focus:border-primary-cta"
|
||||
placeholder="John Doe"
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* Phone */}
|
||||
<div>
|
||||
<label className="block text-sm font-medium mb-2">
|
||||
Phone Number *
|
||||
</label>
|
||||
<input
|
||||
type="tel"
|
||||
name="phone"
|
||||
value={formData.phone}
|
||||
onChange={handleInputChange}
|
||||
required
|
||||
className="w-full px-4 py-2 border border-foreground/20 rounded-lg bg-background focus:outline-none focus:border-primary-cta"
|
||||
placeholder="(555) 123-4567"
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* Email */}
|
||||
<div>
|
||||
<label className="block text-sm font-medium mb-2">
|
||||
Email Address *
|
||||
</label>
|
||||
<input
|
||||
type="email"
|
||||
name="email"
|
||||
value={formData.email}
|
||||
onChange={handleInputChange}
|
||||
required
|
||||
className="w-full px-4 py-2 border border-foreground/20 rounded-lg bg-background focus:outline-none focus:border-primary-cta"
|
||||
placeholder="john@example.com"
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* Home Address */}
|
||||
<div>
|
||||
<label className="block text-sm font-medium mb-2">
|
||||
Home Address *
|
||||
</label>
|
||||
<input
|
||||
type="text"
|
||||
name="homeAddress"
|
||||
value={formData.homeAddress}
|
||||
onChange={handleInputChange}
|
||||
required
|
||||
className="w-full px-4 py-2 border border-foreground/20 rounded-lg bg-background focus:outline-none focus:border-primary-cta"
|
||||
placeholder="123 Main Street, City, State 12345"
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* Property Type */}
|
||||
<div>
|
||||
<label className="block text-sm font-medium mb-2">
|
||||
Property Type *
|
||||
</label>
|
||||
<select
|
||||
name="propertyType"
|
||||
value={formData.propertyType}
|
||||
onChange={handleInputChange}
|
||||
required
|
||||
className="w-full px-4 py-2 border border-foreground/20 rounded-lg bg-background focus:outline-none focus:border-primary-cta"
|
||||
>
|
||||
<option value="">Select a property type</option>
|
||||
<option value="single-family">Single Family Home</option>
|
||||
<option value="condo">Condo/Townhouse</option>
|
||||
<option value="apartment">Apartment</option>
|
||||
<option value="multi-family">Multi-Family</option>
|
||||
<option value="commercial">Commercial</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
{/* Service Description */}
|
||||
<div>
|
||||
<label className="block text-sm font-medium mb-2">
|
||||
Service Description *
|
||||
</label>
|
||||
<textarea
|
||||
name="serviceDescription"
|
||||
value={formData.serviceDescription}
|
||||
onChange={handleInputChange}
|
||||
required
|
||||
rows={4}
|
||||
className="w-full px-4 py-2 border border-foreground/20 rounded-lg bg-background focus:outline-none focus:border-primary-cta"
|
||||
placeholder="Describe the services you need..."
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* Photo Upload */}
|
||||
<div>
|
||||
<label className="block text-sm font-medium mb-2">
|
||||
Upload Photo (Optional)
|
||||
</label>
|
||||
<div className="border-2 border-dashed border-foreground/20 rounded-lg p-6 text-center hover:border-primary-cta transition-colors">
|
||||
<input
|
||||
type="file"
|
||||
name="photo"
|
||||
onChange={handleFileChange}
|
||||
accept="image/*"
|
||||
className="hidden"
|
||||
id="photo-upload"
|
||||
/>
|
||||
<label
|
||||
htmlFor="photo-upload"
|
||||
className="cursor-pointer flex flex-col items-center gap-2"
|
||||
>
|
||||
<Upload className="w-8 h-8 text-primary-cta" />
|
||||
<span className="text-sm font-medium">
|
||||
{formData.photoFile
|
||||
? formData.photoFile.name
|
||||
: "Click to upload or drag and drop"}
|
||||
</span>
|
||||
<span className="text-xs text-foreground/50">
|
||||
PNG, JPG, GIF up to 10MB
|
||||
</span>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Submit Button */}
|
||||
<button
|
||||
type="submit"
|
||||
className="w-full bg-primary-cta text-white font-medium py-3 rounded-lg hover:opacity-90 transition-opacity"
|
||||
>
|
||||
Submit Application
|
||||
</button>
|
||||
</form>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</ThemeProvider>
|
||||
);
|
||||
}
|
||||
240
src/app/page.tsx
240
src/app/page.tsx
@@ -1,203 +1,59 @@
|
||||
"use client";
|
||||
|
||||
import { ThemeProvider } from "@/providers/themeProvider/ThemeProvider";
|
||||
import NavbarLayoutFloatingOverlay from "@/components/navbar/NavbarLayoutFloatingOverlay/NavbarLayoutFloatingOverlay";
|
||||
import HeroSplitKpi from "@/components/sections/hero/HeroSplitKpi";
|
||||
import FeatureCardSeven from "@/components/sections/feature/FeatureCardSeven";
|
||||
import PricingCardOne from "@/components/sections/pricing/PricingCardOne";
|
||||
import TestimonialCardFifteen from "@/components/sections/testimonial/TestimonialCardFifteen";
|
||||
import ContactCTA from "@/components/sections/contact/ContactCTA";
|
||||
import FooterCard from "@/components/sections/footer/FooterCard";
|
||||
import { Crown, Home, Sparkles } from "lucide-react";
|
||||
import { ThemeProvider } from "@/components/theme/ThemeProvider";
|
||||
import NavbarStyleFullscreen from "@/components/navbar/NavbarStyleFullscreen/NavbarStyleFullscreen";
|
||||
|
||||
export default function Home() {
|
||||
const navItems = [
|
||||
{ name: "Home", id: "/" },
|
||||
{ name: "Contact", id: "/contact" },
|
||||
];
|
||||
|
||||
export default function LandingPage() {
|
||||
return (
|
||||
<ThemeProvider
|
||||
defaultButtonVariant="hover-bubble"
|
||||
defaultButtonVariant="hover-magnetic"
|
||||
defaultTextAnimation="entrance-slide"
|
||||
borderRadius="rounded"
|
||||
contentWidth="small"
|
||||
sizing="largeSmallSizeLargeTitles"
|
||||
background="circleGradient"
|
||||
cardStyle="inset"
|
||||
primaryButtonStyle="radial-glow"
|
||||
secondaryButtonStyle="layered"
|
||||
headingFontWeight="medium"
|
||||
contentWidth="medium"
|
||||
sizing="medium"
|
||||
background="none"
|
||||
cardStyle="solid"
|
||||
primaryButtonStyle="gradient"
|
||||
secondaryButtonStyle="glass"
|
||||
headingFontWeight="bold"
|
||||
>
|
||||
<div id="nav" data-section="nav">
|
||||
<NavbarLayoutFloatingOverlay
|
||||
brandName="OW HomeShield Inc."
|
||||
navItems={[
|
||||
{ name: "Home", id: "/" },
|
||||
{ name: "Membership Plans", id: "#pricing" },
|
||||
{ name: "Request Service", id: "#request-service" },
|
||||
{ name: "About", id: "#about" },
|
||||
{ name: "Contact", id: "/contact" }
|
||||
]}
|
||||
button={{
|
||||
text: "Call Now: 226-224-3573", href: "tel:226-224-3573"
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div id="hero" data-section="hero">
|
||||
<HeroSplitKpi
|
||||
title="Protect Your Home with Reliable Monthly Maintenance"
|
||||
description="Repairs • Inspections • Preventative Maintenance"
|
||||
tag="Emergency Service Available"
|
||||
tagAnimation="slide-up"
|
||||
background={{ variant: "plain" }}
|
||||
kpis={[
|
||||
{ value: "24/7", label: "Emergency Support" },
|
||||
{ value: "Licensed", label: "Certified Technicians" },
|
||||
{ value: "Local", label: "Service Team" }
|
||||
]}
|
||||
enableKpiAnimation={true}
|
||||
buttons={[
|
||||
{ text: "NEW CLIENT – JOIN MEMBERSHIP", href: "#membership-signup" },
|
||||
{ text: "EXISTING MEMBER – REQUEST SERVICE", href: "#member-request" }
|
||||
]}
|
||||
mediaAnimation="blur-reveal"
|
||||
buttonAnimation="slide-up"
|
||||
imageSrc="http://img.b2bpic.net/free-photo/high-angle-young-man-taking-break_23-2148384545.jpg"
|
||||
imageAlt="Professional home maintenance service"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div id="benefits" data-section="benefits">
|
||||
<FeatureCardSeven
|
||||
title="Affordable Home Maintenance Made Easy"
|
||||
description="Protect your investment with preventative care and expert repairs"
|
||||
animationType="blur-reveal"
|
||||
textboxLayout="default"
|
||||
useInvertedBackground={false}
|
||||
buttons={[
|
||||
{ text: "Start Your Membership", href: "#pricing" }
|
||||
]}
|
||||
buttonAnimation="slide-up"
|
||||
features={[
|
||||
{
|
||||
id: 1,
|
||||
title: "Keep Your Home Protected", description: "Regular inspections and preventative maintenance catch problems before they become expensive repairs. Our expert technicians identify and address issues early.", imageSrc: "http://img.b2bpic.net/free-vector/protect-against-cyber-attacks-infographic_23-2148534111.jpg", imageAlt: "Home protection"
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
title: "Skilled Technicians On-Demand", description: "Fast and reliable repairs from experienced professionals. Our licensed and insured team handles everything from plumbing and electrical to doors, windows, and drywall.", imageSrc: "http://img.b2bpic.net/free-vector/flat-labor-day-labels-collection_23-2149037530.jpg", imageAlt: "Professional technicians"
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
title: "Save Time & Money", description: "Prevent costly breakdowns before they happen. Our membership plans offer incredible value with discounts on repairs and priority scheduling.", imageSrc: "http://img.b2bpic.net/free-vector/bank-service-concept-labels-template_23-2150487023.jpg", imageAlt: "Cost savings"
|
||||
}
|
||||
]}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div id="pricing" data-section="pricing">
|
||||
<PricingCardOne
|
||||
title="Choose Your Membership Plan"
|
||||
description="Select the perfect plan to protect your home and save money on repairs"
|
||||
animationType="slide-up"
|
||||
textboxLayout="default"
|
||||
useInvertedBackground={false}
|
||||
plans={[
|
||||
{
|
||||
id: "silver", badge: "Basic Protection", price: "$44/month", subtitle: "Perfect for small homes", features: [
|
||||
"1 service visit per month", "Minor plumbing and electrical repairs", "Door adjustments and small fixes", "10% renovation discount", "+$95 one-time enrollment fee"
|
||||
]
|
||||
},
|
||||
{
|
||||
id: "gold", badge: "Most Popular", badgeIcon: Sparkles,
|
||||
price: "$59/month", subtitle: "Enhanced coverage for growing needs", features: [
|
||||
"2 service visits per month", "Priority booking", "Annual preventative inspection", "15% renovation discount", "+$95 one-time enrollment fee"
|
||||
]
|
||||
},
|
||||
{
|
||||
id: "platinum", badge: "Advanced Protection", price: "$84/month", subtitle: "Comprehensive home care", features: [
|
||||
"Unlimited minor service requests", "24/7 emergency phone support", "Seasonal home checkups", "Priority scheduling", "+$95 one-time enrollment fee"
|
||||
]
|
||||
},
|
||||
{
|
||||
id: "vip", badge: "VIP Ultimate", badgeIcon: Crown,
|
||||
price: "$109/month", subtitle: "Premium protection and support", features: [
|
||||
"Same-day priority scheduling", "Dedicated account manager", "29% renovation discount", "Unlimited minor service visits", "Annual full home inspection report", "+$95 one-time enrollment fee"
|
||||
]
|
||||
}
|
||||
]}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div id="how-it-works" data-section="how-it-works">
|
||||
<FeatureCardSeven
|
||||
title="How OW HomeShield Works"
|
||||
description="Simple steps to protect your home and get expert service"
|
||||
animationType="slide-up"
|
||||
textboxLayout="default"
|
||||
useInvertedBackground={false}
|
||||
features={[
|
||||
{
|
||||
id: 1,
|
||||
title: "Choose a Membership Plan", description: "Select the perfect plan that matches your home maintenance needs. Compare features and benefits to find the right fit for your budget.", imageSrc: "http://img.b2bpic.net/free-photo/cheerful-pretty-businesswoman-near-business-plan-showing-it_171337-8559.jpg", imageAlt: "Step 1: Choose membership"
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
title: "Schedule Your Inspection", description: "Book an appointment with our team. We'll assess your home and create a customized maintenance plan based on your specific needs.", imageSrc: "http://img.b2bpic.net/free-vector/appointment-booking-mobile-concept_23-2148570788.jpg", imageAlt: "Step 2: Schedule inspection"
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
title: "Receive Priority Maintenance & Repairs", description: "Enjoy priority service from our licensed technicians. Get fast repairs, preventative maintenance, and peace of mind knowing your home is protected.", imageSrc: "http://img.b2bpic.net/free-vector/labor-day-badges-collection_23-2147547884.jpg", imageAlt: "Step 3: Priority service"
|
||||
}
|
||||
]}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div id="trust" data-section="trust">
|
||||
<TestimonialCardFifteen
|
||||
testimonial="OW HomeShield has transformed how we maintain our home. The professional team is reliable, efficient, and truly cares about customer satisfaction. Highly recommended!"
|
||||
rating={5}
|
||||
author="Local Homeowners Trust OW HomeShield"
|
||||
ratingAnimation="blur-reveal"
|
||||
avatarsAnimation="blur-reveal"
|
||||
useInvertedBackground={false}
|
||||
avatars={[
|
||||
{
|
||||
src: "http://img.b2bpic.net/free-photo/cheerful-excited-businesswoman-blue-blouse-showing-thumb-up_1262-14826.jpg", alt: "happy customer satisfied homeowner"
|
||||
},
|
||||
{
|
||||
src: "http://img.b2bpic.net/free-photo/medium-shot-smiley-woman-home_23-2149412549.jpg", alt: "professional business portrait"
|
||||
},
|
||||
{
|
||||
src: "http://img.b2bpic.net/free-photo/young-businessman-happy-expression_1194-1644.jpg", alt: "diverse customer testimonial photo"
|
||||
},
|
||||
{
|
||||
src: "http://img.b2bpic.net/free-photo/young-blonde-woman-with-white-t-shirt_273609-7217.jpg", alt: "customer review professional portrait"
|
||||
}
|
||||
]}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div id="final-cta" data-section="final-cta">
|
||||
<ContactCTA
|
||||
tag="Ready to Protect Your Home?"
|
||||
tagIcon={Home}
|
||||
tagAnimation="slide-up"
|
||||
title="Worry-Free Home Maintenance Starts Here"
|
||||
description="Join thousands of homeowners who trust OW HomeShield for reliable maintenance and repairs. Contact us today to get started."
|
||||
buttons={[
|
||||
{ text: "Join Membership", href: "#pricing" },
|
||||
{ text: "Book Free Consultation", href: "tel:226-224-3573" }
|
||||
]}
|
||||
buttonAnimation="slide-up"
|
||||
background={{ variant: "plain" }}
|
||||
useInvertedBackground={false}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div id="footer" data-section="footer">
|
||||
<FooterCard
|
||||
logoText="OW HomeShield Inc."
|
||||
copyrightText="© 2025 OW HomeShield Inc. | Emergency Service Available 24/7"
|
||||
/>
|
||||
</div>
|
||||
<NavbarStyleFullscreen
|
||||
navItems={navItems}
|
||||
brandName="OW HomeShield"
|
||||
bottomLeftText="Available 24/7"
|
||||
bottomRightText="support@owhomeshield.com"
|
||||
/>
|
||||
<main>
|
||||
<section className="min-h-screen flex items-center justify-center bg-gradient-to-br from-blue-50 to-indigo-100">
|
||||
<div className="text-center">
|
||||
<h1 className="text-5xl font-bold text-gray-900 mb-4">
|
||||
OW HomeShield
|
||||
</h1>
|
||||
<p className="text-xl text-gray-600 mb-8">
|
||||
Professional Home Maintenance & Repair Services
|
||||
</p>
|
||||
<div className="flex gap-4 justify-center">
|
||||
<a
|
||||
href="/contact"
|
||||
className="px-8 py-3 bg-blue-600 text-white rounded-lg hover:bg-blue-700 transition"
|
||||
>
|
||||
Get Started
|
||||
</a>
|
||||
<a
|
||||
href="#contact"
|
||||
className="px-8 py-3 border-2 border-blue-600 text-blue-600 rounded-lg hover:bg-blue-50 transition"
|
||||
>
|
||||
Learn More
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</main>
|
||||
</ThemeProvider>
|
||||
);
|
||||
}
|
||||
|
||||
258
src/app/service-request/page.tsx
Normal file
258
src/app/service-request/page.tsx
Normal file
@@ -0,0 +1,258 @@
|
||||
"use client";
|
||||
|
||||
import { ThemeProvider } from "@/providers/themeProvider/ThemeProvider";
|
||||
import NavbarStyleFullscreen from "@/components/navbar/NavbarStyleFullscreen/NavbarStyleFullscreen";
|
||||
import { useState } from "react";
|
||||
import { Upload } from "lucide-react";
|
||||
|
||||
const navItems = [
|
||||
{ name: "Home", id: "/" },
|
||||
{ name: "Membership", id: "/membership" },
|
||||
{ name: "Services", id: "#services" },
|
||||
{ name: "Dashboard", id: "/dashboard" },
|
||||
];
|
||||
|
||||
interface ServiceRequestFormData {
|
||||
memberName: string;
|
||||
phone: string;
|
||||
address: string;
|
||||
membershipPlan: string;
|
||||
issueType: string;
|
||||
description: string;
|
||||
photoFile: File | null;
|
||||
}
|
||||
|
||||
export default function ServiceRequestPage() {
|
||||
const [formData, setFormData] = useState<ServiceRequestFormData>({
|
||||
memberName: "", phone: "", address: "", membershipPlan: "", issueType: "", description: "", photoFile: null,
|
||||
});
|
||||
|
||||
const [submitted, setSubmitted] = useState(false);
|
||||
|
||||
const handleInputChange = (
|
||||
e: React.ChangeEvent<
|
||||
HTMLInputElement | HTMLTextAreaElement | HTMLSelectElement
|
||||
>
|
||||
) => {
|
||||
const { name, value } = e.target;
|
||||
setFormData((prev) => ({
|
||||
...prev,
|
||||
[name]: value,
|
||||
}));
|
||||
};
|
||||
|
||||
const handleFileChange = (e: React.ChangeEvent<HTMLInputElement>) => {
|
||||
if (e.target.files && e.target.files[0]) {
|
||||
setFormData((prev) => ({
|
||||
...prev,
|
||||
photoFile: e.target.files![0],
|
||||
}));
|
||||
}
|
||||
};
|
||||
|
||||
const handleSubmit = (e: React.FormEvent) => {
|
||||
e.preventDefault();
|
||||
console.log("Service request submitted:", formData);
|
||||
setSubmitted(true);
|
||||
setTimeout(() => {
|
||||
setFormData({
|
||||
memberName: "", phone: "", address: "", membershipPlan: "", issueType: "", description: "", photoFile: null,
|
||||
});
|
||||
setSubmitted(false);
|
||||
}, 3000);
|
||||
};
|
||||
|
||||
return (
|
||||
<ThemeProvider
|
||||
defaultButtonVariant="hover-magnetic"
|
||||
defaultTextAnimation="entrance-slide"
|
||||
borderRadius="rounded"
|
||||
contentWidth="medium"
|
||||
sizing="medium"
|
||||
background="circleGradient"
|
||||
cardStyle="glass-elevated"
|
||||
primaryButtonStyle="gradient"
|
||||
secondaryButtonStyle="glass"
|
||||
headingFontWeight="bold"
|
||||
>
|
||||
<NavbarStyleFullscreen
|
||||
navItems={navItems}
|
||||
brandName="OW HomeShield"
|
||||
bottomLeftText="24/7 Support"
|
||||
bottomRightText="support@owhomeshield.com"
|
||||
/>
|
||||
|
||||
<div className="min-h-screen pt-20 pb-20 px-4">
|
||||
<div className="max-w-2xl mx-auto">
|
||||
<h1 className="text-4xl font-bold mb-4 text-center">
|
||||
Service Request
|
||||
</h1>
|
||||
<p className="text-center text-foreground/70 mb-12">
|
||||
Submit a service request and our team will respond within 24 hours.
|
||||
</p>
|
||||
|
||||
<div className="bg-card rounded-lg p-8 border border-foreground/10">
|
||||
{submitted ? (
|
||||
<div className="text-center py-12">
|
||||
<div className="text-5xl mb-4">✓</div>
|
||||
<h2 className="text-2xl font-bold mb-2">
|
||||
Service Request Submitted!
|
||||
</h2>
|
||||
<p className="text-foreground/70">
|
||||
A technician will contact you within 24 hours.
|
||||
</p>
|
||||
</div>
|
||||
) : (
|
||||
<form onSubmit={handleSubmit} className="space-y-6">
|
||||
{/* Member Name */}
|
||||
<div>
|
||||
<label className="block text-sm font-medium mb-2">
|
||||
Member Name *
|
||||
</label>
|
||||
<input
|
||||
type="text"
|
||||
name="memberName"
|
||||
value={formData.memberName}
|
||||
onChange={handleInputChange}
|
||||
required
|
||||
className="w-full px-4 py-2 border border-foreground/20 rounded-lg bg-background focus:outline-none focus:border-primary-cta"
|
||||
placeholder="John Doe"
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* Phone */}
|
||||
<div>
|
||||
<label className="block text-sm font-medium mb-2">
|
||||
Phone Number *
|
||||
</label>
|
||||
<input
|
||||
type="tel"
|
||||
name="phone"
|
||||
value={formData.phone}
|
||||
onChange={handleInputChange}
|
||||
required
|
||||
className="w-full px-4 py-2 border border-foreground/20 rounded-lg bg-background focus:outline-none focus:border-primary-cta"
|
||||
placeholder="(555) 123-4567"
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* Address */}
|
||||
<div>
|
||||
<label className="block text-sm font-medium mb-2">
|
||||
Service Address *
|
||||
</label>
|
||||
<input
|
||||
type="text"
|
||||
name="address"
|
||||
value={formData.address}
|
||||
onChange={handleInputChange}
|
||||
required
|
||||
className="w-full px-4 py-2 border border-foreground/20 rounded-lg bg-background focus:outline-none focus:border-primary-cta"
|
||||
placeholder="123 Main Street, City, State 12345"
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* Membership Plan */}
|
||||
<div>
|
||||
<label className="block text-sm font-medium mb-2">
|
||||
Membership Plan *
|
||||
</label>
|
||||
<select
|
||||
name="membershipPlan"
|
||||
value={formData.membershipPlan}
|
||||
onChange={handleInputChange}
|
||||
required
|
||||
className="w-full px-4 py-2 border border-foreground/20 rounded-lg bg-background focus:outline-none focus:border-primary-cta"
|
||||
>
|
||||
<option value="">Select a plan</option>
|
||||
<option value="basic">Basic Plan</option>
|
||||
<option value="standard">Standard Plan</option>
|
||||
<option value="premium">Premium Plan</option>
|
||||
<option value="elite">Elite Plan</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
{/* Issue Type */}
|
||||
<div>
|
||||
<label className="block text-sm font-medium mb-2">
|
||||
Issue Type *
|
||||
</label>
|
||||
<select
|
||||
name="issueType"
|
||||
value={formData.issueType}
|
||||
onChange={handleInputChange}
|
||||
required
|
||||
className="w-full px-4 py-2 border border-foreground/20 rounded-lg bg-background focus:outline-none focus:border-primary-cta"
|
||||
>
|
||||
<option value="">Select issue type</option>
|
||||
<option value="plumbing">Plumbing</option>
|
||||
<option value="electrical">Electrical</option>
|
||||
<option value="hvac">HVAC</option>
|
||||
<option value="roofing">Roofing</option>
|
||||
<option value="general">General Maintenance</option>
|
||||
<option value="emergency">Emergency Repair</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
{/* Description */}
|
||||
<div>
|
||||
<label className="block text-sm font-medium mb-2">
|
||||
Issue Description *
|
||||
</label>
|
||||
<textarea
|
||||
name="description"
|
||||
value={formData.description}
|
||||
onChange={handleInputChange}
|
||||
required
|
||||
rows={4}
|
||||
className="w-full px-4 py-2 border border-foreground/20 rounded-lg bg-background focus:outline-none focus:border-primary-cta"
|
||||
placeholder="Describe the issue in detail..."
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* Photo Upload */}
|
||||
<div>
|
||||
<label className="block text-sm font-medium mb-2">
|
||||
Upload Photo (Optional)
|
||||
</label>
|
||||
<div className="border-2 border-dashed border-foreground/20 rounded-lg p-6 text-center hover:border-primary-cta transition-colors">
|
||||
<input
|
||||
type="file"
|
||||
name="photo"
|
||||
onChange={handleFileChange}
|
||||
accept="image/*"
|
||||
className="hidden"
|
||||
id="photo-upload"
|
||||
/>
|
||||
<label
|
||||
htmlFor="photo-upload"
|
||||
className="cursor-pointer flex flex-col items-center gap-2"
|
||||
>
|
||||
<Upload className="w-8 h-8 text-primary-cta" />
|
||||
<span className="text-sm font-medium">
|
||||
{formData.photoFile
|
||||
? formData.photoFile.name
|
||||
: "Click to upload or drag and drop"}
|
||||
</span>
|
||||
<span className="text-xs text-foreground/50">
|
||||
PNG, JPG, GIF up to 10MB
|
||||
</span>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Submit Button */}
|
||||
<button
|
||||
type="submit"
|
||||
className="w-full bg-primary-cta text-white font-medium py-3 rounded-lg hover:opacity-90 transition-opacity"
|
||||
>
|
||||
Submit Service Request
|
||||
</button>
|
||||
</form>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</ThemeProvider>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user