Newer
Older
My-Portfolio / frontend / src / components / sections / Contact.jsx
import { useState, useEffect, useContext } from "react";
import { motion } from "framer-motion";
import { postData } from "../../api";
import Heading from "../Heading";
import styles from "./Contact.module.css";
import { LoadingContext } from "../utils/LoadingContext";

const Contact = ({ isVisible, contactData }) => {
  const [formData, setFormData] = useState({
    name: "",
    email: "",
    message: "",
  });

  const [error, setError] = useState("");
  const [success, setSuccess] = useState("");
  const { isLoading } = useContext(LoadingContext); // Use the global loading state

  if (isLoading) return <div>Loading...</div>;

  // Automatically clear success/error message after 5 seconds
  useEffect(() => {
    if (success || error) {
      const timer = setTimeout(() => {
        setSuccess("");
        setError("");
      }, 5000);

      return () => clearTimeout(timer); // Cleanup on unmount
    }
  }, [success, error]);

  const handleChange = (e) => {
    setFormData({ ...formData, [e.target.name]: e.target.value });
    setError("");
  };

  const handleSubmit = async (e) => {
    e.preventDefault();

    if (!formData.name || !formData.email || !formData.message) {
      setError("All fields are required.");
      return;
    }

    if (!/\S+@\S+\.\S+/.test(formData.email)) {
      setError("Please enter a valid email.");
      return;
    }

    try {
      const response = await postData("send", formData);
      setSuccess(response.success);
      setFormData({ name: "", email: "", message: "" });
    } catch (error) {
      setError(error.message || "Failed to send message.");
    }
  };

  return (
    <motion.div
      id="contact"
      className="pt-2 sm:pt-10 px-8"
      initial={{ opacity: 0, y: 100 }} // Start off-screen
      animate={isVisible ? { opacity: 1, y: 0 } : { opacity: 0, y: 100 }} // Slide-in when visible
      transition={{ duration: 0.2, ease: "easeOut" }}
    >
      <div className="relative mx-auto rounded-lg z-10 w-full min-h-screen max-w-[1300px]">
        <Heading title="Contact Me Anytime!" />

        {/* Social Media Buttons */}
        <div className="flex justify-center gap-6 lg:gap-12 flex-wrap mb-8">
          {contactData.map((contact) => (
            <a
              key={contact.id}
              href={
                contact.name === "gmail"
                  ? `mailto:${contact.username}`
                  : contact.url
              }
              target={contact.name === "gmail" ? "_self" : "_blank"}
              rel="noopener noreferrer"
              className={`${styles["social-button"]} flex items-center justify-center gap-2.5`}
            >
              <img
                src={contact.logo}
                alt={contact.name}
                className="w-8 h-8 rounded-full"
              />
              <span className="text-lg lg:text-xl font-bold">
                {contact.username}
              </span>
            </a>
          ))}
        </div>

        <form onSubmit={handleSubmit} className="flex flex-col space-y-4">
          <input
            type="text"
            name="name"
            placeholder="Your Name"
            value={formData.name}
            onChange={handleChange}
            className={`${styles["input-field"]} p-2 rounded-md`}
            required
          />
          <input
            type="email"
            name="email"
            placeholder="Your Email"
            value={formData.email}
            onChange={handleChange}
            className={`${styles["input-field"]} p-2 rounded-md`}
            required
          />
          <textarea
            name="message"
            placeholder="Your Message"
            value={formData.message}
            onChange={handleChange}
            className={`${styles["input-field"]} p-2 rounded-md`}
            rows="4"
            required
          ></textarea>

          {/* Success/Error Message Below Message Field */}
          <div className="h-4 flex items-center">
            {error && <p className="text-red-500 text-sm">{error}</p>}
            {success && <p className="text-green-500 text-sm">{success}</p>}
          </div>

          <div className="flex justify-center">
            <button
              type="submit"
              className={`${styles["submit-button"]} px-4 py-2 rounded-lg`}
            >
              Send Message
            </button>
          </div>
        </form>

        {/* Disclaimer */}
        <p className="text-md text-gray-400 text-center mt-4">
          Disclaimer: Please avoid sharing sensitive or confidential information
          in your message.
        </p>
      </div>

      {/* Rights */}
      <p className="text-md text-gray-400 text-center">
        @2025 Nuno Teixeira <br />
        All rights reserved
      </p>
    </motion.div>
  );
};

export default Contact;