297 lines
11 KiB
TypeScript
Raw Normal View History

2025-04-07 13:47:59 +01:00
"use client";
2025-05-13 10:00:09 +01:00
import Image from "next/image";
2025-05-31 21:29:50 +01:00
import React, { useCallback, useEffect, useRef, useState } from "react";
2025-05-25 19:59:53 +01:00
import BottomFooter from "@components/BottomFooter";
2025-04-07 13:47:59 +01:00
2025-04-28 12:35:18 +01:00
const ContactUs = () => {
2025-05-31 21:29:50 +01:00
// Form/modal
const [formData, setFormData] = useState({ name: "", email: "", message: "" });
const [isModalOpen, setIsModalOpen] = useState(false);
// 1. Lava (Instagram): state & timer
const [lavaActive, setLavaActive] = useState(false);
const lavaTimeout = useRef<NodeJS.Timeout | null>(null);
// 2. Pulsating Map (Facebook): state & timer
const [pulsatingActive, setPulsatingActive] = useState(false);
const pulsatingTimeout = useRef<NodeJS.Timeout | null>(null);
// 3. Shake (LinkedIn): state & timer
const [shaking, setShaking] = useState(false);
const shakeTimeout = useRef<NodeJS.Timeout | null>(null);
2025-04-28 19:03:29 +01:00
2025-05-31 21:29:50 +01:00
// 4. Crack & Collapse (X): state & timer
const [showCracks, setShowCracks] = useState(false);
const [collapse, setCollapse] = useState(false);
const crackTimeout = useRef<NodeJS.Timeout | null>(null);
// Lava flood handler (top-down flood)
const handleInstagramClick = useCallback((e: React.MouseEvent) => {
e.preventDefault();
setLavaActive(true);
if (lavaTimeout.current) clearTimeout(lavaTimeout.current);
lavaTimeout.current = setTimeout(() => setLavaActive(false), 2000);
}, []);
// Pulsating Map handler
const handleFacebookClick = useCallback((e: React.MouseEvent) => {
e.preventDefault();
setPulsatingActive(true);
if (pulsatingTimeout.current) clearTimeout(pulsatingTimeout.current);
pulsatingTimeout.current = setTimeout(() => setPulsatingActive(false), 2000);
}, []);
// LinkedIn shake handler
const handleLinkedInClick = useCallback(
(e: React.MouseEvent) => {
e.preventDefault();
if (shaking) return;
setShaking(true);
const body = document.body;
body.classList.remove("shake-screen");
void body.offsetWidth;
body.classList.add("shake-screen");
if (shakeTimeout.current) clearTimeout(shakeTimeout.current);
shakeTimeout.current = setTimeout(() => {
setShaking(false);
body.classList.remove("shake-screen");
}, 1000);
},
[shaking]
);
// X (crack and collapse) handler
const handleXClick = useCallback((e: React.MouseEvent) => {
e.preventDefault();
setShowCracks(true);
if (crackTimeout.current) clearTimeout(crackTimeout.current);
crackTimeout.current = setTimeout(() => {
setCollapse(true);
setTimeout(() => {
setShowCracks(false);
setCollapse(false);
}, 1500);
}, 1000);
}, []);
// Clean up timeouts and shake class
useEffect(() => {
return () => {
if (lavaTimeout.current) clearTimeout(lavaTimeout.current);
if (pulsatingTimeout.current) clearTimeout(pulsatingTimeout.current);
if (shakeTimeout.current) clearTimeout(shakeTimeout.current);
if (crackTimeout.current) clearTimeout(crackTimeout.current);
document.body.classList.remove("shake-screen");
};
}, []);
// Form handlers
const handleChange = (e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>) => {
2025-04-28 19:03:29 +01:00
setFormData({ ...formData, [e.target.name]: e.target.value });
};
2025-05-31 21:29:50 +01:00
const handleSubmit = (e: React.FormEvent) => {
2025-04-28 19:03:29 +01:00
e.preventDefault();
console.log("Form submitted with data:", formData);
2025-05-31 21:29:50 +01:00
setIsModalOpen(true);
2025-04-28 19:03:29 +01:00
setFormData({ name: "", email: "", message: "" });
};
2025-04-28 12:35:18 +01:00
2025-04-28 19:03:29 +01:00
return (
2025-04-29 16:52:03 +01:00
<div className="h-full relative text-white border border-black overflow-hidden">
2025-05-31 21:29:50 +01:00
{/* Lava Flood Overlay */}
{lavaActive && (
<div className="lava-flood-overlay lava-active fixed inset-0 z-[60] flex items-center justify-center">
<img
src="/lava.jpg"
alt="Lava flood"
draggable={false}
className="w-full h-full object-cover opacity-80 pointer-events-none"
/>
</div>
)}
{/* Pulsating Overlay */}
{pulsatingActive && (
<div className="pulsating-map-overlay pulsating-active fixed inset-0 z-[60] flex items-center justify-center">
<img
src="/pulsatingMap.jpg"
alt="Pulsating Map"
draggable={false}
className="w-full h-full object-cover opacity-80 pointer-events-none"
/>
</div>
)}
{/* Crack & Collapse Overlay */}
{(showCracks || collapse) && (
<div
className={`crack-overlay fixed inset-0 z-[60] flex items-center justify-center${collapse ? " crack-collapse" : ""}`}
>
<img className="crack crack1 absolute w-3/4" src="/crack1.png" alt="" />
<img className="crack crack2 absolute w-3/4" src="/crack2.png" alt="" />
</div>
)}
{/* Modal: Submit Success */}
{isModalOpen && (
<div className="fixed inset-0 z-[70] flex items-center justify-center bg-black/60">
<div className="bg-white rounded-lg shadow-lg p-8 max-w-sm w-full text-center">
<h2 className="text-2xl font-bold mb-4 text-neutral-800">Thank You!</h2>
<p className="text-neutral-700 mb-6">Thank you for submitting a message. We will be responding via our email.</p>
<button
className="bg-blue-600 text-white px-5 py-2 rounded-lg font-medium hover:bg-blue-700 transition"
onClick={() => setIsModalOpen(false)}
>
Close
</button>
</div>
</div>
)}
2025-04-29 16:52:03 +01:00
<Image
height={5000}
width={5000}
alt="Logo"
className="border border-neutral-300 absolute z-10 -top-20"
src="/tsunamiWaves.jpg"
/>
2025-04-28 19:03:29 +01:00
{/* Overlay for readability */}
2025-05-09 10:30:12 +01:00
<div className="absolute overflow-hidden w-full h-full bg-gradient-to-b from-black/80 via-black/40 to-black/20 flex flex-col items-center z-20">
2025-04-28 19:03:29 +01:00
{/* Container */}
2025-04-29 16:52:03 +01:00
<div className="max-w-4xl mx-auto p-5 mt-20">
2025-04-28 19:03:29 +01:00
{/* Header */}
2025-05-09 10:30:12 +01:00
<h1 className="text-4xl font-bold text-center text-neutral-50 mb-6">Contact Us</h1>
<p className="text-lg text-center max-w-2xl text-neutral-200 mb-6">
2025-05-13 10:00:09 +01:00
Have questions or concerns about earthquakes, observatories or artefacts? Contact us via phone, email, social media or
using the form below with the relevant contact details.
2025-04-28 19:03:29 +01:00
</p>
<div className="flex flex-col md:flex-row gap-6">
{/* Contact Form Section */}
<div className="flex-1 bg-white bg-opacity-90 text-neutral-800 rounded-lg shadow-lg p-6">
<form onSubmit={handleSubmit}>
<div className="mb-4">
<label htmlFor="name" className="block text-neutral-700 font-medium mb-2">
Name
</label>
<input
type="text"
name="name"
id="name"
value={formData.name}
onChange={handleChange}
placeholder="Your Name"
className="w-full p-3 border border-neutral-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500"
required
/>
</div>
<div className="mb-4">
<label htmlFor="email" className="block text-neutral-700 font-medium mb-2">
Email
</label>
<input
type="email"
name="email"
id="email"
value={formData.email}
onChange={handleChange}
placeholder="Your Email"
className="w-full p-3 border border-neutral-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500"
required
/>
</div>
<div className="mb-4">
<label htmlFor="message" className="block text-neutral-700 font-medium mb-2">
Message
</label>
<textarea
name="message"
id="message"
value={formData.message}
onChange={handleChange}
2025-04-29 16:52:03 +01:00
rows={5}
2025-04-28 19:03:29 +01:00
placeholder="Your Message"
className="w-full p-3 border border-neutral-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500"
required
2025-04-29 16:52:03 +01:00
style={{ resize: "none" }}
2025-04-28 19:03:29 +01:00
/>
</div>
<button
type="submit"
className="w-full bg-blue-600 text-white py-3 rounded-lg font-medium hover:bg-blue-700 transition duration-200"
>
Send Message
</button>
</form>
</div>
{/* Contact Details Section */}
2025-04-29 16:52:03 +01:00
<div className="w-[45%] bg-white bg-opacity-90 text-neutral-800 rounded-lg shadow-lg p-6">
<h2 className="text-2xl font-bold text-neutral-800 mb-4">Get in Touch</h2>
2025-04-28 19:03:29 +01:00
<div className="mb-4">
<h3 className="text-neutral-700 font-bold font-large">Email</h3>
<a href="Mail to:getintouch@tremortracker.com font-medium" style={{ color: "initial" }}>
2025-04-29 16:52:03 +01:00
getintouch@tremortracker.com
</a>
2025-04-28 19:03:29 +01:00
</div>
<div className="mb-4">
<h3 className="text-neutral-700 font-bold font-large">Phone</h3>
<p className="text-neutral-600 font-medium">+44 7538 359022</p>
2025-04-28 19:03:29 +01:00
</div>
<div className="mb-4">
<h3 className="text-neutral-700 font-bold font-large">Address</h3>
2025-05-31 21:29:50 +01:00
<p className="text-neutral-600 font-medium">1 Sweentown Row, Greenwich, London, SE3 0FQ</p>
2025-04-28 19:03:29 +01:00
</div>
<h2 className="text-xl font-bold text-neutral-800 mb-4 mt-6">Follow Us</h2>
<div className="flex justify-around items-center">
2025-05-31 21:29:50 +01:00
{/* Instagram: Lava Flood */}
<a
href="#"
className="w-20 h-20 text-blue-600 hover:text-blue-800 transition duration-200"
aria-label="Instagram"
onClick={handleInstagramClick}
style={{ cursor: "pointer" }}
>
2025-04-28 19:03:29 +01:00
<span className="sr-only">Instagram</span>
<Image height={200} width={200} alt="Logo" className="z-10" src="/insta.webp" />
</a>
2025-05-31 21:29:50 +01:00
{/* Facebook: Pulsating Map */}
<a
href="#"
className="w-20 h-20 text-blue-600 hover:text-blue-800 transition duration-200"
aria-label="Facebook"
onClick={handleFacebookClick}
style={{ cursor: "pointer" }}
>
2025-04-28 19:03:29 +01:00
<span className="sr-only">Facebook</span>
<Image height={200} width={200} alt="Logo" className="z-10" src="/facebook.webp" />
</a>
2025-05-31 21:29:50 +01:00
{/* X: Crack & Collapse */}
<a
href="#"
className="w-20 h-20 p-4 text-blue-600 hover:text-blue-800 transition duration-200"
aria-label="X"
onClick={handleXClick}
style={{ cursor: "pointer" }}
>
2025-04-28 19:03:29 +01:00
<span className="sr-only">X</span>
<Image height={200} width={200} alt="Logo" className="z-10 rounded-lg" src="/x_logo.jpg" />
</a>
2025-05-31 21:29:50 +01:00
{/* LinkedIn: Shake */}
<a
href="#"
className="w-20 h-20 flex items-center text-blue-600 hover:text-blue-800 transition duration-200"
aria-label="LinkedIn"
onClick={handleLinkedInClick}
style={{ cursor: "pointer" }}
>
2025-04-28 19:03:29 +01:00
<span className="sr-only">LinkedIn</span>
<Image height={200} width={200} alt="Logo" className="z-10" src="/linkedIn.png" />
</a>
</div>
</div>
</div>
</div>
</div>
2025-05-31 21:29:50 +01:00
<BottomFooter />
2025-04-28 19:03:29 +01:00
</div>
);
2025-04-28 12:35:18 +01:00
};
2025-04-28 19:03:29 +01:00
export default ContactUs;