diff --git a/src/app/monitoring/page.tsx b/src/app/monitoring/page.tsx
index ae345cc..c66e978 100644
--- a/src/app/monitoring/page.tsx
+++ b/src/app/monitoring/page.tsx
@@ -5,6 +5,7 @@ import { useRouter, useSearchParams } from 'next/navigation';
import { useAuthStore } from '@/lib/authStore';
import { useTheme } from '@/contexts/ThemeContext';
import { useVehicleStore, Vehicle } from '@/lib/vehicleStore';
+import { useCompanyStore } from '@/lib/companyStore';
import {
MinusIcon,
PlusIcon,
@@ -14,7 +15,10 @@ import {
TruckIcon,
ChartBarIcon,
ExclamationCircleIcon,
- MagnifyingGlassIcon
+ MagnifyingGlassIcon,
+ MapIcon,
+ MagnifyingGlassPlusIcon,
+ MagnifyingGlassMinusIcon
} from '@heroicons/react/24/outline';
import PageHeader from '@/components/common/PageHeader';
import CarMap from '@/components/map/CarMap';
@@ -126,14 +130,9 @@ function VehicleSidebar({
useEffect(() => {
if (selectedVehicle) {
- console.log('선택된 차량:', selectedVehicle);
- console.log('차량 상세 정보:', selectedVehicleDetails);
- console.log('스토어의 모든 차량:', storeVehicles);
-
const matchingVehicle = storeVehicles.find(v =>
v.id === selectedVehicle || v.mdn === selectedVehicle
);
- console.log('스토어에서 찾은 차량:', matchingVehicle);
}
}, [selectedVehicle, selectedVehicleDetails, storeVehicles]);
@@ -151,16 +150,6 @@ function VehicleSidebar({
-
@@ -217,7 +206,7 @@ function VehicleSidebar({
)}
- {selectedVehicleData && (
+ {selectedVehicleData && selectedCars.length > 0 && (
@@ -279,21 +268,25 @@ interface RouteGroup {
function MonitoringContent() {
const router = useRouter();
const searchParams = useSearchParams();
- const { isAuthenticated } = useAuthStore();
+ const { isAuthenticated, userProfile } = useAuthStore();
+ const { companyId } = useCompanyStore();
const { currentTheme } = useTheme();
const [wsConnected, setWsConnected] = useState(false);
+ const [wsConnectingState, setWsConnectingState] = useState<'connecting' | 'connected' | 'disconnected'>('disconnected');
const [carLocations, setCarLocations] = useState([]);
const [currentPositions, setCurrentPositions] = useState([]);
const [showRoute, setShowRoute] = useState(false);
const [routePoints, setRoutePoints] = useState([]);
const wsRef = useRef(null);
- const [companyId, setCompanyId] = useState('1');
+ const [currentCompanyId, setCurrentCompanyId] = useState(companyId || '1');
const [selectedCars, setSelectedCars] = useState([]);
const [showAllCars, setShowAllCars] = useState(true);
const animationRef = useRef(null);
const [dataReceived, setDataReceived] = useState(false);
const [lastUpdateTime, setLastUpdateTime] = useState('');
const [error, setError] = useState(null);
+ const [selectedCarsOrder, setSelectedCarsOrder] = useState([]);
+ const [lastSelectedCar, setLastSelectedCar] = useState(null);
const [mapSettings, setMapSettings] = useState({
latitude: 36.5,
@@ -321,6 +314,9 @@ function MonitoringContent() {
const [selectedVehicleDetails, setSelectedVehicleDetails] = useState(null);
+ // 선택된 차량의 상세 정보만 표시할 차량 ID
+ const [displayVehicleId, setDisplayVehicleId] = useState(null);
+
const handleMapDrag = (center: {lat: number, lng: number}, zoom: number) => {
setMapSettings(prev => ({
...prev,
@@ -364,7 +360,6 @@ function MonitoringContent() {
const initialPositions = assignCarColors(carLocations);
setCurrentPositions(initialPositions);
- console.log('초기 위치 설정 완료', initialPositions);
animationRef.current = setInterval(() => {
setCurrentPositions(prev => {
@@ -393,6 +388,12 @@ function MonitoringContent() {
}
}, [carLocations]);
+ useEffect(() => {
+ if (companyId) {
+ setCurrentCompanyId(companyId);
+ }
+ }, [companyId]);
+
useEffect(() => {
connectWebSocket();
@@ -407,12 +408,12 @@ function MonitoringContent() {
}, []);
const handleSubscribe = useCallback(() => {
- if (wsRef.current && companyId && wsConnected) {
- console.log('구독 요청 전송:', companyId);
+ if (wsRef.current && currentCompanyId && wsConnected) {
+ console.log('구독 요청 전송:', currentCompanyId);
const subscribeMsg = JSON.stringify({
type: 'subscribe',
- companyId: companyId
+ companyId: currentCompanyId
});
wsRef.current.send(subscribeMsg);
@@ -420,35 +421,32 @@ function MonitoringContent() {
console.warn('WebSocket이 연결되지 않았거나 회사 ID가 없습니다');
setError('WebSocket이 연결되지 않았거나 회사 ID가 없습니다');
}
- }, [companyId, wsConnected]);
+ }, [currentCompanyId, wsConnected]);
useEffect(() => {
- if (wsConnected && companyId) {
- console.log('WebSocket 연결됨, 자동 구독 시도:', companyId);
+ if (wsConnected && currentCompanyId) {
+ console.log('WebSocket 연결됨, 자동 구독 시도:', currentCompanyId);
handleSubscribe();
}
- }, [wsConnected, companyId, handleSubscribe]);
+ }, [wsConnected, currentCompanyId, handleSubscribe]);
const connectWebSocket = () => {
try {
- const wsUrl = `${process.env.NEXT_PUBLIC_API_WEBSOKET_URL}/ws`;
+ const wsUrl = `${process.env.NEXT_PUBLIC_API_WEBSOCKET_URL}/ws`;
- console.log(`WebSocket 연결 시도: ${wsUrl}`);
+ setWsConnectingState('connecting');
const ws = new WebSocket(wsUrl);
wsRef.current = ws;
ws.onopen = () => {
- console.log('WebSocket 연결됨', new Date().toLocaleString());
setWsConnected(true);
+ setWsConnectingState('connected');
setError(null);
};
ws.onmessage = (event) => {
try {
- console.log('데이터 수신:', new Date().toLocaleString());
-
const data = JSON.parse(event.data);
- console.log('파싱된 데이터:', data);
if (Array.isArray(data)) {
const isValidData = data.every(item =>
@@ -466,50 +464,32 @@ function MonitoringContent() {
if (isValidData) {
processReceivedData(data);
- } else {
- console.error('데이터 형식이 올바르지 않습니다:', data);
- setError('데이터 형식이 올바르지 않습니다');
}
- } else {
- console.error('데이터가 배열이 아닙니다:', data);
- setError('데이터가 배열이 아닙니다');
}
} catch (error) {
- console.error('메시지 파싱 에러:', error);
- setError(`메시지 파싱 에러: ${error}`);
}
};
ws.onclose = () => {
setWsConnected(false);
- console.log('WebSocket 연결 종료', new Date().toLocaleString());
- setTimeout(connectWebSocket, 5000);
+ setWsConnectingState('disconnected');
};
ws.onerror = (error) => {
- console.error('WebSocket 에러:', error);
- setError(`WebSocket 에러: ${error}`);
+ setWsConnectingState('disconnected');
};
} catch (error) {
- console.error('WebSocket 연결 시도 중 예외 발생:', error);
- setError(`WebSocket 연결 시도 중 예외 발생: ${error}`);
+ setWsConnectingState('disconnected');
}
};
const processReceivedData = (data: CarLocation[]) => {
try {
- console.log('데이터 처리 중...', {
- 차량수: data.length,
- 첫차량: data[0]?.carId,
- 데이터포인트: data[0]?.locations.length
- });
-
setCarLocations(data);
setDataReceived(true);
setLastUpdateTime(new Date().toLocaleString());
setError(null);
} catch (error) {
- console.error('데이터 처리 중 오류:', error);
setError(`데이터 처리 중 오류: ${error}`);
}
};
@@ -543,12 +523,25 @@ function MonitoringContent() {
const toggleCarSelection = useCallback((carId: string) => {
setSelectedCars(prev => {
if (prev.includes(carId)) {
- setSelectedVehicleDetails(null);
- return prev.filter(id => id !== carId);
+ // 차량 선택 취소
+ const newSelectedCars = prev.filter(id => id !== carId);
+
+ // 현재 표시 중인 차량이 취소되는 차량이라면
+ if (displayVehicleId === carId) {
+ setDisplayVehicleId(null);
+ setSelectedVehicleDetails(null);
+ }
+
+ return newSelectedCars;
} else {
+ // 차량 선택 - 항상 새 차량 정보를 표시
+ setDisplayVehicleId(carId);
+
+ // 현재 차량의 정보를 상세 정보로 설정
const vehicleInfo = storeVehicles.find(v => v.id === carId || v.mdn === carId);
setSelectedVehicleDetails(vehicleInfo || null);
- return [carId];
+
+ return [...prev, carId]; // 기존 선택 유지하고 새 차량 추가
}
});
}, [storeVehicles]);
@@ -629,16 +622,27 @@ function MonitoringContent() {
-
-
- {wsConnected ? '연결됨' : '연결 끊김'}
-
+ {wsConnectingState === 'connecting' ? (
+ <>
+
+
연결 중
+ >
+ ) : (
+ <>
+
+
+ {wsConnectingState === 'connected' ? '연결됨' : '연결 끊김'}
+
+ >
+ )}
@@ -686,7 +690,7 @@ function MonitoringContent() {
className={`w-7 h-7 flex items-center justify-center rounded-md ${currentTheme.hoverBg} transition-colors`}
title="축소"
>
-
+
{mapSettings.zoom}
@@ -722,7 +726,24 @@ function MonitoringContent() {
-
+
+
+