mirror of
https://github.com/Sea-Haven-Industries/shoc-frontend-new.git
synced 2026-10-07 16:19:01 +00:00
feat(work-orders): show the vendor location map in the Vendor dialog
The last of SH-271's five acceptance bullets. The Work Order Vendor dialog gets one composed address line from the vendor dropdown payload, not the structured parts the form and detail drawer hold, so the preview takes the line directly — it is saved data either way, and the completeness rule exists to stop a map of half-typed input, not to reject a stored address. The dialog's hand-built maps URL now goes through the shared helper, so the link and the preview cannot drift apart.
This commit is contained in:
parent
aa707cb370
commit
2844d97a36
2 changed files with 38 additions and 15 deletions
|
|
@ -1,4 +1,6 @@
|
|||
import { ExternalLink, Mail, MapPin } from "lucide-react";
|
||||
import { AddressMapPreview } from "@/components/common/address-map-preview";
|
||||
import { mapsSearchUrl } from "@/lib/address/vendor-address";
|
||||
import { Detail } from "@/app/(protected)/workorders/_components/wizard/wizard-labels";
|
||||
import type { VendorDropdownItem } from "@/domain/work-orders/types/work-order";
|
||||
import { formatVendorDistance } from "@/domain/work-orders/utils/vendor-dropdown-label";
|
||||
|
|
@ -33,15 +35,23 @@ export function VendorDialogCompanyCard({ company, vendor }: VendorDialogCompany
|
|||
{Boolean(vendor?.address) && <Detail icon={MapPin} text={vendor?.address ?? ""} />}
|
||||
{Boolean(email) && <Detail icon={Mail} text={email} />}
|
||||
{vendor != null && Boolean(vendor.address) && (
|
||||
<a
|
||||
href={`https://www.google.com/maps/search/?api=1&query=${encodeURIComponent(vendor.address)}`}
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
className="inline-flex items-center gap-1.5 text-[12px] hover:underline"
|
||||
style={{ color: "var(--color-primary)" }}
|
||||
>
|
||||
<ExternalLink size={12} /> Open in Google Maps
|
||||
</a>
|
||||
<>
|
||||
<a
|
||||
href={mapsSearchUrl({ street: vendor.address })}
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
className="inline-flex items-center gap-1.5 text-[12px] hover:underline"
|
||||
style={{ color: "var(--color-primary)" }}
|
||||
>
|
||||
<ExternalLink size={12} /> Open in Google Maps
|
||||
</a>
|
||||
{/*
|
||||
SH-271: the vendor dropdown payload carries one composed address
|
||||
line, not the structured parts the form and detail drawer hold, so
|
||||
the preview is given the line directly. It is saved data either way.
|
||||
*/}
|
||||
<AddressMapPreview query={vendor.address} height={140} />
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -7,7 +7,14 @@ import {
|
|||
} from "@/lib/address/vendor-address";
|
||||
|
||||
type AddressMapPreviewProps = {
|
||||
address: Partial<AddressParts>;
|
||||
/** Structured parts, as held by a form or a detail view. */
|
||||
address?: Partial<AddressParts>;
|
||||
/**
|
||||
* An already-composed address line, for callers that hold saved data rather
|
||||
* than live input — the Work Order vendor dialog gets one string from the
|
||||
* vendor dropdown payload. Ignored when `address` is given.
|
||||
*/
|
||||
query?: string;
|
||||
height?: number;
|
||||
};
|
||||
|
||||
|
|
@ -21,10 +28,16 @@ type AddressMapPreviewProps = {
|
|||
* Renders nothing until Street, City and State are all present — a preview of a
|
||||
* half-typed address points somewhere misleading, which is worse than no map.
|
||||
*/
|
||||
export function AddressMapPreview({ address, height = 160 }: AddressMapPreviewProps) {
|
||||
if (!hasCompleteAddress(address)) return null;
|
||||
|
||||
const query = buildAddressQuery(address);
|
||||
export function AddressMapPreview({
|
||||
address,
|
||||
query: rawQuery,
|
||||
height = 160,
|
||||
}: AddressMapPreviewProps) {
|
||||
// Structured input is held to the completeness rule; a pre-composed line is
|
||||
// saved data and only has to be non-empty.
|
||||
const query = address ? buildAddressQuery(address) : (rawQuery ?? "").trim();
|
||||
const renderable = address ? hasCompleteAddress(address) : Boolean(query);
|
||||
if (!renderable) return null;
|
||||
return (
|
||||
<Box
|
||||
sx={{
|
||||
|
|
@ -38,7 +51,7 @@ export function AddressMapPreview({ address, height = 160 }: AddressMapPreviewPr
|
|||
<Box
|
||||
component="iframe"
|
||||
title={`Map of ${query}`}
|
||||
src={mapsEmbedUrl(address)}
|
||||
src={mapsEmbedUrl({ street: query })}
|
||||
loading="lazy"
|
||||
referrerPolicy="no-referrer-when-downgrade"
|
||||
sx={{ display: "block", width: "100%", height, border: 0 }}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue