Skip to content
Merged
Original file line number Diff line number Diff line change
@@ -1,29 +1,15 @@
import React, { useState, useRef, useCallback, useEffect } from 'react';
import BottomButton from '../../../BottomButton/index.tsx';
import BottomSheetMenu from '../../../BottomSheetMenu/index.tsx';
import { SheetItemDto } from '../../../BottomSheetMenu/dto.ts';
import { ReportBottomSheetMenuProps } from './dto.ts';
import { InputLayout, ReportBottomSheetMenuWrappar } from './styles.tsx';
import BottomButton from '@components/BottomButton';
import BottomSheetMenu from '@components/BottomSheetMenu';
import { SheetItemDto } from '@components/BottomSheetMenu/dto';
import type { ReportBottomSheetMenuProps } from './dto';
import { InputLayout, ReportBottomSheetMenuWrappar } from './styles';

const ReportBottomSheetMenu: React.FC<ReportBottomSheetMenuProps> = React.memo(
({ onCloseReportSheet, onOpenStatusModal, sendReport, isUserReport }) => {
const [isVisibleTextarea, setIsTextareaVisible] = useState(false);
const [inputValue, setInputValue] = useState('');
const textareaRef = useRef<HTMLTextAreaElement>(null);
const [isVisibleTextarea, setIsTextareaVisible] = useState(false);

useEffect(() => {
if (textareaRef.current) {
textareaRef.current.focus(); // 마운트 또는 업데이트 시 textarea에 포커스 유지
}
}, []);

const handleInputChange = useCallback((e: React.ChangeEvent<HTMLTextAreaElement>) => {
setInputValue(e.target.value);
}, []);

const handleSubmit = useCallback(() => {
sendReport(inputValue);
}, [onCloseReportSheet, onOpenStatusModal]);

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

const handleInputChange = useCallback((e: React.ChangeEvent<HTMLTextAreaElement>) => {
setInputValue(e.target.value);
}, []);

const handleSubmit = useCallback(() => {
sendReport(inputValue);
}, [onCloseReportSheet, onOpenStatusModal]);

useEffect(() => {
if (textareaRef.current) {
textareaRef.current.focus(); // 마운트 또는 업데이트 시 textarea에 포커스 유지
}
}, []);

return (
<ReportBottomSheetMenuWrappar>
<BottomSheetMenu items={isUserReport ? userReportItems : postReportItems} />
Expand Down
7 changes: 0 additions & 7 deletions src/components/BottomSheet/OptionsBottomSheet/dto.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,3 @@ export interface OptionsBottomSheetProps {
isBottomSheetOpen: boolean;
onClose: () => void;
}

export interface BlockInfoDto {
userId: number;
friendId: number;
friendName: string;
action: 'toggle';
}
86 changes: 45 additions & 41 deletions src/components/BottomSheet/OptionsBottomSheet/index.tsx
Original file line number Diff line number Diff line change
@@ -1,37 +1,39 @@
import { useState } from 'react';
import BottomSheet from '..';
import BottomSheetMenu from '../../BottomSheetMenu';
import BottomSheet from '../index';
import BottomSheetMenu from '@components/BottomSheetMenu';
import ReportBottomSheetMenu from './ReportBottomSheetMenu';
import Modal from '../../Modal';
import Modal from '@components/Modal';

import { OptionsBottomSheetProps } from './dto';
import { BottomSheetProps } from '../dto';
import { BottomSheetMenuProps } from '../../BottomSheetMenu/dto';
import { ReportBottomSheetMenuProps } from './ReportBottomSheetMenu/dto';
import { ModalProps } from '../../Modal/dto';
import type { OptionsBottomSheetProps } from './dto';
import type { BottomSheetProps } from '../dto';
import type { BottomSheetMenuProps } from '@components/BottomSheetMenu/dto';
import type { ReportBottomSheetMenuProps } from './ReportBottomSheetMenu/dto';
import type { ModalProps } from '@components/Modal/dto';

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

import { StyledText } from '../../Text/StyledText';
import { handleError } from '../../../apis/util/handleError';
import blockIcon from '../../../assets/default/block.svg';
import reportIcon from '../../../assets/default/report.svg';
import { StyledText } from '@components/Text/StyledText';
import { handleError } from '@apis/util/handleError';
import blockIcon from '@assets/default/block.svg';
import reportIcon from '@assets/default/report.svg';
import closeIcon from '@assets/default/modal-close-white.svg';

import {
ReportBottomSheetLayout,
ReportModalLayout,
ReportModalWrapper,
ReportModalContainer,
ReportModalHeader,
XButton,
CloseButton,
ReportModalBox,
} from './styles';
import theme from '../../../styles/theme';
import { postUserBlockApi } from '../../../apis/user-block';
import { postUserReportApi } from '../../../apis/user-report';
import { sendPostReportApi } from '../../../apis/post-report';
import theme from '@styles/theme';
import { postUserBlockApi } from '@apis/user-block';
import { postUserReportApi } from '@apis/user-report';
import { sendPostReportApi } from '@apis/post-report';
import { getCurrentUserId } from '@utils/getCurrentUserId';

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

const sendBlock = async () => {
const handleBackgroundClick = (e: React.MouseEvent) => {
e.stopPropagation();
if (e.target === e.currentTarget) {
setIsReportBottomSheetOpen(false);
}
};

// 유저 차단 api
const postUserBlock = async () => {
try {
const blockRequest: PostUserBlockRequest = {
fromUserId: userId,
const request: PostUserBlockRequest = {
fromUserId: currentUserId,
toUserId: targetId.userId || -1,
action: 'block',
};
const response = await postUserBlockApi(blockRequest);
const response = await postUserBlockApi(request);

if (response.isSuccess) {
setModalContent('정상적으로 처리되었습니다.');
}
Expand All @@ -68,19 +77,20 @@ const OptionsBottomSheet: React.FC<OptionsBottomSheetProps> = ({
}
};

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

if (domain === 'user') {
reportData = {
fromUserId: userId,
fromUserId: currentUserId,
toUserId: targetId.userId || -1,
reason: reason,
};
} else {
reportData = {
requesterId: userId,
requesterId: currentUserId,
postId: targetId.postId || -1,
reason: reason,
};
Expand All @@ -91,7 +101,6 @@ const OptionsBottomSheet: React.FC<OptionsBottomSheetProps> = ({
? await postUserReportApi(reportData as PostUserReportRequest)
: await sendPostReportApi(reportData as SendPostReportRequest);

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

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

Expand Down Expand Up @@ -177,13 +186,6 @@ const OptionsBottomSheet: React.FC<OptionsBottomSheetProps> = ({
},
};

const handleBackgroundClick = (e: React.MouseEvent) => {
e.stopPropagation();
if (e.target === e.currentTarget) {
setIsReportBottomSheetOpen(false);
}
};

return (
<>
<BottomSheet {...optionsBottomSheetProps} />
Expand All @@ -201,11 +203,13 @@ const OptionsBottomSheet: React.FC<OptionsBottomSheetProps> = ({
<StyledText $textTheme={{ style: 'heading1-bold' }} color={theme.colors.white}>
신고 사유 선택
</StyledText>
<XButton
<CloseButton
onClick={() => {
setIsReportBottomSheetOpen(false);
}}
/>
>
<img src={closeIcon} alt="닫기" />
</CloseButton>
</ReportModalHeader>
<ReportModalBox>
<ReportBottomSheetMenu {...reportBottomSheetMenuProps} />
Expand Down
11 changes: 4 additions & 7 deletions src/components/BottomSheet/OptionsBottomSheet/styles.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import styled from 'styled-components';
import CloseIcon from '../../../assets/default/modal-close-white.svg';

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

export const XButton = styled.button`
export const CloseButton = styled.button`
width: 1.875rem;
height: 1.875rem;
margin: auto 0 auto auto;
background-image: url(${CloseIcon});
background-repeat: no-repeat;
background-size: 1.875rem;
background-position: center;
display: flex;
justify-content: center;
align-items: center;
opacity: 0.5;
`;
1 change: 0 additions & 1 deletion src/components/BottomSheet/dto.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,4 @@ export interface BottomSheetProps<T = any> {
Component: React.ComponentType<T>; // BottomSheet 내부에 전달할 컴포넌트
componentProps?: T; // props가 있는 경우 객체 형태로 전달
onCloseBottomSheet: () => void; // BottomSheet을 닫는 함수
initialTab?: 'likes' | 'comments'; // 추가: initialTab 속성
}
Loading
Loading