Skip to content

Commit

Permalink
🔀 Merge branch 'epic/FE-29' of into merge/FE-29
Browse files Browse the repository at this point in the history
  • Loading branch information
jangmoonwon committed Jul 28, 2024
2 parents e4b2064 + 4ba94c8 commit ae7c00e
Show file tree
Hide file tree
Showing 7 changed files with 489 additions and 0 deletions.
9 changes: 9 additions & 0 deletions src/apis/add.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { AddEpigramRequestType, AddEpigramResponseType } from '@/schema/addEpigram';
import httpClient from '.';

const postEpigram = async (request: AddEpigramRequestType): Promise<AddEpigramResponseType> => {
const response = await httpClient.post<AddEpigramResponseType>('/epigrams', request);
return response.data;
};

export default postEpigram;
42 changes: 42 additions & 0 deletions src/apis/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,48 @@ const httpClient = axios.create({
paramsSerializer: (parameters) => qs.stringify(parameters, { arrayFormat: 'repeat', encode: false }),
});

// NOTE: eslint-disable no-param-reassign 미해결로 인한 설정
httpClient.interceptors.request.use((config) => {
const accessToken = localStorage.getItem('accessToken');
/* eslint-disable no-param-reassign */
if (accessToken) config.headers.Authorization = `Bearer ${accessToken}`;
/* eslint-enable no-param-reassign */
return config;
});

httpClient.interceptors.response.use(
(response) => response,

(error) => {
if (error.response && error.response.status === 401) {
const refreshToken = localStorage.getItem('refreshToken');

if (!refreshToken) {
window.location.href = '/auth/SignIn';
return Promise.reject(error);
}

return httpClient
.post('/auth/refresh-token', null, {
headers: { Authorization: `Bearer ${refreshToken}` },
})
.then((response) => {
const { accessToken, refreshToken: newRefreshToken } = response.data;
localStorage.setItem('accessToken', accessToken);
localStorage.setItem('refreshToken', newRefreshToken);

const originalRequest = error.config;
return httpClient(originalRequest);
})
.catch(() => {
window.location.href = '/auth/SignIn';
return Promise.reject(error);
});
}
return Promise.reject(error);
},
);

export default httpClient;

// NOTE: eslint-disable no-param-reassign 미해결로 인한 설정
Expand Down
24 changes: 24 additions & 0 deletions src/hooks/epigramQueryHook.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { useMutation, useQueryClient } from '@tanstack/react-query';
import { AddEpigramFormType, AddEpigramResponseType } from '@/schema/addEpigram';
import { MutationOptions } from '@/types/query';
import postEpigram from '@/apis/add';
import { AxiosError } from 'axios';

// TODO: 에피그램 수정과 삭제에도 사용 가능하게 훅 수정 예정

const useAddEpigram = (options?: MutationOptions<AddEpigramFormType, AddEpigramResponseType>) => {
const queryClient = useQueryClient();

return useMutation<AddEpigramResponseType, AxiosError, AddEpigramFormType>({
mutationFn: (newEpigram: AddEpigramFormType) => postEpigram(newEpigram),
...options,
onSuccess: (...args) => {
queryClient.invalidateQueries({ queryKey: ['epigrams'] });
if (options?.onSuccess) {
options.onSuccess(...args);
}
},
});
};

export default useAddEpigram;
47 changes: 47 additions & 0 deletions src/hooks/useTagManagementHook.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import { useState } from 'react';
import { UseFormSetValue, UseFormGetValues, UseFormSetError } from 'react-hook-form';
import { AddEpigramFormType } from '@/schema/addEpigram';

// NOTE: setError메서드로 FormField에 에러 설정 가능
const useTagManagement = ({
setValue,
getValues,
setError,
}: {
setValue: UseFormSetValue<AddEpigramFormType>;
getValues: UseFormGetValues<AddEpigramFormType>;
setError: UseFormSetError<AddEpigramFormType>;
}) => {
const [currentTag, setCurrentTag] = useState('');

const handleAddTag = () => {
if (!currentTag || currentTag.length > 10) {
return;
}
const currentTags = getValues('tags') || [];

if (currentTags.length >= 3) {
return;
}
if (currentTags.includes(currentTag)) {
setError('tags', { type: 'manual', message: '이미 저장된 태그입니다.' });
return;
}

setValue('tags', [...currentTags, currentTag]);
setCurrentTag('');
setError('tags', { type: 'manual', message: '' });
};

const handleRemoveTag = (tagToRemove: string) => {
const currentTags = getValues('tags') || [];
setValue(
'tags',
currentTags.filter((tag) => tag !== tagToRemove),
);
};

return { currentTag, setCurrentTag, handleAddTag, handleRemoveTag };
};

export default useTagManagement;
Loading

0 comments on commit ae7c00e

Please sign in to comment.