373 lines
17 KiB
JavaScript
373 lines
17 KiB
JavaScript
import { useTranslation } from "react-i18next";
|
|
import {
|
|
FaMapMarkerAlt,
|
|
FaPhoneAlt,
|
|
FaEnvelope,
|
|
FaWhatsapp,
|
|
FaPaperPlane,
|
|
} from "react-icons/fa";
|
|
import emailjs from "@emailjs/browser";
|
|
import { useRef, useState } from "react";
|
|
import { motion } from "framer-motion";
|
|
|
|
const Contact = () => {
|
|
const { t } = useTranslation();
|
|
const form = useRef();
|
|
const [message, setMessage] = useState({ text: "", type: "" });
|
|
const [isLoading, setIsLoading] = useState(false);
|
|
|
|
const sendEmail = (e) => {
|
|
e.preventDefault();
|
|
setIsLoading(true);
|
|
setMessage({ text: "", type: "" });
|
|
emailjs
|
|
.sendForm(
|
|
"service_cqcqipd",
|
|
"template_o7xejbn",
|
|
form.current,
|
|
"_JAFEi75xtLgmGaNi"
|
|
)
|
|
.then(
|
|
(result) => {
|
|
console.log("Message sent:", result.text);
|
|
setMessage({
|
|
text: t("contact.successMessage") || "Message sent successfully!",
|
|
type: "success",
|
|
});
|
|
form.current.reset();
|
|
setIsLoading(false);
|
|
setTimeout(() => setMessage({ text: "", type: "" }), 5000);
|
|
},
|
|
(error) => {
|
|
console.error("Failed to send message:", error.text);
|
|
setMessage({
|
|
text:
|
|
t("contact.errorMessage") ||
|
|
"Failed to send message. Please try again.",
|
|
type: "error",
|
|
});
|
|
setIsLoading(false);
|
|
setTimeout(() => setMessage({ text: "", type: "" }), 5000);
|
|
}
|
|
);
|
|
};
|
|
|
|
return (
|
|
<section
|
|
id="contact"
|
|
className="relative min-h-screen py-16 px-4 sm:px-6 font-sans"
|
|
style={{
|
|
direction: "rtl",
|
|
}}
|
|
>
|
|
<div className="absolute inset-0 overflow-hidden">
|
|
<div className="absolute -top-10 -right-40 w-80 h-80 bg-[#446a85] rounded-full mix-blend-multiply filter blur-3xl opacity-20 animate-pulse"></div>
|
|
<div className="absolute -bottom-10 -left-40 w-80 h-80 bg-[#446a85] rounded-full mix-blend-multiply filter blur-3xl opacity-20 animate-pulse delay-1000"></div>
|
|
<div className="absolute top-1/2 left-1/3 w-60 h-60 bg-[#57acd9] rounded-full mix-blend-multiply filter blur-3xl opacity-20 animate-pulse delay-500"></div>
|
|
|
|
<div className="absolute bottom-0 left-0 w-full h-32 bg-gradient-to-t from-[#57acd9]/30 to-transparent"></div>
|
|
</div>
|
|
|
|
<div className="relative z-10 w-full max-w-6xl mx-auto">
|
|
<motion.div
|
|
initial={{ y: -50, opacity: 0 }}
|
|
animate={{ y: 0, opacity: 1 }}
|
|
transition={{ duration: 0.8 }}
|
|
className="text-center mb-12"
|
|
>
|
|
<h1 className="pt-0 mb-0 text-2xl font-extrabold md:text-5xl lg:text-6xl">
|
|
<motion.span
|
|
className="bg-clip-text text-transparent bg-gradient-to-r from-[#57acd9] via-blue-200 to-[#446a85]"
|
|
animate={{
|
|
backgroundPosition: ["0% 50%", "100% 50%", "0% 50%"]
|
|
}}
|
|
transition={{
|
|
duration: 5,
|
|
repeat: Infinity,
|
|
ease: "linear"
|
|
}}
|
|
style={{
|
|
backgroundSize: "200% 100%"
|
|
}}
|
|
>
|
|
{t("contact.title")}
|
|
</motion.span>
|
|
</h1>
|
|
</motion.div>
|
|
<div className="flex flex-col lg:flex-row-reverse gap-8 items-start">
|
|
<motion.div
|
|
initial={{ x: 50, opacity: 0 }}
|
|
animate={{ x: 0, opacity: 1 }}
|
|
transition={{ duration: 0.8, delay: 0.2 }}
|
|
className="space-y-4 lg:w-1/2"
|
|
>
|
|
<motion.div
|
|
whileHover={{ y: -5, scale: 1.02 }}
|
|
transition={{ duration: 0.3 }}
|
|
className="group relative bg-white/95 backdrop-blur-sm p-8 rounded-2xl shadow-lg border border-gray-100 hover:border-[#063e5b]/50 hover:shadow-2xl transition-all duration-300"
|
|
>
|
|
<div className="flex items-start gap-4">
|
|
<motion.div
|
|
whileHover={{ rotate: [0, -10, 10, 0] }}
|
|
transition={{ duration: 0.5 }}
|
|
className="p-3 rounded-xl bg-gradient-to-br from-[#57acd9] to-[#063e5b] text-white shadow-lg"
|
|
>
|
|
<FaMapMarkerAlt className="text-2xl" />
|
|
</motion.div>
|
|
|
|
<div className="flex-1">
|
|
<h3 className="text-[#516475] lg font-bold text- mb-2">
|
|
{t("contact.address")}
|
|
</h3>
|
|
<p className="text-[#063e5b] text-sm leading-relaxed whitespace-pre-line">
|
|
{t("contact.addressText")}
|
|
</p>
|
|
</div>
|
|
</div>
|
|
|
|
<motion.div
|
|
className="absolute inset-0 rounded-2xl bg-gradient-to-br from-[#3c5ee3]/0 via-[#063e5b]/5 to-transparent opacity-0 group-hover:opacity-100 transition-opacity duration-500"
|
|
initial={false}
|
|
/>
|
|
<motion.div
|
|
|
|
/>
|
|
</motion.div>
|
|
<motion.div
|
|
whileHover={{ y: -5, scale: 1.02 }}
|
|
transition={{ duration: 0.3 }}
|
|
className="group relative bg-white/95 backdrop-blur-sm p-8 rounded-2xl shadow-lg border border-gray-100 hover:border-[#3c5ee3]/50 hover:shadow-2xl transition-all duration-300"
|
|
>
|
|
<div className="flex items-start gap-4">
|
|
<motion.div
|
|
whileHover={{ rotate: [0, -10, 10, 0] }}
|
|
transition={{ duration: 0.5 }}
|
|
className="p-3 rounded-xl bg-gradient-to-br from-[#2ecc71] to-[#1abc9c] text-white shadow-lg"
|
|
>
|
|
<FaEnvelope className="text-2xl" />
|
|
</motion.div>
|
|
|
|
<div className="flex-1">
|
|
<h3 className="text-lg font-bold text-[#063e5b] mb-2">
|
|
{t("contact.email")}
|
|
</h3>
|
|
<a
|
|
href="mailto:info@rexnt.com"
|
|
className="inline-block bg-gradient-to-r from-[#e8f4ff] to-[#dceafe] text-[#23558f] font-medium rounded-xl px-4 py-3 hover:from-[#dceafe] hover:to-[#c6e2ff] hover:text-[#3c5ee3] hover:shadow-lg transition-all duration-300"
|
|
>
|
|
Info@rexnt.com
|
|
</a>
|
|
</div>
|
|
</div>
|
|
|
|
<motion.div
|
|
className="absolute inset-0 rounded-2xl bg-gradient-to-br from-[#3c5ee3]/0 via-[#3c5ee3]/5 to-transparent opacity-0 group-hover:opacity-100 transition-opacity duration-500"
|
|
initial={false}
|
|
/>
|
|
|
|
<motion.div
|
|
|
|
|
|
/>
|
|
</motion.div>
|
|
</motion.div>
|
|
|
|
<motion.div
|
|
initial={{ x: -50, opacity: 0 }}
|
|
animate={{ x: 0, opacity: 1 }}
|
|
transition={{ duration: 0.8, delay: 0.4 }}
|
|
className="group relative bg-white/95 backdrop-blur-sm p-8 rounded-2xl shadow-2xl border border-gray-100 hover:border-[#3c5ee3]/50 hover:shadow-3xl transition-all duration-500 lg:w-1/2"
|
|
>
|
|
<div className="relative mb-3 pt-3">
|
|
<h2 className="text-2xl md:text-3xl font-bold text-center" style={{ whiteSpace: 'pre-line' }}>
|
|
<span className="bg-clip-text text-[#063e5b] bg-gradient-to-r from-[#4a7c9b] via-[#063e5b] to-[#57acd9]">
|
|
{t("contact.formTitle")}
|
|
</span>
|
|
</h2>
|
|
<div className="absolute -bottom-2 left-1/2 transform -translate-x-1/2 w-24 h-1 bg-gradient-to-r from-[#4a7c9b] via-[#063e5b] to-[#57acd9] rounded-full"></div>
|
|
</div>
|
|
<form
|
|
ref={form}
|
|
onSubmit={sendEmail}
|
|
className="space-y-2"
|
|
>
|
|
<div className="group/field">
|
|
<label className="block mb-1 font-semibold text-gray-700 text-base transition-colors duration-300 group-hover/field:text-[#23558f]">
|
|
{t("contact.name")}
|
|
</label>
|
|
<div className="relative">
|
|
<input
|
|
type="text"
|
|
name="user_name"
|
|
required
|
|
className="w-full border-2 border-gray-200 p-4 rounded-xl bg-white text-gray-800 text-base placeholder-gray-400 focus:outline-none focus:ring-4 focus:ring-[#3c5ee3]/30 focus:border-[#3c5ee3] transition-all duration-300 hover:border-[#3c5ee3]/50 hover:shadow-lg hover:shadow-[#3c5ee3]/10"
|
|
placeholder={t("contact.namePlaceholder")}
|
|
/>
|
|
<div className="absolute inset-0 rounded-xl bg-gradient-to-r from-[#3c5ee3]/5 to-[#2ecc71]/5 opacity-0 hover:opacity-100 transition-opacity duration-300 pointer-events-none"></div>
|
|
</div>
|
|
</div>
|
|
<div className="group/field">
|
|
<label className="block mb-1 font-semibold text-gray-700 text-base transition-colors duration-300 group-hover/field:text-[#23558f]">
|
|
{t("contact.email")}
|
|
</label>
|
|
<div className="relative">
|
|
<input
|
|
type="email"
|
|
name="user_email"
|
|
required
|
|
className="w-full border-2 border-gray-200 p-4 rounded-xl bg-white text-gray-800 text-base placeholder-gray-400 focus:outline-none focus:ring-4 focus:ring-[#3c5ee3]/30 focus:border-[#3c5ee3] transition-all duration-300 hover:border-[#3c5ee3]/50 hover:shadow-lg hover:shadow-[#3c5ee3]/10"
|
|
placeholder={t("contact.emailPlaceholder")}
|
|
/>
|
|
<div className="absolute inset-0 rounded-xl bg-gradient-to-r from-[#3c5ee3]/5 to-[#2ecc71]/5 opacity-0 hover:opacity-100 transition-opacity duration-300 pointer-events-none"></div>
|
|
</div>
|
|
</div>
|
|
<div className="group/field">
|
|
<label className="block mb-2 font-semibold text-gray-700 text-base transition-colors duration-300 group-hover/field:text-[#23558f]">
|
|
{t("contact.message")}
|
|
</label>
|
|
<div className="relative">
|
|
<textarea
|
|
name="user_message"
|
|
required
|
|
className="w-full border-2 border-gray-200 p-4 rounded-xl resize-none bg-white text-gray-800 text-base placeholder-gray-400 focus:outline-none focus:ring-4 focus:ring-[#3c5ee3]/30 focus:border-[#3c5ee3] transition-all duration-300 hover:border-[#3c5ee3]/50 hover:shadow-lg hover:shadow-[#3c5ee3]/10 min-h-[120px]"
|
|
placeholder={t("contact.messagePlaceholder")}
|
|
></textarea>
|
|
<div className="absolute inset-0 rounded-xl bg-gradient-to-r from-[#3c5ee3]/5 to-[#2ecc71]/5 opacity-0 hover:opacity-100 transition-opacity duration-300 pointer-events-none"></div>
|
|
</div>
|
|
</div>
|
|
{message.text && (
|
|
<motion.div
|
|
initial={{ scale: 0.9, opacity: 0 }}
|
|
animate={{ scale: 1, opacity: 1 }}
|
|
className={`p-4 rounded-xl text-center font-medium transition-all duration-500 ${
|
|
message.type === "success"
|
|
? "bg-gradient-to-r from-[#2ecc71]/20 to-[#1abc9c]/20 border border-[#2ecc71]/50 text-[#2ecc71] shadow-lg shadow-[#2ecc71]/20"
|
|
: "bg-gradient-to-r from-[#e74c3c]/20 to-[#c0392b]/20 border border-[#e74c3c]/50 text-[#e74c3c] shadow-lg shadow-[#e74c3c]/20"
|
|
}`}
|
|
>
|
|
<div className="flex items-center justify-center gap-2">
|
|
{message.type === "success" ? (
|
|
<svg
|
|
className="w-5 h-5"
|
|
fill="none"
|
|
stroke="currentColor"
|
|
viewBox="0 0 24 24"
|
|
>
|
|
<path
|
|
strokeLinecap="round"
|
|
strokeLinejoin="round"
|
|
strokeWidth={2}
|
|
d="M5 13l4 4L19 7"
|
|
/>
|
|
</svg>
|
|
) : (
|
|
<svg
|
|
className="w-5 h-5"
|
|
fill="none"
|
|
stroke="currentColor"
|
|
viewBox="0 0 24 24"
|
|
>
|
|
<path
|
|
strokeLinecap="round"
|
|
strokeLinejoin="round"
|
|
strokeWidth={2}
|
|
d="M6 18L18 6M6 6l12 12"
|
|
/>
|
|
</svg>
|
|
)}
|
|
{message.text}
|
|
</div>
|
|
</motion.div>
|
|
)}
|
|
<div className="pt-2">
|
|
<motion.button
|
|
type="submit"
|
|
disabled={isLoading}
|
|
whileHover={{ scale: 1.02 }}
|
|
whileTap={{ scale: 0.98 }}
|
|
className={`group/btn relative w-full bg-gradient-to-r from-[#57acd9] via-[#063e5b] to-[#4a7c9b] text-white px-6 py-4 text-lg font-semibold rounded-xl hover:shadow-2xl hover:shadow-[#3c5ee3]/30 transition-all duration-500 overflow-hidden ${
|
|
isLoading ? "opacity-70 cursor-not-allowed" : ""
|
|
}`}
|
|
>
|
|
<span className="relative z-10 flex items-center justify-center gap-2">
|
|
{isLoading ? (
|
|
<>
|
|
<svg
|
|
className="animate-spin w-5 h-5"
|
|
fill="none"
|
|
viewBox="0 0 24 24"
|
|
>
|
|
<circle
|
|
className="opacity-25"
|
|
cx="12"
|
|
cy="12"
|
|
r="10"
|
|
stroke="currentColor"
|
|
strokeWidth="4"
|
|
></circle>
|
|
<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"
|
|
></path>
|
|
</svg>
|
|
{t("contact.send")}...
|
|
</>
|
|
) : (
|
|
<>
|
|
{t("contact.send")}
|
|
<FaPaperPlane className="w-5 h-5 transform group-hover/btn:translate-x-1 transition-transform duration-300" />
|
|
</>
|
|
)}
|
|
</span>
|
|
{!isLoading && (
|
|
<div className="absolute inset-0 bg-gradient-to-r from-white/0 via-white/20 to-white/0 transform -skew-x-12 -translate-x-full group-hover/btn:translate-x-full transition-transform duration-1000"></div>
|
|
)}
|
|
</motion.button>
|
|
</div>
|
|
</form>
|
|
<div className="absolute top-0 right-0 w-20 h-20 bg-gradient-to-br from-[#23558f]/10 to-[#3360b2]/10 rounded-full -translate-y-1/2 translate-x-1/2"></div>
|
|
<div className="absolute bottom-0 left-0 w-16 h-16 bg-gradient-to-br from-[#2ecc71]/10 to-[#1abc9c]/10 rounded-full translate-y-1/2 -translate-x-1/2"></div>
|
|
</motion.div>
|
|
</div>
|
|
<motion.div
|
|
initial={{ opacity: 0, y: 30 }}
|
|
animate={{ opacity: 1, y: 0 }}
|
|
transition={{ duration: 0.8, delay: 0.6 }}
|
|
className="mt-16 p-8 rounded-2xl shadow-2xl text-center relative overflow-hidden"
|
|
style={{
|
|
background: "linear-gradient(135deg, #4a7c9b 0%, #063e5b 33%, #57acd9 66%, #4a7c9b 100%)"
|
|
}}
|
|
>
|
|
<div className="absolute inset-0">
|
|
<div className="absolute top-0 right-0 w-32 h-32 bg-white/10 rounded-full blur-2xl"></div>
|
|
<div className="absolute bottom-0 left-0 w-32 h-32 bg-white/10 rounded-full blur-2xl"></div>
|
|
</div>
|
|
|
|
<div className="relative z-10">
|
|
<h3 className="text-xl md:text-2xl font-bold text-white mb-4">
|
|
{t('contact.contactSection.title')}
|
|
</h3>
|
|
<p className="text-white/90 text-lg mb-6 max-w-2xl mx-auto">
|
|
{t('contact.contactSection.description')}
|
|
</p>
|
|
<div className="flex flex-wrap justify-center gap-4">
|
|
{t('contact.contactSection.badges', { returnObjects: true }).map((badge, index) => (
|
|
<motion.div
|
|
key={index}
|
|
whileHover={{ scale: 1.05, y: -2 }}
|
|
whileTap={{ scale: 0.95 }}
|
|
className="px-4 py-2 bg-white/20 rounded-full text-white text-sm font-medium backdrop-blur-sm hover:bg-white/30 transition-all duration-300 cursor-pointer"
|
|
>
|
|
{badge}
|
|
</motion.div>
|
|
))}
|
|
</div>
|
|
</div>
|
|
</motion.div>
|
|
</div>
|
|
</section>
|
|
);
|
|
};
|
|
|
|
export default Contact; |