Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
54 commits
Select commit Hold shift + click to select a range
7564330
#80 [MOD] red색상명 변경
sunhwaaRj Jul 27, 2025
40a5660
#80 [MOD] 진행중 enum 변경
sunhwaaRj Jul 27, 2025
e2daa08
Merge branch 'develop' of https://github.com/vecosystem/VECO_Frontend…
sunhwaaRj Jul 27, 2025
8d11f03
#80 [FEAT] 알림목록 조회 구조 작성
sunhwaaRj Jul 27, 2025
17660d8
#80 [MOD] 변경된 모달 적용
sunhwaaRj Jul 27, 2025
f412196
#80 [MOD] 각 유형별 추가 버튼 navigator 연결
sunhwaaRj Jul 27, 2025
fb9fb77
#80 [MOD] 진행중 enum 변경
sunhwaaRj Jul 28, 2025
748f0f5
Merge branch 'develop' of https://github.com/vecosystem/VECO_Frontend…
sunhwaaRj Jul 28, 2025
34c7668
#80 [MOD] 상태 변수명 변경
sunhwaaRj Jul 29, 2025
7f73d11
#80 [FEAT] 공통 쿼리 파라미터 타입
sunhwaaRj Jul 29, 2025
0fb9e68
#80 [FEAT] 목표 리스트 api
sunhwaaRj Jul 29, 2025
91cde34
#80 [FEAT] 이슈 리스트 api
sunhwaaRj Jul 29, 2025
de38cff
#80 [FEAT] 삭제 요소 id 넘기기
sunhwaaRj Jul 29, 2025
5fff6c2
#80 [FEAT] 알림 종류 타입 추가
sunhwaaRj Jul 29, 2025
2599868
#80 [FEAT] 알림 리스트 api
sunhwaaRj Jul 29, 2025
7380b07
Merge branch 'develop' of https://github.com/vecosystem/VECO_Frontend…
sunhwaaRj Jul 29, 2025
afcc9ed
#80 [FEAT] 쿼리키 상수 추가
sunhwaaRj Jul 30, 2025
d039dab
#80 [FEAT] 목표 훅 함수
sunhwaaRj Jul 30, 2025
43e5ce0
#80 [FEAT] 이슈 훅 함수
sunhwaaRj Jul 30, 2025
a33a19b
#80 [FEAT] 알림 훅 함수
sunhwaaRj Jul 30, 2025
79d8229
#80 [FIX] 날짜 형식 string 추가
sunhwaaRj Jul 30, 2025
1c35d68
#80 [FEAT] 알림 체크 위한 요소 추가
sunhwaaRj Jul 30, 2025
b9d64af
#80 [FEAT] 읽은 알림 배경색 추가
sunhwaaRj Jul 30, 2025
e9baf54
#80 [FIX] 알림 구조 수정
sunhwaaRj Jul 30, 2025
8dc21cf
#80 [FEAT] 알림 api 구조에 맞도록 수정
sunhwaaRj Jul 30, 2025
5d19b76
#80 [FEAT] 목표리스트 api 연결
sunhwaaRj Jul 30, 2025
1eb90ed
#80 [FEAT] 외부 리스트 api
sunhwaaRj Jul 30, 2025
c737fe1
#80 [FEAT] 이슈 리스트 api 연동
sunhwaaRj Jul 31, 2025
8d7ccfb
#80 [FEAT] 이슈 삭제 api 연동
sunhwaaRj Jul 31, 2025
7befdfc
#80 [FEAT] 목표 삭제 api 연동
sunhwaaRj Jul 31, 2025
39308df
#80 [FEAT] 알림 삭제 api
sunhwaaRj Jul 31, 2025
9596a93
#80 [FEAT] 외부 삭제 api
sunhwaaRj Jul 31, 2025
6e7ff7c
Merge branch 'develop' of https://github.com/vecosystem/VECO_Frontend…
sunhwaaRj Jul 31, 2025
8ce087e
#80 [FEAT] 알림 읽음 처리 api
sunhwaaRj Jul 31, 2025
b4bf713
#80 [MOD] 리스트 요소 클릭이벤트 추가
sunhwaaRj Jul 31, 2025
93a7975
#80 [MOD] 외부 클릭이벤트 props 추가
sunhwaaRj Aug 1, 2025
c6d9129
#80 [MOD] 알림 읽음처리 및 담당자 정보 추가
sunhwaaRj Aug 1, 2025
38e2dab
#80 [MOD] 외부 리스트 api 연동
sunhwaaRj Aug 1, 2025
75fb755
#80 [FEAT] 외부 삭제 api 연동
sunhwaaRj Aug 1, 2025
0b40c2a
#80 [FIX] api 주소 변경
sunhwaaRj Aug 1, 2025
9e2cd52
#80 [FEAT] 상세페이지 이동 onclick 이벤트
sunhwaaRj Aug 1, 2025
d6cdd16
Merge branch 'develop' of https://github.com/vecosystem/VECO_Frontend…
sunhwaaRj Aug 1, 2025
d67f1ce
#80 [FIX] 머지 충돌 수정
sunhwaaRj Aug 1, 2025
9bcf905
#80 [MOVE] 알림 api 파일이동
sunhwaaRj Aug 1, 2025
27f6bbb
#80 [MOVE] 외부 api 파일이동
sunhwaaRj Aug 1, 2025
05c3e8c
#80 [MOVE] 목표 api 파일이동
sunhwaaRj Aug 1, 2025
4f4ef1d
#80 [MOVE] 이슈 api 파일이동
sunhwaaRj Aug 1, 2025
a6e493f
#80 [MOD] 워크스페이스 페이지 삭제 모달 수정
sunhwaaRj Aug 1, 2025
87e758b
#80 [FEAT] 워크스페이스 상세페이지 이동 onclick 이벤트
sunhwaaRj Aug 1, 2025
91fdd78
#80 [ADD] 알림 구조 주석추가
sunhwaaRj Aug 1, 2025
3fc7059
#80 [MOD] 알림 구조 더미데이터 수정
sunhwaaRj Aug 1, 2025
8b3a92d
#112 [FIX] 깃허브 api undefined 오류 해결
gaeulzzang Aug 1, 2025
b20bb98
#112 [FIX] 워크스페이스 팀 생성 undefined 오류 해결
gaeulzzang Aug 1, 2025
36cd616
#112 [FIX] 워크스페이스 팀 생성 undefined 오류 해결
gaeulzzang Aug 1, 2025
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
31 changes: 31 additions & 0 deletions src/apis/alarm/useDeleteAlarms.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { useMutation } from '@tanstack/react-query';
import { queryKey } from '../../constants/queryKey';
import queryClient from '../../utils/queryClient';
import type { RequestAlarmListDto } from '../../types/alarm';
import type { CommonResponse } from '../../types/common';
import { axiosInstance } from '../axios';

// notification/NotiHome.tsx
const deleteAlarmItem = async (alarmIds: RequestAlarmListDto): Promise<CommonResponse> => {
try {
const { data } = await axiosInstance.delete(`api/alarms`, {
data: alarmIds,
});
return data;
} catch (error) {
console.error('Error deleting alarm item:', error);
throw error;
}
};

export const useDeleteAlarms = () => {
return useMutation({
mutationFn: deleteAlarmItem,
onSuccess(data, variables) {
console.log('Alarms deleted successfully:', data);
queryClient.invalidateQueries({
queryKey: [queryKey.NOTI_LIST, variables.alarmIds],
});
},
});
};
30 changes: 30 additions & 0 deletions src/apis/alarm/useGetAlarmList.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { useQuery } from '@tanstack/react-query';
import type { PaginationDto } from '../../types/common';
import type { AlarmType } from '../../types/listItem';
import { queryKey } from '../../constants/queryKey';
import type { ResponseAlarmDto } from '../../types/alarm';
import { axiosInstance } from '../axios';

// notification/NotiHome.tsx
const getAlarmList = async (
alarmtype: AlarmType,
paginationDto: PaginationDto
): Promise<ResponseAlarmDto> => {
try {
const { query } = paginationDto;
const { data } = await axiosInstance.get(`api/alarms/${alarmtype}`, {
params: { query },
});
return data;
} catch (error) {
console.error('Error fetching alarm list:', error);
throw error;
}
};

export const useGetAlarmList = (alarmtype: AlarmType, params: PaginationDto) => {
return useQuery({
queryKey: [queryKey.NOTI_LIST, alarmtype, params],
queryFn: () => getAlarmList(alarmtype, params),
});
};
29 changes: 29 additions & 0 deletions src/apis/alarm/usePatchAlarms.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import { useMutation } from '@tanstack/react-query';
import queryClient from '../../utils/queryClient';
import { queryKey } from '../../constants/queryKey';
import type { RequestAlarmListDto } from '../../types/alarm';
import type { CommonResponse } from '../../types/common';
import { axiosInstance } from '../axios';

// notification/NotiHome.tsx
const patchAlarmItem = async ({ alarmId }: RequestAlarmListDto): Promise<CommonResponse> => {
try {
const { data } = await axiosInstance.patch(`api/alarms/${alarmId}`);
return data;
} catch (error) {
console.error('Error patching alarm item:', error);
throw error;
}
};

export const usePatchAlarms = () => {
return useMutation({
mutationFn: patchAlarmItem,
onSuccess(data, variables) {
console.log('Alarm patched successfully:', data);
queryClient.invalidateQueries({
queryKey: [queryKey.NOTI_LIST, variables.alarmId],
});
},
});
};
35 changes: 35 additions & 0 deletions src/apis/external/useDeleteExternals.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { useMutation } from '@tanstack/react-query';
import queryClient from '../../utils/queryClient';
import { queryKey } from '../../constants/queryKey';
import type { RequestExternalListDto } from '../../types/external';
import type { CommonResponse } from '../../types/common';
import { axiosInstance } from '../axios';

// external/externalHome.tsx
export const deleteExternalItem = async ({
teamId,
externalIds,
}: RequestExternalListDto): Promise<CommonResponse> => {
try {
const { data } = await axiosInstance.delete(`/api/teams/${teamId}/externals`, {
data: externalIds,
});

return data;
} catch (error) {
console.error('Error deleting external item:', error);
throw error;
}
};

export const useDeleteExternals = () => {
return useMutation({
mutationFn: deleteExternalItem,
onSuccess(data, variables) {
console.log('Externals deleted successfully:', data);
queryClient.invalidateQueries({
queryKey: [queryKey.EXTERNAL_LIST, variables.teamId],
});
},
});
};
30 changes: 30 additions & 0 deletions src/apis/external/useGetExternalList.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { useQuery } from '@tanstack/react-query';
import { queryKey } from '../../constants/queryKey';
import type { PaginationDto } from '../../types/common';
import type { RequestExternalListDto, ResponseExternalDto } from '../../types/external';
import { axiosInstance } from '../axios';

// external/externalHome.tsx
const getExternalList = async (
{ teamId }: RequestExternalListDto,
paginationDto: PaginationDto
): Promise<ResponseExternalDto> => {
try {
const { data } = await axiosInstance.get(`/api/teams/${teamId}/externals`, {
params: paginationDto,
});

console.log('외부 연동 리스트 데이터 불러오기 성공', data);
return data;
} catch (error) {
console.error('Error fetching external list:', error);
throw error;
}
};

export const useGetExternalList = (teamId: string, params: PaginationDto) => {
return useQuery({
queryKey: [queryKey.EXTERNAL_LIST, teamId, params],
queryFn: () => getExternalList({ teamId }, params),
});
};
4 changes: 3 additions & 1 deletion src/apis/external/useGetGithubConnect.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,10 @@ interface GetGithubConnectResponse {
const getGithubConnect = async (teamId: number): Promise<GetGithubConnectResponse> => {
try {
const response = await axiosInstance.get<CommonResponse<GetGithubConnectResponse>>(
`/github/connect/${teamId}`
`/github/connect`,
{ params: { teamId: teamId } }
);
if (!response.data.result) return Promise.reject(response);
return response.data.result;
} catch (error) {
console.error('Github 연동 실패', error);
Expand Down
32 changes: 32 additions & 0 deletions src/apis/goal/useDeleteGoals.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { useMutation } from '@tanstack/react-query';
import queryClient from '../../utils/queryClient';
import { queryKey } from '../../constants/queryKey';
import type { RequestGoalListDto } from '../../types/goal';
import type { CommonResponse } from '../../types/common';
import { axiosInstance } from '../axios';

// goal/GoalHome.tsx
const deleteGoalItem = async ({ teamId, goalIds }: RequestGoalListDto): Promise<CommonResponse> => {
try {
const { data } = await axiosInstance.delete(`/api/teams/${teamId}/goals`, {
data: { goalIds },
});

return data;
} catch (error) {
console.error('Error deleting goal item:', error);
throw error;
}
};

export const useDeleteGoals = () => {
return useMutation({
mutationFn: deleteGoalItem,
onSuccess(data, variables) {
console.log('Goals deleted successfully:', data);
queryClient.invalidateQueries({
queryKey: [queryKey.GOAL_LIST, variables.teamId],
});
},
});
};
29 changes: 29 additions & 0 deletions src/apis/goal/useGetGoalList.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import { useQuery } from '@tanstack/react-query';
import { queryKey } from '../../constants/queryKey';
import type { PaginationDto } from '../../types/common';
import type { RequestGoalListDto, ResponseGoalDto } from '../../types/goal';
import { axiosInstance } from '../axios';

// goal/GoalHome.tsx
const getGoalList = async (
{ teamId }: RequestGoalListDto,
paginationDto: PaginationDto
): Promise<ResponseGoalDto> => {
try {
const { data } = await axiosInstance.get(`/api/teams/${teamId}/goals`, {
params: paginationDto,
});

return data;
} catch (error) {
console.error('Error fetching goal list:', error);
throw error;
}
};

export const useGetGoalList = (teamId: string, params: PaginationDto) => {
return useQuery({
queryKey: [queryKey.GOAL_LIST, teamId, params],
queryFn: () => getGoalList({ teamId }, params),
});
Comment on lines +25 to +28

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: useInfiniteQuery 사용해서 무한 스크롤로 구현하는게 좋지 않을까요?

};
35 changes: 35 additions & 0 deletions src/apis/issue/useDeleteIssues.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { useMutation } from '@tanstack/react-query';
import queryClient from '../../utils/queryClient';
import { queryKey } from '../../constants/queryKey';
import type { RequestIssueListDto } from '../../types/issue';
import type { CommonResponse } from '../../types/common';
import { axiosInstance } from '../axios';

//issue/IssueHome.tsx
const deleteIssueItem = async ({
teamId,
issueIds,
}: RequestIssueListDto): Promise<CommonResponse> => {
try {
const { data } = await axiosInstance.delete(`/api/teams/${teamId}/issues`, {
data: { issueIds },
});

return data;
} catch (error) {
console.error('Error deleting issue item:', error);
throw error;
}
};

export const useDeleteIssues = () => {
return useMutation({
mutationFn: deleteIssueItem,
onSuccess(data, variables) {
console.log('Issues deleted successfully:', data);
queryClient.invalidateQueries({
queryKey: [queryKey.ISSUE_LIST, variables.teamId],
});
},
});
};
29 changes: 29 additions & 0 deletions src/apis/issue/useGetIssueList.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import { useQuery } from '@tanstack/react-query';
import { queryKey } from '../../constants/queryKey';
import type { PaginationDto } from '../../types/common';
import type { RequestIssueListDto, ResponseIssueDto } from '../../types/issue';
import { axiosInstance } from '../axios';

//issue/IssueHome.tsx
const getIssueList = async (
{ teamId }: RequestIssueListDto,
paginationDto: PaginationDto
): Promise<ResponseIssueDto> => {
try {
const { data } = await axiosInstance.get(`/api/teams/${teamId}/issues`, {
params: paginationDto,
});

return data;
} catch (error) {
console.error('Error fetching issue list:', error);
throw error;
}
};

export const useGetIssueList = (teamId: string, params: PaginationDto) => {
return useQuery({
queryKey: [queryKey.ISSUE_LIST, teamId, params],
queryFn: () => getIssueList({ teamId }, params),
});
};
1 change: 1 addition & 0 deletions src/apis/setting/usePostWorkspaceTeam.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ const postWorkspaceTeam = async (
'/api/workspace/setting/teams',
{ name: name, memberId: memberId }
);
if (!response.data.result) return Promise.reject(response);
return response.data.result;
} catch (error) {
console.error('워크스페이스 팀 생성 실패', error);
Expand Down
22 changes: 16 additions & 6 deletions src/components/ListView/ExternalItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ export const ExternalItem = (props: Partial<ExternalItemProps>) => {

const {
variant = 'default',
onItemClick,
showCheckbox,
checked,
onCheckChange,
Expand All @@ -65,16 +66,21 @@ export const ExternalItem = (props: Partial<ExternalItemProps>) => {
const displayFields = getFilter(filter);

const handleItemClick = (e: React.MouseEvent) => {
if (!showCheckbox) return;
if (!showCheckbox) {
onItemClick?.(e);
return;
}
if ((e.target as HTMLElement).closest('label')) return;
onCheckChange?.(!checked);
};

const dateColor = variant === 'notification' ? (checked ? '' : 'text-red-400') : '';

const dateColor = variant === 'notification' ? 'text-error-400' : '';
return (
<div
className={`font-body-r flex justify-between items-center h-[5.6rem] px-[3.2rem] -mx-[3.2rem] ${showCheckbox && checked ? 'bg-gray-300' : ''}`}
className={`
font-body-r flex justify-between items-center h-[5.6rem] px-[3.2rem] -mx-[3.2rem]
${checked ? 'bg-gray-300' : variant === 'read' ? 'bg-gray-200' : ''}
`}
onClick={handleItemClick}
tabIndex={showCheckbox ? 0 : -1}
style={{ cursor: showCheckbox ? 'pointer' : 'default' }}
Expand Down Expand Up @@ -111,7 +117,7 @@ export const ExternalItem = (props: Partial<ExternalItemProps>) => {
</div>
<div className="flex gap-[3.2rem] items-center">
{/* 상태 */}
{displayFields.includes('status') && (
{displayFields.includes('state') && (
<div className="flex gap-[0.8rem] items-center">
{getStatusIcon(status)}
<div className="truncate">{STATUS_LABELS[status]}</div>
Expand All @@ -136,7 +142,11 @@ export const ExternalItem = (props: Partial<ExternalItemProps>) => {
{/* 기한 */}
<div className="flex gap-[0.8rem] items-center whitespace-nowrap">
<img src={dateIcon} alt="date" className="w-[1.6rem] h-[1.6rem] m-[0.4rem]" />
<div className={`${dateColor}`}>{formatGoalDate(deadline?.start, deadline?.end)}</div>
<div className={dateColor}>
{typeof deadline === 'string'
? formatGoalDate(deadline, deadline)
: formatGoalDate(deadline.start, deadline.end)}
</div>
</div>
{/* 담당자 */}
{displayFields.includes('manage') && <ManagerAvatar managers={managers.info} />}
Expand Down
Loading