116 lines
4.1 KiB
TypeScript
116 lines
4.1 KiB
TypeScript
"use client";
|
|
import { useMemo, useState } from "react";
|
|
import useSWR from "swr";
|
|
import Map from "@components/Map";
|
|
import Sidebar from "@components/Sidebar";
|
|
import { createPoster } from "@utils/axiosHelpers";
|
|
import { Earthquake } from "@prismaclient";
|
|
import { getRelativeDate } from "@utils/formatters";
|
|
import GeologicalEvent from "@appTypes/GeologicalEvent";
|
|
import EarthquakeSearchModal from "@components/EarthquakeSearchModal";
|
|
import EarthquakeLogModal from "@components/EarthquakeLogModal"; // If you use a separate log modal
|
|
import { useStoreState } from "@hooks/store";
|
|
|
|
export default function Earthquakes() {
|
|
const [selectedEventId, setSelectedEventId] = useState("");
|
|
const [hoveredEventId, setHoveredEventId] = useState("");
|
|
const [searchModalOpen, setSearchModalOpen] = useState(false);
|
|
const [logModalOpen, setLogModalOpen] = useState(false);
|
|
const [noAccessModalOpen, setNoAccessModalOpen] = useState(false);
|
|
|
|
const user = useStoreState((state) => state.user);
|
|
const canLogEarthquake = user?.role === "SCIENTIST" || user?.role === "ADMIN";
|
|
|
|
const { data, error, isLoading, mutate } = useSWR("/api/earthquakes", createPoster({ rangeDaysPrev: 10 }));
|
|
|
|
// Shape for Map/Sidebar
|
|
const earthquakeEvents = useMemo(
|
|
() =>
|
|
data && data.earthquakes
|
|
? data.earthquakes
|
|
.map(
|
|
(x: Earthquake): GeologicalEvent => ({
|
|
id: x.code,
|
|
title: `Earthquake in ${x.location || (x.code && x.code.split("-")[2])}`,
|
|
magnitude: x.magnitude,
|
|
longitude: x.longitude,
|
|
latitude: x.latitude,
|
|
text1: "",
|
|
text2: getRelativeDate(x.date),
|
|
date: x.date,
|
|
code: x.code,
|
|
})
|
|
)
|
|
.sort((a: GeologicalEvent, b: GeologicalEvent) => new Date(b.date).getTime() - new Date(a.date).getTime())
|
|
: [],
|
|
[data]
|
|
);
|
|
|
|
// Handler for log
|
|
const handleLogClick = () => {
|
|
if (canLogEarthquake) {
|
|
setLogModalOpen(true);
|
|
} else {
|
|
setNoAccessModalOpen(true);
|
|
}
|
|
};
|
|
|
|
function NoAccessModal({ open, onClose }: { open: typeof noAccessModalOpen; onClose: () => void }) {
|
|
if (!open) return null;
|
|
return (
|
|
<div className="fixed z-50 inset-0 bg-black/40 flex items-center justify-center">
|
|
<div className="bg-white rounded-lg shadow-lg p-8 max-w-xs w-full text-center relative">
|
|
<button onClick={onClose} className="absolute right-4 top-4 text-gray-500 hover:text-black text-lg" aria-label="Close">
|
|
×
|
|
</button>
|
|
<h2 className="font-bold text-xl mb-4">Access Denied</h2>
|
|
<p className="text-gray-600 mb-3">
|
|
Sorry, you do not have access rights to Log an Earthquake. Please Log in here, or contact an Admin if you believe this
|
|
is a mistake
|
|
</p>
|
|
<button onClick={onClose} className="bg-blue-600 text-white px-6 py-2 rounded hover:bg-blue-700 mt-2">
|
|
OK
|
|
</button>
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
return (
|
|
<div className="flex h-[calc(100vh-3.5rem)] w-full overflow-hidden">
|
|
<div className="flex-grow h-full">
|
|
<Map
|
|
events={earthquakeEvents}
|
|
selectedEventId={selectedEventId}
|
|
setSelectedEventId={setSelectedEventId}
|
|
hoveredEventId={hoveredEventId}
|
|
setHoveredEventId={setHoveredEventId}
|
|
mapType="Earthquakes"
|
|
/>
|
|
</div>
|
|
<Sidebar
|
|
logTitle="Log an Earthquake"
|
|
logSubtitle="Record new earthquakes - time/date, location, magnitude, observatory and scientists"
|
|
recentsTitle="Recent Earthquakes"
|
|
events={earthquakeEvents}
|
|
selectedEventId={selectedEventId}
|
|
setSelectedEventId={setSelectedEventId}
|
|
hoveredEventId={hoveredEventId}
|
|
setHoveredEventId={setHoveredEventId}
|
|
button1Name="Log an Earthquake"
|
|
button2Name="Search Earthquakes"
|
|
onButton1Click={handleLogClick}
|
|
onButton2Click={() => setSearchModalOpen(true)}
|
|
button1Disabled={!canLogEarthquake}
|
|
/>
|
|
<EarthquakeSearchModal
|
|
open={searchModalOpen}
|
|
onClose={() => setSearchModalOpen(false)}
|
|
onSelect={(eq) => setSelectedEventId(eq.code)}
|
|
/>
|
|
<EarthquakeLogModal open={logModalOpen} onClose={() => setLogModalOpen(false)} onSuccess={() => mutate()} />
|
|
<NoAccessModal open={noAccessModalOpen} onClose={() => setNoAccessModalOpen(false)} />
|
|
</div>
|
|
);
|
|
}
|