Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file modified public/img/uptime.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions public/locales/cs/common.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
"osm-wiki": "OSM Wiki",
"email": "E-mail",
"copyright": "Copyright © {{year}} MapSwipe",
"uptime-pretext": "",
"privacy": "Soukromí",
"mapswipe-logo": "Mapswipe Logo",
"didnot-find-language": "Přidat chybějící jazyk",
Expand Down
1 change: 1 addition & 0 deletions public/locales/de/common.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
"osm-wiki": "OSM Wiki",
"email": "Email",
"copyright": "Copyright © {{year}} MapSwipe",
"uptime-pretext": "",
"privacy": "Datenschutz",
"mapswipe-logo": "Mapswipe Logo",
"didnot-find-language": "Fehlende Sprache hinzufügen",
Expand Down
1 change: 1 addition & 0 deletions public/locales/en/common.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
"osm-wiki": "OSM Wiki",
"email": "Email",
"copyright": "Copyright © {{year}} MapSwipe",
"uptime-pretext": "System status monitored by",
"privacy": "Privacy",
"mapswipe-logo": "Mapswipe Logo",
"didnot-find-language": "Add missing language",
Expand Down
1 change: 1 addition & 0 deletions public/locales/hu/common.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
"osm-wiki": "OSM Wiki",
"email": "E-mail",
"copyright": "Copyright © {{year}} MapSwipe",
"uptime-pretext": "",
"privacy": "Adatvédelem",
"mapswipe-logo": "Mapswipe logo",
"didnot-find-language": "Hiányzó nyelv hozzáadása",
Expand Down
1 change: 1 addition & 0 deletions public/locales/ne/common.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
"osm-wiki": "OSM Wiki",
"email": "इमेल",
"copyright": "प्रतिलिपि अधिकार © {{year}} MapSwipe",
"uptime-pretext": "",
"privacy": "गोपनीयता",
"mapswipe-logo": "Mapswipe लोगो",
"didnot-find-language": "छुटेको भाषा थप्नुहोस्",
Expand Down
1 change: 1 addition & 0 deletions public/locales/pt/common.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
"osm-wiki": "Wiki OSM",
"email": "Email",
"copyright": "Direitos de autor © {{year}} MapSwipe",
"uptime-pretext": "",
"privacy": "Privacidade",
"mapswipe-logo": "Logótipo Mapswipe",
"didnot-find-language": "Adicionar idioma em falta",
Expand Down
14 changes: 14 additions & 0 deletions src/components/Footer/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import {
} from 'react-icons/io5';

import Heading from 'components/Heading';
import ImageWrapper from 'components/ImageWrapper';

import styles from './styles.module.css';

Expand Down Expand Up @@ -143,6 +144,19 @@ function Footer(props: Props) {
<div className={styles.leftContainer}>
{t('copyright', { year: currentYear })}
</div>
<div className={styles.midContainer}>
{t('uptime-pretext')}
<Link
href="https://uptimerobot.com/"
target="_blank"
>
<ImageWrapper
className={styles.partnerLogo}
src="/img/uptime.png"
alt="Uptime Robot"
/>
</Link>
</div>
<div className={styles.rightContainer}>
<Link
href="/[locale]/privacy"
Expand Down
13 changes: 13 additions & 0 deletions src/components/Footer/styles.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,19 @@
padding: var(--spacing-medium) 0;
}

.midContainer {
display: flex;
align-items: flex-end;

.partnerLogo {
/* NOTE: Margin bottom because logo is text and line height is not
* consistent */
margin-bottom: 2px;
width: 7rem;
height: 1rem;
}
}

.rightContainer {
display: flex;
padding: var(--spacing-medium) 0;
Expand Down
5 changes: 0 additions & 5 deletions src/pages/[locale]/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -72,11 +72,6 @@ const partners = [
imageSrc: '/img/tc.png',
link: 'https://togglecorp.com',
},
{
altText: 'Uptime Robot',
imageSrc: '/img/uptime.png',
link: 'https://uptimerobot.com/',
},
];

interface Props extends SSRConfig {
Expand Down
108 changes: 97 additions & 11 deletions src/pages/[locale]/projects/[id].tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
import React, { useEffect, useState, useMemo } from 'react';
import React, {
useCallback,
useEffect,
useState,
useMemo,
} from 'react';
import dynamic from 'next/dynamic';
import { GetStaticProps, GetStaticPaths } from 'next';
import { useTranslation } from 'next-i18next';
Expand All @@ -22,6 +27,7 @@ import OgMeta from 'components/OgMeta';
import Page from 'components/Page';
import ProjectTypeIcon from 'components/ProjectTypeIcon';
import ImageWrapper from 'components/ImageWrapper';
import Button from 'components/Button';
import Hero from 'components/Hero';
import Tag from 'components/Tag';
import Card from 'components/Card';
Expand Down Expand Up @@ -57,6 +63,25 @@ async function getAllProjects() {
return (data as AllDataQuery)?.publicProjects?.results as unknown as PublicProjects;
}

function transformAoiToGeoJson(
aoi: PublicProjects[number]['aoiGeometry'],
): GeoJSON.FeatureCollection<GeoJSON.Polygon> | undefined {
if (!aoi) {
return undefined;
}
return ({
type: 'FeatureCollection',
features: [{
geometry: {
type: 'Polygon',
coordinates: aoi.bbox,
},
type: 'Feature',
properties: {},
}],
});
}

async function getProjectData(id: string) {
const projects = (
data as AllDataQuery
Expand Down Expand Up @@ -125,24 +150,19 @@ function Project(props: Props) {
exportModerateToHighAgreementYesMaybeGeometries,
numberOfContributorUsers,
aoiGeometry,
firebaseId,
id: projectId,
} = props;

const svgContainerRef = React.useRef<HTMLDivElement>(null);
const svgBounds = useSizeTracking(svgContainerRef);
const [projectGeoJSON, setProjectGeoJSON] = useState(null);
const [projectHistory, setProjectHistory] = useState<{
timestamp: number; progress: number
}[] | undefined>();

useEffect(() => {
async function fetchData() {
try {
if (exportAreaOfInterest?.file?.url) {
const res = await fetch(exportAreaOfInterest.file.url);
setProjectGeoJSON(await res.json());
}

if (exportHistory?.file?.url) {
const history = await getProjectHistory(projectId, exportHistory.file.url);
setProjectHistory(history);
Expand All @@ -153,7 +173,7 @@ function Project(props: Props) {
}
}
fetchData();
}, [exportAreaOfInterest, exportHistory, projectId]);
}, [exportHistory, projectId]);

const [
chartPoints,
Expand Down Expand Up @@ -302,6 +322,35 @@ function Project(props: Props) {

const roundedTotalArea = Math.round(aoiGeometry?.totalArea ?? 0);

const aoiGeometryFeature = useMemo(() => (
transformAoiToGeoJson(aoiGeometry)
), [aoiGeometry]);

const aoiGeometryBlob = useMemo(() => {
if (!aoiGeometryFeature) {
return undefined;
}
const blob = new Blob(
[JSON.stringify(aoiGeometryFeature, null, 2)],
{ type: 'application/geo+json' },
);
return blob;
}, [aoiGeometryFeature]);

const onAoiDownloadClick = useCallback(() => {
if (!aoiGeometryBlob) {
return;
}
const url = URL.createObjectURL(aoiGeometryBlob);

const a = document.createElement('a');
a.href = url;
a.download = `area_of_interest_${firebaseId}.geojson`;
a.click();

URL.revokeObjectURL(url);
}, [aoiGeometryBlob, firebaseId]);

return (
<Page contentClassName={_cs(styles.project, className)}>
<OgMeta
Expand Down Expand Up @@ -432,11 +481,11 @@ function Project(props: Props) {
})
)}
>
{projectGeoJSON && (
{aoiGeometryFeature && (
<div className={styles.mapContainer}>
<DynamicProjectMap
className={styles.projectsMap}
geoJSON={projectGeoJSON}
geoJSON={aoiGeometryFeature}
/>
</div>
)}
Expand Down Expand Up @@ -747,7 +796,44 @@ function Project(props: Props) {
</Link>
</Card>
)}
{exportAreaOfInterest && (
{aoiGeometry && (
<Card
childrenContainerClassName={styles.downloadCard}
heading={t('area-of-interest-title')}
description={t('area-of-interest-description')}
>
<div className={styles.fileDetails}>
<Tag>GEOJSON</Tag>
<div>
{t('download-size', {
size: getFileSizeProperties(
aoiGeometryBlob?.size ?? 0,
).size,
formatParams: {
size: {
style: 'unit',
unit: getFileSizeProperties(
aoiGeometryBlob?.size ?? 0,
).unit,
maximumFractionDigits: 1,
},
},
})}
</div>
</div>
<Button
variant="border"
className={styles.link}
onClick={onAoiDownloadClick}
>
<IoDownloadOutline />
{t('download')}
</Button>
</Card>
)}
{/* NOTE: If in case there is no aoiGeometry,
we show exportAreaOfInterest if present */}
{!aoiGeometry && exportAreaOfInterest && (
<Card
childrenContainerClassName={styles.downloadCard}
key={exportAreaOfInterest?.id}
Expand Down
4 changes: 2 additions & 2 deletions src/pages/[locale]/styles.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -316,8 +316,8 @@
gap: var(--spacing-mega-large);

.partnerLogo {
width: 10rem;
height: 5rem;
width: 8rem;
height: 4rem;
}
}
}
Expand Down
Loading