Skip to content

Commit e4ca4c7

Browse files
committed
design:편지 상세 페이지 퍼블리싱
1 parent 6e91f8c commit e4ca4c7

File tree

3 files changed

+93
-63
lines changed

3 files changed

+93
-63
lines changed

src/assets/icons/index.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ import PersonIcon from './person.svg?react';
1212
import restartIcon from './restart.svg';
1313
import SirenFilledIcon from './siren-filled.svg?react';
1414
import SirenOutlinedIcon from './siren-outlined.svg?react';
15-
import SirenIcon from './siren.svg?react';
1615
import SnowIcon from './snow.svg';
1716
import ThermostatIcon from './thermostat.svg';
1817
import WarmIcon from './warm.svg';
@@ -21,7 +20,6 @@ export {
2120
AlarmIcon,
2221
PersonIcon,
2322
ArrowLeftIcon,
24-
SirenIcon,
2523
EnvelopeIcon,
2624
BoardIcon,
2725
restartIcon,

src/components/LetterDetail.tsx

Lines changed: 82 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -1,69 +1,91 @@
1-
import { CloudIcon, ColorSirenIcon, SnowIcon, ThermostatIcon, WarmIcon } from '@/assets/icons';
2-
import { useState } from 'react';
1+
import { useEffect, useRef, useState } from 'react';
32
import { twMerge } from 'tailwind-merge';
43

4+
import { CloudIcon, ColorSirenIcon, SnowIcon, ThermostatIcon, WarmIcon } from '@/assets/icons';
5+
6+
import ReportModal from './ReportModal';
7+
58
export default function LetterDetail({ title, text }: { title: string; text: string }) {
69
const FONT = '';
7-
const THEME = 'field';
10+
const THEME = 'celebrate';
11+
const DEGREES = [
12+
{ icon: WarmIcon, title: '따뜻해요' },
13+
{ icon: CloudIcon, title: '그럭저럭' },
14+
{ icon: SnowIcon, title: '앗! 차가워' },
15+
];
816
const [degreeModalOpen, setDegreeModalOpen] = useState<boolean>(false);
17+
const [reportModalOpen, setReportModalOpen] = useState<boolean>(false);
18+
19+
const degreeButtonRef = useRef<HTMLButtonElement>(null);
20+
const handleOutsideClick = (event: MouseEvent) => {
21+
const target = event.target as Node;
22+
if (!target || degreeButtonRef.current?.contains(target)) {
23+
return;
24+
}
25+
setDegreeModalOpen(false);
26+
};
27+
useEffect(() => {
28+
document.body.addEventListener('click', handleOutsideClick);
29+
30+
return () => {
31+
document.body.removeEventListener('click', handleOutsideClick);
32+
};
33+
}, []);
934
return (
10-
<div className={twMerge(`flex grow flex-col gap-3 px-5 pb-7.5`, THEME)}>
11-
<div className="absolute top-5 right-5 flex gap-3">
12-
<button
13-
className="flex items-center justify-center gap-1"
14-
onClick={() => {
15-
setDegreeModalOpen(true);
16-
}}
17-
>
18-
<img src={ThermostatIcon} alt="편지 온도 아이콘" />
19-
<span className="caption-b text-primary-1">편지 온도</span>
20-
</button>
21-
<button onClick={() => {}}>
22-
<img src={ColorSirenIcon} alt="신고 아이콘" />
23-
</button>
24-
{degreeModalOpen && (
25-
<div className="caption-b text-primary-1 bg-primary-5 absolute top-7 z-40 flex flex-col gap-1 p-2 shadow">
26-
<button
27-
className="flex items-center justify-center gap-1"
28-
onClick={() => {
29-
setDegreeModalOpen(false);
30-
}}
31-
>
32-
<img src={WarmIcon} alt="따뜻 아이콘" /> 따뜻해요
33-
</button>
34-
<button
35-
className="flex items-center justify-center gap-1"
36-
onClick={() => {
37-
setDegreeModalOpen(false);
38-
}}
39-
>
40-
<img src={CloudIcon} alt="그럭저럭 아이콘" /> 그럭저럭
41-
</button>
42-
<button
43-
className="flex items-center justify-center gap-1"
44-
onClick={() => {
45-
setDegreeModalOpen(false);
46-
}}
47-
>
48-
<img src={SnowIcon} alt="차가움 아이콘" /> 앗! 차가워
49-
</button>
50-
</div>
51-
)}
52-
</div>
53-
<div className="flex flex-col gap-3 px-5">
54-
<span className="body-b mt-[55px]">TO. 따숨이</span>
55-
<span className="body-sb">{title}</span>
35+
<>
36+
{reportModalOpen && <ReportModal onClose={() => setReportModalOpen(false)} />}
37+
<div className={twMerge(`flex grow flex-col gap-3 px-5 pb-7.5`, THEME)}>
38+
<div className="absolute top-5 right-5 flex gap-3">
39+
<button
40+
ref={degreeButtonRef}
41+
className="flex items-center justify-center gap-1"
42+
onClick={() => {
43+
setDegreeModalOpen((cur) => !cur);
44+
}}
45+
>
46+
<img src={ThermostatIcon} alt="편지 온도 아이콘" />
47+
<span className="caption-b text-primary-1">편지 온도</span>
48+
</button>
49+
<button
50+
onClick={() => {
51+
setReportModalOpen(true);
52+
}}
53+
>
54+
<img src={ColorSirenIcon} alt="신고 아이콘" />
55+
</button>
56+
{degreeModalOpen && (
57+
<div className="caption-b text-primary-1 bg-primary-5 absolute top-7 z-40 flex flex-col gap-1 p-2 shadow">
58+
{DEGREES.map((degree, idx) => {
59+
return (
60+
<button
61+
key={idx}
62+
className="flex items-center justify-start gap-1"
63+
onClick={() => {
64+
console.log(idx);
65+
}}
66+
>
67+
<img src={degree.icon} alt={`${degree.title} 아이콘`} /> {degree.title}
68+
</button>
69+
);
70+
})}
71+
</div>
72+
)}
73+
</div>
74+
<div className="flex flex-col gap-3 px-5">
75+
<span className="body-b mt-[55px]">TO. 따숨이</span>
76+
<span className="body-sb">{title}</span>
77+
</div>
78+
<textarea
79+
readOnly
80+
value={text}
81+
className={twMerge(
82+
`body-r basic-theme min-h-full w-full grow px-6 focus:outline-none`,
83+
`${FONT}`,
84+
)}
85+
></textarea>
86+
<span className="body-sb mt-10 flex justify-end">FROM. {'12E12'}</span>
87+
<button className="bg-primary-3 body-m mt-3 w-full rounded-lg py-2">편지 작성하기</button>
5688
</div>
57-
<textarea
58-
readOnly
59-
value={text}
60-
className={twMerge(
61-
`body-r basic-theme min-h-full w-full grow px-6 focus:outline-none`,
62-
`${FONT}`,
63-
)}
64-
></textarea>
65-
<span className="body-sb mt-10 flex justify-end">FROM. {'12E12'}</span>
66-
<button className="bg-primary-3 mt-3 w-full rounded-lg py-2">편지 작성하기</button>
67-
</div>
89+
</>
6890
);
6991
}

src/pages/LetterDetail/index.tsx

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,15 @@
1+
import LetterDetail from '@/components/LetterDetail';
2+
13
const LetterDetailPage = () => {
2-
return <div>LetterDetailPage</div>;
4+
const DUMMY = {
5+
title: '나에게 햄버거 햄부기우기우가 햄북스따스 함부르크 햄버거링고를 대령하거라 ',
6+
text: '이 편지는 영국에서 최초로 시작되어 일년에 한바퀴를 돌면서 받는 사람에게 행운을 주었고 지금은 당신에게로 옮겨진 이 편지는 4일 안에 당신 곁을 떠나야 합니다. 이 편지를 포함해서 7통을 행운이 필요한 사람에게 보내 주셔야 합니다. 복사를 해도 좋습니다. 혹 미신이라 하실지 모르지만 사실입니다.영국에서 HGXWCH이라는 사람은 1930년에 이 편지를 받았습니다. 그는 비서에게 복사해서 보내라고 했습니다. 며칠 뒤에 복권이 당첨되어 20억을 받았습니다. 어떤 이는 이 편지를 받았으나 96시간 이내 자신의 손에서 떠나야 한다는 사실을 잊었습니다. 그는 곧 사직되었습니다. 나중에야 이 사실을 알고 7통의 편지를 보냈는데 다시 좋은 직장을 얻었습니다. 미국의 케네디 대통령은 이 편지를 받았지만 그냥 버렸습니다. 결국 9일 후 그는 암살당했습니다. 기억해 주세요. 이 편지를 보내면 7년의 행운이 있을 것이고 그렇지 않으면 3년의 불행이 있을 것입니다. ',
7+
};
8+
return (
9+
<>
10+
<LetterDetail title={DUMMY.title} text={DUMMY.text}></LetterDetail>
11+
</>
12+
);
313
};
414

515
export default LetterDetailPage;

0 commit comments

Comments
 (0)