mirror of
https://github.com/Sea-Haven-Industries/shoc-frontend-new.git
synced 2026-10-07 09:19:19 +00:00
Vendors and Sites now build the keyless embed URL and the Open in Google Maps link through one helper. The Site map shows the placeholder only in the Add/Edit forms; view mode and the Work Order Site dialog always render it for the saved address, the dialog in its compact form.
69 lines
2.3 KiB
TypeScript
69 lines
2.3 KiB
TypeScript
import { Box, Typography } from "@mui/material";
|
|
import { MapPin } from "lucide-react";
|
|
import type { Location } from "@/domain/locations/types/location";
|
|
import { buildSiteMapEmbedUrl, hasCompleteSiteAddress } from "@/domain/locations/utils/site-maps";
|
|
|
|
type SiteMapPreviewProps = Pick<Location, "address" | "city" | "state" | "zipCode"> & {
|
|
/**
|
|
* Add/Edit forms: hold the map back behind a placeholder until Street, City
|
|
* and State are all filled, so a half-typed address never points somewhere
|
|
* misleading. Saved sites (view mode, Work Order Site dialog) leave this off
|
|
* and always render the map for whatever address they have.
|
|
*/
|
|
placeholderUntilComplete?: boolean;
|
|
/** Hide the "Location preview" caption where the map sits inside an info box. */
|
|
hideLabel?: boolean;
|
|
height?: number;
|
|
};
|
|
|
|
function MapPlaceholder({ height }: { height: number }) {
|
|
return (
|
|
<Box
|
|
role="status"
|
|
className="mt-1 flex flex-col items-center justify-center gap-1 rounded-lg"
|
|
sx={{ height, bgcolor: "var(--color-bg-muted)", border: 1, borderColor: "divider" }}
|
|
>
|
|
<MapPin size={18} aria-hidden style={{ color: "var(--color-text-muted)" }} />
|
|
<Typography variant="body2" sx={{ color: "text.secondary" }}>
|
|
Enter an address to preview the location
|
|
</Typography>
|
|
</Box>
|
|
);
|
|
}
|
|
|
|
/** Read-only key-less Google Maps embed of a site's address. */
|
|
export function SiteMapPreview({
|
|
placeholderUntilComplete = false,
|
|
hideLabel = false,
|
|
height = 140,
|
|
...address
|
|
}: SiteMapPreviewProps) {
|
|
const src = buildSiteMapEmbedUrl(address);
|
|
const showMap = placeholderUntilComplete ? hasCompleteSiteAddress(address) : Boolean(src);
|
|
|
|
if (!showMap && !placeholderUntilComplete) {
|
|
return null;
|
|
}
|
|
|
|
return (
|
|
<Box>
|
|
{!hideLabel && (
|
|
<Typography variant="caption" sx={{ color: "text.secondary" }}>
|
|
Location preview
|
|
</Typography>
|
|
)}
|
|
{showMap && (
|
|
<Box
|
|
component="iframe"
|
|
title="Site location map"
|
|
src={src}
|
|
loading="lazy"
|
|
referrerPolicy="no-referrer-when-downgrade"
|
|
className="mt-1 block w-full rounded-lg border-0"
|
|
sx={{ height }}
|
|
/>
|
|
)}
|
|
{!showMap && <MapPlaceholder height={height} />}
|
|
</Box>
|
|
);
|
|
}
|