Skip to content

Commit

Permalink
feat: adds open graph to address location
Browse files Browse the repository at this point in the history
  • Loading branch information
mikaelbr committed Apr 19, 2024
1 parent b9dcc67 commit 98e4031
Show file tree
Hide file tree
Showing 3 changed files with 213 additions and 9 deletions.
14 changes: 10 additions & 4 deletions src/components/map/static-map.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { mapboxData } from '@atb/modules/org-data';
import { Position } from './types';
import { MapLegType, Position } from './types';
import {
ZOOM_LEVEL,
defaultPosition,
Expand All @@ -10,10 +10,16 @@ import {

export type StaticMapProps = {
layer?: 'address' | 'venue';
position: Position;
initialZoom?: number;
size: { width: number; height: number };
};
} & (
| {
position: Position;
initialZoom?: number;
}
| {
mapLegs: MapLegType[];
}
);

export function getStaticMapUrl(props: StaticMapProps) {
const mapLegs = hasMapLegs(props) ? props.mapLegs : undefined;
Expand Down
34 changes: 29 additions & 5 deletions src/page-modules/departures/nearest-stop-places/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@ import { PageText, useTranslation } from '@atb/translations';
import EmptyMessage from '@atb/components/empty-message';
import { SituationOrNoticeIcon } from '@atb/modules/situations';
import ScreenReaderOnly from '@atb/components/screen-reader-only';
import {
OpenGraphDescription,
OpenGraphImage,
} from '@atb/components/open-graph';

export type NearestStopPlacesProps = {
fromQuery: FromDepartureQuery;
Expand Down Expand Up @@ -40,9 +44,32 @@ export function NearestStopPlaces({
/>
);
}

const pos = {
lon: fromQuery.from?.geometry.coordinates[0]!,
lat: fromQuery.from?.geometry.coordinates[1]!,
};
return (
<section className={style.nearestContainer}>
<ScreenReaderOnly text={t(PageText.Departures.nearest.resultsFound(nearestStopPlaces.length))} role='status' />
{fromQuery.from && (
<>
<OpenGraphImage
image={`api/departures/og-location?lat=${pos.lat}&lon=${pos.lon}`}
/>
{/* Hard coded to norwegian as this should be the default for sharing links where
we dont know what language to show. */}
<OpenGraphDescription
description={`Se oversikt over alle stopp i nærheten av ${fromQuery.from?.name ?? ''}.`}
/>
</>
)}

<ScreenReaderOnly
text={t(
PageText.Departures.nearest.resultsFound(nearestStopPlaces.length),
)}
role="status"
/>

<ul className={style.stopPlacesList}>
{nearestStopPlaces.map((item) => (
Expand All @@ -57,10 +84,7 @@ export function NearestStopPlaces({
<MapWithHeader
name={fromQuery.from.name}
layer="address"
position={{
lon: fromQuery.from.geometry.coordinates[0],
lat: fromQuery.from.geometry.coordinates[1],
}}
position={pos}
onSelectStopPlace={(stopPlaceId) =>
router.push(`/departures/${stopPlaceId}`)
}
Expand Down
174 changes: 174 additions & 0 deletions src/pages/api/departures/og-location.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,174 @@
/* eslint-disable @next/next/no-img-element */
import { getStaticMapUrl } from '@atb/components/map';
import { Resvg } from '@resvg/resvg-js';
import { NextApiResponse } from 'next';
import satori, { type Font } from 'satori';

import { readFile } from 'fs/promises';

import { getOrgData } from '@atb/modules/org-data';
import { theme } from '@atb/modules/theme';
import { handlerWithDepartureClient } from '@atb/page-modules/departures/server';
import { join } from 'path';

export default handlerWithDepartureClient<{}>({
async GET(req, res, { client }) {
const query = req.query as any;
const position = {
lat: parseFloat(query.lat.toString()),
lon: parseFloat(query.lon.toString()),
};

if (Number.isNaN(position.lat) || Number.isNaN(position.lon)) {
return notfound(res);
}

const from = await client.reverse(position.lat, position.lon, 'address');

if (!from) {
notfound(res);
return;
}

const {
fylkeskommune,
urls: {
sitemapUrls: { prod: prodUrl },
},
} = getOrgData();

const mapUrl = getStaticMapUrl({
layer: 'address',
position,
initialZoom: 15,
size: {
width: 1200,
height: 630,
},
});

console.log(from);

const image = await satori(
<div
style={{
color: 'black',
background: '#f6f6f6',
width: '100%',
height: '100%',
flexDirection: 'column',
justifyContent: 'center',
alignItems: 'center',
display: 'flex',
position: 'relative',
}}
>
<img alt="Map" width="1200" height="630" src={mapUrl} />

<div
style={{
position: 'absolute',
bottom: 0,
left: 0,
width: '100%',
background: theme['dark'].static.background.background_0.background,
color: theme['dark'].static.background.background_0.text,
padding: '20px',
display: 'flex',
justifyContent: 'space-between',
alignItems: 'center',
}}
>
<div
style={{
display: 'flex',
flexDirection: 'column',
gap: '0',
}}
>
<p
style={{
fontWeight: 'bold',
fontSize: '40px',
padding: 0,
margin: 0,
}}
>
{from.name}
</p>
<p style={{ padding: 0, margin: 0, fontSize: '24px' }}>
{/* Default to Norwegian as we don't know what language to show */}
Holdeplasser i nærheten av {from.name ?? ''},{' '}
{from.locality ?? ''}
</p>
</div>

{fylkeskommune?.logoSrcDark && (
<img
src={`${prodUrl}${fylkeskommune.logoSrcDark}`}
height="40px"
alt=""
/>
)}
</div>
</div>,
{
width: 1200,
height: 630,
fonts: await getFonts(),
},
);

res.setHeader('Content-Type', 'image/png');
const png = new Resvg(image).render().asPng();
res.end(png);
},
});

async function notfound(res: NextApiResponse) {
const image = await satori(
<div
style={{
color: 'black',
background: '#f6f6f6',
width: '100%',
height: '100%',
flexDirection: 'column',
justifyContent: 'center',
alignItems: 'center',
display: 'flex',
fontSize: '32px',
}}
>
<p>Holdeplass ikke funnet</p>
</div>,
{
width: 1200,
height: 630,
fonts: await getFonts(),
},
);

res.setHeader('Content-Type', 'image/png');
const png = new Resvg(image).render().asPng();
return res.end(png);
}

async function getFonts(): Promise<Font[]> {
return [
{
data: await readFile(
join(process.cwd(), 'public/fonts/Roboto-Regular.ttf'),
),
name: 'Roboto',
weight: 400,
style: 'normal',
},
{
data: await readFile(join(process.cwd(), 'public/fonts/Roboto-Bold.ttf')),
name: 'Roboto',
weight: 600,
style: 'normal',
},
];
}

0 comments on commit 98e4031

Please sign in to comment.