Skip to content

Commit 73f134b

Browse files
committed
feat(#36):create-help-baord구현
1 parent 7c020f8 commit 73f134b

File tree

17 files changed

+748
-196
lines changed

17 files changed

+748
-196
lines changed

package-lock.json

Lines changed: 247 additions & 140 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
"prettier": "^3.1.0",
2020
"react": "^18",
2121
"react-dom": "^18",
22+
"react-quill": "^2.0.0",
2223
"react-slick": "^0.29.0",
2324
"react-slider": "^2.0.6",
2425
"recoil": "^0.7.7",

src/apis/help.ts

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
import { AxiosResponse } from 'axios';
2+
import instance from './axiosInstance';
3+
4+
type createType = {
5+
head: string;
6+
body: string;
7+
category?: number;
8+
};
9+
10+
const HELP = {
11+
path: '/HelpMeBoard',
12+
13+
//도와줘요 게시판 생성 api [post]
14+
//글 업로드 api
15+
async createHelpBoard({ head, body, category }: createType): Promise<any> {
16+
const result: AxiosResponse = await instance.post<createType>(
17+
`${HELP.path}`,
18+
{
19+
head: head,
20+
body: body,
21+
categoryId: category,
22+
},
23+
);
24+
return result.data;
25+
},
26+
27+
//이미지 업로드 api [post]
28+
async createImg(image: FormData, boardId: number): Promise<any> {
29+
const result: AxiosResponse = await instance.post(
30+
`${HELP.path}/images`,
31+
image,
32+
{
33+
params: {
34+
boardId: boardId,
35+
},
36+
headers: {
37+
'Content-Type': 'multipart/form-data',
38+
},
39+
},
40+
);
41+
return result;
42+
},
43+
};
44+
45+
export default HELP;

src/components/organisms/help-board/HelpCategory.tsx renamed to src/components/common/category/Category.tsx

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,21 @@
11
import styled from 'styled-components';
22

3-
const HelpCategory = () => {
3+
const Category = () => {
44
return (
5-
<CategoryWarpper>
5+
<CategoryWrapper>
66
<CategoryContainer>
77
<CategoryBox>카테고리</CategoryBox>
88
<CategoryBox>카테고리2123123</CategoryBox>
99
<CategoryBox>카테고리3</CategoryBox>
1010
<CategoryBox>카테고리4</CategoryBox>
1111
</CategoryContainer>
12-
</CategoryWarpper>
12+
</CategoryWrapper>
1313
);
1414
};
1515

16-
export default HelpCategory;
16+
export default Category;
1717

18-
const CategoryWarpper = styled.div`
18+
const CategoryWrapper = styled.div`
1919
display: flex;
2020
justify-content: center;
2121
margin: 40px 0px 25px 0px;
Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
import styled from 'styled-components';
2+
import React, { useEffect, useState } from 'react';
3+
import { useRecoilState, useResetRecoilState, useSetRecoilState } from 'recoil';
4+
import useModal from '@/hooks/useModal';
5+
import { categoryList } from './categoryList';
6+
import { CategorySelectAtom } from '@/recoil/atoms/CategorySelectAtom';
7+
import { useRouter } from 'next/router';
8+
9+
const CategorySelector = () => {
10+
const [getCategory, setCategory] = useRecoilState(CategorySelectAtom);
11+
const resetSelect = useResetRecoilState(CategorySelectAtom);
12+
const { isOpenModal, handleModal } = useModal();
13+
const router = useRouter();
14+
15+
/** 게시판 선택 시 */
16+
const handleOnChangeSelectValue = (e: React.MouseEvent<HTMLDivElement>) => {
17+
const target = e.target as HTMLDivElement;
18+
setCategory(target.innerHTML);
19+
};
20+
21+
//다른 페이지로 넘어가도 select초기화
22+
useEffect(() => {
23+
router.events.on('routeChangeStart', resetSelect);
24+
return () => {
25+
router.events.off('routeChangeStart', resetSelect);
26+
};
27+
}, []);
28+
29+
return (
30+
<>
31+
<SelectBox onClick={handleModal}>
32+
<Label>{getCategory ? getCategory : '카테고리'}</Label>
33+
<SelectOptions show={`${isOpenModal}`}>
34+
{categoryList.map((list) => {
35+
return (
36+
<div>
37+
<Option key={list.id} onClick={handleOnChangeSelectValue}>
38+
{list.category}
39+
</Option>
40+
</div>
41+
);
42+
})}
43+
</SelectOptions>
44+
{isOpenModal && (
45+
<DropDown
46+
onClick={(e: React.MouseEvent) => {
47+
e.preventDefault();
48+
49+
if (isOpenModal) {
50+
handleModal();
51+
}
52+
}}></DropDown>
53+
)}
54+
</SelectBox>
55+
</>
56+
);
57+
};
58+
59+
const SelectBox = styled.div`
60+
position: relative;
61+
margin-left: auto;
62+
width: 200px;
63+
padding: 8px;
64+
border-radius: 5px;
65+
background-color: #ffffff;
66+
align-self: center;
67+
box-shadow: 0px 5px 15px rgba(0, 0, 0, 25%);
68+
cursor: pointer;
69+
z-index: 1;
70+
&::before {
71+
content: '⌵';
72+
position: absolute;
73+
top: 1px;
74+
right: 8px;
75+
font-size: 20px;
76+
}
77+
`;
78+
79+
const Label = styled.label`
80+
font-size: 14px;
81+
margin-left: 4px;
82+
text-align: center;
83+
`;
84+
85+
interface SO {
86+
show: string;
87+
}
88+
89+
const SelectOptions = styled.div<SO>`
90+
position: absolute;
91+
list-style: none;
92+
top: 36px;
93+
left: 0;
94+
width: 100%;
95+
overflow: hidden;
96+
height: auto;
97+
max-height: ${(props) => (props.show === 'true' ? 'none' : '0')};
98+
padding: 0;
99+
border-radius: 8px;
100+
background-color: #222222;
101+
color: #fefefe;
102+
`;
103+
104+
const Option = styled.div`
105+
font-size: 14px;
106+
padding: 6px 8px;
107+
transition: background-color 0.2s ease-in;
108+
&:hover {
109+
background-color: #595959;
110+
}
111+
`;
112+
113+
const DropDown = styled.div`
114+
background-color: rgba(f, f, f, 100%);
115+
position: fixed;
116+
z-index: -1;
117+
left: 0px;
118+
top: 0px;
119+
width: 10000px;
120+
height: 1000px;
121+
cursor: auto;
122+
`;
123+
124+
export default CategorySelector;
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
export const categoryList = [
2+
{
3+
id: 1,
4+
category: 'IT',
5+
},
6+
{
7+
id: 2,
8+
category: '요리',
9+
},
10+
{
11+
id: 3,
12+
category: '디자인',
13+
},
14+
{
15+
id: 4,
16+
category: '운동',
17+
},
18+
{
19+
id: 5,
20+
category: '패션/뷰티',
21+
},
22+
{
23+
id: 6,
24+
category: '투자',
25+
},
26+
{
27+
id: 7,
28+
category: '게임',
29+
},
30+
{
31+
id: 8,
32+
category: '음악',
33+
},
34+
{
35+
id: 9,
36+
category: '반려동물',
37+
},
38+
{
39+
id: 10,
40+
category: '회화',
41+
},
42+
{
43+
id: 11,
44+
category: '육아',
45+
},
46+
{
47+
id: 12,
48+
category: '공부',
49+
},
50+
];

src/components/common/header/MainPageHeader.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ const MainPageHeader = () => {
1515
const headerElements = ['멘토', '멘티', '콘텐츠', '고객 지원'];
1616
const translationElements: Record<string, string> = {
1717
멘토: 'mentor',
18-
멘티: 'mentee',
18+
멘티: 'help',
1919
콘텐츠: 'contents',
2020
'고객 지원': 'support',
2121
};

src/components/common/header/SubPageHeader.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ const SubPageHeader = () => {
1515
const headerElements = ['멘토', '멘티', '콘텐츠', '고객 지원'];
1616
const translationElements: Record<string, string> = {
1717
멘토: 'mentor',
18-
멘티: 'mentee',
18+
멘티: 'help',
1919
콘텐츠: 'contents',
2020
'고객 지원': 'support',
2121
};

0 commit comments

Comments
 (0)