관제 화면 문구와 화물 패널 정리
This commit is contained in:
@@ -33,6 +33,7 @@ const elements = {
|
||||
driversTab: document.getElementById("driversTab"),
|
||||
locationsPanel: document.getElementById("locationsPanel"),
|
||||
driversPanel: document.getElementById("driversPanel"),
|
||||
mapPanel: document.querySelector(".map-panel"),
|
||||
vehicleList: document.getElementById("vehicleList"),
|
||||
mapMessage: document.getElementById("mapMessage"),
|
||||
totalCount: document.getElementById("totalCount"),
|
||||
@@ -1359,7 +1360,7 @@ function createDestinationMarkerElement(location) {
|
||||
function createDestinationMarkerHtml(location) {
|
||||
const metrics = getRouteMetrics(location);
|
||||
const destinationName = getDestinationName(location) || "목적지";
|
||||
const etaText = metrics ? formatEtaTime(metrics.estimatedArrivalAt) : "ETA";
|
||||
const etaText = metrics ? formatEtaTime(metrics.estimatedArrivalAt) : "도착시간 미정";
|
||||
|
||||
return `
|
||||
<span class="route-destination-pin">도착</span>
|
||||
@@ -1380,7 +1381,7 @@ function refreshSelectedDetail(location) {
|
||||
}
|
||||
|
||||
if (state.activeDetailMode === "cargo") {
|
||||
renderCargoFocusPanel(location);
|
||||
hideRouteFocusPanel();
|
||||
showInfoOverlay(location);
|
||||
return;
|
||||
}
|
||||
@@ -1436,14 +1437,14 @@ function renderMarkerActionPanel(location) {
|
||||
const distance = metrics ? formatDistance(metrics.remainingDistanceKm) : "-";
|
||||
const eta = metrics ? formatEtaTime(metrics.estimatedArrivalAt) : "-";
|
||||
|
||||
elements.markerActionEyebrow.textContent = "차량 선택";
|
||||
elements.markerActionEyebrow.textContent = "차량";
|
||||
elements.markerActionTitle.textContent = `${title} · ${vehicleType.label}`;
|
||||
elements.markerActionMeta.textContent = [driver, status.label, formatSpeed(location.speed)].filter(Boolean).join(" · ");
|
||||
elements.markerActionSummary.replaceChildren(
|
||||
createMarkerActionSummaryItem("화물", getCargoSummary(location)),
|
||||
createMarkerActionSummaryItem("목적지", getRouteSummary(location)),
|
||||
createMarkerActionSummaryItem("남은 거리", distance),
|
||||
createMarkerActionSummaryItem("도착 예정", eta)
|
||||
createMarkerActionSummaryItem("도착 시간", eta)
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1501,7 +1502,7 @@ function showVehicleCargo(location) {
|
||||
hideMarkerActionPanel();
|
||||
elements.historyDrawer.classList.add("is-hidden");
|
||||
clearRouteOverlay();
|
||||
renderCargoFocusPanel(location);
|
||||
hideRouteFocusPanel();
|
||||
render();
|
||||
updateMarkerSelectionClasses();
|
||||
showInfoOverlay(location);
|
||||
@@ -1549,35 +1550,27 @@ function setRouteFocusContent(eyebrow, title, meta) {
|
||||
elements.routeFocusMeta.textContent = meta;
|
||||
}
|
||||
|
||||
function renderCargoFocusPanel(location) {
|
||||
const vehicleType = getVehicleType(location);
|
||||
const product = getCargoName(location) || "미등록";
|
||||
const quantity = getCargoQuantity(location) || "수량 미등록";
|
||||
const weight = getCargoWeight(location) || "중량 미등록";
|
||||
const route = getRouteSummary(location);
|
||||
setRouteFocusContent(
|
||||
"화물 정보",
|
||||
`${location.vehicleNo || location.driverId} · ${vehicleType.label}`,
|
||||
`${product} · ${quantity} · ${weight} · ${route}`
|
||||
);
|
||||
function hideRouteFocusPanel() {
|
||||
elements.routeFocusPanel.classList.remove("is-active");
|
||||
setRouteFocusEyebrow("차량 정보");
|
||||
elements.routeFocusTitle.textContent = "";
|
||||
elements.routeFocusMeta.textContent = "";
|
||||
}
|
||||
|
||||
function renderCurrentLocationPanel(location) {
|
||||
const vehicleType = getVehicleType(location);
|
||||
const coordinate = `${formatCoordinate(location.latitude)}, ${formatCoordinate(location.longitude)}`;
|
||||
setRouteFocusContent(
|
||||
"현재 위치",
|
||||
"지도 중심",
|
||||
`${location.vehicleNo || location.driverId} · ${vehicleType.label}`,
|
||||
`${formatSpeed(location.speed)} · ${coordinate} · ${formatDateTime(location.receivedAt)}`
|
||||
);
|
||||
}
|
||||
|
||||
function renderRouteFocusPanel(location) {
|
||||
setRouteFocusEyebrow("선택 경로");
|
||||
setRouteFocusEyebrow("차량 정보");
|
||||
if (!location) {
|
||||
elements.routeFocusPanel.classList.remove("is-active");
|
||||
elements.routeFocusTitle.textContent = "차량 선택";
|
||||
elements.routeFocusMeta.textContent = "선택하면 경로와 도착 예정 시간이 표시됩니다.";
|
||||
hideRouteFocusPanel();
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1615,7 +1608,7 @@ async function loadLocationHistory(location) {
|
||||
state.activeDetailMode = "history";
|
||||
hideMarkerActionPanel();
|
||||
elements.historyDrawer.classList.remove("is-hidden");
|
||||
elements.historyTitle.textContent = `${location.vehicleNo || location.driverId} 위치 이력`;
|
||||
elements.historyTitle.textContent = `${location.vehicleNo || location.driverId} 수신 이력`;
|
||||
elements.historySummary.textContent = "조회 중";
|
||||
elements.historyList.replaceChildren();
|
||||
|
||||
@@ -1674,48 +1667,34 @@ function closeHistoryDrawer() {
|
||||
}
|
||||
|
||||
function showInfoOverlay(location) {
|
||||
if (!state.map || !state.mapProvider) return;
|
||||
if (!elements.mapPanel) return;
|
||||
|
||||
if (shouldSuppressMapPopup()) {
|
||||
if (shouldSuppressInfoPanel()) {
|
||||
clearInfoOverlay();
|
||||
return;
|
||||
}
|
||||
|
||||
const status = getLocationStatus(location);
|
||||
const content = createPopupElement(location, status);
|
||||
const placement = getInfoPanelPlacement(location);
|
||||
|
||||
if (state.mapProvider === "leaflet") {
|
||||
if (state.infoOverlay) {
|
||||
state.infoOverlay
|
||||
.setLatLng([location.latitude, location.longitude])
|
||||
.setContent(content);
|
||||
return;
|
||||
}
|
||||
|
||||
state.infoOverlay = L.popup({
|
||||
closeButton: true,
|
||||
offset: [0, -24]
|
||||
})
|
||||
.setLatLng([location.latitude, location.longitude])
|
||||
.setContent(content)
|
||||
.openOn(state.map);
|
||||
return;
|
||||
if (!(state.infoOverlay instanceof HTMLElement)) {
|
||||
clearInfoOverlay();
|
||||
state.infoOverlay = document.createElement("section");
|
||||
state.infoOverlay.setAttribute("aria-label", "화물 상세");
|
||||
elements.mapPanel.append(state.infoOverlay);
|
||||
}
|
||||
|
||||
const position = new kakao.maps.LatLng(location.latitude, location.longitude);
|
||||
|
||||
if (!state.infoOverlay) {
|
||||
state.infoOverlay = new kakao.maps.CustomOverlay({ yAnchor: 1.35 });
|
||||
}
|
||||
state.infoOverlay.setContent(content);
|
||||
state.infoOverlay.setPosition(position);
|
||||
state.infoOverlay.setMap(state.map);
|
||||
state.infoOverlay.className = `map-info-panel ${placement}`;
|
||||
state.infoOverlay.replaceChildren(content);
|
||||
}
|
||||
|
||||
function clearInfoOverlay() {
|
||||
if (!state.infoOverlay) return;
|
||||
|
||||
if (typeof state.infoOverlay.setMap === "function") {
|
||||
if (state.infoOverlay instanceof HTMLElement) {
|
||||
state.infoOverlay.remove();
|
||||
} else if (typeof state.infoOverlay.setMap === "function") {
|
||||
state.infoOverlay.setMap(null);
|
||||
} else if (state.mapProvider === "leaflet" && state.map?.closePopup) {
|
||||
state.map.closePopup(state.infoOverlay);
|
||||
@@ -1724,14 +1703,43 @@ function clearInfoOverlay() {
|
||||
state.infoOverlay = null;
|
||||
}
|
||||
|
||||
function shouldSuppressMapPopup() {
|
||||
function shouldSuppressInfoPanel() {
|
||||
return window.matchMedia("(max-width: 560px)").matches;
|
||||
}
|
||||
|
||||
function getInfoPanelPlacement(location) {
|
||||
const center = getCurrentMapCenter();
|
||||
if (!center) return "is-top-right";
|
||||
|
||||
return location.longitude >= center.longitude ? "is-bottom-left" : "is-top-right";
|
||||
}
|
||||
|
||||
function getCurrentMapCenter() {
|
||||
if (!state.map || !state.mapProvider) return null;
|
||||
|
||||
if (state.mapProvider === "kakao" && typeof state.map.getCenter === "function") {
|
||||
const center = state.map.getCenter();
|
||||
return {
|
||||
latitude: center.getLat(),
|
||||
longitude: center.getLng()
|
||||
};
|
||||
}
|
||||
|
||||
if (state.mapProvider === "leaflet" && typeof state.map.getCenter === "function") {
|
||||
const center = state.map.getCenter();
|
||||
return {
|
||||
latitude: center.lat,
|
||||
longitude: center.lng
|
||||
};
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
function createPopupElement(location, status) {
|
||||
const vehicleType = getVehicleType(location);
|
||||
const container = document.createElement("div");
|
||||
container.className = "kakao-popup";
|
||||
container.className = "map-info-card";
|
||||
|
||||
const title = document.createElement("strong");
|
||||
title.className = "popup-title";
|
||||
@@ -1775,12 +1783,10 @@ function createRouteInfoElement(location) {
|
||||
return routeInfo;
|
||||
}
|
||||
|
||||
const source = firstString(location.routeSource, location.routingProvider) || "simulated";
|
||||
routeInfo.append(
|
||||
createPopupRouteLine("남은 거리", formatDistance(metrics.remainingDistanceKm)),
|
||||
createPopupRouteLine("예상 도착", formatEtaTime(metrics.estimatedArrivalAt)),
|
||||
createPopupRouteLine("소요 시간", formatDuration(metrics.etaMinutes)),
|
||||
createPopupRouteLine("경로", source === "simulated" ? "모의 경로" : source)
|
||||
createPopupRouteLine("도착 시간", formatEtaTime(metrics.estimatedArrivalAt)),
|
||||
createPopupRouteLine("남은 시간", formatDuration(metrics.etaMinutes))
|
||||
);
|
||||
return routeInfo;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user