diff --git a/src/app/global.css b/src/app/global.css
index 8602d86..891dc43 100644
--- a/src/app/global.css
+++ b/src/app/global.css
@@ -101,4 +101,8 @@ input[type='number'] {
.shadow-button {
box-shadow: 4px 4px 20px 0px rgba(55, 127, 248, 0.1);
}
+
+ .shadow-noticeItem {
+ box-shadow: 2px 8px 40px -3.034px rgba(50, 65, 96, 0.1);
+ }
}
diff --git a/src/app/stackflow/Stack.tsx b/src/app/stackflow/Stack.tsx
index 1717a06..932f1e7 100644
--- a/src/app/stackflow/Stack.tsx
+++ b/src/app/stackflow/Stack.tsx
@@ -4,10 +4,12 @@ import { stackflow } from '@stackflow/react';
import { LoginScreen } from '@/screen/login/ui';
import { HomeScreen } from '@/screen/home/ui';
+import { NoticeScreen } from '@/screen/notice/ui';
+import { NoticeContentScreen } from '@/screen/notice-content/ui';
export const { Stack, useFlow } = stackflow({
transitionDuration: 350,
- activities: { LoginScreen, HomeScreen },
+ activities: { NoticeScreen, NoticeContentScreen, LoginScreen, HomeScreen },
plugins: [
basicRendererPlugin(),
basicUIPlugin({
diff --git a/src/assets/icon/icon-message.svg b/src/assets/icon/icon-message.svg
new file mode 100644
index 0000000..016c988
--- /dev/null
+++ b/src/assets/icon/icon-message.svg
@@ -0,0 +1,41 @@
+
diff --git a/src/assets/icon/icon-notification.svg b/src/assets/icon/icon-notification.svg
new file mode 100644
index 0000000..6bc0461
--- /dev/null
+++ b/src/assets/icon/icon-notification.svg
@@ -0,0 +1,21 @@
+
diff --git a/src/assets/icon/index.ts b/src/assets/icon/index.ts
index 89cbc40..197429c 100644
--- a/src/assets/icon/index.ts
+++ b/src/assets/icon/index.ts
@@ -1,5 +1,7 @@
import UserIcon from './icon-user.png';
import ResultIcon from './icon-result.svg';
import NoticeIcon from './icon-notice.svg';
+import NotificationIcon from './icon-notification.svg';
+import MessageIcon from './icon-message.svg';
-export { UserIcon, ResultIcon, NoticeIcon };
+export { UserIcon, ResultIcon, NoticeIcon, NotificationIcon, MessageIcon };
diff --git a/src/features/notice/mock/index.ts b/src/features/notice/mock/index.ts
new file mode 100644
index 0000000..6351718
--- /dev/null
+++ b/src/features/notice/mock/index.ts
@@ -0,0 +1 @@
+export * from './notice';
diff --git a/src/features/notice/mock/notice.ts b/src/features/notice/mock/notice.ts
new file mode 100644
index 0000000..9fb973b
--- /dev/null
+++ b/src/features/notice/mock/notice.ts
@@ -0,0 +1,40 @@
+import type { Notice } from '../types';
+
+export const NOTICE_MOCK: Notice[] = [
+ {
+ id: 1,
+ title: '2025년 봄학기 개강 안내',
+ type: 'NOTIFICATION',
+ date: '2025-03-01',
+ },
+ {
+ id: 2,
+ title: '홈페이지 점검 일정 안내',
+ type: 'NOTIFICATION',
+ date: '2025-03-05',
+ },
+ {
+ id: 3,
+ title: '중간고사 일정 공지',
+ type: 'NOTIFICATION',
+ date: '2025-04-10',
+ },
+ {
+ id: 4,
+ title: '신입생 오리엔테이션 안내',
+ type: 'NOTIFICATION',
+ date: '2025-02-25',
+ },
+ {
+ id: 5,
+ title: '장학금 신청 기간 안내',
+ type: 'MESSAGE',
+ date: '2025-03-15',
+ },
+ {
+ id: 6,
+ title: '건물 전기 점검에 따른 이용 제한 안내',
+ type: 'MESSAGE',
+ date: '2025-03-20',
+ },
+];
diff --git a/src/features/notice/types/index.ts b/src/features/notice/types/index.ts
new file mode 100644
index 0000000..6351718
--- /dev/null
+++ b/src/features/notice/types/index.ts
@@ -0,0 +1 @@
+export * from './notice';
diff --git a/src/features/notice/types/notice.ts b/src/features/notice/types/notice.ts
new file mode 100644
index 0000000..c72e46b
--- /dev/null
+++ b/src/features/notice/types/notice.ts
@@ -0,0 +1,8 @@
+export type NoticeType = 'MESSAGE' | 'NOTIFICATION';
+
+export type Notice = {
+ id: number;
+ title: string;
+ type: NoticeType;
+ date: string;
+};
diff --git a/src/features/notice/ui/NoticeItem.tsx b/src/features/notice/ui/NoticeItem.tsx
new file mode 100644
index 0000000..04673a1
--- /dev/null
+++ b/src/features/notice/ui/NoticeItem.tsx
@@ -0,0 +1,44 @@
+import { MessageIcon, NotificationIcon } from '@/assets/icon';
+import type { Notice } from '../types';
+
+import { cn } from '@/shared/utils';
+import { useFlow } from '@/app/stackflow';
+import { PATH } from '@/shared/constants';
+
+export default function NoticeItem({ id, title, type, date }: Notice) {
+ const typeLabel = type === 'NOTIFICATION' ? '알림' : '예정';
+ const { push } = useFlow();
+
+ return (
+
+ );
+}
diff --git a/src/features/notice/ui/NoticeList.tsx b/src/features/notice/ui/NoticeList.tsx
new file mode 100644
index 0000000..17b20fb
--- /dev/null
+++ b/src/features/notice/ui/NoticeList.tsx
@@ -0,0 +1,12 @@
+import { NOTICE_MOCK } from '../mock';
+import NoticeItem from './NoticeItem';
+
+export default function NoticeList() {
+ return (
+
+ {NOTICE_MOCK.map(({ id, title, type, date }) => (
+
+ ))}
+
+ );
+}
diff --git a/src/features/notice/ui/index.ts b/src/features/notice/ui/index.ts
new file mode 100644
index 0000000..86f9a8f
--- /dev/null
+++ b/src/features/notice/ui/index.ts
@@ -0,0 +1,2 @@
+export { default as NoticeList } from './NoticeList';
+export { default as NoticeItem } from './NoticeItem';
diff --git a/src/screen/notice-content/ui/NoticeContentScreen.tsx b/src/screen/notice-content/ui/NoticeContentScreen.tsx
new file mode 100644
index 0000000..8ff5767
--- /dev/null
+++ b/src/screen/notice-content/ui/NoticeContentScreen.tsx
@@ -0,0 +1,24 @@
+import { AppScreen } from '@stackflow/plugin-basic-ui';
+
+import { TitleAppBar } from '@/shared/ui';
+import type { Notice } from '@/features/notice/types';
+import type { ActivityComponentType } from '@stackflow/react';
+import { NoticeContentContainer } from '@/widgets/notice-content/ui';
+
+const NoticeContentScreen: ActivityComponentType<{ notice: Notice }> = ({
+ params,
+}: {
+ params: { notice: Notice };
+}) => {
+ return (
+
+
+
+ );
+};
+
+export default NoticeContentScreen;
diff --git a/src/screen/notice-content/ui/index.ts b/src/screen/notice-content/ui/index.ts
new file mode 100644
index 0000000..bf9a859
--- /dev/null
+++ b/src/screen/notice-content/ui/index.ts
@@ -0,0 +1 @@
+export { default as NoticeContentScreen } from './NoticeContentScreen';
diff --git a/src/screen/notice/ui/NoticeScreen.tsx b/src/screen/notice/ui/NoticeScreen.tsx
new file mode 100644
index 0000000..e0a01cd
--- /dev/null
+++ b/src/screen/notice/ui/NoticeScreen.tsx
@@ -0,0 +1,16 @@
+import { AppScreen } from '@stackflow/plugin-basic-ui';
+
+import { TitleAppBar } from '@/shared/ui';
+import { NoticeContainer } from '@/widgets/notice/ui';
+
+export default function NoticeScreen() {
+ return (
+
+
+
+ );
+}
diff --git a/src/screen/notice/ui/index.ts b/src/screen/notice/ui/index.ts
new file mode 100644
index 0000000..a894689
--- /dev/null
+++ b/src/screen/notice/ui/index.ts
@@ -0,0 +1 @@
+export { default as NoticeScreen } from './NoticeScreen';
diff --git a/src/shared/constants/path.ts b/src/shared/constants/path.ts
index 54b2534..3e37f52 100644
--- a/src/shared/constants/path.ts
+++ b/src/shared/constants/path.ts
@@ -1,4 +1,6 @@
export const PATH = {
HOME: 'HomeScreen',
LOGIN: 'LoginScreen',
+ NOTICE: 'NoticeScreen',
+ NOTICE_CONTENT: 'NoticeContentScreen',
} as const;
diff --git a/src/shared/ui/AppBar.tsx b/src/shared/ui/AppBar.tsx
index 3e564fb..8e745bc 100644
--- a/src/shared/ui/AppBar.tsx
+++ b/src/shared/ui/AppBar.tsx
@@ -19,3 +19,9 @@ export const HomeAppBar = {
),
renderRight: () =>
,
};
+
+export const TitleAppBar = (title: string) => ({
+ ...baseStyle,
+ backgroundColor: '#fff',
+ title: title,
+});
diff --git a/src/widgets/home/ui/HomeContainer.tsx b/src/widgets/home/ui/HomeContainer.tsx
index 922fe87..08ddabd 100644
--- a/src/widgets/home/ui/HomeContainer.tsx
+++ b/src/widgets/home/ui/HomeContainer.tsx
@@ -28,7 +28,7 @@ export default function HomeContainer() {
title="공지사항"
description="예정된 선거를 확인해보세요"
icon={NoticeIcon}
- to={PATH.HOME}
+ to={PATH.NOTICE}
/>
@@ -47,7 +47,11 @@ const ServiceButton = ({