204 lines
7.1 KiB
TypeScript
204 lines
7.1 KiB
TypeScript
import React, { useCallback, useRef, useState } from "react";
|
|
import Link from "next/link";
|
|
|
|
export default function BottomFooter() {
|
|
// Instagram Lava Flood Easter Egg
|
|
const [lavaActive, setLavaActive] = useState(false);
|
|
const lavaTimeout = useRef<any>(null);
|
|
|
|
// Instagram sound
|
|
const earthquakeAudio = useRef<HTMLAudioElement | null>(null);
|
|
|
|
// LinkedIn Shake Easter Egg
|
|
const [shaking, setShaking] = useState(false);
|
|
const shakeTimeout = useRef<any>(null);
|
|
|
|
// X Logo Full-Page Crack & Spin Easter Egg
|
|
const [showCracks, setShowCracks] = useState(false);
|
|
const [crackOverlayActive, setCrackOverlayActive] = useState(false);
|
|
|
|
// Lava flood & sound handler
|
|
const handleInstagramClick = useCallback((e: React.MouseEvent) => {
|
|
e.preventDefault();
|
|
setLavaActive(true);
|
|
// Play earthquake sound
|
|
if (earthquakeAudio.current) {
|
|
earthquakeAudio.current.currentTime = 0;
|
|
earthquakeAudio.current.play();
|
|
}
|
|
clearTimeout(lavaTimeout.current);
|
|
lavaTimeout.current = setTimeout(() => setLavaActive(false), 2000);
|
|
}, []);
|
|
|
|
// LinkedIn shake handler
|
|
const handleLinkedInClick = useCallback(
|
|
(e: React.MouseEvent) => {
|
|
e.preventDefault();
|
|
if (shaking) return; // prevent stacking
|
|
setShaking(true);
|
|
const body = document.body;
|
|
body.classList.remove("shake-screen");
|
|
void body.offsetWidth;
|
|
body.classList.add("shake-screen");
|
|
shakeTimeout.current = setTimeout(() => {
|
|
setShaking(false);
|
|
body.classList.remove("shake-screen");
|
|
}, 1000);
|
|
},
|
|
[shaking]
|
|
);
|
|
|
|
// X click = crack, spin page, then reset after 2s
|
|
const handleXClick = useCallback(
|
|
(e: React.MouseEvent) => {
|
|
e.preventDefault();
|
|
if (crackOverlayActive) return;
|
|
setShowCracks(true);
|
|
setCrackOverlayActive(true);
|
|
document.body.classList.remove("body-spin-back");
|
|
document.body.classList.add("body-cracked");
|
|
setTimeout(() => {
|
|
document.body.classList.remove("body-cracked");
|
|
document.body.classList.add("body-spin-back");
|
|
setTimeout(() => {
|
|
setShowCracks(false);
|
|
setCrackOverlayActive(false);
|
|
document.body.classList.remove("body-spin-back");
|
|
}, 200);
|
|
}, 2000);
|
|
},
|
|
[crackOverlayActive]
|
|
);
|
|
|
|
// Clean up classes and timeouts on unmount
|
|
React.useEffect(() => {
|
|
return () => {
|
|
clearTimeout(lavaTimeout.current);
|
|
clearTimeout(shakeTimeout.current);
|
|
document.body.classList.remove("shake-screen");
|
|
document.body.classList.remove("body-cracked");
|
|
document.body.classList.remove("body-spin-back");
|
|
};
|
|
}, []);
|
|
|
|
return (
|
|
<>
|
|
{/* Hidden audio element */}
|
|
<audio ref={earthquakeAudio} src="/earthquake.mp3" preload="auto" />
|
|
{/* Lava Flood Overlay */}
|
|
{lavaActive && (
|
|
<div className="lava-flood-overlay lava-active">
|
|
<img src="/lava.jpg" alt="Lava flood" draggable={false} />
|
|
</div>
|
|
)}
|
|
{/* Crack overlay for the spinning effect */}
|
|
{showCracks && (
|
|
<div className="crack-overlay" style={{ pointerEvents: "none" }}>
|
|
<img className="crack crack1" src="/crack1.png" alt="" />
|
|
<img className="crack crack2" src="/crack2.png" alt="" />
|
|
</div>
|
|
)}
|
|
|
|
{/* Footer */}
|
|
<footer className="bg-[#16424b] text-white pt-12 pb-4 px-6 mt-12 z-0">
|
|
<div className="max-w-6xl mx-auto flex flex-col md:flex-row justify-between gap-8">
|
|
{/* Useful Links */}
|
|
<div className="min-w-[200px] mb-8 md:mb-0 flex-1">
|
|
<h3 className="font-bold underline text-lg mb-3">Useful links</h3>
|
|
<ul className="space-y-2">
|
|
<li>
|
|
<Link
|
|
href="https://www.gov.uk/guidance/extreme-weather-and-natural-hazards"
|
|
className="hover:underline"
|
|
target="_blank"
|
|
rel="noopener noreferrer"
|
|
>
|
|
Gov.UK guidance
|
|
</Link>
|
|
</li>
|
|
<li>
|
|
<Link
|
|
href="https://www.dysoninstitute.ac.uk/about-us/governance/privacy-notices/"
|
|
className="hover:underline"
|
|
>
|
|
Privacy policy
|
|
</Link>
|
|
</li>
|
|
<li>
|
|
<Link
|
|
href="https://privacy.dyson.com/en/globalcookiepolicy.aspx"
|
|
className="hover:underline"
|
|
>
|
|
Cookies policy
|
|
</Link>
|
|
</li>
|
|
</ul>
|
|
</div>
|
|
{/* Donate Section */}
|
|
<div className="min-w-[220px] mb-8 md:mb-0 flex-1">
|
|
<h3 className="font-bold underline text-lg mb-3">Donate</h3>
|
|
<p className="mb-4">
|
|
We are a nonprofit entirely funded by your donations, every penny helps provide life saving information.
|
|
</p>
|
|
<Link
|
|
href="https://shelterbox.org/"
|
|
className="bg-gray-200 hover:bg-blue-600 hover:text-white text-black font-bold rounded-full px-8 py-2 shadow transition-colors duration-200 inline-block text-center"
|
|
>
|
|
Donate Now
|
|
</Link>
|
|
</div>
|
|
</div>
|
|
{/* Bottom bar */}
|
|
<div className="max-w-6xl mx-auto mt-8 pt-6 flex flex-col md:flex-row items-center justify-between border-t border-gray-200/30">
|
|
<div className="flex flex-row items-center w-full md:w-auto">
|
|
<img
|
|
src="/logo.png"
|
|
alt="TremorTracker logo"
|
|
className="h-16 w-auto mr-4 object-contain"
|
|
style={{ maxHeight: 75 }}
|
|
/>
|
|
</div>
|
|
<span className="text-sm flex items-center">
|
|
<span className="mr-2">©</span> TremorTracker 2025
|
|
</span>
|
|
<div className="flex flex-col items-end">
|
|
<span className="text-sm mb-2">Follow us on</span>
|
|
<div className="flex space-x-3">
|
|
<a
|
|
href="#"
|
|
onClick={handleInstagramClick}
|
|
style={{ cursor: "pointer" }}
|
|
aria-label="Instagram Lava Easter egg"
|
|
>
|
|
<img src="instagram.png" alt="instagram" className="h-7 w-7 rounded-full shadow" />
|
|
</a>
|
|
<a
|
|
href="#"
|
|
onClick={handleLinkedInClick}
|
|
style={{ cursor: "pointer" }}
|
|
aria-label="LinkedIn Shake Easter egg"
|
|
>
|
|
<img src="linkedin.png" alt="linkedin" className="h-7 w-7 rounded-full shadow" />
|
|
</a>
|
|
<a
|
|
href="#"
|
|
onClick={handleXClick}
|
|
style={{ cursor: "pointer" }}
|
|
aria-label="X Crack Easter egg"
|
|
>
|
|
<span className="footer-x-logo-wrap">
|
|
<img
|
|
src="x_logo.jpg"
|
|
alt="X"
|
|
className="h-7 w-7 rounded-full shadow"
|
|
style={{ display: "block"}}
|
|
/>
|
|
</span>
|
|
</a>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</footer>
|
|
</>
|
|
);
|
|
} |