import { VESSEL_TYPES } from "../../entities/vessel/model/meta";
import type { DerivedLegacyVessel } from "../../features/legacyDashboard/model/types";
import { haversineNm } from "../../shared/lib/geo/haversineNm";
type Props = {
selectedVessel: DerivedLegacyVessel | null;
vessels: DerivedLegacyVessel[];
fleetVessels: DerivedLegacyVessel[];
onSelectMmsi: (mmsi: number) => void;
};
export function RelationsPanel({ selectedVessel, vessels, fleetVessels, onSelectMmsi }: Props) {
if (selectedVessel) {
const v = selectedVessel;
const meta = VESSEL_TYPES[v.shipCode];
const ownerLabel = v.ownerCn || v.ownerRoman || v.ownerKey || "-";
const sameOwner = v.ownerKey ? vessels.filter((v2) => v2.ownerKey === v.ownerKey && v2.mmsi !== v.mmsi) : [];
const pair = v.pairPermitNo ? vessels.find((v2) => v2.permitNo === v.pairPermitNo) ?? null : null;
const fcNearby = vessels.filter((fc) => fc.shipCode === "FC" && fc.mmsi !== v.mmsi && haversineNm(fc.lat, fc.lon, v.lat, v.lon) < 5);
return (
{meta.icon}
{v.permitNo}
{v.shipCode}
소유주:{" "}
{ownerLabel}
{pair ? (
<>
⛓ 쌍끌이 쌍
{(() => {
const dist = haversineNm(v.lat, v.lon, pair.lat, pair.lon);
const warn = dist > 3;
const pairMeta = VESSEL_TYPES[pair.shipCode];
return (
<>
onSelectMmsi(v.mmsi)}>
{v.permitNo}
{warn ? "⚠" : "⟷"}
onSelectMmsi(pair.mmsi)}>
{pair.permitNo}
{dist.toFixed(2)}NM
정상 범위: 0.3~1.0NM | {warn ? "⚠ 이격 경고" : "✓ 정상 동기화"}
>
);
})()}
>
) : null}
{fcNearby.length && v.shipCode !== "FC" ? (
<>
🚛 근접 운반선
{fcNearby.slice(0, 6).map((fc) => {
const dist = haversineNm(v.lat, v.lon, fc.lat, fc.lon);
const isSameOwner = !!v.ownerKey && v.ownerKey === fc.ownerKey;
const warn = dist < 0.5;
return (
onSelectMmsi(fc.mmsi)}>
{fc.permitNo}
{dist.toFixed(1)}NM
{isSameOwner ? (
동일소유주
) : null}
{warn ? (
환적의심
) : null}
);
})}
>
) : null}
{sameOwner.length ? (
<>
🏢 동일 소유주 선단 ({sameOwner.length + 1}척)
{sameOwner.slice(0, 8).map((sv) => {
const m = VESSEL_TYPES[sv.shipCode];
return (
onSelectMmsi(sv.mmsi)} style={{ cursor: "pointer" }}>
{sv.shipCode} {sv.permitNo}
{sv.sog ?? "?"}kt {sv.state.label}
);
})}
{sameOwner.length > 8 ?
... +{sameOwner.length - 8}척
: null}
>
) : null}
);
}
// No vessel selected: show top fleets
if (fleetVessels.length === 0) {
return