Files
techzaa-frontend/src/components/ContactModal.tsx
T

212 lines
7.8 KiB
TypeScript
Raw Normal View History

2026-03-30 20:20:21 +06:00
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Textarea } from "@/components/ui/textarea";
import { AnimatePresence, motion } from "framer-motion";
import { CheckCircle, Send, X } from "lucide-react";
import { useState } from "react";
interface ContactModalProps {
isOpen: boolean;
onClose: () => void;
}
export default function ContactModal({ isOpen, onClose }: ContactModalProps) {
const [formData, setFormData] = useState({
name: "",
email: "",
message: "",
});
const [isSubmitting, setIsSubmitting] = useState(false);
const [isSuccess, setIsSuccess] = useState(false);
const handleSubmit = async (e: React.FormEvent) => {
e.preventDefault();
setIsSubmitting(true);
// Simulate form submission
await new Promise((resolve) => setTimeout(resolve, 1500));
setIsSubmitting(false);
setIsSuccess(true);
// Reset after showing success
setTimeout(() => {
setIsSuccess(false);
setFormData({ name: "", email: "", message: "" });
onClose();
}, 2000);
};
const handleChange = (
e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>,
) => {
setFormData((prev) => ({
...prev,
[e.target.name]: e.target.value,
}));
};
return (
<AnimatePresence>
{isOpen && (
<motion.div
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
exit={{ opacity: 0 }}
className="fixed inset-0 z-[100] flex items-center justify-center p-4"
>
{/* Backdrop */}
<motion.div
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
exit={{ opacity: 0 }}
2026-04-30 22:54:35 +06:00
className="absolute inset-0 bg-background/10 backdrop-blur-sm"
2026-03-30 20:20:21 +06:00
onClick={onClose}
/>
{/* Modal */}
<motion.div
initial={{ opacity: 0, scale: 0.9, y: 20 }}
animate={{ opacity: 1, scale: 1, y: 0 }}
exit={{ opacity: 0, scale: 0.9, y: 20 }}
transition={{ type: "spring", damping: 25, stiffness: 300 }}
className="relative w-full max-w-md rounded-3xl p-8 border-gradient overflow-hidden"
>
{/* Close button */}
<motion.button
onClick={onClose}
2026-04-30 22:54:35 +06:00
className="absolute top-4 right-2 p-2 rounded-full glass hover:bg-primary/20 transition-colors"
2026-03-30 20:20:21 +06:00
whileHover={{ scale: 1.1 }}
whileTap={{ scale: 0.9 }}
>
<X className="w-5 h-5" />
</motion.button>
{/* Content */}
<div className="relative z-10">
<AnimatePresence mode="wait">
{isSuccess ? (
<motion.div
key="success"
initial={{ opacity: 0, scale: 0.8 }}
animate={{ opacity: 1, scale: 1 }}
exit={{ opacity: 0, scale: 0.8 }}
className="text-center py-8"
>
<motion.div
initial={{ scale: 0 }}
animate={{ scale: 1 }}
transition={{
type: "spring",
damping: 15,
stiffness: 300,
delay: 0.2,
}}
>
<CheckCircle className="w-20 h-20 text-primary mx-auto mb-4 neon-text-glow" />
</motion.div>
<h3 className="text-2xl font-bold mb-2">Message Sent!</h3>
<p className="text-muted-foreground">
We'll get back to you soon.
</p>
</motion.div>
) : (
<motion.div
key="form"
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
exit={{ opacity: 0 }}
>
<h2 className="text-2xl font-bold mb-2">Let's Talk</h2>
<p className="text-muted-foreground mb-6">
Ready to start your project? Tell us about it.
</p>
<form onSubmit={handleSubmit} className="space-y-4">
<motion.div
initial={{ opacity: 0, y: 10 }}
animate={{ opacity: 1, y: 0 }}
transition={{ delay: 0.1 }}
>
<Input
name="name"
placeholder="Your Name"
value={formData.name}
onChange={handleChange}
required
className=" border focus:border-primary focus:neon-glow transition-all"
/>
</motion.div>
<motion.div
initial={{ opacity: 0, y: 10 }}
animate={{ opacity: 1, y: 0 }}
transition={{ delay: 0.2 }}
>
<Input
name="email"
type="email"
placeholder="Your Email"
value={formData.email}
onChange={handleChange}
required
className=" border focus:border-primary focus:neon-glow transition-all"
/>
</motion.div>
<motion.div
initial={{ opacity: 0, y: 10 }}
animate={{ opacity: 1, y: 0 }}
transition={{ delay: 0.3 }}
>
<Textarea
name="message"
placeholder="Tell us about your project..."
value={formData.message}
onChange={handleChange}
required
rows={4}
className=" border focus:border-primary focus:neon-glow transition-all resize-none"
/>
</motion.div>
<motion.div
initial={{ opacity: 0, y: 10 }}
animate={{ opacity: 1, y: 0 }}
transition={{ delay: 0.4 }}
>
<Button
type="submit"
disabled={isSubmitting}
className="w-full bg-primary text-primary-foreground font-semibold py-3 rounded-full neon-glow hover:neon-glow-strong transition-all group"
>
{isSubmitting ? (
<motion.div
animate={{ rotate: 360 }}
transition={{
duration: 1,
repeat: Infinity,
ease: "linear",
}}
className="w-5 h-5 border-2 border-primary-foreground/30 border-t-primary-foreground rounded-full"
/>
) : (
<>
Send Message
<Send className="w-4 h-4 ml-2 group-hover:translate-x-1 transition-transform" />
</>
)}
</Button>
</motion.div>
</form>
</motion.div>
)}
</AnimatePresence>
</div>
</motion.div>
</motion.div>
)}
</AnimatePresence>
);
}