Skip to content

Commit f0910e4

Browse files
committed
feat: 공유 요청 상세 조회 기능 구현
1 parent b6db503 commit f0910e4

File tree

3 files changed

+130
-5
lines changed

3 files changed

+130
-5
lines changed

src/apis/share.ts

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,24 @@ export interface ShareProposal {
3939
status: 'REJECTED' | 'APPROVED' | 'PENDING';
4040
}
4141

42+
//편지 공유 요청 상세 조회
43+
export interface ShareProposalLetter {
44+
id: number;
45+
content: string;
46+
writerZipCode: string;
47+
receiverZipCode: string;
48+
createdAt: string;
49+
}
50+
51+
export interface ShareProposalDetail {
52+
shareProposalId: number;
53+
requesterZipCode: string;
54+
recipientZipCode: string;
55+
message: string;
56+
status: 'PENDING' | 'ACCEPTED' | 'REJECTED';
57+
letters: ShareProposalLetter[];
58+
}
59+
4260
// 편지 공유 수락 / 거절
4361
export interface ShareProposalApproval {
4462
shareProposalId: number;
@@ -106,13 +124,27 @@ export const getShareProposalList = async () => {
106124
}
107125
};
108126

127+
// 편지 공유 요청 상세 조회
128+
export const getShareProposalDetail = async (
129+
shareProposalId: number,
130+
): Promise<ShareProposalDetail> => {
131+
try {
132+
const response = await client.get(`/api/share-proposals/${shareProposalId}`);
133+
console.log(`😎공유 요청 상세 조회 데이터 `, response.data);
134+
return response.data.data;
135+
} catch (error) {
136+
console.error('❌ 편지 공유 요청을 상세 조회하던 중 에러가 발생했습니다', error);
137+
throw error;
138+
}
139+
};
140+
109141
// 편지 공유 수락 / 거절
110142
export const postShareProposalApproval = async (
111143
shareProposalId: number,
112144
action: 'approve' | 'reject',
113145
): Promise<ShareProposalApproval> => {
114146
try {
115-
const response = await client.patch(`/api/share-proposal/${shareProposalId}/${action}`);
147+
const response = await client.patch(`/api/share-proposals/${shareProposalId}/${action}`);
116148
return response.data;
117149
} catch (error) {
118150
console.error(

src/pages/Home/components/ShowShareAccessModal.tsx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import React, { useEffect, useState } from 'react';
22
import { useNavigate } from 'react-router';
33

4-
import { getSharePostDetail } from '@/apis/share';
4+
import { getShareProposalDetail } from '@/apis/share';
55
import { getShareProposalList } from '@/apis/share';
66
import { ShareProposal } from '@/apis/share';
77

@@ -30,9 +30,9 @@ const ShowShareAccessModal = ({ onClose }: ShowShareAccessModalProps) => {
3030

3131
const handleNavigation = async (shareProposalId: number) => {
3232
try {
33-
const postDetail = await getSharePostDetail(shareProposalId);
34-
navigate(`/board/letter/${shareProposalId}`, {
35-
state: { postDetail, isShareLetterPreview: true },
33+
const proposalDetail = await getShareProposalDetail(shareProposalId);
34+
navigate(`/board/share/${shareProposalId}`, {
35+
state: { proposalDetail },
3636
});
3737
} catch (error) {
3838
console.error('❌ 게시글 상세 페이지로 이동하는 데에 실패했습니다.', error);

src/pages/Share/index.tsx

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
import { useEffect, useState } from 'react';
2+
import { useNavigate, useParams } from 'react-router';
3+
4+
import { getShareProposalDetail } from '@/apis/share';
5+
import { postShareProposalApproval, ShareProposalDetail } from '@/apis/share';
6+
7+
import { twMerge } from 'tailwind-merge';
8+
import Letter from '../LetterBoardDetail/components/Letter';
9+
10+
import BlurImg from '@/assets/images/landing-blur.png';
11+
12+
const ShareApprovalPage = () => {
13+
const navigate = useNavigate();
14+
const { shareProposalId } = useParams();
15+
console.log(shareProposalId);
16+
17+
const [proposalDetail, setProposalDetail] = useState<ShareProposalDetail>();
18+
19+
const handleProposalApproval = async (action: 'approve' | 'reject') => {
20+
try {
21+
const result = await postShareProposalApproval(Number(shareProposalId), action);
22+
console.log(`✅ 편지 공유 ${action === 'approve' ? '수락' : '거절'}됨:`, result);
23+
navigate('/');
24+
} catch (error) {
25+
console.error('❌공유 요청 처리 중 에러 발생', error);
26+
}
27+
};
28+
useEffect(() => {
29+
const fetchProposalDetail = async (id: string) => {
30+
try {
31+
const data = await getShareProposalDetail(Number(id));
32+
setProposalDetail(data);
33+
} catch (error) {
34+
console.error('❌ 공유 요청 상세 조회에 실패했습니다.', error);
35+
throw error;
36+
}
37+
};
38+
39+
if (shareProposalId) {
40+
fetchProposalDetail(shareProposalId);
41+
}
42+
}, [shareProposalId]);
43+
44+
return (
45+
<div className="grow bg-white">
46+
<main className="px-5 pt-18 pb-3">
47+
<p className="body-b mb-6 px-5">FROM. {proposalDetail?.requesterZipCode}</p>
48+
<p
49+
className={twMerge(
50+
'body-r bg-[repeating-linear-gradient(transparent,transparent_25px,#ffe6e3_26px)] px-5 whitespace-pre-wrap',
51+
'leading-[26px]',
52+
)}
53+
>
54+
{proposalDetail?.message}
55+
</p>
56+
<section className="flex flex-col gap-6.5 px-5 py-6.5">
57+
{proposalDetail?.letters.map((letter, index) => (
58+
<Letter
59+
key={index}
60+
letter={letter}
61+
isWriter={letter.writerZipCode === proposalDetail.requesterZipCode}
62+
/>
63+
))}
64+
</section>
65+
66+
{proposalDetail && (
67+
<>
68+
<img src={BlurImg} alt="landing blur" className="fixed bottom-0 left-0 z-10 w-screen" />
69+
<section className="fixed bottom-[30px] left-1/2 z-20 flex w-73 translate-x-[-50%] gap-6">
70+
<button
71+
type="button"
72+
className="body-m secondary-btn h-10 flex-1 basis-1/2"
73+
onClick={() => handleProposalApproval('reject')}
74+
>
75+
거부하기
76+
</button>
77+
78+
<button
79+
type="button"
80+
className="primary-btn body-m h-10 flex-1 basis-1/2"
81+
onClick={() => handleProposalApproval('approve')}
82+
>
83+
승인하기
84+
</button>
85+
</section>
86+
</>
87+
)}
88+
</main>
89+
</div>
90+
);
91+
};
92+
93+
export default ShareApprovalPage;

0 commit comments

Comments
 (0)