diff --git a/api/maps/AddMarkers.tsx b/api/maps/AddMarkers.tsx index 97bbbce..a493026 100644 --- a/api/maps/AddMarkers.tsx +++ b/api/maps/AddMarkers.tsx @@ -1,22 +1,25 @@ -import { useMemo, useState } from 'react'; +import { useMemo } from 'react'; import ReactDOM from 'react-dom/client'; import { Cluster, MarkerClusterer } from '@googlemaps/markerclusterer'; import { useMap } from '@vis.gl/react-google-maps'; import { ClusterIcon } from '@/assets/Clusters/icons'; -import ProjectModal from '@/components/ProjectModal'; import { Project } from '../../types/schema'; import { MarkerInfoWindow } from './MarkerInfoWindow'; export default function AddMarker({ projects, + selectedProjectId, + map, + setSelectedProjectId, + setMap, }: { projects: Project[] | null; + selectedProjectId: number | null; + map: google.maps.Map | null; + setSelectedProjectId: React.Dispatch>; + setMap: React.Dispatch>; }) { - const [selectedProjectId, setSelectedProjectId] = useState( - null, - ); // track currently open modal - - const map = useMap(); + setMap(useMap()); const handleMarkerClick = ( projectId: number, @@ -28,11 +31,6 @@ export default function AddMarker({ document.title = 'ACE NY'; } }; - - const closeModal = () => { - document.title = 'ACE NY'; - setSelectedProjectId(null); // close modal - }; /* function euclideanDistance(point1: number[], point2: number[]): number { const [x1, y1] = point1; @@ -164,14 +162,6 @@ export default function AddMarker({ /> ); })} - - {selectedProjectId && ( - - )} ); } diff --git a/api/maps/MarkerInfoWindow.tsx b/api/maps/MarkerInfoWindow.tsx index 284034e..467b9bc 100644 --- a/api/maps/MarkerInfoWindow.tsx +++ b/api/maps/MarkerInfoWindow.tsx @@ -48,7 +48,6 @@ export const MarkerInfoWindow = ({ }) => { const [markerRef, marker] = useAdvancedMarkerRef(); const [infoWindowShown, setInfoWindowShown] = useState(false); - const [modalOpen, setModalOpen] = useState(false); // open infowindow when marker is hovered and not already open const handleMarkerEnter = useCallback(() => { @@ -59,17 +58,16 @@ export const MarkerInfoWindow = ({ // close infowindow when modal is closed const handleClose = useCallback(() => { - if (!modalOpen) { + if (selectedProjectId !== projectId) { setInfoWindowShown(false); } - }, [modalOpen]); + }, [projectId, selectedProjectId]); const handleMarkerClick = () => { onMarkerClick(projectId, position); - setModalOpen(!modalOpen); // toggle infowindow when marker is clicked - if (!modalOpen) { + if (selectedProjectId === null) { setInfoWindowShown(true); } else { setInfoWindowShown(false); @@ -80,7 +78,8 @@ export const MarkerInfoWindow = ({ // close infowindow and modal if new marker is clicked if (selectedProjectId !== projectId) { setInfoWindowShown(false); - setModalOpen(false); + } else { + setInfoWindowShown(true); } }, [selectedProjectId, projectId]); diff --git a/app/testing/page.tsx b/app/testing/page.tsx deleted file mode 100644 index 52420fb..0000000 --- a/app/testing/page.tsx +++ /dev/null @@ -1,23 +0,0 @@ -'use client'; - -import { CSSProperties } from 'react'; -import ProjectItem from '@/components/ProjectItem'; - -export default function Home() { - return ( -
- -
- ); -} - -// CSS styles - -const mainStyles: CSSProperties = { - width: '100%', - height: '100%', - display: 'flex', - flexDirection: 'column', - alignItems: 'center', - justifyContent: 'center', -}; diff --git a/components/Map/index.tsx b/components/Map/index.tsx index b9d71ea..8432420 100644 --- a/components/Map/index.tsx +++ b/components/Map/index.tsx @@ -28,7 +28,19 @@ const center = { const mapId = '54eb1c7baba5a715'; // needed for AdvancedMarker -export default function Map(props: { projects: Project[] | null }) { +export default function Map({ + projects, + selectedProjectId, + map, + setMap, + setSelectedProjectId, +}: { + projects: Project[] | null; + selectedProjectId: number | null; + map: google.maps.Map | null; + setMap: React.Dispatch>; + setSelectedProjectId: React.Dispatch>; +}) { return ( - + ); diff --git a/components/MapViewScreen/index.tsx b/components/MapViewScreen/index.tsx index 7e1969f..a9e2ccf 100644 --- a/components/MapViewScreen/index.tsx +++ b/components/MapViewScreen/index.tsx @@ -1,4 +1,5 @@ import { useEffect, useState } from 'react'; +import { useMap } from '@vis.gl/react-google-maps'; import { LocationIcon, ProjectSizeIcon, @@ -10,6 +11,7 @@ import Map from '@/components/Map'; import { SearchBar } from '@/components/SearchBar'; import { Filters, FilterType } from '@/types/schema'; import { Project } from '../../types/schema'; +import ProjectModal from '../ProjectModal'; import ProjectsListingModal from '../ProjectsListingModal'; export default function MapViewScreen({ @@ -43,7 +45,10 @@ export default function MapViewScreen({ icon: , }, ]; - + const [map, setMap] = useState(useMap()); + const [selectedProjectId, setSelectedProjectId] = useState( + null, + ); const [searchTerm, setSearchTerm] = useState(''); const [selectedFilters, setSelectedFilters] = useState({ status: [], @@ -75,8 +80,24 @@ export default function MapViewScreen({ selectedFilters={selectedFilters} setSelectedFilters={setSelectedFilters} /> - - + + + {selectedProjectId && ( + + )} ); } diff --git a/components/ProjectItem/index.tsx b/components/ProjectItem/index.tsx index fea5f29..b79f5b6 100644 --- a/components/ProjectItem/index.tsx +++ b/components/ProjectItem/index.tsx @@ -23,7 +23,6 @@ import { import COLORS from '@/styles/colors'; import { Heading2, TagText1 } from '@/styles/texts'; import { Project } from '@/types/schema'; -import ProjectModal from '../ProjectModal'; import { projectImageStyles, ProjectInfo, @@ -35,10 +34,17 @@ import { StyledProjectItem, } from './styles'; -export default function ProjectItem({ project_id }: { project_id: number }) { +export default function ProjectItem({ + project_id, + map, + setSelectedProjectId, +}: { + project_id: number; + map: google.maps.Map | null; + setSelectedProjectId: React.Dispatch>; +}) { const [project, setProject] = useState(null); const [defaultImage, setDefaultImage] = useState(null); - const [modalOpen, setModalOpen] = useState(false); useEffect(() => { queryProjectbyId(project_id).then(data => { @@ -69,8 +75,8 @@ export default function ProjectItem({ project_id }: { project_id: number }) { renewable_energy_technology, size, // developer, - // longitude, - // latitude, + longitude, + latitude, project_status, // county, // town, @@ -141,19 +147,11 @@ export default function ProjectItem({ project_id }: { project_id: number }) { }; const handleProjectClick = () => { - setModalOpen(true); + const position = new google.maps.LatLng(latitude ?? 0, longitude ?? 0); + map?.panTo(position); + setSelectedProjectId(project_id); }; - if (modalOpen) { - return ( - setModalOpen(false)} - openFirst={true} - /> - ); - } - return ( diff --git a/components/ProjectModal/index.tsx b/components/ProjectModal/index.tsx index 728e3a4..05b4ad6 100644 --- a/components/ProjectModal/index.tsx +++ b/components/ProjectModal/index.tsx @@ -37,22 +37,20 @@ import { } from './styles'; export default function ProjectModal({ - project_id, - closeModal, - openFirst, + selectedProjectId, + setSelectedProjectId, }: { - project_id: number; - closeModal: () => void; - openFirst: boolean; + selectedProjectId: number | null; + setSelectedProjectId: React.Dispatch>; }) { const [project, setProject] = useState(null); const [defaultImage, setDefaultImage] = useState(null); useEffect(() => { - queryProjectbyId(project_id).then(data => { + queryProjectbyId(selectedProjectId ?? 0).then(data => { setProject(data); }); - }, [project_id]); + }, [selectedProjectId]); useEffect(() => { // Fetch default image when project data is available @@ -117,9 +115,14 @@ export default function ProjectModal({ ? `${renewable_energy_technology} default image` : 'No image available'; + const closeModal = () => { + document.title = 'ACE NY'; + setSelectedProjectId(null); // close modal + }; + return ( - {developer ? Developer ‣ {developer} : null} + {developer ? 'Developer ‣ ' + developer : ''} @@ -157,17 +160,15 @@ export default function ProjectModal({ {KDMs} - {additional_information ? ( - - - DETAILS - - - - {additional_information} - - - ) : null} + + + DETAILS + + + + {additional_information} + + ); diff --git a/components/ProjectModal/styles.ts b/components/ProjectModal/styles.ts index e812e73..6016ec1 100644 --- a/components/ProjectModal/styles.ts +++ b/components/ProjectModal/styles.ts @@ -112,8 +112,9 @@ export const AdditionalInfo = styled.div` padding: 1.25rem; `; -export const DetailsContainer = styled.div` +export const DetailsContainer = styled.div<{ $isEmpty: boolean }>` display: flex; + visibility: ${({ $isEmpty }) => ($isEmpty ? 'hidden' : 'visible')}; align-items: center; width: 100%; gap: 0.5rem; diff --git a/components/ProjectsListingModal/index.tsx b/components/ProjectsListingModal/index.tsx index 545ddd0..d3a40ae 100644 --- a/components/ProjectsListingModal/index.tsx +++ b/components/ProjectsListingModal/index.tsx @@ -13,11 +13,22 @@ import { export default function ProjectsListingModal({ projects, + map, + setSelectedProjectId, }: { projects: Project[] | null; + map: google.maps.Map | null; + setSelectedProjectId: React.Dispatch>; }) { const projectItems = projects?.map((project: Project) => { - return ; + return ( + + ); }); return (