Skip to content

Commit 41f03f2

Browse files
Api(client): Dashboard category 전체 조회 & 생성 API 연결 (#73)
* feat: dashboard axios 함수 구현 * feat: dashboard categories 전체 조회 query 작성 * api: dashboard categories 전체 조회 api 연결 * chore: axios, queries 파일 apis 폴더에 분리 * feat: 카테고리 생성 api axios 함수 구현 * feat: 카테고리 생성 api query 함수 구현 * feat: popportal에 onChange interface 추가 및 inputChange 연결 * fix: category dto 수정 * fix: axios 함수 return값 수정 * api: 대시보드 카테고리 생성 api 연결
1 parent c028044 commit 41f03f2

File tree

5 files changed

+88
-26
lines changed

5 files changed

+88
-26
lines changed

apps/client/src/shared/components/sidebar/PopupPortal.tsx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import type { PopupState } from '@shared/hooks/useCategoryPopups';
55
interface Props {
66
popup: PopupState;
77
onClose: () => void;
8+
onChange?: (value: string) => void;
89
onCreateConfirm?: () => void;
910
onEditConfirm?: (id: number, draft?: string) => void;
1011
onDeleteConfirm?: (id: number) => void;
@@ -13,6 +14,7 @@ interface Props {
1314
export default function PopupPortal({
1415
popup,
1516
onClose,
17+
onChange,
1618
onCreateConfirm,
1719
onEditConfirm,
1820
onDeleteConfirm,
@@ -29,6 +31,7 @@ export default function PopupPortal({
2931
title="카테고리 추가하기"
3032
left="취소"
3133
right="추가"
34+
onInputChange={onChange}
3235
placeholder="카테고리 제목을 입력해주세요"
3336
onLeftClick={onClose}
3437
onRightClick={() => onCreateConfirm?.()}

apps/client/src/shared/components/sidebar/Sidebar.tsx

Lines changed: 40 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -10,21 +10,20 @@ import { useSidebarNav } from '@shared/hooks/useSidebarNav';
1010
import { useCategoryPopups } from '@shared/hooks/useCategoryPopups';
1111
import OptionsMenuPortal from './OptionsMenuPortal';
1212
import PopupPortal from './PopupPortal';
13-
14-
const CATEGORIES = [
15-
{ id: 1, label: '일정' },
16-
{ id: 2, label: '공부' },
17-
{ id: 3, label: '운동' },
18-
{ id: 4, label: '취미' },
19-
{ id: 5, label: '기타' },
20-
{ id: 6, label: '기타' },
21-
{ id: 7, label: '기타' },
22-
{ id: 8, label: '기타' },
23-
{ id: 9, label: '기타' },
24-
{ id: 10, label: '기타' },
25-
];
13+
import {
14+
useGetDashboardCategories,
15+
usePostCategory,
16+
} from '@shared/components/sidebar/apis/queries';
17+
import { useState } from 'react';
18+
import { useQueryClient } from '@tanstack/react-query';
2619

2720
export function Sidebar() {
21+
const [newCategoryName, setNewCategoryName] = useState('');
22+
const queryClient = useQueryClient();
23+
24+
const { data: categories } = useGetDashboardCategories();
25+
const { mutate: createCategory } = usePostCategory();
26+
2827
const {
2928
activeTab,
3029
selectedCategoryId,
@@ -35,6 +34,9 @@ export function Sidebar() {
3534
setSelectedCategoryId,
3635
} = useSidebarNav();
3736

37+
const { popup, openCreate, openEdit, openDelete, close } =
38+
useCategoryPopups();
39+
3840
const {
3941
state: menu,
4042
open: openMenu,
@@ -43,11 +45,25 @@ export function Sidebar() {
4345
style,
4446
} = useAnchoredMenu((anchor) => rightOf(anchor, 30));
4547

46-
const { popup, openCreate, openEdit, openDelete, close } =
47-
useCategoryPopups();
48-
4948
const getCategoryName = (id: number | null) =>
50-
CATEGORIES.find((c) => c.id === id)?.label ?? '';
49+
categories?.categories.find((category) => category.id === id)?.name ?? '';
50+
51+
const handleCategoryChange = (name: string) => {
52+
setNewCategoryName(name);
53+
};
54+
55+
const handleCreateCategory = () => {
56+
createCategory(newCategoryName, {
57+
onSuccess: () => {
58+
handleCategoryChange('');
59+
queryClient.invalidateQueries({ queryKey: ['dashboardCategories'] });
60+
close();
61+
},
62+
onError: (error) => {
63+
console.error('카테고리 생성 실패:', error);
64+
},
65+
});
66+
};
5167

5268
return (
5369
<aside className="bg-white-bg sticky top-0 h-screen w-[24rem] border-r border-gray-300">
@@ -86,12 +102,12 @@ export function Sidebar() {
86102
}}
87103
>
88104
<ul className="bg-none">
89-
{CATEGORIES.map((c) => (
105+
{categories?.categories?.map((category) => (
90106
<CategoryItem
91-
key={c.id}
92-
id={c.id}
93-
label={c.label}
94-
active={selectedCategoryId === c.id}
107+
key={category.id}
108+
id={category.id}
109+
label={category.name}
110+
active={selectedCategoryId === category.id}
95111
onClick={(id) => {
96112
closeMenu();
97113
selectCategory(id);
@@ -132,10 +148,8 @@ export function Sidebar() {
132148
<PopupPortal
133149
popup={popup}
134150
onClose={close}
135-
onCreateConfirm={() => {
136-
// TODO: 생성 API
137-
close();
138-
}}
151+
onChange={handleCategoryChange}
152+
onCreateConfirm={handleCreateCategory}
139153
onEditConfirm={() => {
140154
// TODO: 수정 API
141155
close();
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import apiRequest from '@shared/apis/axiosInstance';
2+
3+
export const getDashboardCategories = async () => {
4+
const { data } = await apiRequest.get('/api/v1/categories/dashboard');
5+
return data.data;
6+
};
7+
8+
export const postCategory = async (categoryName: string) => {
9+
const response = await apiRequest.post('/api/v1/categories', {
10+
categoryName,
11+
});
12+
return response;
13+
};
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import { useMutation, useQuery, UseQueryResult } from '@tanstack/react-query';
2+
import {
3+
getDashboardCategories,
4+
postCategory,
5+
} from '@shared/components/sidebar/apis/axios';
6+
import { AxiosError } from 'axios';
7+
import { DashboardCategoriesResponse } from '@shared/components/sidebar/types/api';
8+
9+
export const useGetDashboardCategories = (): UseQueryResult<
10+
DashboardCategoriesResponse,
11+
AxiosError
12+
> => {
13+
return useQuery({
14+
queryKey: ['dashboardCategories'],
15+
queryFn: () => getDashboardCategories(),
16+
});
17+
};
18+
19+
export const usePostCategory = () => {
20+
return useMutation({
21+
mutationFn: (categoryName: string) => postCategory(categoryName),
22+
});
23+
};
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
export interface Category {
2+
id: number;
3+
name: string;
4+
unreadCount: number;
5+
}
6+
7+
export interface DashboardCategoriesResponse {
8+
categories: Category[];
9+
}

0 commit comments

Comments
 (0)