Skip to content

Commit

Permalink
feat(api): 개별 차량 검색 API 연동 및 기능구현 (#97)
Browse files Browse the repository at this point in the history
- 기존 목데이터 관련 코드 삭제
- 응답 데이터에 따른 타입 수정
- API 연동 및 예외처리
  • Loading branch information
red-dev-Mark committed Jan 25, 2025
1 parent d1f82aa commit a8c8fb2
Show file tree
Hide file tree
Showing 5 changed files with 67 additions and 66 deletions.
8 changes: 6 additions & 2 deletions app/(main)/location/components/VehicleMarker/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,14 @@ const VehicleMarker = ({ vehicleInfo, onVehicleClick }: VehicleMarkerProps) => {
}, [])

const vehicleNumber = vehicleInfo.vehicleNumber.slice(0, 3) + ' ' + vehicleInfo.vehicleNumber.slice(3)
const vehicleCurrentLocation = {
lat: vehicleInfo?.recentCycleInfo.lat,
lng: vehicleInfo?.recentCycleInfo.lat,
}

return (
<CustomOverlayMap position={vehicleInfo?.location}>
<MapMarker position={vehicleInfo?.location} image={MARKER_IMAGE} />
<CustomOverlayMap position={vehicleCurrentLocation}>
<MapMarker position={vehicleCurrentLocation} image={MARKER_IMAGE} />
<p className={styles.vehicleCard} onClick={onVehicleClick} role='presentation'>
{vehicleNumber}
</p>
Expand Down
43 changes: 16 additions & 27 deletions hooks/useSearchSingleVehicle.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { ChangeEventHandler, useEffect, useState } from 'react'
import { ChangeEventHandler, useState } from 'react'

import { ZOOM_LEVEL } from '@/constants/map'
import { useMapControl } from '@/hooks/useMapControl'
import { useModal } from '@/hooks/useModal'
import { vehicleAPI } from '@/lib/apis'
import { validateVehicleNumber } from '@/lib/utils/validation'
import mockData from '@/mock/single_vehicle_search_ok.json'
import { VehicleInfoModel } from '@/types/vehicle'

export const useSearchSingleVehicle = () => {
Expand All @@ -15,26 +15,8 @@ export const useSearchSingleVehicle = () => {
const { isOpen, modalMessage, closeModal, showMessage } = useModal()
const { mapState, updateMapLocation } = useMapControl()

useEffect(() => {
const getSingleVehicleData = () => {
// TODO: 실제 데이터페칭으로 수정
const data = mockData.vehicle

const singleVehicleData = {
vehicleId: data.vehicleId,
vehicleNumber: data.vehicleNumber,
status: data.status,
location: { lat: data.lat, lng: data.lng },
}

setVehicleInfo(singleVehicleData)
}

getSingleVehicleData()
}, [])

const handleVehicleSearch = () => {
if (!vehicleInfo) return
const handleVehicleSearch = async () => {
if (!searchTerm) return

const validation = validateVehicleNumber(searchTerm)

Expand All @@ -43,20 +25,27 @@ export const useSearchSingleVehicle = () => {
return
}

// TODO: API 호출 로직으로 변경하기
if (validation.value !== mockData.vehicle.vehicleNumber) {
showMessage('등록되지 않은 차량번호입니다.')
const response = await vehicleAPI.getVehicleInfo(searchTerm)

console.log(response)

// TODO: 등록되지 않은 차량의 경우 어떤 에러코드가 오는지 확인 후 처리
if (!response.isValid) {
showMessage(response.value)
return
}

const vehicleInfo = response.value

updateMapLocation(
{
lat: vehicleInfo?.location.lat,
lng: vehicleInfo?.location.lng,
lat: vehicleInfo?.recentCycleInfo.lat,
lng: vehicleInfo?.recentCycleInfo.lng,
},
ZOOM_LEVEL.SINGLE_VEHICLE,
)

setVehicleInfo(vehicleInfo)
setIsVehicleVisible(true)
setSearchTerm('')
}
Expand Down
21 changes: 15 additions & 6 deletions hooks/useSearchVehicle.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { useState } from 'react'

import { useModal } from '@/hooks/useModal'
import { vehicleAPI } from '@/lib/apis'
// import { vehicleAPI } from '@/lib/apis'
import { validateVehicleNumber } from '@/lib/utils/validation'
import { VehicleDateModel } from '@/types/vehicle'

Expand All @@ -20,7 +20,15 @@ export const useSearchVehicle = (vehicleNumber: string = '') => {
}

try {
const response = await vehicleAPI.fetchVehicleData(vehicleNumber)
// const response = await vehicleAPI.fetchVehicleData(vehicleNumber)
const response = {
vehicleId: '1',
vehicleNumber: '123가1234',
searchableDates: {
firstDateAt: '2024-02-02T11:11:11',
lastDateAt: '2024-02-02T11:11:11',
},
}

// TODO: 등록되지 않는 차량 API 에러 메세지로 대체
if (validation.value !== response.vehicleNumber) {
Expand All @@ -31,10 +39,11 @@ export const useSearchVehicle = (vehicleNumber: string = '') => {
const vehicleData = {
vehicleId: response.vehicleId,
vehicleNumber: response.vehicleNumber,
searchableDates: {
firstDateAt: response.firstDateAt,
lastDateAt: response.lastDateAt,
},
// searchableDates: {
// firstDateAt: response.firstDateAt,
// lastDateAt: response.lastDateAt,
// },
searchableDates: response.searchableDates,
}

setSearchedVehicle(vehicleData)
Expand Down
50 changes: 22 additions & 28 deletions lib/apis/vehicle.ts
Original file line number Diff line number Diff line change
@@ -1,41 +1,22 @@
// import { API_URL } from '@/constants/api'
// import { apiClient } from '@/lib/apis/client'
import { API_URL } from '@/constants/api'
import { apiClient } from '@/lib/apis/client'
// import { DateTime } from '@/app/route/types/date'
// import { formatToISODate } from '@/lib/utils/date'
import mockRoutesData from '@/mock/vehicle_route_data.json'
// import mockRoutesData from '@/mock/vehicle_route_data.json'
import { VehicleDetailsModel, VehicleStatusType } from '@/types/vehicle'

// 예시 API 구조
export const vehicleAPI = {
fetchVehicleData: async (_vehicleNumber: string) => {
// const response = await apiClient.get(`${API_URL}/api/v1/vehicles?vehicleNumber=${vehicleNumber}`)
getVehicleInfo: async (vehicleNumber: string) => {
const response = await apiClient.get(`${API_URL}/api/v1/vehicles/search?vehicle-number=${vehicleNumber}`)

const response = {
isSuccess: true,
message: '요청 성공',
result: {
vehicleId: 'V123',
vehicleNumber: '54하2902',
firstDateAt: '2024-01-15T09:30:00',
lastDateAt: '2024-01-21T14:30:00',
},
if (!response.data.isSuccess) {
if (response.data.errorCode === 1003) {
return { isValid: false, value: '등록되지 않은 차량입니다.' }
}
}

return response.result
},
fetchVehicleRoutesData: async () => {
// fetchVehicleRoutesData: async (vehicleId: string, startDate: DateTime, endDate: DateTime, interval = 60) => {
// const formattedStartDate = formatToISODate(startDate)
// const formattedEndDate = formatToISODate(endDate)
// const response = await apiClient.get(
// `${API_URL}/api/vi/vehicles/${vehicleId}/routes?startTime=${formattedStartDate}&endTime=${formattedEndDate}&interval=${interval}`,
// )
// console.log(formattedStartDate, formattedEndDate, vehicleId, interval)

// return response.result

return mockRoutesData
return { isValid: true, value: response.data.result }
},
// fetchVehicleDetails: async (vehicleId: string) => {
fetchVehicleDetails: async (): Promise<VehicleDetailsModel> => {
Expand Down Expand Up @@ -67,4 +48,17 @@ export const vehicleAPI = {
}
return response.result
},
fetchVehicleRoutesData: async () => {
// fetchVehicleRoutesData: async (vehicleId: string, startDate: DateTime, endDate: DateTime, interval = 60) => {
// const formattedStartDate = formatToISODate(startDate)
// const formattedEndDate = formatToISODate(endDate)
// const response = await apiClient.get(
// `${API_URL}/api/vi/vehicles/${vehicleId}/routes?startTime=${formattedStartDate}&endTime=${formattedEndDate}&interval=${interval}`,
// )
// console.log(formattedStartDate, formattedEndDate, vehicleId, interval)

// return response.result

return mockRoutesData
},
}
11 changes: 8 additions & 3 deletions types/vehicle.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,15 @@
import { LatLng } from '@/types/location'

export interface VehicleInfoModel {
vehicleId: string
vehicleNumber: string
recentCycleInfo: RecentCycleInfo
status: string
location: LatLng
}

interface RecentCycleInfo {
speed: number
lat: number
lng: number
lastUpdated: string
}

export interface VehicleDateModel {
Expand Down

0 comments on commit a8c8fb2

Please sign in to comment.