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
14 changes: 14 additions & 0 deletions src/api/inquiry.api.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { httpClient } from './http.api';

export const postInquiry = async (formData: FormData) => {
try {
const response = await httpClient.post('/inquiry', formData, {
headers: {
'Content-Type': 'multipart/form-data',
},
});
console.log(response);
} catch (e) {
console.log('문의하기 에러', e);
}
};
Comment on lines +3 to +14
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

에러 처리 및 반환 값 개선이 필요합니다

현재 API 함수는 console.log를 사용하여 응답과 오류를 기록하고 있으며, 반환 값이 없습니다. 이는 호출하는 컴포넌트에서 성공/실패 여부를 확인하기 어렵게 만듭니다.

다음과 같이 개선하는 것을 추천합니다:

-export const postInquiry = async (formData: FormData) => {
+export const postInquiry = async (formData: FormData): Promise<any> => {
  try {
    const response = await httpClient.post('/inquiry', formData, {
      headers: {
        'Content-Type': 'multipart/form-data',
      },
    });
-    console.log(response);
+    return response.data;
  } catch (e) {
-    console.log('문의하기 에러', e);
+    console.error('문의하기 에러', e);
+    throw e;
  }
};

이렇게 수정하면:

  1. 함수가 응답 데이터를 반환하게 되어 호출하는 측에서 사용할 수 있습니다.
  2. 에러가 발생하면 더 명확하게 로깅하고 상위로 전파하여 호출하는 측에서 처리할 수 있게 됩니다.
  3. Promise의 반환 타입을 명시하여 타입 안전성이 향상됩니다.
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
export const postInquiry = async (formData: FormData) => {
try {
const response = await httpClient.post('/inquiry', formData, {
headers: {
'Content-Type': 'multipart/form-data',
},
});
console.log(response);
} catch (e) {
console.log('문의하기 에러', e);
}
};
export const postInquiry = async (formData: FormData): Promise<any> => {
try {
const response = await httpClient.post('/inquiry', formData, {
headers: {
'Content-Type': 'multipart/form-data',
},
});
return response.data;
} catch (e) {
console.error('문의하기 에러', e);
throw e;
}
};

2 changes: 1 addition & 1 deletion src/components/common/header/Header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ function Header() {
<Link to={ROUTES.manageProjectsRoot}>
<S.Item>공고관리</S.Item>
</Link>
<Link to={ROUTES.support}>
<Link to={ROUTES.inquiry}>
<S.Item>문의하기</S.Item>
</Link>
<Link to='#' onClick={(e) => e.preventDefault()}>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import styled from 'styled-components';
import styled, { css } from 'styled-components';

export const Container = styled.div`
width: 100%;
Expand Down Expand Up @@ -35,14 +35,24 @@ export const SkillTagButtonWrapper = styled.div`
z-index: 1000;
`;

export const SkillTagButton = styled.button`
export const SkillTagButton = styled.button<{ $isOpen: boolean }>`
border-radius: 1.5rem;
width: 100%;
height: 100%;
padding: 0 1rem;
display: flex;
justify-content: space-between;
align-items: center;

svg {
transition: transform 300ms ease-in-out;
transform: rotate(0deg);
${({ $isOpen }) =>
$isOpen &&
css`
transform: rotate(180deg);
`}
}
`;

export const SkillTagBoxWrapper = styled.div`
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,10 @@ export default function FilteringContents() {
return (
<S.Container>
<S.SkillTagButtonWrapper ref={filteringRef}>
<S.SkillTagButton onClick={handleSkillTagBoxToggle}>
<S.SkillTagButton
onClick={handleSkillTagBoxToggle}
$isOpen={skillTagButtonToggle}
>
언어선택
<ChevronDownIcon />
</S.SkillTagButton>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import styled from 'styled-components';
import styled, { css } from 'styled-components';

export const Container = styled.div``;

Expand All @@ -16,14 +16,24 @@ export const RefWrapper = styled.div`
border-radius: 1.5rem;
`;

export const DefaultValueButton = styled.button`
export const DefaultValueButton = styled.button<{ $isOpen: boolean }>`
width: 100%;
height: 100%;
display: flex;
justify-content: space-between;
align-items: center;
padding: 0 1rem;
border-radius: 1.5rem;

svg {
transition: transform 300ms ease-in-out;
transform: rotate(0deg);
${({ $isOpen }) =>
$isOpen &&
css`
transform: rotate(180deg);
`}
}
`;

export const SelectWrapper = styled.div`
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,10 @@ export default function Filtering({ selects, defaultValue }: FilteringProps) {
<S.Container>
<S.Wrapper ref={filteringRef}>
<S.RefWrapper>
<S.DefaultValueButton onClick={handleDropDownToggle}>
<S.DefaultValueButton
onClick={handleDropDownToggle}
$isOpen={dropDownToggle}
>
{changeValue}
<ChevronDownIcon />
</S.DefaultValueButton>
Expand Down
2 changes: 1 addition & 1 deletion src/components/mypage/ContentTab.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { useEffect, useState } from 'react';
import * as S from './ContentTab.styled';
import { Link, Outlet, useLocation } from 'react-router-dom';
import { ROUTES } from '../../constants/routes';
import MovedInquiredLink from '../common/customerService/MoveInquiredLink';
import MovedInquiredLink from '../../pages/customerService/MoveInquiredLink';

interface Filter {
title: string;
Expand Down
4 changes: 2 additions & 2 deletions src/components/mypage/activityLog/ActivityLog.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { activityFilter } from '../../../constants/myPageFilter';
import { ACTIVITY_FILTER } from '../../../constants/myPageFilter';
import ContentTab from '../ContentTab';

export default function ActivityLog() {
return (
<>
<ContentTab $justifyContent='space-around' filter={activityFilter} />
<ContentTab $justifyContent='space-around' filter={ACTIVITY_FILTER} />
</>
);
}
4 changes: 2 additions & 2 deletions src/components/mypage/notifications/Notifications.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { notificationFilter } from '../../../constants/myPageFilter';
import { NOTIFICATION_FILTER } from '../../../constants/myPageFilter';
import ContentTab from '../ContentTab';

export default function Notifications() {
return (
<ContentTab $justifyContent='space-between' filter={notificationFilter} />
<ContentTab $justifyContent='space-between' filter={NOTIFICATION_FILTER} />
);
}
12 changes: 6 additions & 6 deletions src/components/userPage/joinedProject/UserJoinProject.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,9 @@ const UserJoinProject = () => {
return (
<S.Section>
<S.Wrapper>
<S.TitleWrapper>
<Title size='semiLarge'>참여한 프로젝트 리스트</Title>
</S.TitleWrapper>
<S.FilterWrapper>
<S.FilterTitle>참여한 프로젝트 리스트</S.FilterTitle>
</S.FilterWrapper>
{userJoinedProjectListData?.acceptedProjects &&
userJoinedProjectListData?.acceptedProjects?.length > 0 ? (
<S.Container>
Expand All @@ -44,9 +44,9 @@ const UserJoinProject = () => {
)}
</S.Wrapper>
<S.Wrapper>
<S.TitleWrapper>
<Title size='semiLarge'>기획한 프로젝트 리스트</Title>
</S.TitleWrapper>
<S.FilterWrapper>
<S.FilterTitle>기획한 프로젝트 리스트</S.FilterTitle>
</S.FilterWrapper>
{userJoinedProjectListData?.ownProjects &&
userJoinedProjectListData?.ownProjects?.length > 0 ? (
<S.Container>
Expand Down
14 changes: 14 additions & 0 deletions src/constants/customerService.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
export const INQUIRY_CATEGORY = [
{ title: '사이트 오류' },
{ title: '공고모집' },
{ title: '제안하기' },
{ title: '기타' },
] as const;

export const EMPTY_IMAGE =
'data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7' as const;

export const INQUIRY_MESSAGE = {
categoryDefault: '카테고리',
fileDefault: '선택된 파일이 없습니다.',
};
4 changes: 2 additions & 2 deletions src/constants/myPageFilter.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { ROUTES } from './routes';

export const notificationFilter = [
export const NOTIFICATION_FILTER = [
{ title: '전체', url: ``, id: 0 },
{
title: '지원한 프로젝트',
Expand All @@ -22,7 +22,7 @@ export const notificationFilter = [
},
] as const;

export const activityFilter = [
export const ACTIVITY_FILTER = [
{ title: '내 댓글', url: ROUTES.comments, id: 0 },
{ title: '내 문의글', url: ROUTES.activityInquiries, id: 1 },
] as const;
16 changes: 16 additions & 0 deletions src/hooks/usePostInquiry.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { useMutation, useQueryClient } from '@tanstack/react-query';
import { postInquiry } from '../api/inquiry.api';
import { AxiosError } from 'axios';

export const usePostInquiry = () => {
const queryClient = useQueryClient();

const mutate = useMutation<void, AxiosError, FormData>({
mutationFn: (formData) => postInquiry(formData),
onSuccess: () => {
queryClient.invalidateQueries();
},
});
Comment on lines +8 to +13
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

useMutation이 API 함수의 반환 값과 일치하도록 업데이트가 필요합니다.

현재 postInquiry API 함수는 성공 시 응답을 반환하지 않고 내부에서만 콘솔에 기록하고 있습니다. 또한 에러를 내부에서 캐치하여 상위로 전파하지 않아 useMutation이 에러를 적절히 처리할 수 없습니다.

API 함수를 다음과 같이 수정하는 것을 권장합니다:

export const postInquiry = async (formData: FormData) => {
  const response = await httpClient.post('/inquiry', formData, {
    headers: {
      'Content-Type': 'multipart/form-data',
    },
  });
  return response.data;
};

이렇게 수정하면 에러를 적절히 전파하고 결과 데이터를 반환하여 훅에서 더 효과적으로 처리할 수 있습니다.


return mutate;
};
5 changes: 5 additions & 0 deletions src/models/inquiry.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export interface InquiryFormData {
category: string;
title: string;
content: string;
}
2 changes: 1 addition & 1 deletion src/models/userProject.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ export interface ApiAppliedProject extends ApiCommonType {

export interface SelectUserProject {
acceptedProjects: JoinedProject[];
ownProjects: AppliedProject[];
ownProjects: JoinedProject[];
}

export interface ApiSelectUserProject extends ApiCommonType {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { ROUTES } from '../../../constants/routes';
import { ROUTES } from '../../constants/routes';
import * as S from './MoveInquiredLink.styled';

export default function MovedInquiredLink() {
Expand Down
Loading