Compare commits
27 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 5f6dcacc6e | |||
| 252e3182aa | |||
| f7820690ad | |||
| ef397ae2ff | |||
| 90f7b1c37f | |||
| f143e629cb | |||
| 1d5eb0daa5 | |||
| 1481d8893b | |||
| aaa87ce578 | |||
| 18065969f5 | |||
| e98c8c5d5f | |||
| 175ae4498f | |||
| 50df1b89f7 | |||
| 371275a0d2 | |||
| 2147f00101 | |||
| c6827bc6d0 | |||
| 4139dce37d | |||
| 5cccffb965 | |||
| 77cb47421f | |||
| 84a9b6cced | |||
| 1820e0dc1e | |||
| a6aee2f71c | |||
| 63b2abab97 | |||
| 177b11fff0 | |||
| d68596f792 | |||
| cafccc2bb9 | |||
| 0de718b267 |
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,190 +1,260 @@
|
||||
"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 { Linkedin, Twitter, Mail } from "lucide-react";
|
||||
import Link from "next/link";
|
||||
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 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 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: "Membership Plans", id: "pricing" },
|
||||
{ name: "Request Service", id: "how-it-works" },
|
||||
{ name: "About", id: "benefits" },
|
||||
{ name: "Contact", id: "final-cta" }
|
||||
]}
|
||||
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">
|
||||
<HeroSplitKpi
|
||||
<HeroBillboardTestimonial
|
||||
title="Get in Touch with OW HomeShield"
|
||||
description="Have questions about our membership plans or need immediate assistance? We're here to help."
|
||||
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" }}
|
||||
kpis={[
|
||||
{ value: "10+", label: "Years Experience" },
|
||||
{ value: "24/7", label: "Emergency Support" },
|
||||
{ value: "500+", label: "Satisfied Customers" }
|
||||
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"},
|
||||
]}
|
||||
enableKpiAnimation={true}
|
||||
buttons={[
|
||||
{ text: "Call Now", href: "tel:226-224-3573" },
|
||||
{ text: "Email Us", href: "mailto:info@owhomeshield.com" }
|
||||
{ text: "Call Now", href: "tel:1-800-123-4567" },
|
||||
{ text: "Schedule Service", href: "#contact-form" },
|
||||
]}
|
||||
buttonAnimation="slide-up"
|
||||
mediaAnimation="blur-reveal"
|
||||
imageSrc="http://img.b2bpic.net/free-photo/high-angle-young-man-taking-break_23-2148384545.jpg?_wi=1"
|
||||
imageAlt="Contact our team"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div id="benefits" data-section="benefits">
|
||||
<FeatureCardSeven
|
||||
<div id="about" data-section="about">
|
||||
<MediaAbout
|
||||
title="Why Choose OW HomeShield?"
|
||||
description="We pride ourselves on delivering exceptional service across all areas"
|
||||
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">
|
||||
<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={[
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div id="products" data-section="products">
|
||||
<ProductCardFour
|
||||
title="Service Packages"
|
||||
description="Choose from our selection of professional home maintenance services"
|
||||
tag="Available Services"
|
||||
products={[
|
||||
{
|
||||
id: 1,
|
||||
title: "Expert Technicians", description: "Licensed and insured professionals with years of experience", imageSrc: "http://img.b2bpic.net/free-photo/high-angle-young-man-taking-break_23-2148384545.jpg?_wi=2", imageAlt: "Expert technicians"
|
||||
},
|
||||
id: "1", name: "HVAC Maintenance", price: "$150", variant: "Quarterly Service", imageSrc: "/service1.jpg", imageAlt: "HVAC Service"},
|
||||
{
|
||||
id: 2,
|
||||
title: "Fast Response", description: "Quick turnaround times for all service requests", imageSrc: "http://img.b2bpic.net/free-photo/high-angle-young-man-taking-break_23-2148384545.jpg?_wi=3", imageAlt: "Fast response service"
|
||||
},
|
||||
id: "2", name: "Plumbing Inspection", price: "$120", variant: "Annual Check", imageSrc: "/service2.jpg", imageAlt: "Plumbing Service"},
|
||||
{
|
||||
id: 3,
|
||||
title: "Affordable Pricing", description: "Competitive rates with membership discounts", imageSrc: "http://img.b2bpic.net/free-photo/high-angle-young-man-taking-break_23-2148384545.jpg?_wi=4", imageAlt: "Affordable pricing"
|
||||
}
|
||||
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}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div id="pricing" data-section="pricing">
|
||||
<PricingCardOne
|
||||
title="Our Membership Plans"
|
||||
description="Choose the perfect plan for your home protection needs"
|
||||
animationType="slide-up"
|
||||
textboxLayout="default"
|
||||
useInvertedBackground={false}
|
||||
<PricingCardNine
|
||||
title="Membership Plans"
|
||||
description="Choose the perfect plan for your home maintenance needs"
|
||||
tag="Pricing"
|
||||
plans={[
|
||||
{
|
||||
id: "basic", badge: "Basic", price: "$44/month", subtitle: "Essential coverage", features: ["1 service visit per month", "10% renovation discount"]
|
||||
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: "standard", badge: "Standard", price: "$59/month", subtitle: "Popular choice", features: ["2 service visits per month", "15% renovation discount", "Priority booking"]
|
||||
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"],
|
||||
},
|
||||
{
|
||||
id: "premium", badge: "Premium", price: "$84/month", subtitle: "Full coverage", features: ["Unlimited service requests", "24/7 emergency support", "Priority scheduling"]
|
||||
}
|
||||
]}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div id="how-it-works" data-section="how-it-works">
|
||||
<FeatureCardSeven
|
||||
title="How Our Service Works"
|
||||
description="Simple steps to get your home protected"
|
||||
animationType="slide-up"
|
||||
textboxLayout="default"
|
||||
useInvertedBackground={false}
|
||||
features={[
|
||||
{
|
||||
id: 1,
|
||||
title: "Choose Your Plan", description: "Select from our three membership options based on your needs", imageSrc: "http://img.b2bpic.net/free-photo/high-angle-young-man-taking-break_23-2148384545.jpg?_wi=5", imageAlt: "Choose your plan"
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
title: "Sign Up Online", description: "Quick registration process takes just a few minutes", imageSrc: "http://img.b2bpic.net/free-photo/high-angle-young-man-taking-break_23-2148384545.jpg?_wi=6", imageAlt: "Sign up online"
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
title: "Get Immediate Service", description: "Start receiving professional home maintenance and repairs", imageSrc: "http://img.b2bpic.net/free-photo/high-angle-young-man-taking-break_23-2148384545.jpg?_wi=7", imageAlt: "Get immediate service"
|
||||
}
|
||||
]}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div id="trust" data-section="trust">
|
||||
<TestimonialCardFifteen
|
||||
testimonial="Outstanding service! The team was professional and efficient. They fixed my plumbing issue quickly and at a fair price. Highly recommended."
|
||||
rating={5}
|
||||
author="John Smith"
|
||||
avatars={[
|
||||
<div id="pricing-cards" data-section="pricing-cards">
|
||||
<PricingCardTwo
|
||||
title="Annual Membership"
|
||||
description="Save more with annual commitment"
|
||||
tag="Best Value"
|
||||
plans={[
|
||||
{
|
||||
src: "http://img.b2bpic.net/free-photo/cheerful-excited-businesswoman-blue-blouse-showing-thumb-up_1262-14826.jpg", alt: "Customer John"
|
||||
}
|
||||
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,
|
||||
},
|
||||
]}
|
||||
ratingAnimation="slide-up"
|
||||
avatarsAnimation="slide-up"
|
||||
animationType="slide-up"
|
||||
textboxLayout="default"
|
||||
useInvertedBackground={false}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div id="final-cta" data-section="final-cta">
|
||||
<ContactCTA
|
||||
tag="Ready to Get Started?"
|
||||
title="Join OW HomeShield Today"
|
||||
description="Experience the peace of mind that comes with reliable home maintenance and emergency support available 24/7."
|
||||
buttons={[
|
||||
{ text: "Start Free Trial", href: "#" },
|
||||
{ text: "Call Us Now", href: "tel:226-224-3573" }
|
||||
<div id="testimonials" data-section="testimonials">
|
||||
<TestimonialCardSix
|
||||
testimonials={[
|
||||
{
|
||||
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", 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"},
|
||||
]}
|
||||
buttonAnimation="slide-up"
|
||||
background={{ variant: "plain" }}
|
||||
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="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="/contact-split.jpg"
|
||||
imageAlt="OW HomeShield team"
|
||||
mediaAnimation="slide-up"
|
||||
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">
|
||||
<FooterCard
|
||||
logoText="OW HomeShield Inc."
|
||||
copyrightText="© 2025 OW HomeShield Inc. All rights reserved."
|
||||
socialLinks={[
|
||||
<FooterBaseCard
|
||||
logoText="OW HomeShield"
|
||||
columns={[
|
||||
{
|
||||
icon: Linkedin,
|
||||
href: "https://linkedin.com", ariaLabel: "LinkedIn"
|
||||
title: "Product", items: [
|
||||
{ label: "Membership Plans", href: "#pricing" },
|
||||
{ label: "Services", href: "#services" },
|
||||
{ label: "Pricing", href: "#pricing" },
|
||||
],
|
||||
},
|
||||
{
|
||||
icon: Twitter,
|
||||
href: "https://twitter.com", ariaLabel: "Twitter"
|
||||
title: "Company", items: [
|
||||
{ label: "About Us", href: "#about" },
|
||||
{ label: "Contact", href: "#contact-form" },
|
||||
{ label: "Blog", href: "#blog" },
|
||||
],
|
||||
},
|
||||
{
|
||||
icon: Mail,
|
||||
href: "mailto:info@owhomeshield.com", ariaLabel: "Email"
|
||||
}
|
||||
title: "Support", items: [
|
||||
{ label: "24/7 Hotline", href: "tel:1-800-123-4567" },
|
||||
{ label: "Emergency Service", href: "tel:1-800-123-4567" },
|
||||
{ label: "FAQ", href: "#faq" },
|
||||
],
|
||||
},
|
||||
]}
|
||||
copyrightText="© 2025 OW HomeShield. All rights reserved."
|
||||
onPrivacyClick={() => console.log("Privacy clicked")}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div id="footer-simple" data-section="footer-simple">
|
||||
<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>
|
||||
);
|
||||
}
|
||||
242
src/app/page.tsx
242
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: "home" },
|
||||
{ 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