diff --git a/src/app/administrator/page.tsx b/src/app/administrator/page.tsx index fea5bc8..1e161e0 100644 --- a/src/app/administrator/page.tsx +++ b/src/app/administrator/page.tsx @@ -1,5 +1,5 @@ "use client"; -import React, { useRef, useState } from 'react'; +import React, { useRef, useState } from "react"; type Role = "ADMIN" | "GUEST" | "SCIENTIST"; const roleLabels: Record = { diff --git a/src/app/earthquakes/page.tsx b/src/app/earthquakes/page.tsx index b3a944b..7a0ea80 100644 --- a/src/app/earthquakes/page.tsx +++ b/src/app/earthquakes/page.tsx @@ -10,149 +10,150 @@ import { getRelativeDate } from "@utils/formatters"; import GeologicalEvent from "@appTypes/Event"; import axios from "axios"; +// todo (optional) add in filtering of map earthquakes + // --- SEARCH MODAL COMPONENT --- function EarthquakeSearchModal({ open, onClose, onSelect }) { - const [search, setSearch] = useState(""); - const [results, setResults] = useState([]); - const [loading, setLoading] = useState(false); + const [search, setSearch] = useState(""); + const [results, setResults] = useState([]); + const [loading, setLoading] = useState(false); - const handleSearch = async (e) => { - e.preventDefault(); - setLoading(true); - setResults([]); - try { - const res = await axios.post("/api/earthquakes/search", { query: search }); - setResults(res.data.earthquakes || []); - } catch (e) { - alert("Failed to search."); - } - setLoading(false); - }; + const handleSearch = async (e) => { + e.preventDefault(); + setLoading(true); + setResults([]); + try { + const res = await axios.post("/api/earthquakes/search", { query: search }); + setResults(res.data.earthquakes || []); + } catch (e) { + alert("Failed to search."); + } + setLoading(false); + }; - if (!open) return null; - return ( -
-
- -

Search Earthquakes

-
- setSearch(e.target.value)} - className="flex-grow px-3 py-2 border rounded" - required - /> - -
-
- {results.length === 0 && !loading && search !== "" && ( -

No results found.

- )} -
    - {results.map(eq => ( -
  • { onSelect(eq); onClose(); }} - tabIndex={0} - > -
    - {eq.code} {" "} - {eq.location} {new Date(eq.date).toLocaleDateString()} -
    -
    = 7 ? "bg-red-500" : eq.magnitude >= 6 ? "bg-orange-400" : "bg-yellow-400"}`}> - {eq.magnitude} -
    -
  • - ))} -
-
-
-
- ); + if (!open) return null; + return ( +
+
+ +

Search Earthquakes

+
+ setSearch(e.target.value)} + className="flex-grow px-3 py-2 border rounded" + required + /> + +
+
+ {results.length === 0 && !loading && search !== "" &&

No results found.

} +
    + {results.map((eq) => ( +
  • { + onSelect(eq); + onClose(); + }} + tabIndex={0} + > +
    + {eq.code} {eq.location}{" "} + {new Date(eq.date).toLocaleDateString()} +
    +
    = 7 ? "bg-red-500" : eq.magnitude >= 6 ? "bg-orange-400" : "bg-yellow-400" + }`} + > + {eq.magnitude} +
    +
  • + ))} +
+
+
+
+ ); } // --- MAIN PAGE COMPONENT --- export default function Earthquakes() { - const [selectedEventId, setSelectedEventId] = useState(""); - const [hoveredEventId, setHoveredEventId] = useState(""); + const [selectedEventId, setSelectedEventId] = useState(""); + const [hoveredEventId, setHoveredEventId] = useState(""); - // Search modal state - const [searchModalOpen, setSearchModalOpen] = useState(false); + // Search modal state + const [searchModalOpen, setSearchModalOpen] = useState(false); - // Fetch recent earthquakes as before - const { data, error, isLoading } = useSWR("/api/earthquakes", createPoster({ rangeDaysPrev: 5 })); + // Fetch recent earthquakes as before + const { data, error, isLoading } = useSWR("/api/earthquakes", createPoster({ rangeDaysPrev: 5 })); - // Prepare events for maps/sidebar - const earthquakeEvents = useMemo( - () => - data && data.earthquakes - ? data.earthquakes - .map( - (x: Earthquake): GeologicalEvent => ({ - id: x.code, - title: `Earthquake in ${x.code.split("-")[2]}`, - magnitude: x.magnitude, - longitude: x.longitude, - latitude: x.latitude, - text1: "", - text2: getRelativeDate(x.date), - date: x.date, - }) - ) - .sort((a: GeologicalEvent, b: GeologicalEvent) => new Date(b.date).getTime() - new Date(a.date).getTime()) - : [], - [data] - ); + // Prepare events for maps/sidebar + const earthquakeEvents = useMemo( + () => + data && data.earthquakes + ? data.earthquakes + .map( + (x: Earthquake): GeologicalEvent => ({ + id: x.code, + title: `Earthquake in ${x.code.split("-")[2]}`, + magnitude: x.magnitude, + longitude: x.longitude, + latitude: x.latitude, + text1: "", + text2: getRelativeDate(x.date), + date: x.date, + }) + ) + .sort((a: GeologicalEvent, b: GeologicalEvent) => new Date(b.date).getTime() - new Date(a.date).getTime()) + : [], + [data] + ); - // Optional: show details of selected search result (not implemented here) - // const [selectedSearchResult, setSelectedSearchResult] = useState(null); + // Optional: show details of selected search result (not implemented here) + // const [selectedSearchResult, setSelectedSearchResult] = useState(null); - return ( -
-
- -
- setSearchModalOpen(true)} // <-- important! - /> - setSearchModalOpen(false)} - onSelect={eq => { - setSelectedEventId(eq.code); // select on map/sidebar - // setSelectedSearchResult(eq); // you can use this if you want to show detail modal - }} - /> -
- ); -} \ No newline at end of file + return ( +
+
+ +
+ setSearchModalOpen(true)} // <-- important! + /> + setSearchModalOpen(false)} + onSelect={(eq) => { + setSelectedEventId(eq.code); // select on map/sidebar + // setSelectedSearchResult(eq); // you can use this if you want to show detail modal + }} + /> +
+ ); +} diff --git a/src/app/observatories/page.tsx b/src/app/observatories/page.tsx index e147def..b496a09 100644 --- a/src/app/observatories/page.tsx +++ b/src/app/observatories/page.tsx @@ -11,6 +11,10 @@ import { Observatory } from "@prismaclient"; import { getRelativeDate } from "@utils/formatters"; import GeologicalEvent from "@appTypes/Event"; +// todo add in showing of observatory stats when searching +// todo add in deleting observatory when searching +// todo add in changing colour of observatory icons if non-functional + export default function Observatories() { const [selectedEventId, setSelectedEventId] = useState(""); const [hoveredEventId, setHoveredEventId] = useState(""); diff --git a/src/app/shop/page.tsx b/src/app/shop/page.tsx index fad26d6..09dee39 100644 --- a/src/app/shop/page.tsx +++ b/src/app/shop/page.tsx @@ -7,6 +7,8 @@ import { ExtendedArtefact } from "@appTypes/ApiTypes"; import { Currency } from "@appTypes/StoreModel"; import { useStoreState } from "@hooks/store"; +// todo hide from shop after purchase + export default function Shop() { const [artefacts, setArtefacts] = useState([]); const [loading, setLoading] = useState(true); @@ -16,6 +18,7 @@ export default function Shop() { async function fetchArtefacts() { setLoading(true); try { + // todo only show only non-required artefacts const res = await fetch("/api/artefacts"); const data = await res.json();