Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
4b6181d
design: 홈 페이지 에셋 추가
tifsy Feb 20, 2025
04bbbea
design: 홈 페이지 퍼블리싱
tifsy Feb 20, 2025
0e3f25f
design: 홈 페이지 모달 퍼블리싱
tifsy Feb 20, 2025
c16c1bd
design: 홈 페이지 퍼블리싱
tifsy Feb 20, 2025
5465dc5
design: 홈 페이지 모달 퍼블리싱
tifsy Feb 20, 2025
535782f
Merge branch '4-design-home' of https://github.com/prgrms-web-devcour…
tifsy Feb 20, 2025
f37f950
refactor: package-json 삭제
tifsy Feb 20, 2025
8b6c011
refactor: ModalOverlay 컴포넌트 새 속성에 맞춰 모달 정리
tifsy Feb 20, 2025
2621f47
Merge branch 'develop' into 4-design-home
tifsy Feb 20, 2025
01a3856
fix: import 오류 해결
tifsy Feb 20, 2025
8957b0f
refactor: SpecialLetterBanner 애니메이션 animation.css로 분리
tifsy Feb 20, 2025
29956e2
design: Home에서 grow 적용으로 불필요한 h-screen 제거
tifsy Feb 20, 2025
7f0a102
rename: 에셋 파일명을 케밥 케이스로 변경
tifsy Feb 20, 2025
59020e6
remove: 필요없는 에셋 삭제
tifsy Feb 20, 2025
dbcc80f
fix: 이미지 경로 import 방식 수정
tifsy Feb 20, 2025
1ae90fb
refactor: 버튼 컴포넌트 반복 로직 개선
tifsy Feb 20, 2025
ef72e2e
style: HomeRight 레이아웃 수정
tifsy Feb 20, 2025
c642d81
refactor: max-w 값 수정 및 불필요한 삼항 연산자 제거
tifsy Feb 20, 2025
26ff140
Merge branch '4-design-home' of https://github.com/prgrms-web-devcour…
tifsy Feb 20, 2025
e735722
rename: Navbar를 HomeHeader로 대체
tifsy Feb 20, 2025
3dc606d
rename: 홈 페이지 배경 이미지 업데이트
tifsy Feb 20, 2025
ce5ef44
fix: 모바일 및 웹에서 레이아웃 오류 해결, 홈 페이지 구조 리팩토링
tifsy Feb 20, 2025
6755831
design: 홈 페이지 왼쪽 배경 width 조정
tifsy Feb 20, 2025
0a80cb9
design: SpecialLetterBanner width 조정
tifsy Feb 20, 2025
d223843
design: 게시판 이미지 버튼 width 조정
tifsy Feb 20, 2025
e80b0e2
Merge branch 'develop' into 4-design-home
tifsy Feb 20, 2025
c1240e7
fix: coflict 오류 해결
tifsy Feb 21, 2025
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
5 changes: 5 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,16 @@
"preview": "vite preview"
},
"dependencies": {
"@emotion/react": "^11.14.0",
"@emotion/styled": "^11.14.0",
"@egjs/react-infinitegrid": "^4.12.0",
"@mui/icons-material": "^6.4.4",
"@mui/material": "^6.4.4",
"@tailwindcss/vite": "^4.0.6",
"@tanstack/react-query": "^5.66.0",
"axios": "^1.7.9",
"gsap": "^3.12.7",
"pnpm": "^10.4.1",
"react": "^18.3.1",
"react-dom": "^18.3.1",
"react-router": "^7.1.5",
Expand Down
205 changes: 196 additions & 9 deletions pnpm-lock.yaml

Large diffs are not rendered by default.

Binary file added src/assets/images/go-to-letter-board.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/assets/images/go-to-letter-box.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/assets/images/go-to-random-letter.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/assets/images/go-to-write.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/assets/images/home-left-mountain.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/assets/images/home-right-mountain-bottom.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/assets/images/home-right-mountain-top.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/assets/images/letter-1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/assets/images/letter-2.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/assets/images/letter-3.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/assets/images/letter-4.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/assets/images/random-cheer-bird.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
17 changes: 17 additions & 0 deletions src/components/HomeButton.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import HomeOutlinedIcon from '@mui/icons-material/HomeOutlined';
import { Link } from 'react-router';

export default function HomeButton() {
return (
<>
<div className="flex w-full max-w-150 justify-end pr-5 text-center">
<Link
to="/"
className="bg-primary-3 fixed bottom-[30px] z-50 h-13 w-13 content-center rounded-full text-white transition-all duration-200 hover:scale-105 active:scale-90"
>
<HomeOutlinedIcon />
</Link>
</div>
</>
);
}
48 changes: 48 additions & 0 deletions src/pages/Home/components/FloatingLetters.tsx
Copy link
Collaborator

Choose a reason for hiding this comment

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

여기서 걱정이 되는게 있습니다!
지난 번에 제가 말씀드렸듯이 모바일의 vh랑 웹의 vh를 좀 다르게 다룰 필요가 있어요.
그래서 일반적인 vh를 사용하면 웹과 모바일에서 차이가 발생할 것 같아요. 물론 그 차이가 미세할 수도 있지많요!
그래서 만약 vh를 사용해야 한다면 제가 스타일 변수로 --vh를 만들어뒀는데 이걸 사용하거나 1vh window.innerHeight * 0.01로 계산해서 하면 어떨까 해요!

Copy link
Collaborator Author

Choose a reason for hiding this comment

The 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,48 @@
import { useEffect, useRef } from 'react';
import gsap from 'gsap';
import letter1 from '@/assets/images/letter-1.png';
import letter2 from '@/assets/images/letter-2.png';
import letter3 from '@/assets/images/letter-3.png';
import letter4 from '@/assets/images/letter-4.png';

const images = [letter1, letter2, letter3, letter4];

const FloatingLetters = () => {
const lettersRef = useRef<HTMLImageElement[]>([]);
useEffect(() => {
if (!lettersRef.current) return;

lettersRef.current.forEach((letter, index) => {
gsap.to(letter, {
// x: Math.random() * 50 - 40,
y: Math.random() * 20 - 40 + 'vh', // 위아래 이동
rotation: Math.random() * 50 - 25, // 회전
duration: Math.random() * 3 + 2, // 지속 시간
repeat: -1, // 무한 반복
yoyo: true, // 왕복
ease: 'power1.inOut',
delay: index * 1, // 편지마다 시차
});
});
}, []);
return (
<>
{images.map((src, index) => (
<img
key={index}
src={src}
ref={(el) => {
if (el) lettersRef.current[index] = el;
}}
className="absolute w-20 opacity-90"
style={{
left: `${index * 30 + 30}px`, // 편지지 간격
top: '60vh',
}}
/>
))}
</>
);
};

export default FloatingLetters;
17 changes: 17 additions & 0 deletions src/pages/Home/components/GoToLetterBoard.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { Link } from 'react-router';
import goToLetterBoard from '@/assets/images/go-to-letter-board.png';

const GoToLetterBoard = () => {
return (
<div className="absolute bottom-48 left-[calc(var(--vh)*36)] z-9 flex w-full">
<div className="text-left">
<p className="text-gray-60 body-r mb-1 ml-2">게시판</p>
<Link to="/letter/board">
<img src={goToLetterBoard} alt="go to letter board" className="w-[177px]" />
</Link>
</div>
</div>
);
};

export default GoToLetterBoard;
24 changes: 24 additions & 0 deletions src/pages/Home/components/GoToLetterBox.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { Link } from 'react-router';
import goToLetterBoxNewLetters from '@/assets/images/go-to-letter-box-new-letters.png';
import goToLetterBox from '@/assets/images/go-to-letter-box.png';

const GoToLetterBox = () => {
//TODO : hasNewLetters 전역으로 상태 관리하기
let hasNewLetters = true;
return (
<div className="absolute bottom-10 left-5 z-9 flex w-fit">
<div className="text-left">
<p className="text-gray-60 body-r mb-1 ml-2">내 편지함</p>
<Link to="/letter/box">
<img
src={hasNewLetters ? goToLetterBoxNewLetters : goToLetterBox}
alt="go to letter box"
className="w-[206.5px]"
/>
</Link>
</div>
</div>
);
};

export default GoToLetterBox;
17 changes: 17 additions & 0 deletions src/pages/Home/components/GoToRandomLetter.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { Link } from 'react-router';
import goToRandomLetter from '@/assets/images/go-to-random-letter.png';

const GoToRandomLetter = () => {
return (
<>
<div className="z-20 h-fit w-fit">
<p className="text-gray-60 body-r mb-1 ml-5 rotate-[-5.277deg]">고민편지 보러가기</p>
<Link to={'/letter/random'}>
<img src={goToRandomLetter} alt="go to random letter" />
</Link>
</div>
</>
);
};

export default GoToRandomLetter;
15 changes: 15 additions & 0 deletions src/pages/Home/components/GoToWrite.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { Link } from 'react-router';
import goToWrite from '@/assets/images/go-to-write.png';

const GoToWrite = () => {
return (
<div className="h-fit w-fit pl-[87px]">
<p className="text-gray-60 body-r mb-1 rotate-[-5.277deg]">속마음 나누기</p>
<Link to={'/letter/write'}>
<img src={goToWrite} alt="go to write" />
</Link>
</div>
);
};

export default GoToWrite;
14 changes: 14 additions & 0 deletions src/pages/Home/components/HomeBackgroundLeft.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import BackgroundImageWrapper from '@/components/BackgroundImageWrapper';
import homeLeftMountain from '@/assets/images/home-left-mountain.png';

const HomeBackgroundLeft = () => {
return (
<BackgroundImageWrapper
as="div"
className="absolute bottom-0 left-0 z-[11] h-[calc(var(--vh)*25)] w-full min-w-[700px] -translate-x-1/3"
imageUrl={homeLeftMountain}
/>
);
};

export default HomeBackgroundLeft;
13 changes: 13 additions & 0 deletions src/pages/Home/components/HomeBackgroundRightBottom.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import BackgroundImageWrapper from '@/components/BackgroundImageWrapper';
import homeRightMountainBottom from '@/assets/images/home-right-mountain-bottom.png';
const HomeBackgroundRightBottom = () => {
return (
<BackgroundImageWrapper
as="div"
className="absolute bottom-0 z-[10] h-[calc(var(--vh)*20)] w-full min-w-[600px] -translate-x-1/4 overflow-hidden"
imageUrl={homeRightMountainBottom}
/>
);
};

export default HomeBackgroundRightBottom;
13 changes: 13 additions & 0 deletions src/pages/Home/components/HomeBackgroundRightTop.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import BackgroundImageWrapper from '@/components/BackgroundImageWrapper';
import homeRightMountainTop from '@/assets/images/home-right-mountain-top.png';
const HomeBackgroundRightTop = () => {
return (
<BackgroundImageWrapper
as="div"
className="absolute bottom-0 z-8 h-[calc(var(--vh)*32)] w-full min-w-[760px] -translate-x-1/4 overflow-hidden"
imageUrl={homeRightMountainTop}
/>
);
};

export default HomeBackgroundRightTop;
20 changes: 20 additions & 0 deletions src/pages/Home/components/HomeHeader.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { Link } from 'react-router';

import { AlarmIcon, PersonIcon } from '@/assets/icons';

const HomeHeader = () => {
return (
<header className="fixed top-0 z-40 flex h-16 w-full max-w-150 items-center justify-end p-5">
<div className="flex items-center gap-3">
<Link to="/mypage/notifications">
<AlarmIcon className="h-6 w-6 text-white" />
</Link>
<Link to="/mypage">
<PersonIcon className="h-6 w-6 text-white" />
</Link>
</div>
</header>
);
};

export default HomeHeader;
18 changes: 18 additions & 0 deletions src/pages/Home/components/HomeLeft.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import RandomCheer from './RandomCheer';
import GoToWrite from './GoToWrite';
import GoToRandomLetter from './GoToRandomLetter';

const HomeLeft = () => {
return (
<div
style={{ top: 'calc(-240px + var(--vh) * 64)' }}
className="absolute flex w-full max-w-150 min-w-[300px] flex-shrink-0 grow snap-start flex-col space-y-[calc(var(--vh)*2)]"
>
<RandomCheer />
<GoToWrite />
<GoToRandomLetter />
</div>
);
};

export default HomeLeft;
20 changes: 20 additions & 0 deletions src/pages/Home/components/HomeRight.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import FloatingLetters from './FloatingLetters';
import GoToLetterBoard from './GoToLetterBoard';
import GoToLetterBox from './GoToLetterBox';
import NewLetterModal from './NewLetterModal';

const HomeRight = () => {
//TODO : hasNewLetters 전역으로 상태 관리할지
let hasNewLetters = true;

return (
<div className="flex h-screen w-full max-w-150 min-w-[300px] flex-shrink-0 grow snap-start flex-col items-center overflow-x-hidden pt-5">
{hasNewLetters && <FloatingLetters />}
<GoToLetterBox />
<GoToLetterBoard />
{hasNewLetters && <NewLetterModal />}
</div>
);
};

export default HomeRight;
52 changes: 52 additions & 0 deletions src/pages/Home/components/LetterActions.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import { useState } from 'react';
import SendOutlinedIcon from '@mui/icons-material/SendOutlined';
import DriveFileRenameOutlineOutlinedIcon from '@mui/icons-material/DriveFileRenameOutlineOutlined';
import ShareOutlinedIcon from '@mui/icons-material/ShareOutlined';
import ShowIncomingLettersModal from './ShowIncomingLettersModal';
import ShowDraftModal from './ShowDraftModal';
import ShowShareAccessModal from './ShowShareAccessModal';
Comment on lines +1 to +7
Copy link
Collaborator

Choose a reason for hiding this comment

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

오 뭔가... 린트가 반영이 안된 것 같은데 혹시 format on save 설정이 되어 있으신가요?

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 린트가 반영이 안되는 것 같습니다 🥲


const LetterActions = () => {
const [activeModal, setActiveModal] = useState<
null | 'incomingLetters' | 'draft' | 'shareAccess'
>(null);

const arr: { title: 'incomingLetters' | 'draft' | 'shareAccess'; icon: React.ReactNode }[] = [
{
title: 'incomingLetters',
icon: <SendOutlinedIcon />,
},
{
title: 'draft',
icon: <DriveFileRenameOutlineOutlinedIcon />,
},
{
title: 'shareAccess',
icon: <ShareOutlinedIcon />,
},
];
return (
<div className="fixed top-24 z-31 mt-3 flex w-full max-w-150 justify-end pr-5">
<div className="flex flex-col gap-y-3">
{arr.map((item, index) => (
<button
key={index}
onClick={() => setActiveModal(item.title)}
className="flex h-12 w-12 items-center justify-center gap-[10px] rounded-full bg-white/40 text-gray-50 shadow-[inset_0_-2px_2px_0_rgba(208,169,14,0.30),_0_0px_4px_0_rgba(199,164,29,0.30)]"
>
{item.icon}
</button>
))}
</div>
{activeModal === 'incomingLetters' && (
<ShowIncomingLettersModal onClose={() => setActiveModal(null)} />
)}
{activeModal === 'draft' && <ShowDraftModal onClose={() => setActiveModal(null)} />}
{activeModal === 'shareAccess' && (
<ShowShareAccessModal onClose={() => setActiveModal(null)} />
)}
</div>
);
};

export default LetterActions;
7 changes: 7 additions & 0 deletions src/pages/Home/components/LetterPreview.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import React from 'react';

const LetterPreview = () => {
return <div>LetterPreview</div>;
};

export default LetterPreview;
13 changes: 13 additions & 0 deletions src/pages/Home/components/NewLetterModal.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { useState } from 'react';

const NewLetterModal = () => {
const [newLetterCount, setNewLetterCount] = useState(0);

return (
<p className="text-gray-60 body-b absolute top-30 mb-10 w-fit animate-pulse rounded-full bg-white px-6 py-4">
{newLetterCount}통의 편지가 도착했어요!
</p>
);
};

export default NewLetterModal;
31 changes: 31 additions & 0 deletions src/pages/Home/components/RandomCheer.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { useState } from 'react';
import { RANDOM_CHEER_LIST } from '../constants';
import randomCheerBird from '@/assets/images/random-cheer-bird.png';

const RandomCheer = () => {
const getRandomCheer = (): string => {
const randomIndex = Math.floor(Math.random() * RANDOM_CHEER_LIST.length);
return RANDOM_CHEER_LIST[randomIndex];
};

const [randomCheer, setRandomCheer] = useState(getRandomCheer());

return (
<div className="flex flex-col items-end pr-20">
<div
className="relative mb-3 w-fit rounded-lg border-1 border-white bg-white px-6 py-[7px] text-center"
onClick={() => setRandomCheer(getRandomCheer())}
>
<p className="caption-m">{randomCheer}</p>
<div className="absolute right-2 bottom-[-15px] -translate-x-1/2 transform border-x-[10px] border-t-[15px] border-x-transparent border-t-white"></div>
</div>
<img
src={randomCheerBird}
alt="random cheer bird"
className="h-[26.5px] w-[21px] opacity-80"
/>
</div>
);
};

export default RandomCheer;
Loading