Files
ArtSplash/app/(pages)/contact/page.tsx

358 lines
14 KiB
TypeScript

"use client";
import { useState } from "react";
import { motion } from "framer-motion";
import {
Mail,
Phone,
MapPin,
Send,
Instagram,
Linkedin,
MessageSquare,
Clock,
CheckCircle
} from "lucide-react";
const contactMethods = [
{
icon: Mail,
label: "Email",
value: "artsplash@sjec.ac.in",
href: "mailto:artsplash@sjec.ac.in",
description: "Best for detailed inquiries",
},
{
icon: Phone,
label: "Phone",
value: "+91 98765 43210",
href: "tel:+919876543210",
description: "Mon-Fri, 10AM-5PM",
},
{
icon: MapPin,
label: "Location",
value: "SJEC, Mangalore",
href: "https://maps.google.com/?q=St+Joseph+Engineering+College+Mangalore",
description: "Visit us on campus",
},
];
const socialLinks = [
{
icon: Instagram,
label: "Instagram",
href: "https://instagram.com/sceptix_sjec",
username: "@sceptix_sjec",
},
{
icon: Linkedin,
label: "LinkedIn",
href: "https://linkedin.com/company/sceptix-sjec",
username: "Sceptix SJEC",
},
];
const departments = [
"General Inquiry",
"Registration Help",
"Technical Support",
"Submission Issues",
"Voting Questions",
"Partnership & Sponsorship",
"Other",
];
export default function ContactPage() {
const [formState, setFormState] = useState({
name: "",
email: "",
department: "",
subject: "",
message: "",
});
const [isSubmitting, setIsSubmitting] = useState(false);
const [isSubmitted, setIsSubmitted] = useState(false);
const handleChange = (e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement | HTMLSelectElement>) => {
const { name, value } = e.target;
setFormState((prev) => ({ ...prev, [name]: value }));
};
const handleSubmit = async (e: React.FormEvent) => {
e.preventDefault();
setIsSubmitting(true);
// Simulate API call
await new Promise((resolve) => setTimeout(resolve, 1500));
setIsSubmitting(false);
setIsSubmitted(true);
};
if (isSubmitted) {
return (
<main className="min-h-screen bg-black pt-32 pb-20 flex items-center">
<div className="max-w-xl mx-auto px-4 sm:px-6 lg:px-8 text-center">
<motion.div
initial={{ scale: 0.8, opacity: 0 }}
animate={{ scale: 1, opacity: 1 }}
transition={{ duration: 0.5 }}
>
<div className="w-20 h-20 rounded-full bg-lime-400 flex items-center justify-center mx-auto mb-6">
<CheckCircle className="w-10 h-10 text-black" />
</div>
<h1 className="text-3xl sm:text-4xl font-black text-white mb-4">
Message Sent!
</h1>
<p className="text-zinc-400 text-lg mb-8">
Thank you for reaching out. We'll get back to you within 24-48 hours.
</p>
<a
href="/"
className="inline-flex items-center justify-center bg-zinc-900 border border-zinc-800 text-white px-6 py-3 rounded-xl font-semibold hover:border-zinc-700 transition-colors"
>
Back to Home
</a>
</motion.div>
</div>
</main>
);
}
return (
<main className="min-h-screen bg-black pt-32 pb-20">
<div className="max-w-6xl mx-auto px-4 sm:px-6 lg:px-8">
{/* Header */}
<motion.div
initial={{ opacity: 0, y: 20 }}
animate={{ opacity: 1, y: 0 }}
transition={{ duration: 0.6 }}
className="text-center mb-16"
>
<span className="inline-block bg-lime-400 text-black px-4 py-1.5 text-xs font-bold tracking-wider rounded-full mb-6">
CONTACT
</span>
<h1 className="text-4xl sm:text-5xl font-black tracking-tight text-white mb-4">
Get in <span className="text-lime-400">Touch</span>
</h1>
<p className="text-zinc-400 text-lg max-w-2xl mx-auto">
Have a question about ArtSplash? We're here to help. Reach out to us
through any of the channels below.
</p>
</motion.div>
<div className="grid lg:grid-cols-5 gap-8 lg:gap-12">
{/* Contact Info Column */}
<motion.div
initial={{ opacity: 0, x: -20 }}
animate={{ opacity: 1, x: 0 }}
transition={{ duration: 0.6, delay: 0.1 }}
className="lg:col-span-2 space-y-6"
>
{/* Contact Methods */}
<div className="space-y-4">
{contactMethods.map((method, index) => (
<a
key={method.label}
href={method.href}
target={method.label === "Location" ? "_blank" : undefined}
rel={method.label === "Location" ? "noopener noreferrer" : undefined}
className="block bg-zinc-900 border border-zinc-800 rounded-xl p-5 hover:border-zinc-700 transition-colors group"
>
<div className="flex items-start gap-4">
<div className="p-3 bg-lime-400/10 rounded-lg group-hover:bg-lime-400/20 transition-colors">
<method.icon className="w-6 h-6 text-lime-400" />
</div>
<div>
<p className="text-zinc-500 text-sm mb-1">{method.label}</p>
<p className="text-white font-semibold">{method.value}</p>
<p className="text-zinc-500 text-sm mt-1">{method.description}</p>
</div>
</div>
</a>
))}
</div>
{/* Response Time */}
<div className="bg-zinc-900 border border-zinc-800 rounded-xl p-5">
<div className="flex items-center gap-3 mb-3">
<div className="p-2 bg-lime-400/10 rounded-lg">
<Clock className="w-5 h-5 text-lime-400" />
</div>
<h3 className="text-white font-semibold">Response Time</h3>
</div>
<p className="text-zinc-400 text-sm">
We typically respond within <span className="text-lime-400 font-semibold">24-48 hours</span> on
business days. For urgent issues during the competition, we'll prioritize your query.
</p>
</div>
{/* Social Links */}
<div className="bg-zinc-900 border border-zinc-800 rounded-xl p-5">
<h3 className="text-white font-semibold mb-4">Follow Us</h3>
<div className="flex gap-3">
{socialLinks.map((social) => (
<a
key={social.label}
href={social.href}
target="_blank"
rel="noopener noreferrer"
className="flex items-center gap-2 bg-zinc-800 text-zinc-300 px-4 py-3 rounded-xl hover:bg-zinc-700 hover:text-white transition-colors"
>
<social.icon className="w-5 h-5" />
<span className="text-sm font-medium">{social.username}</span>
</a>
))}
</div>
</div>
</motion.div>
{/* Contact Form */}
<motion.div
initial={{ opacity: 0, x: 20 }}
animate={{ opacity: 1, x: 0 }}
transition={{ duration: 0.6, delay: 0.2 }}
className="lg:col-span-3"
>
<div className="bg-zinc-900 border border-zinc-800 rounded-2xl p-6 sm:p-8">
<div className="flex items-center gap-3 mb-6">
<div className="p-2 bg-lime-400/10 rounded-lg">
<MessageSquare className="w-5 h-5 text-lime-400" />
</div>
<h2 className="text-xl font-bold text-white">Send us a Message</h2>
</div>
<form onSubmit={handleSubmit} className="space-y-5">
{/* Name & Email Row */}
<div className="grid sm:grid-cols-2 gap-5">
<div>
<label htmlFor="name" className="block text-sm font-medium text-zinc-300 mb-2">
Your Name <span className="text-lime-400">*</span>
</label>
<input
type="text"
id="name"
name="name"
value={formState.name}
onChange={handleChange}
required
placeholder="John Doe"
className="w-full bg-zinc-800 border border-zinc-700 rounded-xl px-4 py-3 text-white placeholder-zinc-500 focus:outline-none focus:border-lime-400 transition-colors"
/>
</div>
<div>
<label htmlFor="email" className="block text-sm font-medium text-zinc-300 mb-2">
Email Address <span className="text-lime-400">*</span>
</label>
<input
type="email"
id="email"
name="email"
value={formState.email}
onChange={handleChange}
required
placeholder="john@example.com"
className="w-full bg-zinc-800 border border-zinc-700 rounded-xl px-4 py-3 text-white placeholder-zinc-500 focus:outline-none focus:border-lime-400 transition-colors"
/>
</div>
</div>
{/* Department & Subject Row */}
<div className="grid sm:grid-cols-2 gap-5">
<div>
<label htmlFor="department" className="block text-sm font-medium text-zinc-300 mb-2">
Topic <span className="text-lime-400">*</span>
</label>
<div className="relative">
<select
id="department"
name="department"
value={formState.department}
onChange={handleChange}
required
className="w-full bg-zinc-800 border border-zinc-700 rounded-xl px-4 py-3 text-white appearance-none focus:outline-none focus:border-lime-400 transition-colors cursor-pointer"
>
<option value="">Select a topic</option>
{departments.map((dept) => (
<option key={dept} value={dept}>{dept}</option>
))}
</select>
<div className="pointer-events-none absolute inset-y-0 right-0 flex items-center pr-4">
<svg className="w-5 h-5 text-zinc-500" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M19 9l-7 7-7-7" />
</svg>
</div>
</div>
</div>
<div>
<label htmlFor="subject" className="block text-sm font-medium text-zinc-300 mb-2">
Subject <span className="text-lime-400">*</span>
</label>
<input
type="text"
id="subject"
name="subject"
value={formState.subject}
onChange={handleChange}
required
placeholder="Brief subject"
className="w-full bg-zinc-800 border border-zinc-700 rounded-xl px-4 py-3 text-white placeholder-zinc-500 focus:outline-none focus:border-lime-400 transition-colors"
/>
</div>
</div>
{/* Message */}
<div>
<label htmlFor="message" className="block text-sm font-medium text-zinc-300 mb-2">
Your Message <span className="text-lime-400">*</span>
</label>
<textarea
id="message"
name="message"
value={formState.message}
onChange={handleChange}
required
rows={5}
placeholder="Describe your question or issue in detail..."
className="w-full bg-zinc-800 border border-zinc-700 rounded-xl px-4 py-3 text-white placeholder-zinc-500 focus:outline-none focus:border-lime-400 transition-colors resize-none"
/>
<p className="text-zinc-500 text-sm mt-2">
{formState.message.length}/1000 characters
</p>
</div>
{/* Submit Button */}
<button
type="submit"
disabled={isSubmitting}
className={`w-full flex items-center justify-center gap-2 px-6 py-4 rounded-xl font-bold transition-all ${
isSubmitting
? "bg-zinc-700 text-zinc-400 cursor-not-allowed"
: "bg-lime-400 text-black hover:bg-lime-300"
}`}
>
{isSubmitting ? (
<>
<svg className="animate-spin w-5 h-5" viewBox="0 0 24 24">
<circle className="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" strokeWidth="4" fill="none" />
<path className="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z" />
</svg>
Sending...
</>
) : (
<>
<Send className="w-5 h-5" />
Send Message
</>
)}
</button>
</form>
</div>
</motion.div>
</div>
</div>
</main>
);
}