Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/app/logs/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -94,8 +94,8 @@ export default function LogsPage() {
// carLogs를 VehicleLog 형식으로 변환해서 전달
const mappedLogs = carLogs.map(log => {
// API 응답의 driveType을 변환
let driveType: DriveType = 'UNREGISTERED';
if (log.driveType === 'COMMUTE' || log.driveType === 'WORK') {
let driveType: DriveType = 'UNCLASSIFIED';
if (log.driveType === 'COMMUTE' || log.driveType === 'BUSINESS' || log.driveType === 'PERSONAL') {
driveType = log.driveType as DriveType;
}

Expand Down
7 changes: 5 additions & 2 deletions src/app/profile/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,7 @@ export default function ProfilePage() {
setIsLoading(true);
setApiError(null);

await fetchApi('/api/users/password', undefined, {
await fetchApi<{data: any, message: string, statusCode: number}>('/api/users/password', undefined, {
method: 'PUT',
headers: {
'Content-Type': 'application/json',
Expand Down Expand Up @@ -234,7 +234,10 @@ export default function ProfilePage() {

setLoadingPermissions(true);
try {
const response = await fetchApi<{ permissionTypes: string[] }>('/api/users/permissions/my');
const apiResponse = await fetchApi<{data: { permissionTypes: string[] }, message: string, statusCode: number}>('/api/users/permissions/my');

// 새로운 API 응답 형식 처리 (data 필드에 실제 데이터가 있음)
const response = apiResponse.data || apiResponse;

if (response && response.permissionTypes) {
// 권한 ID 배열을 Permission 객체로 변환
Expand Down
21 changes: 12 additions & 9 deletions src/components/logs/VehicleLogDetailSlidePanel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ export default function VehicleLogDetailSlidePanel({ isOpen, onClose, log, onDel
if (editedLog) {
try {
const updateData = {
driveType: editedLog.driveType === 'UNREGISTERED' ? null : editedLog.driveType,
driveType: editedLog.driveType,
driver: editedLog.driver?.name || '',
description: editedLog.note || ''
};
Expand Down Expand Up @@ -206,20 +206,22 @@ export default function VehicleLogDetailSlidePanel({ isOpen, onClose, log, onDel
switch (type) {
case 'COMMUTE':
return 'bg-blue-50 text-blue-700 dark:bg-blue-50 dark:text-blue-700';
case 'WORK':
case 'BUSINESS':
return 'bg-teal-50 text-teal-700 dark:bg-teal-50 dark:text-teal-700';
case 'UNREGISTERED':
return 'bg-slate-50 text-slate-700 dark:bg-slate-50 dark:text-slate-700';
case 'PERSONAL':
return 'bg-purple-50 text-purple-700 dark:bg-purple-50 dark:text-purple-700';
case 'UNCLASSIFIED':
default:
return '';
return 'bg-slate-50 text-slate-700 dark:bg-slate-50 dark:text-slate-700';
}
};

const getDriveTypeLabel = (type: DriveType) => {
const types = {
COMMUTE: '출퇴근',
WORK: '업무',
UNREGISTERED: '미등록',
BUSINESS: '업무',
PERSONAL: '개인',
UNCLASSIFIED: '미분류',
} as const;
return types[type];
};
Expand Down Expand Up @@ -355,8 +357,9 @@ export default function VehicleLogDetailSlidePanel({ isOpen, onClose, log, onDel
className={`ml-2 rounded-md border ${currentTheme.border} ${currentTheme.inputBg} ${currentTheme.text} px-2 py-1 text-sm focus:outline-none focus:ring-2 focus:ring-indigo-500`}
>
<option value="COMMUTE">출퇴근</option>
<option value="WORK">업무</option>
<option value="UNREGISTERED">미등록</option>
<option value="BUSINESS">업무</option>
<option value="PERSONAL">개인</option>
<option value="UNCLASSIFIED">미분류</option>
</select>
)}
</div>
Expand Down
29 changes: 28 additions & 1 deletion src/components/logs/VehicleLogFilter.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,7 @@ export function VehicleLogFilter({ onChange, onApplyFilter, initialFilter }: Veh
</div>
</div>

<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
<div className="grid grid-cols-1 md:grid-cols-3 gap-4">
<div>
<label className={`block text-xs font-medium ${currentTheme.subtext} mb-1`}>시작 날짜</label>
<div className={`relative border ${currentTheme.border} rounded-lg`}>
Expand Down Expand Up @@ -197,6 +197,33 @@ export function VehicleLogFilter({ onChange, onApplyFilter, initialFilter }: Veh
)}
</div>
</div>
<div>
<label className={`block text-xs font-medium ${currentTheme.subtext} mb-1`}>운행 유형</label>
<div className={`relative border ${currentTheme.border} rounded-lg`}>
<select
name="driveType"
value={localFilter.driveType || ''}
onChange={handleFilterChange}
className={`w-full py-2 px-3 ${currentTheme.cardBg} ${currentTheme.text} rounded-lg text-sm focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:border-indigo-500 transition-all duration-200`}
>
<option value="">전체</option>
<option value="COMMUTE">출퇴근</option>
<option value="BUSINESS">업무</option>
<option value="PERSONAL">개인</option>
<option value="UNCLASSIFIED">미분류</option>
</select>
{localFilter.driveType && (
<div className="absolute inset-y-0 right-0 pr-2 flex items-center">
<button
onClick={() => handleResetFilter('driveType')}
className="text-gray-400 hover:text-gray-500 focus:outline-none"
>
<XCircleIcon className="h-4 w-4" />
</button>
</div>
)}
</div>
</div>
</div>

<div className="mt-4 flex justify-end space-x-2">
Expand Down
18 changes: 10 additions & 8 deletions src/components/logs/VehicleLogList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,8 @@ export function VehicleLogList({
const mappedLogs = useMemo(() => {
return carLogs.map(log => {
// API 응답의 driveType을 변환
let driveType: DriveType = 'UNREGISTERED';
if (log.driveType === 'COMMUTE' || log.driveType === 'WORK') {
let driveType: DriveType = 'UNCLASSIFIED';
if (log.driveType === 'COMMUTE' || log.driveType === 'BUSINESS' || log.driveType === 'PERSONAL') {
driveType = log.driveType as DriveType;
}

Expand Down Expand Up @@ -108,20 +108,22 @@ export function VehicleLogList({
switch (type) {
case 'COMMUTE':
return 'bg-blue-50 text-blue-700 dark:bg-blue-50 dark:text-blue-700';
case 'WORK':
case 'BUSINESS':
return 'bg-teal-50 text-teal-700 dark:bg-teal-50 dark:text-teal-700';
case 'UNREGISTERED':
return 'bg-slate-50 text-slate-700 dark:bg-slate-50 dark:text-slate-700';
case 'PERSONAL':
return 'bg-purple-50 text-purple-700 dark:bg-purple-50 dark:text-purple-700';
case 'UNCLASSIFIED':
default:
return '';
return 'bg-slate-50 text-slate-700 dark:bg-slate-50 dark:text-slate-700';
}
};

const getDriveTypeLabel = (type: DriveType) => {
const types = {
COMMUTE: '출퇴근',
WORK: '업무',
UNREGISTERED: '미등록',
BUSINESS: '업무',
PERSONAL: '개인',
UNCLASSIFIED: '미분류',
} as const;
return types[type];
};
Expand Down
14 changes: 10 additions & 4 deletions src/lib/announcementStore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,15 @@ export const useAnnouncementStore = create<AnnouncementState>((set) => ({
fetchAnnouncements: async (page = 0, size = 10) => {
set({ isLoading: true, error: null });
try {
const response = await fetchApi<AnnouncementsResponse>('/api/announcement', {
const apiResponse = await fetchApi<{data: AnnouncementsResponse, message: string, statusCode: number}>('/api/announcements', {
page,
size
});

console.log('API 원본 응답:', response);
console.log('API 원본 응답:', apiResponse);

// 새로운 API 응답 형식 처리 (data 필드에 실제 데이터가 있음)
const response = apiResponse.data || apiResponse;

// announcementId를 id로 매핑하여 처리
const processedAnnouncements = response.content.map((item, index) => {
Expand Down Expand Up @@ -73,9 +76,12 @@ export const useAnnouncementStore = create<AnnouncementState>((set) => ({
fetchAnnouncementDetail: async (id: number) => {
set({ isLoading: true, error: null });
try {
const response = await fetchApi<AnnouncementApiResponse>(`/api/announcement/${id}`);
const apiResponse = await fetchApi<{data: AnnouncementApiResponse, message: string, statusCode: number}>(`/api/announcements/${id}`);

console.log('상세 API 원본 응답:', apiResponse);

console.log('상세 API 원본 응답:', response);
// 새로운 API 응답 형식 처리 (data 필드에 실제 데이터가 있음)
const response = apiResponse.data || apiResponse;

// announcementId를 id로 매핑하여 처리
const processedDetail = {
Expand Down
7 changes: 5 additions & 2 deletions src/lib/authStore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,10 @@ export const useAuthStore = create<AuthState>((set, get) => ({
set({ profileLoading: true, profileError: null });

// 백엔드 API 호출
const response = await fetchApi<UserResponse>('/api/users/my');
const apiResponse = await fetchApi<{data: UserResponse, message: string, statusCode: number}>('/api/users/my');

// 새로운 API 응답 형식 처리 (data 필드에 실제 데이터가 있음)
const response = apiResponse.data || apiResponse;

// API 응답을 UserInfo 형태로 변환
const userInfo: UserInfo = {
Expand Down Expand Up @@ -322,7 +325,7 @@ export const useAuthStore = create<AuthState>((set, get) => ({
// 사용자 정보 업데이트
updateUserProfile: async (userRequest: UserRequest) => {
try {
await fetchApi<void>('/api/users/my', undefined, {
await fetchApi<{data: any, message: string, statusCode: number}>('/api/users/my', undefined, {
method: 'PUT',
body: JSON.stringify(userRequest)
});
Expand Down
26 changes: 16 additions & 10 deletions src/lib/carLogsStore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -125,14 +125,17 @@ export const useCarLogsStore = create<CarLogsState>((set, get) => ({
requestBody.driveType = driveType;
}

const data = await fetchApi<any>(`/api/carLogs?page=${page}&size=${size}`, undefined, {
const data = await fetchApi<{data: any, message: string, statusCode: number}>(`/api/carLogs?page=${page}&size=${size}`, undefined, {
method: 'POST',
body: JSON.stringify(requestBody)
});

const content = Array.isArray(data.content) ? data.content : (Array.isArray(data) ? data : []);
const totalPages = data.totalPages || 1;
const totalElements = data.totalElements || content.length;
// 새로운 API 응답 형식 처리 (data 필드에 실제 데이터가 있음)
const responseData = data.data || data;

const content = Array.isArray(responseData.content) ? responseData.content : (Array.isArray(responseData) ? responseData : []);
const totalPages = responseData.totalPages || 1;
const totalElements = responseData.totalElements || content.length;

if (params) {
const newFilter = { ...currentFilter };
Expand All @@ -158,7 +161,7 @@ export const useCarLogsStore = create<CarLogsState>((set, get) => ({
});
}

return data;
return responseData;
} catch (error) {
console.error('운행일지 데이터 가져오기 실패:', error);
set({
Expand All @@ -173,10 +176,13 @@ export const useCarLogsStore = create<CarLogsState>((set, get) => ({
try {
set({ isLoading: true, error: null });

const data = await fetchApi<any>('/api/carLogs/statics', undefined, {
const response = await fetchApi<{data: any, message: string, statusCode: number}>('/api/carLogs/statics', undefined, {
method: 'GET'
});

// 새로운 API 응답 형식 처리 (data 필드에 실제 데이터가 있음)
const data = response.data || response;

set({
stats: {
totalMileage: data.totalMileage || 0,
Expand All @@ -198,7 +204,7 @@ export const useCarLogsStore = create<CarLogsState>((set, get) => ({
try {
set({ isLoading: true, error: null });

const responseText = await fetchApi<string>(`/api/carLogs/${logId}`, undefined, {
const response = await fetchApi<{data: string, message: string, statusCode: number}>(`/api/carLogs/${logId}`, undefined, {
method: 'PUT',
body: JSON.stringify(data)
});
Expand All @@ -207,7 +213,7 @@ export const useCarLogsStore = create<CarLogsState>((set, get) => ({

return {
success: true,
message: responseText || '운행일지가 성공적으로 수정되었습니다.'
message: response.message || response.data || '운행일지가 성공적으로 수정되었습니다.'
};
} catch (error) {
console.error('운행일지 수정 실패:', error);
Expand All @@ -227,15 +233,15 @@ export const useCarLogsStore = create<CarLogsState>((set, get) => ({
try {
set({ isLoading: true, error: null });

const responseText = await fetchApi<string>(`/api/carLogs/${logId}`, undefined, {
const response = await fetchApi<{data: string, message: string, statusCode: number}>(`/api/carLogs/${logId}`, undefined, {
method: 'DELETE'
});

await get().fetchCarLogs();

return {
success: true,
message: responseText || '운행일지가 성공적으로 삭제되었습니다.'
message: response.message || response.data || '운행일지가 성공적으로 삭제되었습니다.'
};
} catch (error) {
console.error('운행일지 삭제 실패:', error);
Expand Down
5 changes: 4 additions & 1 deletion src/lib/carOverviewStore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,10 @@ export const useCarOverviewStore = create<CarOverviewState>((set) => ({
try {
set({ isLoading: true, error: null });

const data = await fetchApi<CarOverviewData>('/api/cars/overview');
const response = await fetchApi<{data: CarOverviewData, message: string, statusCode: number}>('/api/cars/overview');

// 새로운 API 응답 형식 처리 (data 필드에 실제 데이터가 있음)
const data = response.data || response;

set({
data: data,
Expand Down
10 changes: 7 additions & 3 deletions src/lib/companyStore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,10 @@ export const useCompanyStore = create<CompanyState>((set) => ({
try {
set({ isLoading: true, error: null });

const data = await fetchApi<CompanyResponse>('/api/companies/my');
const response = await fetchApi<{data: CompanyResponse, message: string, statusCode: number}>('/api/companies/my');

// 새로운 API 응답 형식 처리 (data 필드에 실제 데이터가 있음)
const data = response.data || response;

set({
company: data,
Expand All @@ -66,13 +69,14 @@ export const useCompanyStore = create<CompanyState>((set) => ({
try {
set({ updating: true, updateError: null, updateSuccess: false });

await fetchApi<void>('/api/companies/my', undefined, {
const updateResponse = await fetchApi<{data: any, message: string, statusCode: number}>('/api/companies/my', undefined, {
method: 'PUT',
body: JSON.stringify(companyRequest)
});

// 업데이트가 성공하면 회사 정보를 다시 가져옴
const updatedCompany = await fetchApi<CompanyResponse>('/api/companies/my');
const response = await fetchApi<{data: CompanyResponse, message: string, statusCode: number}>('/api/companies/my');
const updatedCompany = response.data || response;

set({
company: updatedCompany,
Expand Down
Loading