-
Notifications
You must be signed in to change notification settings - Fork 2
design, feat, chore : 편지 작성 페이지 추가 퍼블리싱 + 기능구현 + API연결 + 관리자페이지 퍼블리싱 #28
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 15 commits
2341700
83500ef
b585b4a
eed708a
4e709cc
f3180fc
0a4f949
38757ae
a181914
45b0434
dce8d2e
b0d7161
45bdda0
6227d93
29a67a9
c3135aa
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,26 @@ | ||
| import { client } from './client'; | ||
|
|
||
| const getLetter = async ( | ||
| letterId: string, | ||
| setLetterState: React.Dispatch<React.SetStateAction<LetterDetail | null>>, | ||
| ) => { | ||
| try { | ||
| const res = await client.get(`/api/letters/${letterId}`); | ||
| setLetterState(res.data.data); | ||
| console.log(res); | ||
| } catch (error) { | ||
| console.error(error); | ||
| } | ||
| }; | ||
|
|
||
| const deleteLetter = async (letterId: string) => { | ||
| try { | ||
| console.log(`/api/letters/${letterId}`); | ||
| const res = await client.delete(`/api/letters/${letterId}`); | ||
| console.log(res); | ||
| } catch (error) { | ||
| console.error(error); | ||
| } | ||
| }; | ||
|
|
||
| export { getLetter, deleteLetter }; |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,29 @@ | ||
| import { client } from './client'; | ||
|
|
||
| const postLetter = async ( | ||
| data: LetterRequest, | ||
| setState?: React.Dispatch<React.SetStateAction<boolean>>, | ||
| ) => { | ||
| try { | ||
| const res = await client.post('/api/letters', data); | ||
| if (setState) setState(true); | ||
| console.log(res); | ||
| } catch (error) { | ||
| console.error(error); | ||
| } | ||
| }; | ||
|
|
||
| const getPrevLetter = async ( | ||
| setPrevLetterState: React.Dispatch<React.SetStateAction<PrevLetter[]>>, | ||
| searchParams: URLSearchParams, | ||
| ) => { | ||
| try { | ||
| const res = await client.get(`/api/letters/${searchParams.get('letterId')}/previous`); | ||
| setPrevLetterState(res.data.data); | ||
| console.log(res); | ||
| } catch (error) { | ||
| console.error(error); | ||
| } | ||
| }; | ||
|
|
||
| export { postLetter, getPrevLetter }; | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,9 @@ | ||
| import { ArrowLeftIcon } from '@/assets/icons'; | ||
|
|
||
| export default function BackButton() { | ||
| return ( | ||
| <button onClick={() => window.history.back()}> | ||
| <ArrowLeftIcon className="text-primary-1 h-6 w-6" /> | ||
| </button> | ||
| ); | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,12 +1,12 @@ | ||
| import letterPink from '@/assets/images/letter-pink.png'; | ||
|
|
||
| import { STAMPS } from '../pages/Write/constants'; | ||
| import { CATEGORYS } from '../pages/Write/constants'; | ||
|
|
||
| export default function ResultLetter({ | ||
| stampName = '위로와 공감', | ||
| categoryName = 'CONSOLATION', | ||
| title, | ||
| }: { | ||
| stampName: Stamp; | ||
| categoryName: Category; | ||
| title: string; | ||
| }) { | ||
| const address = '1A3E2'; | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
|
|
@@ -15,15 +15,15 @@ export default function ResultLetter({ | |
|
|
||
| return ( | ||
| <div | ||
| className="flex w-full flex-col gap-[35px] p-4" | ||
| className="flex w-full max-w-[300px] flex-col gap-[35px] p-4" | ||
| style={{ backgroundImage: `url(${letterPink})` }} | ||
| > | ||
| <div className="flex justify-between gap-3"> | ||
| <div className="flex flex-col gap-2.5"> | ||
| <span className="caption-b text-gray-60">따숨이님께</span> | ||
| <span className="caption-r text-gray-80 line-clamp-3 break-all">{title}</span> | ||
| </div> | ||
| <img src={STAMPS[stampName]} alt="우표" /> | ||
| <img src={CATEGORYS[categoryName]} alt="우표" /> | ||
| </div> | ||
| <div className="flex flex-col gap-[5px]"> | ||
| <span className="caption-sb text-gray-60">{today}</span> | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,12 @@ | ||
| import { Outlet } from 'react-router'; | ||
|
|
||
| const MobileLayout = () => { | ||
| return ( | ||
| <div className="mobile-bg"> | ||
| <div className="mobile-layout"> | ||
| <Outlet /> | ||
| </div> | ||
| </div> | ||
| ); | ||
| }; | ||
| export default MobileLayout; |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,139 @@ | ||
| import { useEffect, useState } from 'react'; | ||
|
|
||
| import { client } from '@/apis/client'; | ||
| import { AlarmIcon } from '@/assets/icons'; | ||
|
|
||
| import DetailFrame from './components/DetailFrame'; | ||
| import ListItem from './components/ListItem'; | ||
| import WrapperFrame from './components/WrapperFrame'; | ||
|
|
||
| export default function ReportManage() { | ||
| const [detailModalOpen, setDetailModalOpen] = useState<boolean>(false); | ||
| // { | ||
| // id: '001', | ||
| // reporterEmail: '[email protected]', | ||
| // targetEmail: '[email protected]', | ||
| // reportedAt: new Date(2025, 1, 20), | ||
| // letterId:2001, | ||
| // sharePostId:null, | ||
| // eventId:null, | ||
| // reportType:'LETTER', | ||
| // reason:"ABUSE", | ||
| // reasonDetail:null, | ||
| // status: 'PENDING', | ||
| // }, | ||
| const DUMMY = [ | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 어떤 더미 데이터인지 적어주시는 게 직관적일 것 같아요 ex) DUMMY_REPORTS |
||
| { | ||
| id: '001', | ||
| reporterEmail: '[email protected]', | ||
| targetEmail: '[email protected]', | ||
| reportedAt: new Date(2020, 12, 4), | ||
| reason: '욕설', | ||
| }, | ||
| { | ||
| id: '002', | ||
| reporterEmail: '[email protected]', | ||
| targetEmail: '[email protected]', | ||
| reportedAt: new Date(2020, 12, 4), | ||
| reason: '욕설', | ||
| }, | ||
| { | ||
| id: '003', | ||
| reporterEmail: '[email protected]', | ||
| targetEmail: '[email protected]', | ||
| reportedAt: new Date(2000, 6, 23), | ||
| reason: '욕설', | ||
| }, | ||
| { | ||
| id: '004', | ||
| reporterEmail: '[email protected]', | ||
| targetEmail: '[email protected]', | ||
| reportedAt: new Date(1080, 11, 5), | ||
| reason: '욕설', | ||
| }, | ||
| { | ||
| id: '005', | ||
| reporterEmail: '[email protected]', | ||
| targetEmail: '[email protected]', | ||
| reportedAt: new Date(2040, 1, 2), | ||
| reason: '욕설', | ||
| }, | ||
| { | ||
| id: '006', | ||
| reporterEmail: '[email protected]', | ||
| targetEmail: '[email protected]', | ||
| reportedAt: new Date(2025, 1, 23), | ||
| reason: '욕설', | ||
| }, | ||
| ]; | ||
| const modalContents = [ | ||
| { | ||
| title: '신고 목록 삭제', | ||
| onClick: () => { | ||
| console.log('삭제'); | ||
| }, | ||
| }, | ||
| { | ||
| title: '작성자 활동 정지', | ||
| onClick: () => { | ||
| console.log('정지'); | ||
| }, | ||
| }, | ||
| ]; | ||
| // const [allReports, setAllReports] = useState(); | ||
| useEffect(() => { | ||
| const getAllReports = async () => { | ||
| const res = await client.get('/api/reports'); | ||
| console.log(res); | ||
| }; | ||
| getAllReports(); | ||
| const getReportDetail = async () => { | ||
| const res = await client.get('/api/reports/2'); | ||
| console.log(res); | ||
| }; | ||
| getReportDetail(); | ||
| const postReport = async () => { | ||
| const res = await client.post('/api/reports', { | ||
| letterId: 2010, | ||
| reportType: 'POST', | ||
| reason: 'HARASSMENT', | ||
| reasonDetail: '테스트용', | ||
| }); | ||
| console.log(res); | ||
| }; | ||
| postReport(); | ||
| }, []); | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
| return ( | ||
| <WrapperFrame> | ||
| <span className="h3-sb flex items-center gap-4.5"> | ||
| <AlarmIcon className="h-9 w-9"></AlarmIcon> 신고 편지 목록 | ||
| </span> | ||
| <section className="mt-5 flex flex-col"> | ||
| <div className="bg-primary-3 flex w-full border-b px-6 py-4"> | ||
| <div className="flex w-[80%] items-center"> | ||
| <span className="ml-4 flex basis-1/10 overflow-ellipsis">ID</span> | ||
| <span className="ml-4 flex basis-2/10">제보자 이메일</span> | ||
| <span className="ml-4 flex basis-2/10">작성자 이메일</span> | ||
| <span className="ml-4 flex basis-2/10">제보 일자</span> | ||
| <span className="ml-4 flex basis-3/10">제보 사유</span> | ||
| </div> | ||
| </div> | ||
| {DUMMY.map((data, idx) => ( | ||
| <ListItem | ||
| data={data} | ||
| modalContents={modalContents} | ||
| key={idx} | ||
| setDetailModalOpen={setDetailModalOpen} | ||
| /> | ||
| ))} | ||
| </section> | ||
| {detailModalOpen && ( | ||
| <DetailFrame closeEvent={setDetailModalOpen}> | ||
| <> | ||
| <span className="h2-sb">제보 편지 상세 조회</span> | ||
| </> | ||
| </DetailFrame> | ||
| )} | ||
| </WrapperFrame> | ||
| ); | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,31 @@ | ||
| interface Report { | ||
| id: number; | ||
| reporterEmail: string; | ||
| targetEmail: string; | ||
| reportedAt: Date; | ||
| letterId: number | null; | ||
| comment: string | null; | ||
| sharePostId: number | null; | ||
| reportType: 'LETTER' | 'POST' | 'COMMENT'; | ||
| reason: 'ABUSE' | 'DEFAMATION' | 'HARASSMENT' | 'THREATS' | 'ETC'; | ||
| reasonDetail: string | null; | ||
| status: 'PENDING' | 'RESOLVED' | 'REJECTED'; | ||
| } | ||
|
|
||
| interface ReportDetail { | ||
| id: number; | ||
| memberId: number | null; | ||
| letterId: number | null; | ||
| sharePostId: number | null; | ||
| eventId: number | null; | ||
| reportType: 'LETTER' | 'POST' | 'COMMENT' | 'EVENT'; | ||
| reason: 'ABUSE' | 'DEFAMATION' | 'HARASSMENT' | 'THREATS' | 'ETC'; | ||
| reasonDetail: string | null; | ||
| status: 'PENDING' | 'RESOLVED' | 'REJECTED'; | ||
| reportedAt: Date; | ||
| createdAt: Date; | ||
| letterDetail: { | ||
| title: string; | ||
| content: string; | ||
| }; | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
letterId를 바로 넘겨도 될 거 같은데 따로searchParams를 다루신 이유가 있을까요?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
오 이제보니 불필요하게 params까지 넘기고 있었군요😅 다음 커밋때 수정해서 올리겠습니다!!