diff --git a/src/App.tsx b/src/App.tsx index 359b744..0e05801 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,6 +1,7 @@ import { Route, Routes } from 'react-router'; import useViewport from './hooks/useViewport'; +import Header from './layouts/Header'; import Home from './pages/Home'; import LetterBoardPage from './pages/LetterBoard'; import LetterBoardDetailPage from './pages/LetterBoardDetail'; @@ -34,7 +35,7 @@ const App = () => { } /> } /> - + }> } /> } /> diff --git a/src/assets/icons/alarm.svg b/src/assets/icons/alarm.svg new file mode 100644 index 0000000..08ac647 --- /dev/null +++ b/src/assets/icons/alarm.svg @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/src/assets/icons/arrow-left.svg b/src/assets/icons/arrow-left.svg new file mode 100644 index 0000000..e07f071 --- /dev/null +++ b/src/assets/icons/arrow-left.svg @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/src/assets/icons/index.ts b/src/assets/icons/index.ts new file mode 100644 index 0000000..4016f3f --- /dev/null +++ b/src/assets/icons/index.ts @@ -0,0 +1,5 @@ +import AlarmIcon from './alarm.svg?react'; +import ArrowLeftIcon from './arrow-left.svg?react'; +import PersonIcon from './person.svg?react'; + +export { AlarmIcon, PersonIcon, ArrowLeftIcon }; diff --git a/src/assets/icons/person.svg b/src/assets/icons/person.svg new file mode 100644 index 0000000..aca27fb --- /dev/null +++ b/src/assets/icons/person.svg @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/src/assets/images/background-overlay.png b/src/assets/images/background-overlay.png new file mode 100644 index 0000000..e492dbe Binary files /dev/null and b/src/assets/images/background-overlay.png differ diff --git a/src/assets/images/yellow-modal.png b/src/assets/images/yellow-modal.png new file mode 100644 index 0000000..1c78c32 Binary files /dev/null and b/src/assets/images/yellow-modal.png differ diff --git a/src/components/.gitkeep b/src/components/.gitkeep deleted file mode 100644 index e69de29..0000000 diff --git a/src/components/ConfirmModal.tsx b/src/components/ConfirmModal.tsx new file mode 100644 index 0000000..69e67b3 --- /dev/null +++ b/src/components/ConfirmModal.tsx @@ -0,0 +1,58 @@ +import ModalBg from '@/assets/images/yellow-modal.png'; + +import ModalOverlay from './ModalOverlay'; + +interface ConfirmModalProps { + title: string; + description: string; + cancelText: string; + confirmText: string; + children?: React.ReactNode; + onCancel: () => void; + onConfirm: () => void; +} + +const ConfirmModal = ({ + title, + description, + cancelText, + confirmText, + children, + onCancel, + onConfirm, +}: ConfirmModalProps) => { + // TODO: 배경 이미지 삽입 + // TODO: 전역 상태로 관리해야하는지 고민 + return ( + +
+
+ +
+

{title}

+

{description}

+
+ {children} +
+
+ + +
+
+
+ ); +}; + +export default ConfirmModal; diff --git a/src/components/ModalOverlay.tsx b/src/components/ModalOverlay.tsx new file mode 100644 index 0000000..2c637ab --- /dev/null +++ b/src/components/ModalOverlay.tsx @@ -0,0 +1,13 @@ +interface ModalOverlayProps { + children: React.ReactElement; +} + +const ModalOverlay = ({ children }: ModalOverlayProps) => { + return ( +
+ {children} +
+ ); +}; + +export default ModalOverlay; diff --git a/src/hooks/useViewport.ts b/src/hooks/useViewport.ts index 971b0e2..feb0447 100644 --- a/src/hooks/useViewport.ts +++ b/src/hooks/useViewport.ts @@ -3,8 +3,8 @@ import { useEffect } from 'react'; function useViewport() { useEffect(() => { const setViewport = () => { - const vh = window.innerHeight * 0.00999; - const vw = document.documentElement.clientWidth * 0.00999; + const vh = window.innerHeight * 0.01; + const vw = document.documentElement.clientWidth * 0.01; document.documentElement.style.setProperty('--vh', `${vh}px`); document.documentElement.style.setProperty('--vw', `${vw}px`); }; diff --git a/src/layouts/Header.tsx b/src/layouts/Header.tsx new file mode 100644 index 0000000..2b7ebd7 --- /dev/null +++ b/src/layouts/Header.tsx @@ -0,0 +1,22 @@ +import { Outlet } from 'react-router'; + +import { AlarmIcon, ArrowLeftIcon, PersonIcon } from '@/assets/icons'; + +const Header = () => { + // TODO: 뒤로 가기 버튼이 보이는 조건 추가 + // TODO: 스크롤 발생 시, 어떻게 보여져야 하는지 + return ( + <> +
+ +
+ + +
+
+ + + ); +}; + +export default Header; diff --git a/src/pages/MyPage/constants/index.ts b/src/pages/MyPage/constants/index.ts new file mode 100644 index 0000000..b605b37 --- /dev/null +++ b/src/pages/MyPage/constants/index.ts @@ -0,0 +1,9 @@ +export const TEMPERATURE_RANGE = [ + { min: 0, max: 10, description: '따뜻함이 필요한 따숨님' }, + { min: 10, max: 25, description: '살짝 포근한 따숨님' }, + { min: 25, max: 40, description: '따스한 온기를 가진 따숨님' }, + { min: 40, max: 55, description: '마음이 따뜻한 따숨님' }, + { min: 55, max: 70, description: '훈훈한 따숨님' }, + { min: 70, max: 80, description: '정말 따뜻한 따숨님' }, + { min: 85, max: 100, description: '사랑이 넘치는 따숨님' }, +]; diff --git a/src/pages/MyPage/index.tsx b/src/pages/MyPage/index.tsx index 706b622..9554805 100644 --- a/src/pages/MyPage/index.tsx +++ b/src/pages/MyPage/index.tsx @@ -1,5 +1,88 @@ +import { useState } from 'react'; + +import ConfirmModal from '@/components/ConfirmModal'; + +import { TEMPERATURE_RANGE } from './constants'; + +const DUMMY_TEMP = 48.5; +const DUMMY_ZIP_CODE = '235EA'; + const MyPage = () => { - return
MyPage
; + const [isOpenModal, setIsOpenModal] = useState(false); + + const getDescriptionByTemperature = (temp: number) => { + const range = TEMPERATURE_RANGE.find((range) => temp >= range.min && temp < range.max); + return range?.description; + }; + + const description = getDescriptionByTemperature(DUMMY_TEMP); + + return ( + <> + {isOpenModal && ( + setIsOpenModal(false)} + onConfirm={() => setIsOpenModal(false)} + /> + )} +
+

+ {DUMMY_ZIP_CODE.split('').map((code, index) => ( +
+ {code} +
+ ))} +

+
+

+

{description}

+

{DUMMY_TEMP}도

+

+
+
+
+
+
+
+

활동

+

내가 올린 게시물

+
+
+

고객 센터

+

운영자에게 문의하기

+
+
+

계정

+
+

로그인 정보

+

+ 카카오 + kakaoAccount@kakao.com +

+
+

로그아웃

+
+
+ +
+ + ); }; export default MyPage; diff --git a/src/styles/components.css b/src/styles/components.css index d608fb9..e45dfa1 100644 --- a/src/styles/components.css +++ b/src/styles/components.css @@ -1,4 +1,11 @@ /* 재사용 가능한 UI 컴포넌트의 스타일 정의 */ @layer components { + .primary-btn { + @apply bg-primary-3 rounded-lg text-black; + } + + .secondary-btn { + @apply bg-primary-4 rounded-lg text-gray-50; + } } diff --git a/src/styles/preflight.css b/src/styles/preflight.css index 5e69cdd..3d0b045 100644 --- a/src/styles/preflight.css +++ b/src/styles/preflight.css @@ -7,11 +7,26 @@ --vw: 1vw; } + * { + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + } + body { font-family: 'Pretendard Variable', Pretendard, sans-serif; overflow-y: scroll; overflow-x: hidden; /* 그라데이션 배경 들어가는 곳 */ + background: + url('/src/assets/images/background-overlay.png') repeat, + linear-gradient( + 180deg, + rgba(234, 191, 23, 0.5) 2.83%, + rgba(255, 245, 221, 0.5) 35.47%, + rgba(255, 251, 248, 0.5) 55.48% + ), + #f2f2f2; + background-blend-mode: overlay, normal, normal; } #root { @@ -23,4 +38,8 @@ margin: 0 auto; position: relative; } + + button { + cursor: pointer; + } } diff --git a/src/vite-env.d.ts b/src/vite-env.d.ts index 11f02fe..b1f45c7 100644 --- a/src/vite-env.d.ts +++ b/src/vite-env.d.ts @@ -1 +1,2 @@ /// +///