From aefbdb9ec8585e9cc47ffcea62abad25cb78a2b4 Mon Sep 17 00:00:00 2001 From: AAminha Date: Tue, 18 Feb 2025 17:39:05 +0900 Subject: [PATCH 1/6] =?UTF-8?q?design:=20=EC=95=8C=EB=A6=BC=20=ED=8E=98?= =?UTF-8?q?=EC=9D=B4=EC=A7=80=20=EC=97=90=EC=85=8B=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/assets/icons/board.svg | 8 ++++++++ src/assets/icons/envelope.svg | 8 ++++++++ src/assets/icons/index.ts | 5 ++++- src/assets/icons/message.svg | 8 ++++++++ src/assets/icons/siren.svg | 8 ++++++++ 5 files changed, 36 insertions(+), 1 deletion(-) create mode 100644 src/assets/icons/board.svg create mode 100644 src/assets/icons/envelope.svg create mode 100644 src/assets/icons/message.svg create mode 100644 src/assets/icons/siren.svg diff --git a/src/assets/icons/board.svg b/src/assets/icons/board.svg new file mode 100644 index 0000000..11c2560 --- /dev/null +++ b/src/assets/icons/board.svg @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/src/assets/icons/envelope.svg b/src/assets/icons/envelope.svg new file mode 100644 index 0000000..60281da --- /dev/null +++ b/src/assets/icons/envelope.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 index 4016f3f..bd9733e 100644 --- a/src/assets/icons/index.ts +++ b/src/assets/icons/index.ts @@ -1,5 +1,8 @@ import AlarmIcon from './alarm.svg?react'; import ArrowLeftIcon from './arrow-left.svg?react'; +import BoardIcon from './board.svg?react'; +import EnvelopeIcon from './envelope.svg?react'; import PersonIcon from './person.svg?react'; +import SirenIcon from './siren.svg?react'; -export { AlarmIcon, PersonIcon, ArrowLeftIcon }; +export { AlarmIcon, PersonIcon, ArrowLeftIcon, SirenIcon, EnvelopeIcon, BoardIcon }; diff --git a/src/assets/icons/message.svg b/src/assets/icons/message.svg new file mode 100644 index 0000000..dd01d4e --- /dev/null +++ b/src/assets/icons/message.svg @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/src/assets/icons/siren.svg b/src/assets/icons/siren.svg new file mode 100644 index 0000000..f95ec1b --- /dev/null +++ b/src/assets/icons/siren.svg @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file From 1a7be8d23efadec2f5a5173d658aef0c0b4986b0 Mon Sep 17 00:00:00 2001 From: AAminha Date: Tue, 18 Feb 2025 17:39:31 +0900 Subject: [PATCH 2/6] =?UTF-8?q?feat:=20=EC=95=8C=EB=A6=BC=20=EC=95=84?= =?UTF-8?q?=EC=9D=B4=EC=BD=98=20-=20=EC=95=8C=EB=A6=BC=20=ED=8E=98?= =?UTF-8?q?=EC=9D=B4=EC=A7=80=20=EB=9D=BC=EC=9A=B0=ED=8C=85=20=EC=97=B0?= =?UTF-8?q?=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/layouts/.gitkeep | 0 src/layouts/Header.tsx | 6 ++++-- 2 files changed, 4 insertions(+), 2 deletions(-) delete mode 100644 src/layouts/.gitkeep diff --git a/src/layouts/.gitkeep b/src/layouts/.gitkeep deleted file mode 100644 index e69de29..0000000 diff --git a/src/layouts/Header.tsx b/src/layouts/Header.tsx index 2b7ebd7..eceba39 100644 --- a/src/layouts/Header.tsx +++ b/src/layouts/Header.tsx @@ -1,4 +1,4 @@ -import { Outlet } from 'react-router'; +import { Link, Outlet } from 'react-router'; import { AlarmIcon, ArrowLeftIcon, PersonIcon } from '@/assets/icons'; @@ -10,7 +10,9 @@ const Header = () => {
- + + +
From 54f3de3283e4e2c35965261c4856159e94d69adf Mon Sep 17 00:00:00 2001 From: AAminha Date: Tue, 18 Feb 2025 17:40:00 +0900 Subject: [PATCH 3/6] =?UTF-8?q?design:=20=EA=B2=BD=EA=B3=A0=20=EB=AA=A8?= =?UTF-8?q?=EB=8B=AC=EC=B0=BD=20=ED=8D=BC=EB=B8=94=EB=A6=AC=EC=8B=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/ConfirmModal.tsx | 1 - .../Notifications/components/WarningModal.tsx | 58 +++++++++++++++++++ 2 files changed, 58 insertions(+), 1 deletion(-) create mode 100644 src/pages/Notifications/components/WarningModal.tsx diff --git a/src/components/ConfirmModal.tsx b/src/components/ConfirmModal.tsx index 69e67b3..dd1336b 100644 --- a/src/components/ConfirmModal.tsx +++ b/src/components/ConfirmModal.tsx @@ -21,7 +21,6 @@ const ConfirmModal = ({ onCancel, onConfirm, }: ConfirmModalProps) => { - // TODO: 배경 이미지 삽입 // TODO: 전역 상태로 관리해야하는지 고민 return ( diff --git a/src/pages/Notifications/components/WarningModal.tsx b/src/pages/Notifications/components/WarningModal.tsx new file mode 100644 index 0000000..e378603 --- /dev/null +++ b/src/pages/Notifications/components/WarningModal.tsx @@ -0,0 +1,58 @@ +import { useEffect, useRef } from 'react'; +import { twMerge } from 'tailwind-merge'; + +import ModalOverlay from '@/components/ModalOverlay'; + +interface WarningModalProps { + isOpen: boolean; + onClose: () => void; +} + +const WarningModal = ({ isOpen, onClose }: WarningModalProps) => { + const ref = useRef(null); + + useEffect(() => { + const handleOutsideClick = (e: MouseEvent) => { + if (ref.current && !ref.current.contains(e.target as Node)) onClose(); + }; + + if (isOpen) document.addEventListener('click', handleOutsideClick); + + return () => { + document.removeEventListener('click', handleOutsideClick); + }; + }, [isOpen, onClose]); + + if (!isOpen) return null; + + return ( + +
+
+
+

경고 안내

+

+ 따사로운 서비스 이용을 위해, 부적절하다고 판단되는 편지는 반려하고 있어요. 서로를 + 존중하는 따뜻한 공간을 만들기 위해 협조 부탁드립니다. +

+

경고 규칙

+

+ 1회 경고: 주의 안내 +
+ 2회 경고: 7일 동안 서비스 이용 제한 +
+ 3회 경고: 서비스 이용 불가능 +

+
+
+
+ ); +}; + +export default WarningModal; From e72db2c685b048e13860d9bedc6c9f749b935266 Mon Sep 17 00:00:00 2001 From: AAminha Date: Tue, 18 Feb 2025 17:40:13 +0900 Subject: [PATCH 4/6] =?UTF-8?q?design:=20=EC=95=8C=EB=A6=BC=20=ED=8E=98?= =?UTF-8?q?=EC=9D=B4=EC=A7=80=20=ED=8D=BC=EB=B8=94=EB=A6=AC=EC=8B=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../components/NotificationItem.tsx | 36 +++++++++++++ src/pages/Notifications/constants/index.ts | 10 ++++ src/pages/Notifications/index.tsx | 52 ++++++++++++++++++- src/styles/components.css | 14 +++++ 4 files changed, 111 insertions(+), 1 deletion(-) create mode 100644 src/pages/Notifications/components/NotificationItem.tsx create mode 100644 src/pages/Notifications/constants/index.ts diff --git a/src/pages/Notifications/components/NotificationItem.tsx b/src/pages/Notifications/components/NotificationItem.tsx new file mode 100644 index 0000000..bd423fb --- /dev/null +++ b/src/pages/Notifications/components/NotificationItem.tsx @@ -0,0 +1,36 @@ +import { twMerge } from 'tailwind-merge'; + +import { NOTIFICATION_ICON } from '../constants'; + +interface NotificationItemProps { + type: string; + message: string; + isRead: boolean; + onClick: () => void; +} + +const NotificationItem = ({ type, message, isRead, onClick }: NotificationItemProps) => { + const Icon = NOTIFICATION_ICON[type]; + + const handleClick = (e: React.MouseEvent) => { + e.stopPropagation(); + onClick(); + }; + + return ( +
+ {isRead &&
} +
+ +

{message}

+
+ ); +}; + +export default NotificationItem; diff --git a/src/pages/Notifications/constants/index.ts b/src/pages/Notifications/constants/index.ts new file mode 100644 index 0000000..5640733 --- /dev/null +++ b/src/pages/Notifications/constants/index.ts @@ -0,0 +1,10 @@ +import { BoardIcon, EnvelopeIcon, SirenIcon } from '@/assets/icons'; + +export const NOTIFICATION_ICON: Record< + string, + React.ComponentType> +> = { + letter: EnvelopeIcon, + warning: SirenIcon, + board: BoardIcon, +}; diff --git a/src/pages/Notifications/index.tsx b/src/pages/Notifications/index.tsx index 99de346..0db70c0 100644 --- a/src/pages/Notifications/index.tsx +++ b/src/pages/Notifications/index.tsx @@ -1,5 +1,55 @@ +import { useState } from 'react'; + +import NotificationItem from './components/NotificationItem'; +import WarningModal from './components/WarningModal'; + +const DUMMY_NOTI = [ + { id: 1, type: 'letter', message: '12E31님이 편지를 보냈습니다.', isRead: false }, + { id: 2, type: 'warning', message: '따숨님, 욕설로 인해 경고를 받으셨어요.', isRead: false }, + { id: 3, type: 'letter', message: '12E31님이 편지를 보냈습니다.', isRead: false }, + { id: 4, type: 'letter', message: '12E31님이 편지를 보냈습니다.', isRead: true }, + { id: 5, type: 'letter', message: '12E31님이 편지를 보냈습니다.', isRead: false }, + { id: 6, type: 'board', message: '12E31님과의 대화가 게시판에 공유되었어요.', isRead: false }, + { + id: 7, + type: 'board', + message: '12E31님과의 게시글에 대한 공유요청을 보냈어요.', + isRead: false, + }, +]; + const NotificationsPage = () => { - return
NotificationsPage
; + const [isOpenWarningModal, setIsOpenWarningModal] = useState(false); + + const handleClickItem = (type: string) => { + if (type === 'warning') { + setIsOpenWarningModal(true); + } + }; + + return ( + <> + setIsOpenWarningModal(false)} /> +
+

알림

+ +
    + {DUMMY_NOTI.map((notification) => ( +
  • + handleClickItem(notification.type)} + /> +
  • + ))} +
+
+ + ); }; export default NotificationsPage; diff --git a/src/styles/components.css b/src/styles/components.css index e45dfa1..d08e121 100644 --- a/src/styles/components.css +++ b/src/styles/components.css @@ -8,4 +8,18 @@ .secondary-btn { @apply bg-primary-4 rounded-lg text-gray-50; } + + .alarm-default-bg { + background: + url('/src/assets/images/background-overlay.png') repeat, + linear-gradient(180deg, #ffb5ac 0%, #ffc1ba 28%, #ffd3ce 98.5%); + background-blend-mode: overlay, normal, normal; + } + + .alarm-warning-bg { + background: + url('/src/assets/images/background-overlay.png') repeat, + linear-gradient(180deg, #fad446 0%, #f8de8c 28%, #ffeab8 98.5%); + background-blend-mode: overlay, normal, normal; + } } From b2839808f706586f58863df502b2ab8ba20cb46b Mon Sep 17 00:00:00 2001 From: AAminha Date: Tue, 18 Feb 2025 20:42:23 +0900 Subject: [PATCH 5/6] =?UTF-8?q?design:=20=ED=8E=98=EC=9D=B4=EC=A7=80=20?= =?UTF-8?q?=EC=83=81=EB=8B=A8=20=EA=B0=84=EA=B2=A9=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/layouts/Header.tsx | 2 +- src/pages/MyPage/index.tsx | 2 +- src/pages/Notifications/index.tsx | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/layouts/Header.tsx b/src/layouts/Header.tsx index eceba39..70a6a5a 100644 --- a/src/layouts/Header.tsx +++ b/src/layouts/Header.tsx @@ -7,7 +7,7 @@ const Header = () => { // TODO: 스크롤 발생 시, 어떻게 보여져야 하는지 return ( <> -
+
diff --git a/src/pages/MyPage/index.tsx b/src/pages/MyPage/index.tsx index 9554805..5c3a4a6 100644 --- a/src/pages/MyPage/index.tsx +++ b/src/pages/MyPage/index.tsx @@ -29,7 +29,7 @@ const MyPage = () => { onConfirm={() => setIsOpenModal(false)} /> )} -
+

{DUMMY_ZIP_CODE.split('').map((code, index) => (
{ return ( <> setIsOpenWarningModal(false)} /> -
+

알림