From f2ecc1803f3ea294a0c6b7915b61348ed0395b26 Mon Sep 17 00:00:00 2001 From: Marcin Zelent Date: Wed, 16 Nov 2022 15:16:38 +0100 Subject: Remade and extended the app using React --- components/Gallery/Gallery.module.css | 63 ------------------ components/Gallery/Gallery.tsx | 80 ---------------------- components/Map/Map.module.css | 28 -------- components/Map/Map.tsx | 121 ---------------------------------- components/Sidebar/Sidebar.module.css | 54 --------------- components/Sidebar/Sidebar.tsx | 71 -------------------- 6 files changed, 417 deletions(-) delete mode 100644 components/Gallery/Gallery.module.css delete mode 100644 components/Gallery/Gallery.tsx delete mode 100644 components/Map/Map.module.css delete mode 100644 components/Map/Map.tsx delete mode 100644 components/Sidebar/Sidebar.module.css delete mode 100644 components/Sidebar/Sidebar.tsx (limited to 'components') diff --git a/components/Gallery/Gallery.module.css b/components/Gallery/Gallery.module.css deleted file mode 100644 index 01e8037..0000000 --- a/components/Gallery/Gallery.module.css +++ /dev/null @@ -1,63 +0,0 @@ -.galleryContainer { - padding: 20px; - position: fixed; - top: 0; - right: 0; - bottom: 0; - left: 0; - z-index: 99999; - background: rgba(0, 0, 0, 0.8); -} - -.photoContainer { - width: 100%; - height: 100%; - padding: 20px; - position: relative; -} - -.photo { - max-width: 100%; - max-height: 100%; - position: absolute; - top: 50%; - left: 50%; - transform: translate(-50%, -50%); -} - -.btn { - position: absolute; - z-index: 99999; - font-size: 2rem; - color: #eee; - background: none; - border: none; - cursor: pointer; - outline: currentcolor none medium; -} - -.btn:hover { - color: #fff; -} - -.arrowLeft { - top: 50%; - left: 0; - transform: translateY(-50%); -} - -.arrowRight { - top: 50%; - right: 0; - transform: translateY(-50%); -} - -.closeBtn { - width: 64px; - height: 64px; - top: 0; - right: 0; - font-size: 4rem; - line-height: 4rem; - font-weight: 300; -} diff --git a/components/Gallery/Gallery.tsx b/components/Gallery/Gallery.tsx deleted file mode 100644 index dfadbc0..0000000 --- a/components/Gallery/Gallery.tsx +++ /dev/null @@ -1,80 +0,0 @@ -import { useEffect, useRef } from 'react'; - -import { Photo } from 'models'; -import useEvent from 'lib/useEvent'; -import styles from './Gallery.module.css'; - -interface Props { - currentPhoto: Photo; - handleClose: () => void; - handlePhotoChange: (direction: boolean) => void; -} - -export default function Gallery({ - currentPhoto, - handleClose, - handlePhotoChange, -}: Props): JSX.Element { - const wrapperRef = useRef(null); - - useEffect(() => { - function handleClickOutside(e: MouseEvent) { - if ( - wrapperRef.current && - !wrapperRef.current.contains(e.target) && - (e.target as Node).nodeName !== 'BUTTON' - ) { - handleClose(); - } - } - - document.addEventListener('mousedown', handleClickOutside); - return () => { - document.removeEventListener('mousedown', handleClickOutside); - }; - }, [wrapperRef]); - - useEvent('keydown', (e: KeyboardEvent) => { - if (e.key === 'ArrowLeft') { - handlePhotoChange(false); - } else if (e.key === 'ArrowRight') { - handlePhotoChange(true); - } else if (e.key === 'Escape') { - handleClose(); - } - }); - - return ( -
- -
- {currentPhoto.name} -
- - -
- ); -} diff --git a/components/Map/Map.module.css b/components/Map/Map.module.css deleted file mode 100644 index b13f5d2..0000000 --- a/components/Map/Map.module.css +++ /dev/null @@ -1,28 +0,0 @@ -.popup { - width: auto; - min-height: 90%; -} - -.popup .leaflet-popup-content { - margin: 0; -} - -.markerIcon { - border: 2px solid #fff; - border-radius: 2px; - overflow: hidden; -} - -.markerItemCount { - width: 18px; - height: 18px; - display: block; - position: absolute; - top: 50%; - left: 50%; - transform: translate(-50%, -50%); - border-radius: 10px; - background: #fff; - text-align: center; - font-weight: bold; -} diff --git a/components/Map/Map.tsx b/components/Map/Map.tsx deleted file mode 100644 index 8ecde47..0000000 --- a/components/Map/Map.tsx +++ /dev/null @@ -1,121 +0,0 @@ -import { LatLngBounds, DivIcon, Icon } from 'leaflet'; -import { useEffect, useState } from 'react'; -import ReactDom from 'react-dom/server'; -import { MapContainer, Marker, TileLayer, GeoJSON, ZoomControl } from 'react-leaflet'; -import MarkerClusterGroup from 'react-leaflet-markercluster'; - -import { Trip, Photo } from 'models'; -import { distanceBetween } from 'lib/util'; - -import 'leaflet/dist/leaflet.css'; -import styles from './Map.module.css'; - -interface Props { - trip: Trip; - handleMarkerClick: (photo: string) => void; -} - -export default function Map({ trip, handleMarkerClick }: Props): JSX.Element { - const [map, setMap] = useState(null); - - const bounds = trip - ? new LatLngBounds( - [trip.track.bbox[1], trip.track.bbox[0]], - [trip.track.bbox[3], trip.track.bbox[2]], - ) - : new LatLngBounds([75, -145], [-52, 145]); - - function createMarkers(photos: Photo[]): JSX.Element[] { - // cluster photos that are close to each other - const clusters: Photo[][] = []; - for (let i = 0; i < photos.length; i += 1) { - if (clusters.filter((c) => c.includes(photos[i])).length === 0) { - const cluster = [photos[i]]; - for (let j = 0; j < photos.length; j += 1) { - if (photos[i] !== photos[j]) { - const a = [photos[i].latitude, photos[i].longitude]; - const b = [photos[j].latitude, photos[j].longitude]; - const distance = distanceBetween(a, b); - if (distance < 10) cluster.push(photos[j]); - } - } - clusters.push(cluster); - } - } - - // create React elements based on the clusters - const markers = clusters.map((cluster) => { - let Wrapper = ({ children }) => <>{children}; - if (cluster.length > 1) { - Wrapper = ({ children }) => ( - - new DivIcon({ - html: ReactDom.renderToString( - <> - - {markerCluster.getChildCount()} - , - ), - iconSize: [36, 36], - className: styles.markerIcon, - }) - } - > - {children} - - ); - } - - const children = cluster.map((photo) => ( - handleMarkerClick(photo.name) }} - /> - )); - - return {children}; - }); - - return markers; - } - - useEffect(() => { - if (map) { - map.setView(bounds.getCenter()); - map.fitBounds(bounds); - } - }, [trip]); - - return ( - - - - {trip && } - {trip && createMarkers(trip.photos)} - - ); -} diff --git a/components/Sidebar/Sidebar.module.css b/components/Sidebar/Sidebar.module.css deleted file mode 100644 index a3c8a1a..0000000 --- a/components/Sidebar/Sidebar.module.css +++ /dev/null @@ -1,54 +0,0 @@ -.aside { - min-width: 272px; - height: 100%; - padding: 5px; - display: flex; - flex-direction: column; - border-right: 1px solid #e5e5e5; - box-shadow: -2px 0 10px #000; - z-index: 9999; - background-color: #fff; -} - -.aside h2 { - padding-left: 1.5rem; -} - -.list { - margin: 0; - padding: 0; - list-style: none; - overflow-y: auto; -} - -.listItem { - margin-bottom: 5px; - padding: 1rem 2rem 1rem 1.5rem; - display: block; - border-radius: 10px; - cursor: pointer; - user-select: none; - outline: currentcolor none medium; -} - -.listItem:hover { - background-color: #f5f5f5; -} - -.listItemActive { - background-color: #e9f3ff !important; -} - -@media only screen and (max-width: 500px) { - .aside { - position: absolute; - top: 0; - bottom: 0; - left: -100vw; - transition: left 0.3s ease-in; - } - - .asideOpen { - left: 0; - } -} diff --git a/components/Sidebar/Sidebar.tsx b/components/Sidebar/Sidebar.tsx deleted file mode 100644 index 6b0473a..0000000 --- a/components/Sidebar/Sidebar.tsx +++ /dev/null @@ -1,71 +0,0 @@ -import { useEffect, useRef } from 'react'; - -import { Trip } from 'models'; -import { secondsToTimeString } from 'lib/util'; - -import styles from './Sidebar.module.css'; - -interface Props { - trips: Trip[]; - currentTrip: Trip; - asideOpen: boolean; - handleClose: () => void; - setCurrentTrip: (trip: Trip) => void; -} - -export default function Sidebar({ - trips, - currentTrip, - asideOpen, - handleClose, - setCurrentTrip, -}: Props): JSX.Element { - const wrapperRef = useRef(null); - - useEffect(() => { - function handleClickOutside(e: MouseEvent) { - if (wrapperRef.current && !wrapperRef.current.contains(e.target)) { - handleClose(); - } - } - - document.addEventListener('mousedown', handleClickOutside); - return () => { - document.removeEventListener('mousedown', handleClickOutside); - }; - }, [wrapperRef]); - - function handleTripChange(trip: Trip): void { - setCurrentTrip(trip); - handleClose(); - } - - return ( - - ); -} -- cgit v1.2.3