Compare commits
21 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 991029a66a | |||
| 5d680badc5 | |||
| 3040ee7707 | |||
| 9a3f4d6c2c | |||
| 1a1ca65727 | |||
| e779a2f06d | |||
| de509fb6f9 | |||
| fd1d1351d5 | |||
| d9cca644e1 | |||
| 83a1fc5e15 | |||
| 6e3dc7d215 | |||
| 4cd5edc456 | |||
| 03c0beff67 | |||
| 86262a145e | |||
| 53cbc550eb | |||
| 283cbc8441 | |||
| 8e4a6f0594 | |||
| 7813c4d12c | |||
| f46a8dcd39 | |||
| d86585a83e | |||
| 7d9e0f70a9 |
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,128 +1,25 @@
|
||||
"use client";
|
||||
|
||||
import { ThemeProvider } from "@/components/theme/ThemeProvider";
|
||||
import NavbarStyleCentered from "@/components/navbar/NavbarStyleCentered/NavbarStyleCentered";
|
||||
import HeroBillboardRotatedCarousel from "@/components/sections/hero/HeroBillboardRotatedCarousel";
|
||||
import TextSplitAbout from "@/components/sections/about/TextSplitAbout";
|
||||
import FeatureCardTwentySeven from "@/components/sections/feature/FeatureCardTwentySeven";
|
||||
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 TestimonialCardTwelve from "@/components/sections/testimonial/TestimonialCardTwelve";
|
||||
import ContactFaq from "@/components/sections/contact/ContactFaq";
|
||||
import FooterBase from "@/components/sections/footer/FooterBase";
|
||||
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 { Phone, Mail, MessageCircle, ArrowRight, Check } from "lucide-react";
|
||||
import { Mail, Phone, MapPin } from "lucide-react";
|
||||
|
||||
export default function ContactPage() {
|
||||
const navItems = [
|
||||
{ name: "Home", id: "/" },
|
||||
{ name: "About", id: "#about" },
|
||||
{ name: "Services", id: "#services" },
|
||||
{ name: "Pricing", id: "#pricing" },
|
||||
{ name: "Contact", id: "/contact" },
|
||||
];
|
||||
|
||||
const carouselItems = [
|
||||
{ id: "1", imageSrc: "/carousel-1.jpg", imageAlt: "Service 1" },
|
||||
{ id: "2", imageSrc: "/carousel-2.jpg", imageAlt: "Service 2" },
|
||||
{ id: "3", imageSrc: "/carousel-3.jpg", imageAlt: "Service 3" },
|
||||
{ id: "4", imageSrc: "/carousel-4.jpg", imageAlt: "Service 4" },
|
||||
{ id: "5", imageSrc: "/carousel-5.jpg", imageAlt: "Service 5" },
|
||||
{ id: "6", imageSrc: "/carousel-6.jpg", imageAlt: "Service 6" },
|
||||
];
|
||||
|
||||
const features = [
|
||||
{
|
||||
id: "1", title: "Expert Consultation", descriptions: [
|
||||
"Our experienced team provides professional guidance", "We assess your needs thoroughly", "Personalized solutions for your situation"],
|
||||
imageSrc: "/feature-1.jpg", imageAlt: "Expert Consultation"},
|
||||
{
|
||||
id: "2", title: "24/7 Support", descriptions: [
|
||||
"Round-the-clock customer support", "Rapid response to urgent inquiries", "Dedicated support specialists"],
|
||||
imageSrc: "/feature-2.jpg", imageAlt: "24/7 Support"},
|
||||
{
|
||||
id: "3", title: "Quality Assurance", descriptions: [
|
||||
"Rigorous testing and verification", "Industry-leading standards compliance", "Continuous improvement processes"],
|
||||
imageSrc: "/feature-3.jpg", imageAlt: "Quality Assurance"},
|
||||
{
|
||||
id: "4", title: "Professional Team", descriptions: [
|
||||
"Certified and experienced professionals", "Ongoing training and development", "Commitment to excellence"],
|
||||
imageSrc: "/feature-4.jpg", imageAlt: "Professional Team"},
|
||||
];
|
||||
|
||||
const products = [
|
||||
{
|
||||
id: "1", name: "Premium Service Package", price: "$199", variant: "Comprehensive coverage", imageSrc: "/product-1.jpg", imageAlt: "Premium Package"},
|
||||
{
|
||||
id: "2", name: "Standard Service Package", price: "$99", variant: "Essential services", imageSrc: "/product-2.jpg", imageAlt: "Standard Package"},
|
||||
{
|
||||
id: "3", name: "Professional Service Package", price: "$149", variant: "Extended features", imageSrc: "/product-3.jpg", imageAlt: "Professional Package"},
|
||||
{
|
||||
id: "4", name: "Enterprise Service Package", price: "$299", variant: "Full suite access", imageSrc: "/product-4.jpg", imageAlt: "Enterprise Package"},
|
||||
];
|
||||
|
||||
const pricingPlans = [
|
||||
{
|
||||
id: "starter", title: "Starter", price: "$29", period: "/month", imageSrc: "/pricing-1.jpg", imageAlt: "Starter Plan", button: { text: "Get Started", href: "#contact" },
|
||||
features: ["Basic support", "Monthly consultations", "Email assistance"],
|
||||
},
|
||||
{
|
||||
id: "professional", title: "Professional", price: "$79", period: "/month", imageSrc: "/pricing-2.jpg", imageAlt: "Professional Plan", button: { text: "Choose Plan", href: "#contact" },
|
||||
features: [
|
||||
"Priority support", "Weekly consultations", "Phone and email support", "Dedicated account manager"],
|
||||
},
|
||||
];
|
||||
|
||||
const testimonials = [
|
||||
{
|
||||
id: "1", name: "Sarah Johnson", imageSrc: "/testimonial-1.jpg", imageAlt: "Sarah Johnson"},
|
||||
{
|
||||
id: "2", name: "Michael Chen", imageSrc: "/testimonial-2.jpg", imageAlt: "Michael Chen"},
|
||||
{
|
||||
id: "3", name: "Emma Davis", imageSrc: "/testimonial-3.jpg", imageAlt: "Emma Davis"},
|
||||
{
|
||||
id: "4", name: "James Wilson", imageSrc: "/testimonial-4.jpg", imageAlt: "James Wilson"},
|
||||
];
|
||||
|
||||
const faqs = [
|
||||
{
|
||||
id: "1", title: "What services are included?", content:
|
||||
"Our comprehensive service package includes professional consultation, 24/7 support, quality assurance, and ongoing assistance from our experienced team."},
|
||||
{
|
||||
id: "2", title: "How quickly can you respond?", content:
|
||||
"We pride ourselves on rapid response times. Most inquiries are addressed within 24 hours, and urgent matters are handled immediately by our dedicated support team."},
|
||||
{
|
||||
id: "3", title: "Do you offer customized solutions?", content:
|
||||
"Yes! We provide personalized solutions tailored to your specific needs. Contact us to discuss your requirements and we'll create a customized plan."},
|
||||
{
|
||||
id: "4", title: "What are your pricing options?", content:
|
||||
"We offer flexible pricing plans ranging from basic to enterprise solutions. Choose the plan that best fits your needs, and upgrade or downgrade anytime."},
|
||||
];
|
||||
|
||||
const footerColumns = [
|
||||
{
|
||||
title: "Product", items: [
|
||||
{ label: "Features", href: "#features" },
|
||||
{ label: "Pricing", href: "#pricing" },
|
||||
{ label: "Security", href: "#security" },
|
||||
],
|
||||
},
|
||||
{
|
||||
title: "Company", items: [
|
||||
{ label: "About", href: "#about" },
|
||||
{ label: "Blog", href: "#blog" },
|
||||
{ label: "Careers", href: "#careers" },
|
||||
],
|
||||
},
|
||||
{
|
||||
title: "Resources", items: [
|
||||
{ label: "Help Center", href: "#help" },
|
||||
{ label: "Contact", href: "/contact" },
|
||||
{ label: "Status", href: "#status" },
|
||||
],
|
||||
},
|
||||
];
|
||||
|
||||
return (
|
||||
<ThemeProvider
|
||||
defaultButtonVariant="hover-magnetic"
|
||||
@@ -130,58 +27,74 @@ export default function ContactPage() {
|
||||
borderRadius="rounded"
|
||||
contentWidth="medium"
|
||||
sizing="medium"
|
||||
background="circleGradient"
|
||||
background="none"
|
||||
cardStyle="solid"
|
||||
primaryButtonStyle="gradient"
|
||||
secondaryButtonStyle="glass"
|
||||
headingFontWeight="bold"
|
||||
>
|
||||
<NavbarStyleCentered
|
||||
<NavbarStyleFullscreen
|
||||
navItems={navItems}
|
||||
button={{ text: "Get Started", href: "#contact" }}
|
||||
brandName="ContactHub"
|
||||
brandName="OW HomeShield"
|
||||
bottomLeftText="Available 24/7"
|
||||
bottomRightText="support@owhomeshield.com"
|
||||
/>
|
||||
|
||||
<div id="hero" data-section="hero">
|
||||
<HeroBillboardRotatedCarousel
|
||||
title="Get in Touch with Our Team"
|
||||
description="We're here to help. Reach out to us with any questions or to schedule a consultation."
|
||||
background={{ variant: "sparkles-gradient" }}
|
||||
<HeroBillboardTestimonial
|
||||
title="Get in Touch with OW HomeShield"
|
||||
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"
|
||||
tagIcon={MessageCircle}
|
||||
buttons={[
|
||||
{ text: "Start Conversation", href: "#contact" },
|
||||
{ text: "Learn More", href: "#about" },
|
||||
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" },
|
||||
]}
|
||||
carouselItems={carouselItems}
|
||||
autoPlay={true}
|
||||
autoPlayInterval={4000}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div id="about" data-section="about">
|
||||
<TextSplitAbout
|
||||
title="Why Choose Us"
|
||||
description={[
|
||||
"We pride ourselves on delivering exceptional service with professionalism and integrity.", "Our dedicated team is committed to understanding your needs and providing tailored solutions.", "With years of experience, we've built lasting relationships with thousands of satisfied customers."]}
|
||||
<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 Services", href: "#services" },
|
||||
{ text: "View Plans", href: "#pricing" },
|
||||
]}
|
||||
useInvertedBackground={false}
|
||||
showBorder={true}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div id="features" data-section="features">
|
||||
<FeatureCardTwentySeven
|
||||
features={features}
|
||||
gridVariant="four-items-2x2-equal-grid"
|
||||
animationType="slide-up"
|
||||
<FeatureCardTwelve
|
||||
title="Our Services"
|
||||
description="Discover the comprehensive solutions we offer to meet your needs"
|
||||
tag="Services"
|
||||
tagIcon={Check}
|
||||
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}
|
||||
/>
|
||||
@@ -189,62 +102,158 @@ export default function ContactPage() {
|
||||
|
||||
<div id="products" data-section="products">
|
||||
<ProductCardFour
|
||||
products={products}
|
||||
title="Service Packages"
|
||||
description="Choose the package that best fits your requirements"
|
||||
tag="Packages"
|
||||
textboxLayout="default"
|
||||
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}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div id="pricing" data-section="pricing">
|
||||
<PricingCardNine
|
||||
plans={pricingPlans}
|
||||
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}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div id="pricing-cards" data-section="pricing-cards">
|
||||
<PricingCardTwo
|
||||
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"
|
||||
title="Flexible Pricing Plans"
|
||||
description="Select the plan that works best for your budget and needs"
|
||||
textboxLayout="default"
|
||||
useInvertedBackground={false}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div id="testimonials" data-section="testimonials">
|
||||
<TestimonialCardTwelve
|
||||
testimonials={testimonials}
|
||||
cardTitle="Over 5,000 satisfied customers trust us for their needs"
|
||||
cardTag="See what they say"
|
||||
cardAnimation="slide-up"
|
||||
useInvertedBackground={false}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div id="contact" data-section="contact">
|
||||
<ContactFaq
|
||||
faqs={faqs}
|
||||
ctaTitle="Ready to Get Started?"
|
||||
ctaDescription="Let's discuss how we can help you achieve your goals."
|
||||
ctaButton={{ text: "Schedule a Call", href: "#contact" }}
|
||||
ctaIcon={Phone}
|
||||
<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"},
|
||||
]}
|
||||
title="What Our Customers Say"
|
||||
description="Trusted by thousands of homeowners across the Pacific Northwest"
|
||||
textboxLayout="default"
|
||||
useInvertedBackground={false}
|
||||
animationType="slide-up"
|
||||
accordionAnimationType="smooth"
|
||||
showCard={true}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div id="footer-base" data-section="footer-base">
|
||||
<FooterBase
|
||||
columns={footerColumns}
|
||||
logoText="ContactHub"
|
||||
copyrightText="© 2025 | ContactHub. All rights reserved."
|
||||
<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">
|
||||
<FooterBaseCard
|
||||
logoText="OW HomeShield"
|
||||
columns={[
|
||||
{
|
||||
title: "Product", items: [
|
||||
{ label: "Membership Plans", href: "#pricing" },
|
||||
{ label: "Services", href: "#services" },
|
||||
{ label: "Pricing", href: "#pricing" },
|
||||
],
|
||||
},
|
||||
{
|
||||
title: "Company", items: [
|
||||
{ label: "About Us", href: "#about" },
|
||||
{ label: "Contact", href: "#contact-form" },
|
||||
{ label: "Blog", href: "#blog" },
|
||||
],
|
||||
},
|
||||
{
|
||||
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 copyrightText="Privacy Policy • Terms of Service • Contact" />
|
||||
<FooterSimple
|
||||
text="© 2025 OW HomeShield. Professional home maintenance and repair services."
|
||||
/>
|
||||
</div>
|
||||
</ThemeProvider>
|
||||
);
|
||||
|
||||
@@ -1,286 +0,0 @@
|
||||
"use client";
|
||||
|
||||
import { ThemeProvider } from "@/components/theme/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>
|
||||
);
|
||||
}
|
||||
@@ -1,254 +0,0 @@
|
||||
"use client";
|
||||
|
||||
import { ThemeProvider } from "@/components/theme/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>
|
||||
);
|
||||
}
|
||||
@@ -1,15 +1,11 @@
|
||||
"use client";
|
||||
|
||||
import { ThemeProvider } from "@/components/theme/ThemeProvider";
|
||||
import NavbarStyleCentered from "@/components/navbar/NavbarStyleCentered/NavbarStyleCentered";
|
||||
import { useState } from "react";
|
||||
import NavbarStyleFullscreen from "@/components/navbar/NavbarStyleFullscreen/NavbarStyleFullscreen";
|
||||
|
||||
export default function Home() {
|
||||
const navItems = [
|
||||
{ name: "Home", id: "/" },
|
||||
{ name: "About", id: "#about" },
|
||||
{ name: "Services", id: "#services" },
|
||||
{ name: "Pricing", id: "#pricing" },
|
||||
{ name: "Contact", id: "/contact" },
|
||||
];
|
||||
|
||||
@@ -20,20 +16,44 @@ export default function Home() {
|
||||
borderRadius="rounded"
|
||||
contentWidth="medium"
|
||||
sizing="medium"
|
||||
background="circleGradient"
|
||||
background="none"
|
||||
cardStyle="solid"
|
||||
primaryButtonStyle="gradient"
|
||||
secondaryButtonStyle="glass"
|
||||
headingFontWeight="bold"
|
||||
>
|
||||
<NavbarStyleCentered
|
||||
<NavbarStyleFullscreen
|
||||
navItems={navItems}
|
||||
button={{ text: "Get Started", href: "/contact" }}
|
||||
brandName="OW HomeShield"
|
||||
bottomLeftText="Available 24/7"
|
||||
bottomRightText="support@owhomeshield.com"
|
||||
/>
|
||||
<div className="min-h-screen flex items-center justify-center">
|
||||
<h1 className="text-4xl font-bold">Welcome to OW HomeShield</h1>
|
||||
</div>
|
||||
<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>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,258 +0,0 @@
|
||||
"use client";
|
||||
|
||||
import { ThemeProvider } from "@/components/theme/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>
|
||||
);
|
||||
}
|
||||
@@ -10,15 +10,15 @@
|
||||
--accent: #ffffff;
|
||||
--background-accent: #ffffff; */
|
||||
|
||||
--background: #ffffff;
|
||||
--card: #f9f9f9;
|
||||
--foreground: #000612e6;
|
||||
--primary-cta: #106EFB;
|
||||
--background: #f7f6f7;
|
||||
--card: #ffffff;
|
||||
--foreground: #1a1a1a;
|
||||
--primary-cta: #0798ff;
|
||||
--primary-cta-text: #ffffff;
|
||||
--secondary-cta: #f9f9f9;
|
||||
--secondary-cta: #ffffff;
|
||||
--secondary-cta-text: #000612e6;
|
||||
--accent: #e2e2e2;
|
||||
--background-accent: #106EFB;
|
||||
--accent: #93c7ff;
|
||||
--background-accent: #a8cde8;
|
||||
|
||||
/* text sizing - set by ThemeProvider */
|
||||
/* --text-2xs: clamp(0.465rem, 0.62vw, 0.62rem);
|
||||
|
||||
Reference in New Issue
Block a user