remove unused files
This commit is contained in:
@@ -1,17 +1,416 @@
|
||||
"use client";
|
||||
|
||||
import React, { useState } from "react";
|
||||
import Link from "next/link";
|
||||
import { MaterialIcon } from "@/components/ui/MaterialIcon";
|
||||
|
||||
type FormData = {
|
||||
name: string;
|
||||
email: string;
|
||||
message: string;
|
||||
};
|
||||
|
||||
type FormErrors = {
|
||||
name?: string;
|
||||
email?: string;
|
||||
message?: string;
|
||||
};
|
||||
|
||||
export default function ContactPage() {
|
||||
const [formData, setFormData] = useState<FormData>({
|
||||
name: "",
|
||||
email: "",
|
||||
message: "",
|
||||
});
|
||||
|
||||
const [errors, setErrors] = useState<FormErrors>({});
|
||||
const [isSubmitting, setIsSubmitting] = useState(false);
|
||||
const [showToast, setShowToast] = useState(false);
|
||||
|
||||
const handleInputChange = (
|
||||
e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>
|
||||
) => {
|
||||
const { name, value } = e.target;
|
||||
setFormData((prev) => ({
|
||||
...prev,
|
||||
[name]: value,
|
||||
}));
|
||||
// Clear error for this field as the user types
|
||||
if (errors[name as keyof FormErrors]) {
|
||||
setErrors((prev) => ({
|
||||
...prev,
|
||||
[name]: undefined,
|
||||
}));
|
||||
}
|
||||
};
|
||||
|
||||
const validateForm = (): boolean => {
|
||||
const tempErrors: FormErrors = {};
|
||||
let isValid = true;
|
||||
|
||||
if (!formData.name.trim()) {
|
||||
tempErrors.name = "Name is required";
|
||||
isValid = false;
|
||||
}
|
||||
|
||||
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
||||
if (!formData.email.trim()) {
|
||||
tempErrors.email = "Email is required";
|
||||
isValid = false;
|
||||
} else if (!emailRegex.test(formData.email)) {
|
||||
tempErrors.email = "Please enter a valid email address";
|
||||
isValid = false;
|
||||
}
|
||||
|
||||
if (!formData.message.trim()) {
|
||||
tempErrors.message = "Message is required";
|
||||
isValid = false;
|
||||
} else if (formData.message.trim().length < 10) {
|
||||
tempErrors.message = "Message must be at least 10 characters long";
|
||||
isValid = false;
|
||||
}
|
||||
|
||||
setErrors(tempErrors);
|
||||
return isValid;
|
||||
};
|
||||
|
||||
const handleSubmit = async (e: React.FormEvent) => {
|
||||
e.preventDefault();
|
||||
|
||||
if (!validateForm()) return;
|
||||
|
||||
setIsSubmitting(true);
|
||||
|
||||
// Simulate API Request delay
|
||||
await new Promise((resolve) => setTimeout(resolve, 1200));
|
||||
|
||||
setIsSubmitting(false);
|
||||
setShowToast(true);
|
||||
setFormData({ name: "", email: "", message: "" });
|
||||
|
||||
// Auto-hide toast after 5 seconds
|
||||
setTimeout(() => {
|
||||
setShowToast(false);
|
||||
}, 5000);
|
||||
};
|
||||
|
||||
return (
|
||||
<section className="min-h-[70vh] bg-surface px-margin-mobile md:px-margin-desktop py-24">
|
||||
<div className="mx-auto max-w-container-max text-center">
|
||||
<p className="text-label-sm font-black uppercase tracking-widest text-primary">
|
||||
Contact
|
||||
</p>
|
||||
<h1 className="mt-4 font-display text-4xl font-black text-brand-dark md:text-6xl">
|
||||
Talk to the Nearle team.
|
||||
</h1>
|
||||
<p className="mx-auto mt-6 max-w-2xl text-body-lg text-on-surface-variant">
|
||||
Reach out for partnerships, support, business onboarding, or neighborhood launch enquiries.
|
||||
</p>
|
||||
</div>
|
||||
</section>
|
||||
<div className="relative min-h-screen bg-background">
|
||||
{/* ─── Breadcrumbs & Hero Page Header ─── */}
|
||||
<section className="relative overflow-hidden bg-brand-dark px-margin-mobile md:px-margin-desktop pt-20 pb-24 text-center">
|
||||
{/* Background Decorative Gradients */}
|
||||
<div className="absolute inset-0 bg-[radial-gradient(circle_at_30%_30%,rgba(108,14,128,0.25),transparent_40%)]" />
|
||||
<div className="absolute inset-0 bg-[radial-gradient(circle_at_70%_80%,rgba(252,163,17,0.08),transparent_50%)]" />
|
||||
|
||||
<div className="relative z-10 mx-auto max-w-container-max">
|
||||
{/* Breadcrumbs */}
|
||||
<nav className="flex justify-center mb-6">
|
||||
<ol className="inline-flex items-center space-x-1 md:space-x-2 text-body-sm font-bold text-white/50">
|
||||
<li className="inline-flex items-center">
|
||||
<Link
|
||||
href="/"
|
||||
className="hover:text-brand-accent transition-colors flex items-center gap-1"
|
||||
>
|
||||
<MaterialIcon icon="home" size={14} />
|
||||
Home
|
||||
</Link>
|
||||
</li>
|
||||
<li>
|
||||
<div className="flex items-center">
|
||||
<span className="mx-1 text-white/30">/</span>
|
||||
<span className="text-brand-accent">Contact</span>
|
||||
</div>
|
||||
</li>
|
||||
</ol>
|
||||
</nav>
|
||||
|
||||
<p className="text-label-sm font-black uppercase tracking-[0.2em] text-brand-accent">
|
||||
Get in touch
|
||||
</p>
|
||||
<h1 className="mt-4 font-display text-4xl font-black text-white md:text-6xl tracking-tight">
|
||||
Talk to the Nearle Team
|
||||
</h1>
|
||||
<p className="mx-auto mt-6 max-w-2xl text-body-lg text-white/70">
|
||||
Have questions about orders, partner onboardings, or neighborhood launches? Reach out and we'll help you.
|
||||
</p>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* ─── Four Contact Info Cards ─── */}
|
||||
<section className="relative z-20 mx-auto -mt-10 max-w-container-max px-margin-mobile md:px-margin-desktop">
|
||||
<div className="grid grid-cols-1 gap-6 sm:grid-cols-2 lg:grid-cols-4">
|
||||
|
||||
{/* Card 1: Location */}
|
||||
<div className="premium-card bg-white rounded-3xl p-7 border border-outline-variant/15 flex flex-col items-center text-center shadow-lg">
|
||||
<div className="w-14 h-14 rounded-2xl bg-primary/5 text-primary flex items-center justify-center mb-5">
|
||||
<MaterialIcon icon="location_on" size={28} className="text-primary" />
|
||||
</div>
|
||||
<h3 className="font-display text-lg font-black text-brand-dark mb-2">Our Location</h3>
|
||||
<p className="text-body-sm text-on-surface-variant leading-relaxed">
|
||||
Nearle HQ, 29 Avinashi Road,<br />
|
||||
Coimbatore, Tamil Nadu,<br />
|
||||
641018, India
|
||||
</p>
|
||||
<a
|
||||
href="https://maps.google.com/?q=Avinashi+Road,+Coimbatore,+Tamil+Nadu,+India"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="mt-auto pt-4 text-label-sm text-primary hover:text-primary-container font-black flex items-center gap-1 group"
|
||||
>
|
||||
Get Directions
|
||||
<MaterialIcon icon="arrow_forward" size={14} className="group-hover:translate-x-1 transition-transform" />
|
||||
</a>
|
||||
</div>
|
||||
|
||||
{/* Card 2: Phones */}
|
||||
<div className="premium-card bg-white rounded-3xl p-7 border border-outline-variant/15 flex flex-col items-center text-center shadow-lg">
|
||||
<div className="w-14 h-14 rounded-2xl bg-secondary/5 text-secondary flex items-center justify-center mb-5">
|
||||
<MaterialIcon icon="call" size={28} className="text-secondary" />
|
||||
</div>
|
||||
<h3 className="font-display text-lg font-black text-brand-dark mb-2">Phones</h3>
|
||||
<p className="text-body-sm text-on-surface-variant leading-relaxed flex flex-col gap-1">
|
||||
<span>+91 80 4912 3456</span>
|
||||
<span>+91 422 491 2345</span>
|
||||
</p>
|
||||
<div className="mt-auto pt-4 flex gap-4">
|
||||
<a
|
||||
href="tel:+918049123456"
|
||||
className="text-label-sm text-secondary hover:text-on-secondary-container font-black flex items-center gap-1 group"
|
||||
>
|
||||
Helpdesk
|
||||
<MaterialIcon icon="phone" size={14} className="group-hover:scale-110 transition-transform" />
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Card 3: Email */}
|
||||
<div className="premium-card bg-white rounded-3xl p-7 border border-outline-variant/15 flex flex-col items-center text-center shadow-lg">
|
||||
<div className="w-14 h-14 rounded-2xl bg-primary/5 text-primary flex items-center justify-center mb-5">
|
||||
<MaterialIcon icon="mail" size={28} className="text-primary" />
|
||||
</div>
|
||||
<h3 className="font-display text-lg font-black text-brand-dark mb-2">Email Us</h3>
|
||||
<p className="text-body-sm text-on-surface-variant leading-relaxed flex flex-col gap-1">
|
||||
<a href="mailto:support@nearle.in" className="hover:text-primary transition-colors">support@nearle.in</a>
|
||||
<a href="mailto:partners@nearle.in" className="hover:text-primary transition-colors">partners@nearle.in</a>
|
||||
</p>
|
||||
<a
|
||||
href="mailto:support@nearle.in"
|
||||
className="mt-auto pt-4 text-label-sm text-primary hover:text-primary-container font-black flex items-center gap-1 group"
|
||||
>
|
||||
Write to us
|
||||
<MaterialIcon icon="drafts" size={14} className="group-hover:-translate-y-0.5 transition-transform" />
|
||||
</a>
|
||||
</div>
|
||||
|
||||
{/* Card 4: Working Hours */}
|
||||
<div className="premium-card bg-white rounded-3xl p-7 border border-outline-variant/15 flex flex-col items-center text-center shadow-lg">
|
||||
<div className="w-14 h-14 rounded-2xl bg-brand-accent/10 text-brand-accent flex items-center justify-center mb-5">
|
||||
<MaterialIcon icon="schedule" size={28} className="text-brand-accent" />
|
||||
</div>
|
||||
<h3 className="font-display text-lg font-black text-brand-dark mb-2">Working Hours</h3>
|
||||
<p className="text-body-sm text-on-surface-variant leading-relaxed">
|
||||
Monday - Saturday<br />
|
||||
9:00 AM - 6:00 PM<br />
|
||||
<span className="font-bold text-secondary">24/7 Phone Helpdesk</span>
|
||||
</p>
|
||||
<div className="mt-auto pt-4">
|
||||
<span className="inline-flex items-center gap-1.5 px-3 py-1 rounded-full text-[10px] font-black tracking-wider uppercase bg-secondary/10 text-secondary">
|
||||
<span className="w-2 h-2 rounded-full bg-secondary animate-pulse" />
|
||||
Helpdesk Active
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* ─── Map & Form Section ─── */}
|
||||
<section className="mx-auto max-w-container-max px-margin-mobile md:px-margin-desktop py-20">
|
||||
<div className="grid grid-cols-1 lg:grid-cols-12 gap-12 items-start">
|
||||
|
||||
{/* Left: Google Map (5 Cols) */}
|
||||
<div className="lg:col-span-5 w-full">
|
||||
<div className="relative bg-white rounded-3xl overflow-hidden shadow-xl border border-outline-variant/20 group h-[450px]">
|
||||
<iframe
|
||||
title="Nearle Coimbatore Location Map"
|
||||
src="https://www.google.com/maps/embed?pb=!1m18!1m12!1m3!1d3916.2816999266157!2d76.9587!3d11.0168!2m3!1f0!2f0!3f0!3m2!1i1024!2i768!4f13.1!3m3!1m2!1s0x3ba859af2f97b047%3A0x36b04859873d6e5a!2sAvinashi%20Rd%2C%20Coimbatore%2C%20Tamil%20Nadu!5e0!3m2!1sen!2sin!4v1719000000000!5m2!1sen!2sin"
|
||||
width="100%"
|
||||
height="100%"
|
||||
style={{ border: 0 }}
|
||||
allowFullScreen
|
||||
loading="lazy"
|
||||
referrerPolicy="no-referrer-when-downgrade"
|
||||
className="filter contrast-[1.05] saturate-[0.9] hover:scale-[1.02] transition-transform duration-700"
|
||||
/>
|
||||
{/* Map Floating Info Badge */}
|
||||
<div className="absolute bottom-6 left-6 right-6 bg-white/95 backdrop-blur-md rounded-2xl p-4 border border-outline-variant/20 shadow-lg flex items-center gap-3">
|
||||
<div className="w-10 h-10 rounded-xl bg-primary flex items-center justify-center shrink-0">
|
||||
<MaterialIcon icon="store" size={20} className="text-white" />
|
||||
</div>
|
||||
<div>
|
||||
<h4 className="text-body-sm font-black text-brand-dark">Coimbatore Hub</h4>
|
||||
<p className="text-[11px] text-on-surface-variant">Connecting local vendors & residents</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Right: Message Form (7 Cols) */}
|
||||
<div className="lg:col-span-7 bg-white rounded-3xl p-8 md:p-10 border border-outline-variant/25 shadow-xl relative overflow-hidden">
|
||||
{/* Background Accent Mesh */}
|
||||
<div className="absolute top-0 right-0 w-32 h-32 bg-primary/5 rounded-full blur-3xl" />
|
||||
<div className="absolute bottom-0 left-0 w-32 h-32 bg-secondary/5 rounded-full blur-3xl" />
|
||||
|
||||
<div className="relative z-10">
|
||||
<span className="text-label-sm font-black text-primary uppercase tracking-widest">
|
||||
Write to us
|
||||
</span>
|
||||
<h2 className="font-display text-2xl md:text-3xl font-black text-brand-dark mt-2 mb-8">
|
||||
Send Message
|
||||
</h2>
|
||||
|
||||
<form onSubmit={handleSubmit} className="space-y-6">
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 gap-6">
|
||||
{/* Name field */}
|
||||
<div className="flex flex-col">
|
||||
<label htmlFor="field-name" className="text-label-sm text-on-surface-variant font-bold mb-2">
|
||||
Your Name
|
||||
</label>
|
||||
<div className="relative">
|
||||
<span className="absolute inset-y-0 left-0 flex items-center pl-4 text-on-surface-variant/40">
|
||||
<MaterialIcon icon="person" size={20} />
|
||||
</span>
|
||||
<input
|
||||
type="text"
|
||||
id="field-name"
|
||||
name="name"
|
||||
value={formData.name}
|
||||
onChange={handleInputChange}
|
||||
placeholder="e.g. John Doe"
|
||||
className={`w-full pl-11 pr-4 py-3.5 bg-surface rounded-xl border ${
|
||||
errors.name ? "border-error" : "border-outline-variant/30"
|
||||
} text-body-md text-on-surface placeholder:text-on-surface-variant/45 focus:outline-none focus:ring-2 ${
|
||||
errors.name ? "focus:ring-error/20" : "focus:ring-primary/20"
|
||||
} focus:border-primary transition-all`}
|
||||
/>
|
||||
</div>
|
||||
{errors.name && (
|
||||
<span className="text-body-sm text-error font-bold mt-1.5 flex items-center gap-1">
|
||||
<MaterialIcon icon="error" size={14} />
|
||||
{errors.name}
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{/* Email field */}
|
||||
<div className="flex flex-col">
|
||||
<label htmlFor="field-email" className="text-label-sm text-on-surface-variant font-bold mb-2">
|
||||
Your Email
|
||||
</label>
|
||||
<div className="relative">
|
||||
<span className="absolute inset-y-0 left-0 flex items-center pl-4 text-on-surface-variant/40">
|
||||
<MaterialIcon icon="email" size={20} />
|
||||
</span>
|
||||
<input
|
||||
type="email"
|
||||
id="field-email"
|
||||
name="email"
|
||||
value={formData.email}
|
||||
onChange={handleInputChange}
|
||||
placeholder="e.g. john@example.com"
|
||||
className={`w-full pl-11 pr-4 py-3.5 bg-surface rounded-xl border ${
|
||||
errors.email ? "border-error" : "border-outline-variant/30"
|
||||
} text-body-md text-on-surface placeholder:text-on-surface-variant/45 focus:outline-none focus:ring-2 ${
|
||||
errors.email ? "focus:ring-error/20" : "focus:ring-primary/20"
|
||||
} focus:border-primary transition-all`}
|
||||
/>
|
||||
</div>
|
||||
{errors.email && (
|
||||
<span className="text-body-sm text-error font-bold mt-1.5 flex items-center gap-1">
|
||||
<MaterialIcon icon="error" size={14} />
|
||||
{errors.email}
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Message field */}
|
||||
<div className="flex flex-col">
|
||||
<label htmlFor="field-message" className="text-label-sm text-on-surface-variant font-bold mb-2">
|
||||
Message
|
||||
</label>
|
||||
<div className="relative">
|
||||
<span className="absolute top-3.5 left-4 text-on-surface-variant/40">
|
||||
<MaterialIcon icon="chat_bubble" size={20} />
|
||||
</span>
|
||||
<textarea
|
||||
id="field-message"
|
||||
name="message"
|
||||
rows={5}
|
||||
value={formData.message}
|
||||
onChange={handleInputChange}
|
||||
placeholder="Describe your inquiry in detail (e.g. partnership options, tech support, etc.)"
|
||||
className={`w-full pl-11 pr-4 py-3.5 bg-surface rounded-xl border ${
|
||||
errors.message ? "border-error" : "border-outline-variant/30"
|
||||
} text-body-md text-on-surface placeholder:text-on-surface-variant/45 focus:outline-none focus:ring-2 ${
|
||||
errors.message ? "focus:ring-error/20" : "focus:ring-primary/20"
|
||||
} focus:border-primary transition-all resize-none`}
|
||||
/>
|
||||
</div>
|
||||
{errors.message && (
|
||||
<span className="text-body-sm text-error font-bold mt-1.5 flex items-center gap-1">
|
||||
<MaterialIcon icon="error" size={14} />
|
||||
{errors.message}
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{/* Submit button */}
|
||||
<button
|
||||
type="submit"
|
||||
disabled={isSubmitting}
|
||||
className="w-full bg-primary hover:bg-primary-container disabled:bg-primary-container/60 text-on-primary font-black px-8 py-4 rounded-xl text-label-md hover:shadow-lg transition-all duration-300 hover:-translate-y-0.5 active:translate-y-0 active:scale-[0.98] flex items-center justify-center gap-2 cursor-pointer"
|
||||
>
|
||||
{isSubmitting ? (
|
||||
<>
|
||||
<span className="w-5 h-5 border-2 border-white/30 border-t-white rounded-full animate-spin" />
|
||||
<span>Sending Message...</span>
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<MaterialIcon icon="send" size={18} />
|
||||
<span>Submit Message</span>
|
||||
</>
|
||||
)}
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* ─── Success Toast Notification ─── */}
|
||||
{showToast && (
|
||||
<div className="fixed bottom-8 right-8 z-50 animate-bounce-subtle max-w-sm w-full bg-brand-dark-surface border border-brand-accent/30 rounded-2xl shadow-2xl p-4 flex gap-4 items-start">
|
||||
<div className="w-10 h-10 rounded-xl bg-secondary text-white flex items-center justify-center shrink-0">
|
||||
<MaterialIcon icon="check_circle" size={24} />
|
||||
</div>
|
||||
<div className="flex-1">
|
||||
<h4 className="text-body-md font-black text-white">Message Sent!</h4>
|
||||
<p className="text-body-sm text-white/70 mt-1 leading-normal">
|
||||
Thank you for reaching out. We will get back to you within 24 hours.
|
||||
</p>
|
||||
</div>
|
||||
<button
|
||||
onClick={() => setShowToast(false)}
|
||||
className="text-white/40 hover:text-white transition-colors cursor-pointer shrink-0"
|
||||
aria-label="Close Toast"
|
||||
>
|
||||
<MaterialIcon icon="close" size={18} />
|
||||
</button>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user