-
Notifications
You must be signed in to change notification settings - Fork 2
design: 홈 페이지 퍼블리싱 #19
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 10 commits
4b6181d
04bbbea
0e3f25f
c16c1bd
5465dc5
535782f
f37f950
8b6c011
2621f47
01a3856
8957b0f
29956e2
7f0a102
59020e6
dbcc80f
1ae90fb
ef72e2e
c642d81
26ff140
e735722
3dc606d
ce5ef44
6755831
0a80cb9
d223843
e80b0e2
c1240e7
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Large diffs are not rendered by default.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,15 @@ | ||
| import HomeOutlinedIcon from '@mui/icons-material/HomeOutlined'; | ||
| import { Link } from 'react-router'; | ||
|
|
||
| export default function HomeButton() { | ||
| return ( | ||
| <> | ||
| <Link | ||
| to="/" | ||
| className="bg-primary-3 absolute right-5 bottom-[30px] z-50 flex h-13 w-13 items-center justify-center rounded-full text-white transition-all duration-200 hover:scale-105 active:scale-90" | ||
| > | ||
| <HomeOutlinedIcon /> | ||
| </Link> | ||
| </> | ||
| ); | ||
| } |
|
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. 여기서 걱정이 되는게 있습니다!
Collaborator
Author
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,41 @@ | ||
| import { useEffect, useRef } from 'react'; | ||
| import gsap from 'gsap'; | ||
| 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 - 25 + 'vh', // 위아래 이동 | ||
| rotation: Math.random() * 50 - 25, // 회전 | ||
| duration: Math.random() * 3 + 2, // 지속 시간 | ||
| repeat: -1, // 무한 반복 | ||
| yoyo: true, // 왕복 | ||
| ease: 'power1.inOut', | ||
| delay: index * 1, // 편지마다 시차 | ||
| }); | ||
| }); | ||
| }, []); | ||
| return ( | ||
| <> | ||
| {Array.from({ length: 4 }).map((_, index) => ( | ||
| <img | ||
| key={index} | ||
| src={`/src/assets/letter_${index + 1}.png`} | ||
| 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; |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,20 @@ | ||
| import { Link } from 'react-router'; | ||
|
|
||
| const GoToLetterBoard = () => { | ||
| return ( | ||
| <div className="absolute right-[-30px] bottom-48 z-20 flex w-fit"> | ||
| <div className="text-left"> | ||
| <p className="text-gray-60 body-r mb-1 ml-2">게시판</p> | ||
| <Link to="/letter/board"> | ||
| <img | ||
| src="/src/assets/go_to_letter_board.png" | ||
| alt="go to letter board" | ||
| className="w-[177px]" | ||
| /> | ||
| </Link> | ||
| </div> | ||
| </div> | ||
| ); | ||
| }; | ||
|
|
||
| export default GoToLetterBoard; |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,26 @@ | ||
| import { Link } from 'react-router'; | ||
|
|
||
| const GoToLetterBox = () => { | ||
| //TODO : hasNewLetters 전역으로 상태 관리하기 | ||
| let hasNewLetters = true; | ||
| return ( | ||
| <div className="absolute bottom-10 left-5 z-30 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 | ||
| ? 'src/assets/go_to_letter_box_new_letters.png' | ||
| : '/src/assets/go_to_letter_box.png' | ||
| } | ||
| alt="go to letter box" | ||
| className="w-[206.5px]" | ||
| /> | ||
| </Link> | ||
| </div> | ||
| </div> | ||
| ); | ||
| }; | ||
|
|
||
| export default GoToLetterBox; |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,14 @@ | ||
| import { Link } from 'react-router'; | ||
|
|
||
| const GoToRandomLetter = () => { | ||
| return ( | ||
| <> | ||
| <p className="text-gray-60 body-r mb-1 rotate-[-5.277deg] pl-5">고민편지 보러가기</p> | ||
| <Link to={'/letter/random'}> | ||
| <img src="/src/assets/go_to_random_letter.png" alt="go to random letter" /> | ||
| </Link> | ||
| </> | ||
| ); | ||
| }; | ||
|
|
||
| export default GoToRandomLetter; |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,14 @@ | ||
| import { Link } from 'react-router'; | ||
|
|
||
| const GoToWrite = () => { | ||
| return ( | ||
| <div className="h-fit pl-[87px]"> | ||
| <p className="text-gray-60 body-r mb-1 rotate-[-5.277deg]">속마음 나누기</p> | ||
| <Link to={'/letter/write'}> | ||
| <img src="/src/assets/go_to_write.png" alt="go to wrte" /> | ||
| </Link> | ||
| </div> | ||
| ); | ||
| }; | ||
|
|
||
| export default GoToWrite; |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,25 @@ | ||
| import RandomCheer from './RandomCheer'; | ||
| import GoToWrite from './GoToWrite'; | ||
| import GoToRandomLetter from './GoToRandomLetter'; | ||
|
|
||
| const HomeLeft = () => { | ||
| return ( | ||
| <div className="flex w-full flex-shrink-0 grow snap-start flex-col justify-between pt-64"> | ||
| <RandomCheer /> | ||
| <GoToWrite /> | ||
|
|
||
| <div className="relative mt-24 flex h-fit w-full flex-col justify-center"> | ||
| <div className="absolute top-[-94px] z-20 w-full"> | ||
| <GoToRandomLetter /> | ||
| </div> | ||
| <img | ||
| src="/src/assets/home_left_mountain.png" | ||
| alt="home left mountain" | ||
| className="z-10 w-full max-w-[600px]" | ||
| /> | ||
| </div> | ||
| </div> | ||
| ); | ||
| }; | ||
|
|
||
| export default HomeLeft; |
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
| @@ -0,0 +1,30 @@ | ||||||
| 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="relative flex h-screen w-full max-w-[800px] flex-shrink-0 grow snap-start flex-col justify-between overflow-x-hidden pt-5"> | ||||||
|
||||||
| {hasNewLetters ? <FloatingLetters /> : null} | ||||||
| <GoToLetterBox /> | ||||||
| <GoToLetterBoard /> | ||||||
| {hasNewLetters ? <NewLetterModal /> : null} | ||||||
|
||||||
| {hasNewLetters ? <NewLetterModal /> : null} | |
| {hasNewLetters && <NewLetterModal />} |
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.
AND 쓰는 게 더 직관적이네요 수정했어요!
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,49 @@ | ||
| 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
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. 오 뭔가... 린트가 반영이 안된 것 같은데 혹시 format on save 설정이 되어 있으신가요?
Collaborator
Author
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. 되어있다고는 뜨는데 계속 import 린트가 반영이 안되는 것 같습니다 🥲 |
||
|
|
||
| const LetterActions = () => { | ||
| const [activeModal, setActiveModal] = useState< | ||
| null | 'incomingLetters' | 'draft' | 'shareAccess' | ||
| >(null); | ||
|
|
||
| return ( | ||
| <div className="absolute top-24 right-5 z-31 mt-3 flex justify-end"> | ||
| <div className="flex flex-col gap-y-3"> | ||
| <button | ||
| onClick={() => { | ||
| setActiveModal('incomingLetters'); | ||
| }} | ||
| 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)]" | ||
| > | ||
| <SendOutlinedIcon /> | ||
| </button> | ||
| <button | ||
| onClick={() => setActiveModal('draft')} | ||
| 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)]" | ||
| > | ||
| <DriveFileRenameOutlineOutlinedIcon /> | ||
| </button> | ||
| <button | ||
| onClick={() => setActiveModal('shareAccess')} | ||
| 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)]" | ||
| > | ||
| <ShareOutlinedIcon /> | ||
| </button> | ||
|
||
| </div> | ||
| {activeModal === 'incomingLetters' && ( | ||
| <ShowIncomingLettersModal onClose={() => setActiveModal(null)} /> | ||
| )} | ||
| {activeModal === 'draft' && <ShowDraftModal onClose={() => setActiveModal(null)} />} | ||
| {activeModal === 'shareAccess' && ( | ||
| <ShowShareAccessModal onClose={() => setActiveModal(null)} /> | ||
| )} | ||
| </div> | ||
| ); | ||
| }; | ||
|
|
||
| export default LetterActions; | ||
|
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. 이건 아직 구현이 안된 게 맞을까요?
Collaborator
Author
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. 네~ merge 후에 develop 브랜치 pull 받고 지원님,민하님 컴포넌트 이용해서 구현할 예정이에요! |
| 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; |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,18 @@ | ||
| import { Link } from 'react-router'; | ||
| import NotificationsNoneRoundedIcon from '@mui/icons-material/NotificationsNoneRounded'; | ||
| import PermIdentityRoundedIcon from '@mui/icons-material/PermIdentityRounded'; | ||
|
|
||
| const NavBar = () => { | ||
| return ( | ||
| <div className="fixed top-[18px] right-5 flex w-full justify-end gap-x-3 text-white"> | ||
| <Link to={'/mypage/notifications'}> | ||
| <NotificationsNoneRoundedIcon /> | ||
| </Link> | ||
| <Link to={'/mypage'}> | ||
| <PermIdentityRoundedIcon /> | ||
| </Link> | ||
| </div> | ||
| ); | ||
| }; | ||
|
|
||
| export default NavBar; |
| 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 relative top-30 mb-10 w-fit animate-pulse self-center rounded-full bg-white px-6 py-4"> | ||
| {newLetterCount}통의 편지가 도착했어요! | ||
| </p> | ||
| ); | ||
| }; | ||
|
|
||
| export default NewLetterModal; |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,30 @@ | ||
| import { useState } from 'react'; | ||
| import { RANDOM_CHEER_LIST } from '../constants'; | ||
|
|
||
| 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="/src/assets/random_cheer_bird.png" | ||
|
||
| alt="random cheer bird" | ||
| className="h-[26.5px] w-[21px] opacity-80" | ||
| /> | ||
| </div> | ||
| ); | ||
| }; | ||
|
|
||
| export default RandomCheer; | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,53 @@ | ||
| import React from 'react'; | ||
| import ModalBg from '@/assets/images/modal-yellow.png'; | ||
| import ModalOverlay from '@/components/ModalOverlay'; | ||
|
|
||
| import DeleteOutlineRoundedIcon from '@mui/icons-material/DeleteOutlineRounded'; | ||
|
|
||
| interface ShowDraftModalProps { | ||
| children?: React.ReactNode; | ||
| onClose: () => void; | ||
| } | ||
|
|
||
| const DUMMY_DRAFT = [ | ||
| { id: 1, title: '취업 때문에 고민이 많아요!!' }, | ||
| { id: 2, title: '배고파서 죽을 거 같아요 😭' }, | ||
| { id: 3, title: '개발하니까 밖에 나갈 일이 없어서 너무 심심하고 피곤해요' }, | ||
| { id: 4, title: '마라샹궈 먹고 싶어요' }, | ||
| ]; | ||
|
|
||
| const ShowDraftModal = ({ onClose }: ShowDraftModalProps) => { | ||
| return ( | ||
| <ModalOverlay closeOnOutsideClick onClose={onClose}> | ||
| <div className="flex h-full flex-col items-center justify-center"> | ||
| <p className="body-sb mb-4 h-fit max-w-[170px] text-center text-white"> | ||
| 임시저장된 편지가 있어요! | ||
| </p> | ||
| <div className="flex w-73 justify-center"> | ||
| <section className="relative overflow-hidden rounded-lg p-5"> | ||
| <img src={ModalBg} className="absolute inset-0 z-[-10] h-full w-full" /> | ||
| <div className="flex flex-col gap-1"> | ||
| <p className="body-sb text-gray-80">임시저장 편지</p> | ||
| <p className="caption-r text-black">로그아웃 시 임시 저장된 편지는 사라집니다</p> | ||
| </div> | ||
| <div className="mt-6 flex w-[251px] flex-col gap-[10px]"> | ||
| {DUMMY_DRAFT.map((draft) => ( | ||
| <div | ||
| className="text-gray-80 body-m flex h-10 w-full items-center justify-between gap-1 rounded-lg bg-white p-3" | ||
| key={draft.id} | ||
| > | ||
| <p className="truncate">{draft.title}</p> | ||
| <div className="text-gray-20"> | ||
| <DeleteOutlineRoundedIcon /> | ||
| </div> | ||
| </div> | ||
| ))} | ||
| </div> | ||
| </section> | ||
| </div> | ||
| </div> | ||
| </ModalOverlay> | ||
| ); | ||
| }; | ||
|
|
||
| export default ShowDraftModal; |
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.
home_left.png랑 home_left_mountain.png가 배경 유무만 다른 것 같은데 둘 다 있는 이유가 있을까요?
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.
home_left.png는 필요없는 파일이라 삭제했습니다!