Skip to content
Merged
Show file tree
Hide file tree
Changes from 11 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
"react": "^18.3.1",
"react-dom": "^18.3.1",
"react-router": "^7.1.5",
"swiper": "^11.2.4",
"tailwind-merge": "^3.0.1",
"tailwindcss": "^4.0.6",
"zustand": "^5.0.3"
Expand Down
9 changes: 9 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 8 additions & 0 deletions src/assets/icons/cloud.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
8 changes: 8 additions & 0 deletions src/assets/icons/color-siren.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
16 changes: 14 additions & 2 deletions src/assets/icons/index.ts
Original file line number Diff line number Diff line change
@@ -1,25 +1,37 @@
import AlarmIcon from './alarm.svg?react';
import ArrowLeftIcon from './arrow-left.svg?react';
import BoardIcon from './board.svg?react';
import CloudIcon from './cloud.svg';
import ColorSirenIcon from './color-siren.svg';
import DeleteIcon from './delete.svg?react';
import EnvelopeIcon from './envelope.svg?react';
import InformationIcon from './infromation.svg?react';
import LikeFilledIcon from './like-filled.svg?react';
import LikeOutlinedIcon from './like-outlined.svg?react';
import NoticeIcon from './notice.svg?react';
import PersonIcon from './person.svg?react';
import restartIcon from './restart.svg';
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이 친구만 네이밍 방식이 다릅니다!

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

엇 이걸 캐치해주시다니 ㄷㄷㄷㄷ 수정해놓겠습니다!!

import SirenFilledIcon from './siren-filled.svg?react';
import SirenOutlinedIcon from './siren-outlined.svg?react';
import SnowIcon from './snow.svg';
import ThermostatIcon from './thermostat.svg';
import WarmIcon from './warm.svg';

export {
AlarmIcon,
PersonIcon,
ArrowLeftIcon,
InformationIcon,
SirenFilledIcon,
SirenOutlinedIcon,
EnvelopeIcon,
BoardIcon,
restartIcon,
CloudIcon,
SnowIcon,
ThermostatIcon,
WarmIcon,
ColorSirenIcon,
SirenFilledIcon,
SirenOutlinedIcon,
NoticeIcon,
LikeFilledIcon,
LikeOutlinedIcon,
Expand Down
8 changes: 8 additions & 0 deletions src/assets/icons/restart.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
8 changes: 8 additions & 0 deletions src/assets/icons/snow.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
8 changes: 8 additions & 0 deletions src/assets/icons/thermostat.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
8 changes: 8 additions & 0 deletions src/assets/icons/warm.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified src/assets/images/field-4.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
91 changes: 91 additions & 0 deletions src/components/LetterDetail.tsx
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이걸 LetterDetailPage에서 구현하지 않고 component로 빼두신 이유가 있으신가요?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

오 처음에 letterDetail이 공용으로 쓰이는곳이 좀 있는줄 알고(게시판-공유게시글 부분 등등..) 컴포넌트 따로 만들어놨는데 이제보니 공용으로 사용하는데가 없었네요 헣 상세페이지에 통합시켜놓겠습니다!!

Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
import { useEffect, useRef, useState } from 'react';
import { twMerge } from 'tailwind-merge';

import { CloudIcon, ColorSirenIcon, SnowIcon, ThermostatIcon, WarmIcon } from '@/assets/icons';

import ReportModal from './ReportModal';

export default function LetterDetail({ title, text }: { title: string; text: string }) {
const FONT = '';
const THEME = 'celebrate';
const DEGREES = [
{ icon: WarmIcon, title: '따뜻해요' },
{ icon: CloudIcon, title: '그럭저럭' },
{ icon: SnowIcon, title: '앗! 차가워' },
];
const [degreeModalOpen, setDegreeModalOpen] = useState<boolean>(false);
const [reportModalOpen, setReportModalOpen] = useState<boolean>(false);

const degreeButtonRef = useRef<HTMLButtonElement>(null);
const handleOutsideClick = (event: MouseEvent) => {
const target = event.target as Node;
if (!target || degreeButtonRef.current?.contains(target)) {
return;
}
setDegreeModalOpen(false);
};
useEffect(() => {
document.body.addEventListener('click', handleOutsideClick);

return () => {
document.body.removeEventListener('click', handleOutsideClick);
};
}, []);
return (
<>
{reportModalOpen && <ReportModal onClose={() => setReportModalOpen(false)} />}
<div className={twMerge(`flex grow flex-col gap-3 px-5 pb-7.5`, THEME)}>
<div className="absolute top-5 right-5 flex gap-3">
<button
ref={degreeButtonRef}
className="flex items-center justify-center gap-1"
onClick={() => {
setDegreeModalOpen((cur) => !cur);
}}
>
<img src={ThermostatIcon} alt="편지 온도 아이콘" />
<span className="caption-b text-primary-1">편지 온도</span>
</button>
<button
onClick={() => {
setReportModalOpen(true);
}}
>
<img src={ColorSirenIcon} alt="신고 아이콘" />
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이거 컴포넌트로 사용하도록 만들어뒀어요! 이렇게 해도 문제는 없겠지만
<ColorSirenIcon />으로 사용 가능합니다!!

그리고 제가 <SirenOutlinedIcon />을 하나 만들어두었어요. 이렇게 하면 className으로 아이콘 색상 지정도 가능합니다!
예를 들면 이렇게요!

Suggested change
<img src={ColorSirenIcon} alt="신고 아이콘" />
<SirenOutlinedIcon className="text-primary-1" />

이렇게 했을 때의 장점은!! svg 에셋이 줄어든다는 것이지용~~
컬러마다 svg 추출없이 하나의 svg만 뽑아서 색상 변경만 하면 되니까요!

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

앗차차! 아이콘 크기가 다양할 수 있어서 width랑 height는 반드시 포함시키도록 해놔서..
제가 제안드린 방식대로 하신다면 className에 width랑 height 반드시 넣어주셔야 합니다...ㅎㅎㅎ

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

오오오 이게 svgr이군요 ㄷㄷㄷㄷ 잘 적용해서 사용해보겠습니당 감사합니다!!!👍👍👍👍👍

</button>
{degreeModalOpen && (
<div className="caption-b text-primary-1 bg-primary-5 absolute top-7 z-40 flex flex-col gap-1 p-2 shadow">
{DEGREES.map((degree, idx) => {
return (
<button
key={idx}
className="flex items-center justify-start gap-1"
onClick={() => {
console.log(idx);
}}
>
<img src={degree.icon} alt={`${degree.title} 아이콘`} /> {degree.title}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이것도 아마 <degree.icon /> 이런식으로 사용 가능할거에요!!

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

svgr 굉장히 좋군요✨✨

</button>
);
})}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이것도 취향차이겠지만! 이렇게 하면 return 키워드 사용없이도 가능합니당

Suggested change
{DEGREES.map((degree, idx) => {
return (
<button
key={idx}
className="flex items-center justify-start gap-1"
onClick={() => {
console.log(idx);
}}
>
<img src={degree.icon} alt={`${degree.title} 아이콘`} /> {degree.title}
</button>
);
})}
{DEGREES.map((degree, idx) => (
<button
key={idx}
className="flex items-center justify-start gap-1"
onClick={() => {
console.log(idx);
}}
>
<img src={degree.icon} alt={`${degree.title} 아이콘`} /> {degree.title}
</button>
)
)}

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

오홍 return 넣는거 귀찮아서 이 방법도 한번 고려해봐야겠습니다!!!

</div>
)}
</div>
<div className="flex flex-col gap-3 px-5">
<span className="body-b mt-[55px]">TO. 따숨이</span>
<span className="body-sb">{title}</span>
</div>
<textarea
readOnly
value={text}
className={twMerge(
`body-r basic-theme min-h-full w-full grow px-6 focus:outline-none`,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

focus:outline-none도 전역 스타일로 빼둬서 없애도 될 것 같습니다!

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

엇 전역으로 만들어주셨군용 바로 제거하겠습니다!!!👍👍👍

`${FONT}`,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FONT가 이미 문자열로 들어오는 것 같은데 템플릿 리터럴을 적용하지 않아도 되지 않나 싶습니다!

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

엇 나중에 상세페이지 데이터를 받을때 저기에 폰트속성이 들어갈 거 같아서 미리 템플릿리터럴로 자리만 만들어 놨습니다!! 주석도 없이 그냥 만들어놨었군요 제가😅

)}
></textarea>
<span className="body-sb mt-10 flex justify-end">FROM. {'12E12'}</span>
<button className="bg-primary-3 body-m mt-3 w-full rounded-lg py-2">편지 작성하기</button>
</div>
</>
);
}
Loading