Skip to content

Commit 956d313

Browse files
committed
Merge branch 'dev' of https://github.com/oodd-team/oodd-web-react into feat/OD-156
2 parents 348c85f + 937d340 commit 956d313

94 files changed

Lines changed: 813 additions & 771 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

package.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,10 @@
1717
"dayjs": "^1.11.12",
1818
"firebase": "^10.13.0",
1919
"heic2any": "^0.0.4",
20+
"lodash": "^4.17.21",
2021
"react": "^18.3.1",
2122
"react-dom": "^18.3.1",
22-
"react-responsive": "^10.0.0",
23+
"react-responsive": "^10.0.0",
2324
"react-router-dom": "^6.24.1",
2425
"recoil": "^0.7.7",
2526
"recoil-persist": "^5.1.0",
@@ -29,6 +30,7 @@
2930
"swiper": "^11.1.8"
3031
},
3132
"devDependencies": {
33+
"@types/lodash": "^4.17.13",
3234
"@types/node": "^20.14.10",
3335
"@types/react": "^18.3.3",
3436
"@types/react-dom": "^18.3.0",

src/App.tsx

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,9 +57,10 @@ const protectedRoutes = [
5757
// 인증이 필요 없는 페이지 배열
5858
const publicRoutes = [
5959
{ path: '/login', element: <Login /> },
60-
{ path: '/signup', element: <SignUp /> },
6160
{ path: '/login/complete', element: <LoginComplete /> },
62-
{ path: '/terms-agreement', element: <TermsAgreement /> },
61+
62+
{ path: '/signup', element: <SignUp /> },
63+
{ path: '/signup/terms-agreement', element: <TermsAgreement /> },
6364
];
6465

6566
const App: React.FC = () => {

src/components/BottomSheet/OptionsBottomSheet/ReportBottomSheetMenu/index.tsx

Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,15 @@
11
import React, { useState, useRef, useCallback, useEffect } from 'react';
2-
import BottomButton from '../../../BottomButton/index.tsx';
3-
import BottomSheetMenu from '../../../BottomSheetMenu/index.tsx';
4-
import { SheetItemDto } from '../../../BottomSheetMenu/dto.ts';
5-
import { ReportBottomSheetMenuProps } from './dto.ts';
6-
import { InputLayout, ReportBottomSheetMenuWrappar } from './styles.tsx';
2+
import BottomButton from '@components/BottomButton';
3+
import BottomSheetMenu from '@components/BottomSheetMenu';
4+
import { SheetItemDto } from '@components/BottomSheetMenu/dto';
5+
import type { ReportBottomSheetMenuProps } from './dto';
6+
import { InputLayout, ReportBottomSheetMenuWrappar } from './styles';
77

88
const ReportBottomSheetMenu: React.FC<ReportBottomSheetMenuProps> = React.memo(
99
({ onCloseReportSheet, onOpenStatusModal, sendReport, isUserReport }) => {
10+
const [isVisibleTextarea, setIsTextareaVisible] = useState(false);
1011
const [inputValue, setInputValue] = useState('');
1112
const textareaRef = useRef<HTMLTextAreaElement>(null);
12-
const [isVisibleTextarea, setIsTextareaVisible] = useState(false);
13-
14-
useEffect(() => {
15-
if (textareaRef.current) {
16-
textareaRef.current.focus(); // 마운트 또는 업데이트 시 textarea에 포커스 유지
17-
}
18-
}, []);
19-
20-
const handleInputChange = useCallback((e: React.ChangeEvent<HTMLTextAreaElement>) => {
21-
setInputValue(e.target.value);
22-
}, []);
23-
24-
const handleSubmit = useCallback(() => {
25-
sendReport(inputValue);
26-
}, [onCloseReportSheet, onOpenStatusModal]);
2713

2814
// 유저 신고 사유 목록
2915
const userReportItems: SheetItemDto[] = [
@@ -111,6 +97,20 @@ const ReportBottomSheetMenu: React.FC<ReportBottomSheetMenuProps> = React.memo(
11197
},
11298
];
11399

100+
const handleInputChange = useCallback((e: React.ChangeEvent<HTMLTextAreaElement>) => {
101+
setInputValue(e.target.value);
102+
}, []);
103+
104+
const handleSubmit = useCallback(() => {
105+
sendReport(inputValue);
106+
}, [onCloseReportSheet, onOpenStatusModal]);
107+
108+
useEffect(() => {
109+
if (textareaRef.current) {
110+
textareaRef.current.focus(); // 마운트 또는 업데이트 시 textarea에 포커스 유지
111+
}
112+
}, []);
113+
114114
return (
115115
<ReportBottomSheetMenuWrappar>
116116
<BottomSheetMenu items={isUserReport ? userReportItems : postReportItems} />

src/components/BottomSheet/OptionsBottomSheet/dto.ts

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,3 @@ export interface OptionsBottomSheetProps {
99
isBottomSheetOpen: boolean;
1010
onClose: () => void;
1111
}
12-
13-
export interface BlockInfoDto {
14-
userId: number;
15-
friendId: number;
16-
friendName: string;
17-
action: 'toggle';
18-
}

src/components/BottomSheet/OptionsBottomSheet/index.tsx

Lines changed: 45 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,37 +1,39 @@
11
import { useState } from 'react';
2-
import BottomSheet from '..';
3-
import BottomSheetMenu from '../../BottomSheetMenu';
2+
import BottomSheet from '../index';
3+
import BottomSheetMenu from '@components/BottomSheetMenu';
44
import ReportBottomSheetMenu from './ReportBottomSheetMenu';
5-
import Modal from '../../Modal';
5+
import Modal from '@components/Modal';
66

7-
import { OptionsBottomSheetProps } from './dto';
8-
import { BottomSheetProps } from '../dto';
9-
import { BottomSheetMenuProps } from '../../BottomSheetMenu/dto';
10-
import { ReportBottomSheetMenuProps } from './ReportBottomSheetMenu/dto';
11-
import { ModalProps } from '../../Modal/dto';
7+
import type { OptionsBottomSheetProps } from './dto';
8+
import type { BottomSheetProps } from '../dto';
9+
import type { BottomSheetMenuProps } from '@components/BottomSheetMenu/dto';
10+
import type { ReportBottomSheetMenuProps } from './ReportBottomSheetMenu/dto';
11+
import type { ModalProps } from '@components/Modal/dto';
1212

13-
import { SendPostReportRequest } from '../../../apis/post-report/dto';
14-
import { PostUserReportRequest } from '../../../apis/user-report/dto';
15-
import { PostUserBlockRequest } from '../../../apis/user-block/dto';
13+
import type { SendPostReportRequest } from '@apis/post-report/dto';
14+
import type { PostUserReportRequest } from '@apis/user-report/dto';
15+
import type { PostUserBlockRequest } from '@apis/user-block/dto';
1616

17-
import { StyledText } from '../../Text/StyledText';
18-
import { handleError } from '../../../apis/util/handleError';
19-
import blockIcon from '../../../assets/default/block.svg';
20-
import reportIcon from '../../../assets/default/report.svg';
17+
import { StyledText } from '@components/Text/StyledText';
18+
import { handleError } from '@apis/util/handleError';
19+
import blockIcon from '@assets/default/block.svg';
20+
import reportIcon from '@assets/default/report.svg';
21+
import closeIcon from '@assets/default/modal-close-white.svg';
2122

2223
import {
2324
ReportBottomSheetLayout,
2425
ReportModalLayout,
2526
ReportModalWrapper,
2627
ReportModalContainer,
2728
ReportModalHeader,
28-
XButton,
29+
CloseButton,
2930
ReportModalBox,
3031
} from './styles';
31-
import theme from '../../../styles/theme';
32-
import { postUserBlockApi } from '../../../apis/user-block';
33-
import { postUserReportApi } from '../../../apis/user-report';
34-
import { sendPostReportApi } from '../../../apis/post-report';
32+
import theme from '@styles/theme';
33+
import { postUserBlockApi } from '@apis/user-block';
34+
import { postUserReportApi } from '@apis/user-report';
35+
import { sendPostReportApi } from '@apis/post-report';
36+
import { getCurrentUserId } from '@utils/getCurrentUserId';
3537

3638
const OptionsBottomSheet: React.FC<OptionsBottomSheetProps> = ({
3739
domain,
@@ -44,18 +46,25 @@ const OptionsBottomSheet: React.FC<OptionsBottomSheetProps> = ({
4446
const [isReportBottomSheetOpen, setIsReportBottomSheetOpen] = useState(false);
4547
const [isStatusModalOpen, setIsStatusModalOpen] = useState(false);
4648
const [modalContent, setModalContent] = useState('알 수 없는 오류입니다.\n관리자에게 문의해 주세요.');
47-
const storageValue = localStorage.getItem('my_id');
48-
const userId = Number(storageValue);
49+
const currentUserId = getCurrentUserId();
4950

50-
const sendBlock = async () => {
51+
const handleBackgroundClick = (e: React.MouseEvent) => {
52+
e.stopPropagation();
53+
if (e.target === e.currentTarget) {
54+
setIsReportBottomSheetOpen(false);
55+
}
56+
};
57+
58+
// 유저 차단 api
59+
const postUserBlock = async () => {
5160
try {
52-
const blockRequest: PostUserBlockRequest = {
53-
fromUserId: userId,
61+
const request: PostUserBlockRequest = {
62+
fromUserId: currentUserId,
5463
toUserId: targetId.userId || -1,
5564
action: 'block',
5665
};
57-
const response = await postUserBlockApi(blockRequest);
58-
66+
const response = await postUserBlockApi(request);
67+
5968
if (response.isSuccess) {
6069
setModalContent('정상적으로 처리되었습니다.');
6170
}
@@ -68,19 +77,20 @@ const OptionsBottomSheet: React.FC<OptionsBottomSheetProps> = ({
6877
}
6978
};
7079

80+
// 유저 또는 게시글 신고 api
7181
const sendReport = async (reason: string) => {
7282
try {
7383
let reportData: PostUserReportRequest | SendPostReportRequest;
7484

7585
if (domain === 'user') {
7686
reportData = {
77-
fromUserId: userId,
87+
fromUserId: currentUserId,
7888
toUserId: targetId.userId || -1,
7989
reason: reason,
8090
};
8191
} else {
8292
reportData = {
83-
requesterId: userId,
93+
requesterId: currentUserId,
8494
postId: targetId.postId || -1,
8595
reason: reason,
8696
};
@@ -91,7 +101,6 @@ const OptionsBottomSheet: React.FC<OptionsBottomSheetProps> = ({
91101
? await postUserReportApi(reportData as PostUserReportRequest)
92102
: await sendPostReportApi(reportData as SendPostReportRequest);
93103

94-
// response.isSuccess
95104
if (response.isSuccess) {
96105
setModalContent('정상적으로 처리되었습니다.');
97106
}
@@ -126,7 +135,7 @@ const OptionsBottomSheet: React.FC<OptionsBottomSheetProps> = ({
126135
],
127136
};
128137

129-
// 더보기(kebab) 메뉴 바텀시트
138+
// 더보기 바텀시트
130139
const optionsBottomSheetProps: BottomSheetProps = {
131140
isOpenBottomSheet: isBottomSheetOpen,
132141
Component: BottomSheetMenu,
@@ -143,7 +152,7 @@ const OptionsBottomSheet: React.FC<OptionsBottomSheetProps> = ({
143152
content: `${targetNickname || '알수없음'} 님을\n정말로 차단하시겠어요?`,
144153
button: {
145154
content: '차단하기',
146-
onClick: sendBlock,
155+
onClick: postUserBlock,
147156
},
148157
};
149158

@@ -177,13 +186,6 @@ const OptionsBottomSheet: React.FC<OptionsBottomSheetProps> = ({
177186
},
178187
};
179188

180-
const handleBackgroundClick = (e: React.MouseEvent) => {
181-
e.stopPropagation();
182-
if (e.target === e.currentTarget) {
183-
setIsReportBottomSheetOpen(false);
184-
}
185-
};
186-
187189
return (
188190
<>
189191
<BottomSheet {...optionsBottomSheetProps} />
@@ -201,11 +203,13 @@ const OptionsBottomSheet: React.FC<OptionsBottomSheetProps> = ({
201203
<StyledText $textTheme={{ style: 'heading1-bold' }} color={theme.colors.white}>
202204
신고 사유 선택
203205
</StyledText>
204-
<XButton
206+
<CloseButton
205207
onClick={() => {
206208
setIsReportBottomSheetOpen(false);
207209
}}
208-
/>
210+
>
211+
<img src={closeIcon} alt="닫기" />
212+
</CloseButton>
209213
</ReportModalHeader>
210214
<ReportModalBox>
211215
<ReportBottomSheetMenu {...reportBottomSheetMenuProps} />

src/components/BottomSheet/OptionsBottomSheet/styles.tsx

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import styled from 'styled-components';
2-
import CloseIcon from '../../../assets/default/modal-close-white.svg';
32

43
export const ReportBottomSheetLayout = styled.div`
54
${({ theme }) => theme.visibleOnMobileTablet};
@@ -54,13 +53,11 @@ export const ReportModalBox = styled.section`
5453
width: 100%;
5554
`;
5655

57-
export const XButton = styled.button`
56+
export const CloseButton = styled.button`
5857
width: 1.875rem;
5958
height: 1.875rem;
60-
margin: auto 0 auto auto;
61-
background-image: url(${CloseIcon});
62-
background-repeat: no-repeat;
63-
background-size: 1.875rem;
64-
background-position: center;
59+
display: flex;
60+
justify-content: center;
61+
align-items: center;
6562
opacity: 0.5;
6663
`;

src/components/BottomSheet/dto.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,4 @@ export interface BottomSheetProps<T = any> {
44
Component: React.ComponentType<T>; // BottomSheet 내부에 전달할 컴포넌트
55
componentProps?: T; // props가 있는 경우 객체 형태로 전달
66
onCloseBottomSheet: () => void; // BottomSheet을 닫는 함수
7-
initialTab?: 'likes' | 'comments'; // 추가: initialTab 속성
87
}

0 commit comments

Comments
 (0)