Skip to content

Commit

Permalink
feature-046: 카테고리 삭제, 추가 API 수정
Browse files Browse the repository at this point in the history
  • Loading branch information
gs0428 committed Feb 9, 2024
1 parent f3cd503 commit 560bfd0
Show file tree
Hide file tree
Showing 11 changed files with 102 additions and 92 deletions.
18 changes: 5 additions & 13 deletions src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { useRecoilValue, useSetRecoilState } from 'recoil';
import { useRecoilValue } from 'recoil';
import { BrowserRouter, Navigate, Route, Routes } from 'react-router-dom';
import { ThemeProvider } from 'styled-components';

Expand Down Expand Up @@ -30,22 +30,14 @@ import { ToastList } from './components/common';
// Store
import { userTokenState } from './stores/user';
import { useEffect } from 'react';
import { categoryState } from './stores/category';
import { getCategories } from './apis/category';
import handleCategory from './utils/handleCategory';
import useUpdateCategories from './hooks/useUpdateCategories';

const App = () => {
const setCategories = useSetRecoilState(categoryState);
const userToken = useRecoilValue(userTokenState);
const { initializeCategory } = handleCategory();
const { updateCategories } = useUpdateCategories();
useEffect(() => {
userToken &&
getCategories()
.then((res) => {
setCategories(initializeCategory(res));
})
.catch((err) => console.log(err));
}, [userToken]);
userToken && updateCategories();
}, [updateCategories, userToken]);

return (
<ThemeProvider theme={theme}>
Expand Down
37 changes: 26 additions & 11 deletions src/apis/category.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import { APIResponse } from '@/models/config/axios';
import axiosInstance from './config/instance';
import { ICreateCategoryResponse } from '@/models/category';

// 모든 카테고리 가져오는 API
export const getCategories = async () => {
const response = await axiosInstance.get('/category');
return response.data.result;
return response.data;
};

// 카테고리 이동1 API
Expand All @@ -14,13 +16,13 @@ export const putSubToOtherTop = async (
const response = await axiosInstance.put(
`/category/${categoryId}/${topCategoryId}`,
);
return response.data.result;
return response.data;
};

// 카테고리 이동2 API
export const putSubToTop = async (categoryId: number) => {
const response = await axiosInstance.put(`/category/up/${categoryId}`);
return response.data.result;
return response.data;
};

// 카테고리 이동3 API
Expand All @@ -31,17 +33,30 @@ export const putTopToOtherTop = async (
const response = await axiosInstance.put(
`/category/down/${categoryId}/${topCategoryId}`,
);
return response.data.result;
return response.data;
};

// 상위 카테고리 추가 API
export const postTopCategroy = async () => {
const response = await axiosInstance.post('/category');
return response.data.result;
export const postTopCategroy = async (
name: string,
): Promise<APIResponse<ICreateCategoryResponse>> => {
const response = await axiosInstance.post('/category', { name });
return response.data;
};

// 상위 카테고리 추가 API
export const postSubCategroy = async (topCategoryId: number) => {
const response = await axiosInstance.post(`/category/${topCategoryId}`);
return response.data.result;
// 하위 카테고리 추가 API
export const postSubCategroy = async (
name: string,
topCategoryId: number,
): Promise<APIResponse<ICreateCategoryResponse>> => {
const response = await axiosInstance.post(`/category/${topCategoryId}`, {
name,
});
return response.data;
};

// 카테고리 삭제 API
export const deleteCategory = async (category_id: number) => {
const response = await axiosInstance.delete(`/category/${category_id}`);
return response.data;
};
3 changes: 3 additions & 0 deletions src/components/layout/sideBar/SubCategory.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ interface ISubCategoryProps {
setIsDeleteModalOpen: React.Dispatch<React.SetStateAction<boolean>>;
grabedCategory: React.MutableRefObject<ISubFolderProps | undefined>;
putCategoryFolder: () => void;
setCategoryId: React.Dispatch<React.SetStateAction<number | null>>;
}

const SubCategory = ({
Expand All @@ -25,6 +26,7 @@ const SubCategory = ({
setIsDeleteModalOpen,
grabedCategory,
putCategoryFolder,
setCategoryId,
}: ISubCategoryProps) => {
const [subFolderOptionModalOpen, setSubFolderOptionModalOpen] =
useState(false);
Expand All @@ -45,6 +47,7 @@ const SubCategory = ({
if (option === '수정') {
setIsEditing(true);
} else if (option === '삭제') {
setCategoryId(categoryId);
setIsDeleteModalOpen(true);
}
setSubFolderOptionModalOpen(false);
Expand Down
4 changes: 4 additions & 0 deletions src/components/layout/sideBar/TopCategory.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ interface ITopCategoryProps {
dropedCategory: React.MutableRefObject<number | undefined>;
setIsSubCategoryModalOpen: React.Dispatch<React.SetStateAction<boolean>>;
setIsDeleteModalOpen: React.Dispatch<React.SetStateAction<boolean>>;
setCategoryId: React.Dispatch<React.SetStateAction<number | null>>;
putCategoryFolder: () => void;
}

Expand All @@ -36,6 +37,7 @@ const TopCategory = ({
setIsSubCategoryModalOpen,
setIsDeleteModalOpen,
putCategoryFolder,
setCategoryId,
}: ITopCategoryProps) => {
const [folderOptionModalOpen, setFolderOptionModalOpen] = useState(false);
const [folderOptionModalRef] = useOutsideClick<HTMLDivElement>(() =>
Expand Down Expand Up @@ -66,6 +68,7 @@ const TopCategory = ({
setIsEditing(true);
setBeforeEdit(edit);
} else if (option === '삭제') {
setCategoryId(categoryId);
setIsDeleteModalOpen(true);
}
setFolderOptionModalOpen(false);
Expand Down Expand Up @@ -176,6 +179,7 @@ const TopCategory = ({
setIsDeleteModalOpen={setIsDeleteModalOpen}
grabedCategory={grabedCategory}
putCategoryFolder={putCategoryFolder}
setCategoryId={setCategoryId}
key={`${subFolder.name}-${subFolder.categoryId}`}
/>
))}
Expand Down
35 changes: 17 additions & 18 deletions src/components/layout/sideBar/UserMode.tsx
Original file line number Diff line number Diff line change
@@ -1,30 +1,33 @@
import LookSvg from '@/assets/icons/look.svg?react';
import * as UserModeStyle from '@/styles/layout/sideBar/UserMode.style';
import { useLocation } from 'react-router-dom';
import { useRecoilState, useRecoilValue } from 'recoil';
import { useLocation, useNavigate } from 'react-router-dom';
import { useRecoilValue } from 'recoil';
import { topCategoryModalState } from '@/stores/modal';
import AddCategoryModal from '@/components/modals/AddCategoryModal';
import SuccessAddCategoryModal from '@/components/modals/SuccessAddCategoryModal';
import { useRef, useState } from 'react';
import TopCategory from './TopCategory';
import DeleteCategory from './DeleteCategory';
import handleCategory from '@/utils/handleCategory';
import { categoryState } from '@/stores/category';
import { IFolderProps, ISubFolderProps } from 'types/category';
import useMoveCategory from '@/hooks/useMoveCategory';
import { deleteCategory } from '@/apis/category';
import useUpdateCategories from '@/hooks/useUpdateCategories';

const UserMode = () => {
const isTopCategoryModalOpen = useRecoilValue(topCategoryModalState);
const [isSuccessAddCategoryModalOpen, setIsSuccessAddCategoryModalOpen] =
useState(false);
const [isDeleteModalOpen, setIsDeleteModalOpen] = useState(false);
const [isSubAdded, setIsSubAdded] = useState(false);
const [categoryName, setCategoryName] = useState('');
const [categories, setCategories] = useRecoilState(categoryState);
const [categoryId, setCategoryId] = useState<number | null>(null);
const categories = useRecoilValue(categoryState);
const [isSubCategoryModalOpen, setIsSubCategoryModalOpen] = useState(false);
const grabedCategory = useRef<ISubFolderProps | undefined>(undefined);
const dropedCategory = useRef<number | undefined>(undefined);
const { deleteSubCategory } = handleCategory();
const navigate = useNavigate();

const { updateCategories } = useUpdateCategories();

const { subToOtherTop, subToTop, topToOtherTop } = useMoveCategory();

Expand All @@ -34,14 +37,11 @@ const UserMode = () => {
const topId = Number(href[0]);
const subId = Number(href[1]);

const handleDeleteCategory = () => {
if (!isNaN(subId)) {
setCategories([...deleteSubCategory(categories, topId, subId)]);
} else {
const newData = categories.filter(
(myFolder) => myFolder.categoryId !== topId,
);
setCategories([...newData]);
const handleDeleteCategory = async () => {
const response = await deleteCategory(categoryId!);
if (response.isSuccess) {
updateCategories();
navigate('/category/recent');
}
setIsDeleteModalOpen(false);
};
Expand Down Expand Up @@ -85,6 +85,7 @@ const UserMode = () => {
setIsSubCategoryModalOpen={setIsSubCategoryModalOpen}
setIsDeleteModalOpen={setIsDeleteModalOpen}
putCategoryFolder={putCategoryFolder}
setCategoryId={setCategoryId}
key={`${category.name}-${category.categoryId}`}
/>
))}
Expand All @@ -96,8 +97,8 @@ const UserMode = () => {
categoryName={categoryName}
setCategoryName={setCategoryName}
setIsSuccessAddCategoryModalOpen={setIsSuccessAddCategoryModalOpen}
setIsSubAdded={setIsSubAdded}
topCategoryId={topId}
setCategoryId={setCategoryId}
/>
)}
{isDeleteModalOpen && (
Expand All @@ -111,9 +112,7 @@ const UserMode = () => {
categoryName={categoryName}
setCategoryName={setCategoryName}
setIsSuccessAddCategoryModalOpen={setIsSuccessAddCategoryModalOpen}
isSubAdded={isSubAdded}
setIsSubAdded={setIsSubAdded}
topId={topId}
categoryId={categoryId}
/>
)}
</>
Expand Down
23 changes: 17 additions & 6 deletions src/components/modals/AddCategoryModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,13 @@ import {
import { ICommonModalProps } from 'types/modal';
import handleEdit from '@/utils/handleEdit';
import { postSubCategroy, postTopCategroy } from '@/apis/category';
import useUpdateCategories from '@/hooks/useUpdateCategories';

interface IAddTopCategoryModalProps extends ICommonModalProps {
isTopCategoryModalOpen: boolean;
setIsSubCategoryModalOpen: React.Dispatch<React.SetStateAction<boolean>>;
setIsSubAdded: React.Dispatch<React.SetStateAction<boolean>>;
topCategoryId: number;
setCategoryId: React.Dispatch<React.SetStateAction<number | null>>;
}

const AddCategoryModal = ({
Expand All @@ -27,10 +28,11 @@ const AddCategoryModal = ({
categoryName,
setCategoryName,
setIsSuccessAddCategoryModalOpen,
setIsSubAdded,
topCategoryId,
setCategoryId,
}: IAddTopCategoryModalProps) => {
const setIsTopCategoryModalOpen = useSetRecoilState(topCategoryModalState);
const { updateCategories } = useUpdateCategories();

const [isFocused, setIsFocused] = useState(false);

Expand All @@ -42,19 +44,28 @@ const AddCategoryModal = ({
isTopCategoryModalOpen
? setIsTopCategoryModalOpen(false)
: setIsSubCategoryModalOpen(false);
!isTopCategoryModalOpen && setIsSubAdded(true);
};

const [topCategoryModalRef] = useOutsideClick<HTMLDivElement>(onCloseModal);

const handleInputCategoryName = (e: React.ChangeEvent<HTMLInputElement>) =>
handleEdit(e, setCategoryName);

const addCategory = (e: React.MouseEvent) => {
isTopCategoryModalOpen ? postTopCategroy() : postSubCategroy(topCategoryId);
const addCategory = async (e: React.MouseEvent) => {
const response = isTopCategoryModalOpen
? await postTopCategroy(categoryName)
: await postSubCategroy(categoryName, topCategoryId);
if (response.isSuccess) {
updateCategories();
setCategoryId(
isTopCategoryModalOpen
? response.result.categoryId
: response.result.topCategoryId,
);
setIsSuccessAddCategoryModalOpen(true);
}
e.stopPropagation();
onCloseModal();
setIsSuccessAddCategoryModalOpen(true);
};
return (
<BlurBackground>
Expand Down
45 changes: 4 additions & 41 deletions src/components/modals/SuccessAddCategoryModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,58 +7,25 @@ import {
import CloseSvg from '@/assets/icons/close.svg?react';
import * as SuccessAddCategoryStyles from '@/styles/modals/SuccessAddCategoryModal.style';
import { ICommonModalProps } from 'types/modal';
import { useRecoilState } from 'recoil';
import { categoryState } from '@/stores/category';

import FileImage from '@/assets/file.png';

interface ISuccessAddCategory extends ICommonModalProps {
isSubAdded: boolean;
setIsSubAdded: React.Dispatch<React.SetStateAction<boolean>>;
topId: number;
categoryId: number | null;
}

const SuccessAddCategoryModal = ({
categoryName,
setCategoryName,
setIsSuccessAddCategoryModalOpen,
isSubAdded,
setIsSubAdded,
topId,
categoryId,
}: ISuccessAddCategory) => {
const onCloseModal = () => {
setIsSuccessAddCategoryModalOpen(false);
setCategoryName('');
};
const [categories, setCategories] = useRecoilState(categoryState);

const [successAddCategoryModalRef] =
useOutsideClick<HTMLDivElement>(onCloseModal);

const handleGoToCategory = () => {
if (isSubAdded) {
const index = categories.findIndex(
(folder) => folder.categoryId === topId,
);
categories[index].subFolders.push({
name: categoryName,
categoryId: categories[index].categoryId,
topCategoryId: topId,
});
} else {
setCategories([
...categories,
{
categoryId: categories.length + 1,
name: categoryName,
topCategoryId: null,
subFolders: [],
},
]);
}
setIsSubAdded(false);
onCloseModal();
};
return (
<BlurBackground>
<CommonCategoryContainer ref={successAddCategoryModalRef}>
Expand All @@ -73,12 +40,8 @@ const SuccessAddCategoryModal = ({
생성 완료!
</SuccessAddCategoryStyles.Title>
<SuccessAddCategoryStyles.GoToCategoryButton
to={
isSubAdded
? `/category/${topId}`
: `/category/${categories.length + 1}`
}
onClick={handleGoToCategory}
to={`/category/${categoryId}`}
onClick={onCloseModal}
>
보러가기
</SuccessAddCategoryStyles.GoToCategoryButton>
Expand Down
Loading

0 comments on commit 560bfd0

Please sign in to comment.