Skip to content

Commit

Permalink
feat : 편지 상세 보기 페이지 신고하기 버튼, 모달 레이아웃 (#246)
Browse files Browse the repository at this point in the history
  • Loading branch information
mmjjaa authored Dec 5, 2024
1 parent 5feadb5 commit 755b6ad
Show file tree
Hide file tree
Showing 4 changed files with 160 additions and 1 deletion.
33 changes: 33 additions & 0 deletions src/components/LetterDetailPage/Report/ReportButton.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import { AiOutlineAlert } from 'react-icons/ai';
import { useState } from 'react';
import { ReportModal } from './ReportModal';

type ReportButtonProps = {
id: string;
};

export const ReportButton = ({ id }: ReportButtonProps) => {
const [isModalOpen, setIsModalOpen] = useState(false);

const openModal = () => {
setIsModalOpen(true);
};

const closeModal = () => {
setIsModalOpen(false);
};

return (
<>
<button className="flex-center gap-1 p-2 " onClick={openModal}>
<AiOutlineAlert />
</button>

{isModalOpen && (
<div className="fixed inset-0 bg-black bg-opacity-50 flex justify-center items-center z-50">
<ReportModal id={id} closeModal={closeModal} />
</div>
)}
</>
);
};
29 changes: 29 additions & 0 deletions src/components/LetterDetailPage/Report/ReportModal.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import type { Meta, StoryObj } from '@storybook/react';
import { ReportModal } from './ReportModal';

const meta: Meta<typeof ReportModal> = {
component: ReportModal,
title: 'molecule/ReportModal',
tags: ['autodocs']
};
export default meta;

type Story = StoryObj<typeof ReportModal>;

export const Default: Story = {
args: {}
};

export const WithCustomReason: Story = {
args: {},
parameters: {
docs: {
description: {
story: '기타 옵션 선택 시, 텍스트 입력 필드가 활성화'
}
}
},
render: (args) => {
return <ReportModal {...args} />;
}
};
95 changes: 95 additions & 0 deletions src/components/LetterDetailPage/Report/ReportModal.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
import { Margin } from '@/components/Common/Margin/Margin';
import React, { useState } from 'react';

type ReportModalProps = {
id: string;
closeModal: () => void;
};

export const ReportModal = ({ id, closeModal }: ReportModalProps) => {
const [selectedReason, setSelectedReason] = useState<string>('');
const [customReason, setCustomReason] = useState<string>('');

const reportReasons = [
'유해한 편지 내용',
'선정적인 내용',
'스팸성(광고) 내용',
'만남 유도',
'개인정보 과도한 노출',
'의미없는 도배',
'기타'
];

const handleReasonChange = (reason: string) => {
setSelectedReason(reason);
if (reason !== '기타') {
setCustomReason('');
}
};

const handleCustomReasonChange = (
event: React.ChangeEvent<HTMLInputElement>
) => {
setCustomReason(event.target.value);
};

return (
<div>
<div className="flex flex-col bg-white rounded-2xl items-center justify-center w-full h-full p-4">
<Margin top={10} />
<span className="font-bold mb-4 text-2xl">
편지 신고하기{id}
</span>
<span className="text-sm text-gray-700 mb-4">
신고 이유 및 설명
</span>

<form className="flex flex-col items-start gap-4">
{reportReasons.map((reason, index) => (
<label
key={index}
className="flex items-center text-lg"
>
<input
type="radio"
name="reportReason"
value={reason}
checked={selectedReason === reason}
onChange={() => handleReasonChange(reason)}
className="mr-2"
/>
{reason}
</label>
))}
{selectedReason === '기타' && (
<input
type="text"
placeholder="신고 사유를 입력해주세요."
value={customReason}
onChange={handleCustomReasonChange}
className="border rounded-lg p-2 w-full mt-2"
/>
)}
</form>
<div className="flex-center gap-2">
<button
onClick={closeModal}
className="mt-6 bg-slate-300 w-24 text-white px-4 py-2 rounded-lg"
>
닫기
</button>
<button
className="mt-6 bg-red-500 w-24 text-white px-4 py-2 rounded-lg"
disabled={
!selectedReason ||
(selectedReason === '기타' &&
customReason.trim() === '')
}
>
신고하기
</button>
</div>
</div>
</div>
);
};
4 changes: 3 additions & 1 deletion src/pages/Letter/Detail/LetterDetailPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { KeywordLetterDetail } from '@/components/LetterDetailPage/KeywordLetter
import { useParams } from 'react-router-dom';
import { DeleteButton } from '@/components/LetterDetailPage/DeleteButton/DeleteButton';
import { ReplyList } from '@/components/LetterDetailPage/ReplyList/ReplyList';
import { ReportButton } from '@/components/LetterDetailPage/Report/ReportButton';

type LetterDetailPageProps = {
isAuthor?: boolean;
Expand Down Expand Up @@ -61,8 +62,9 @@ export const LetterDetailPage = ({
<BackButton onClick={onBackClick} />
</div>
{id && (
<div className="mt-10 absolute top-0 right-8">
<div className="mt-10 flex absolute top-0 right-8">
<DeleteButton id={id} onClick={onDeleteClick} />
<ReportButton id={id} />
</div>
)}
<div className="mt-16 flex-center relative">
Expand Down

0 comments on commit 755b6ad

Please sign in to comment.