Merged in feat/sw-3240-move-staticmap-to-design-system (pull request #2654)
feat(SW-3240): Move StaticMap to design-system * Move StaticMap to design-system Approved-by: Joakim Jäderberg
This commit is contained in:
@@ -1,61 +1,22 @@
|
||||
/* eslint-disable @next/next/no-img-element */
|
||||
import StaticMapPrimitive from "@scandic-hotels/design-system/StaticMap"
|
||||
|
||||
import { env } from "@/env/server"
|
||||
|
||||
import { getUrlWithSignature } from "@/utils/map"
|
||||
import type { ComponentProps } from "react"
|
||||
|
||||
import type { StaticMapProps } from "@/types/components/maps/staticMap"
|
||||
|
||||
function getCenter({
|
||||
coordinates,
|
||||
city,
|
||||
country,
|
||||
}: {
|
||||
coordinates?: { lat: number; lng: number }
|
||||
city?: string
|
||||
country?: string
|
||||
}): string | undefined {
|
||||
if (coordinates) {
|
||||
return `${coordinates.lat},${coordinates.lng}`
|
||||
}
|
||||
if (city && country) {
|
||||
return `${city}, ${country}`
|
||||
}
|
||||
if (country) {
|
||||
return country
|
||||
}
|
||||
return city
|
||||
}
|
||||
|
||||
export default function StaticMap({
|
||||
city,
|
||||
country,
|
||||
coordinates,
|
||||
width,
|
||||
height,
|
||||
zoomLevel = 14,
|
||||
mapType = "roadmap",
|
||||
altText,
|
||||
mapId,
|
||||
}: StaticMapProps) {
|
||||
type Props = Omit<
|
||||
ComponentProps<typeof StaticMapPrimitive>,
|
||||
"googleMapKey" | "googleMapSecret"
|
||||
>
|
||||
export default async function StaticMap(props: Props) {
|
||||
const key = env.GOOGLE_STATIC_MAP_KEY
|
||||
const secret = env.GOOGLE_STATIC_MAP_SIGNATURE_SECRET
|
||||
const baseUrl = "https://maps.googleapis.com/maps/api/staticmap"
|
||||
const center = getCenter({ coordinates, city, country })
|
||||
|
||||
if (!center) {
|
||||
return null
|
||||
}
|
||||
|
||||
// Google Maps Static API only supports images smaller than 640x640px. Read: https://developers.google.com/maps/documentation/maps-static/start#Largerimagesizes
|
||||
const url = new URL(
|
||||
`${baseUrl}?center=${center}&zoom=${zoomLevel}&size=${width}x${height}&maptype=${mapType}&key=${key}`
|
||||
return (
|
||||
<StaticMapPrimitive
|
||||
{...props}
|
||||
googleMapKey={key}
|
||||
googleMapSecret={secret}
|
||||
/>
|
||||
)
|
||||
|
||||
if (mapId) {
|
||||
url.searchParams.append("map_id", mapId)
|
||||
}
|
||||
|
||||
const src = getUrlWithSignature(url, secret)
|
||||
|
||||
return <img src={src} alt={altText} />
|
||||
}
|
||||
|
||||
@@ -1,13 +0,0 @@
|
||||
import type { Coordinates } from "./coordinates"
|
||||
|
||||
export type StaticMapProps = {
|
||||
city?: string
|
||||
country?: string
|
||||
coordinates?: Coordinates
|
||||
width: number
|
||||
height: number
|
||||
zoomLevel?: number
|
||||
mapType?: "roadmap" | "satellite" | "terrain" | "hybrid"
|
||||
altText: string
|
||||
mapId?: string
|
||||
}
|
||||
@@ -1,5 +1,3 @@
|
||||
import crypto from "node:crypto"
|
||||
|
||||
// Helper function to calculate the latitude offset
|
||||
export function calculateLatWithOffset(
|
||||
latitude: number,
|
||||
@@ -23,66 +21,3 @@ export function calculateLatWithOffset(
|
||||
// Return the new latitude by subtracting the offset
|
||||
return latitude - latOffset
|
||||
}
|
||||
|
||||
/**
|
||||
* Util functions taken from https://developers.google.com/maps/documentation/maps-static/digital-signature#sample-code-for-url-signing
|
||||
* Used to sign the URL for the Google Static Maps API.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Convert from 'web safe' base64 to true base64.
|
||||
*
|
||||
* @param {string} safeEncodedString The code you want to translate
|
||||
* from a web safe form.
|
||||
* @return {string}
|
||||
*/
|
||||
function removeWebSafe(safeEncodedString: string) {
|
||||
return safeEncodedString.replace(/-/g, "+").replace(/_/g, "/")
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert from true base64 to 'web safe' base64
|
||||
*
|
||||
* @param {string} encodedString The code you want to translate to a
|
||||
* web safe form.
|
||||
* @return {string}
|
||||
*/
|
||||
function makeWebSafe(encodedString: string) {
|
||||
return encodedString.replace(/\+/g, "-").replace(/\//g, "_")
|
||||
}
|
||||
|
||||
/**
|
||||
* Takes a base64 code and decodes it.
|
||||
*
|
||||
* @param {string} code The encoded data.
|
||||
* @return {string}
|
||||
*/
|
||||
function decodeBase64Hash(code: string) {
|
||||
return Buffer.from(code, "base64")
|
||||
}
|
||||
|
||||
/**
|
||||
* Takes a key and signs the data with it.
|
||||
*
|
||||
* @param {string} key Your unique secret key.
|
||||
* @param {string} data The url to sign.
|
||||
* @return {string}
|
||||
*/
|
||||
function encodeBase64Hash(key: Buffer, data: string) {
|
||||
return crypto.createHmac("sha1", key).update(data).digest("base64")
|
||||
}
|
||||
|
||||
/**
|
||||
* Sign a URL using a secret key.
|
||||
*
|
||||
* @param {URL} url The url you want to sign.
|
||||
* @param {string} secret Your unique secret key.
|
||||
* @return {string}
|
||||
*/
|
||||
export function getUrlWithSignature(url: URL, secret = "") {
|
||||
const path = url.pathname + url.search
|
||||
const safeSecret = decodeBase64Hash(removeWebSafe(secret))
|
||||
const hashedSignature = makeWebSafe(encodeBase64Hash(safeSecret, path))
|
||||
|
||||
return `${url.toString()}&signature=${hashedSignature}`
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user