Skip to content

Commit 479f1fc

Browse files
authored
Merge pull request #87 from Element84/rm/frontend-demo-polish
Add fontend demo polish
2 parents 645a75e + 0106430 commit 479f1fc

25 files changed

Lines changed: 679 additions & 188 deletions

demo/api/backends/earthsearch_backend.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,10 @@
1818
MAX_MAX_ITEMS = 100
1919

2020
LANDSAT_COLLECTION_ID = "landsat-c2-l2"
21-
SENTINEL_COLLECTION_ID = "sentinel-2-l1c"
21+
SENTINEL_L1C_COLLECTION_ID = "sentinel-2-l1c"
22+
SENTINEL_L2A_COLLECTION_ID = "sentinel-2-l2a"
2223

23-
PRODUCT_IDS = [LANDSAT_COLLECTION_ID, SENTINEL_COLLECTION_ID]
24+
PRODUCT_IDS = [LANDSAT_COLLECTION_ID, SENTINEL_L1C_COLLECTION_ID, SENTINEL_L2A_COLLECTION_ID]
2425

2526
# The api works by pretending the past is the future. It takes a users search request and searches for data in the
2627
# past. This is the amount of time in the past we search from a request.

demo/app/public/BlackSkyLogo.png

30.4 KB
Loading
3.96 KB
Loading

demo/app/public/PlanetLogo.png

11.8 KB
Loading

demo/app/public/UmbraLogo.png

10.1 KB
Loading

demo/app/src/components/Footer/Footer.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
import Container from '@components/Container';
2-
2+
import { E84Logo } from './../../utils/constants';
33
import styles from './Footer.module.scss';
44

55
const Footer = ({ ...rest }) => {
66
return (
77
<footer className={styles.footer} {...rest}>
88
<Container className={`${styles.footerContainer} ${styles.footerLegal}`}>
99
<p>
10-
powered by <a href="https://element84.com" target="_blank">Element 84</a> &copy; {new Date().getFullYear()}
10+
powered by <a href="https://element84.com" target="_blank">{E84Logo}</a> &copy; {new Date().getFullYear()}
1111
</p>
1212
</Container>
1313
</footer>

demo/app/src/components/Header/Header.js

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,26 @@
11
import Link from 'next/link';
22
import { FaGithub } from 'react-icons/fa';
33
import DateRangePicker from '@wojtekmaj/react-daterange-picker/dist/DateRangePicker';
4-
54
import { useAppContext } from 'src/context/appContext';
65
import Container from '@components/Container';
76

7+
import {
8+
UTurnArrowLeft
9+
} from '@vectopus/atlas-icons-react';
10+
11+
import { STATLogo } from './../../utils/constants';
812
import styles from './Header.module.scss';
913

1014
const Header = () => {
11-
const { userParams, setUserParams } = useAppContext();
15+
const { userParams, setUserParams, opportunities, resetSearch } = useAppContext();
1216

1317
return (
1418
<>
1519
<header className={styles.header}>
1620
<Container className={styles.headerContainer}>
1721
<p className={styles.headerTitle}>
22+
{STATLogo}
1823
<Link href="/">
19-
{/* <Image src="/logo.png" alt="logo" width={35} height={35} /> */}
2024
Task a Satellite
2125
</Link>
2226
</p>
@@ -31,6 +35,7 @@ const Header = () => {
3135
</header>
3236
<div className={styles.toolbar}>
3337
<DateRangePicker onChange={(v) => setUserParams({...userParams, dateRange: v})} value={userParams.dateRange} clearIcon={null} minDate={new Date()} />
38+
{opportunities && <button className={styles.resetSearch} onClick={resetSearch}>Reset Search <UTurnArrowLeft size={12} className={styles.resetSearchIcon}/> </button>}
3439
</div>
3540
</>
3641
);

demo/app/src/components/Header/Header.module.scss

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,17 +15,19 @@
1515
justify-content: space-between;
1616
align-items: center;
1717
width: 100%;
18-
1918
}
2019

2120
.headerTitle {
2221
font-size: 1.6em;
2322
font-weight: bold;
2423
margin: 0;
25-
}
24+
display: inline;
2625

27-
.headerLogo {
28-
height: 1.6em;
26+
svg {
27+
margin-left: 20px;
28+
margin-right: 10px;
29+
vertical-align: middle;
30+
}
2931
}
3032

3133
.headerLinks {
@@ -61,4 +63,21 @@
6163
height: 35px;
6264
background-color: $color-light-gray;
6365
z-index: 9999;
66+
padding-left: 20px;
67+
padding-top: 4px;
68+
69+
.resetSearch,
70+
.resetSearchIcon {
71+
display: inline-block;
72+
vertical-align: middle;
73+
}
74+
75+
.resetSearch {
76+
margin-left: 20px;
77+
background: none;
78+
color: grey;
79+
padding: 0;
80+
text-decoration: none;
81+
border: none;
82+
}
6483
}

demo/app/src/components/Map/DynamicMap.js

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,15 @@ import { useEffect } from 'react';
22
import Leaflet from 'leaflet';
33
import * as ReactLeaflet from 'react-leaflet';
44
import 'leaflet/dist/leaflet.css';
5+
import Footprint from './Footprint';
6+
import { useAppContext } from 'src/context/appContext';
57

68
import styles from './Map.module.scss';
79

810
const { MapContainer } = ReactLeaflet;
911

1012
const Map = ({ children, className, width, height, ...rest }) => {
13+
const { selectedOpportunity } = useAppContext();
1114
let mapClassName = styles.map;
1215

1316
if ( className ) {
@@ -26,7 +29,8 @@ const Map = ({ children, className, width, height, ...rest }) => {
2629
}, []);
2730

2831
return (
29-
<MapContainer className={mapClassName} {...rest}>
32+
<MapContainer className={`${mapClassName} ${selectedOpportunity && styles.mapContainerDetailView}`} {...rest}>
33+
<Footprint />
3034
{children(ReactLeaflet, Leaflet)}
3135
</MapContainer>
3236
)
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
import { useMap } from 'react-leaflet';
2+
import { useEffect, useState } from 'react';
3+
import { useAppContext } from 'src/context/appContext';
4+
5+
import styles from './Map.module.scss';
6+
7+
8+
function getCoords(geojson){
9+
return [geojson.geometry.coordinates[1], geojson.geometry.coordinates[0]]
10+
}
11+
12+
export default function Footprint() {
13+
const map = useMap();
14+
const [activeMarkerHover, setActiveMarkerHover] = useState(null);
15+
const [previousMarkerHover, setPreviousMarkerHover] = useState(null);
16+
const [activeMarkerClick, setActiveMarkerClick] = useState(null);
17+
const [previousMarkerClick, setPreviousMarkerClick] = useState(null);
18+
const { selectedOpportunity, hoveredOpportunity } = useAppContext();
19+
const footprintIcon = new L.divIcon({className: styles.footprintCircle});
20+
21+
useEffect(() => {
22+
if (!activeMarkerClick && previousMarkerClick){
23+
map.removeLayer(previousMarkerClick);
24+
setPreviousMarkerClick(null);
25+
}
26+
if (!activeMarkerHover && previousMarkerHover){
27+
map.removeLayer(previousMarkerHover);
28+
setPreviousMarkerHover(null);
29+
}
30+
if (activeMarkerClick && previousMarkerClick && (activeMarkerClick !== previousMarkerClick)){
31+
map.removeLayer(previousMarkerClick);
32+
setPreviousMarkerClick(activeMarkerClick);
33+
}
34+
previousMarkerHover && map.removeLayer(previousMarkerHover);
35+
activeMarkerHover && map.addLayer(activeMarkerHover);
36+
activeMarkerClick && map.addLayer(activeMarkerClick) && map.flyTo(getCoords(selectedOpportunity), 9);
37+
},[activeMarkerHover, previousMarkerHover, activeMarkerClick, previousMarkerClick]);
38+
39+
useEffect(() => {
40+
activeMarkerHover && setPreviousMarkerHover(activeMarkerHover);
41+
activeMarkerClick && setPreviousMarkerClick(activeMarkerClick);
42+
if (hoveredOpportunity){
43+
setActiveMarkerHover(new L.Marker(getCoords(hoveredOpportunity), {
44+
icon: footprintIcon
45+
}));
46+
}
47+
else {
48+
setActiveMarkerHover(null);
49+
}
50+
51+
if(selectedOpportunity) {
52+
setActiveMarkerClick(new L.Marker(getCoords(selectedOpportunity), {
53+
icon: footprintIcon
54+
}));
55+
setActiveMarkerHover(null);
56+
}
57+
else {
58+
setActiveMarkerClick(null);
59+
}
60+
}, [hoveredOpportunity, selectedOpportunity]);
61+
62+
return null;
63+
}

0 commit comments

Comments
 (0)