diff --git a/package.json b/package.json index af558fe..c1b1988 100644 --- a/package.json +++ b/package.json @@ -22,6 +22,7 @@ "react": "^19.1.0", "react-dom": "^19.1.0", "react-hook-form": "^7.56.4", + "react-icons": "^5.5.0", "tailwind-merge": "^3.3.0", "tailwindcss": "^4.1.7" }, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 6058ffc..4b9225f 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -44,6 +44,9 @@ importers: react-hook-form: specifier: ^7.56.4 version: 7.56.4(react@19.1.0) + react-icons: + specifier: ^5.5.0 + version: 5.5.0(react@19.1.0) tailwind-merge: specifier: ^3.3.0 version: 3.3.0 @@ -1311,6 +1314,11 @@ packages: peerDependencies: react: ^16.8.0 || ^17 || ^18 || ^19 + react-icons@5.5.0: + resolution: {integrity: sha512-MEFcXdkP3dLo8uumGI5xN3lDFNsRtrjbOEKDLD7yv76v4wpnEq2Lt2qeHaQOr34I/wPN3s3+N08WkQ+CW37Xiw==} + peerDependencies: + react: '*' + react@19.1.0: resolution: {integrity: sha512-FS+XFBNvn3GTAWq26joslQgWNoFu08F4kl0J4CgdNKADkdSGXQyTCnKteIAJy96Br6YbpEU1LSzV5dYtjMkMDg==} engines: {node: '>=0.10.0'} @@ -2462,6 +2470,10 @@ snapshots: dependencies: react: 19.1.0 + react-icons@5.5.0(react@19.1.0): + dependencies: + react: 19.1.0 + react@19.1.0: {} resolve-from@4.0.0: {} diff --git a/src/app/global.css b/src/app/global.css index 891dc43..ee18471 100644 --- a/src/app/global.css +++ b/src/app/global.css @@ -26,6 +26,7 @@ --spacing-normal: 20px; --spacing-normal-half: 10px; + --spacing-mt: 24px; --radius-lg: 20px; --radius-md: 12px; @@ -86,6 +87,18 @@ input[type='number'] { scrollbar-width: none; } + .overlay { + position: fixed; + inset: 0; + z-index: 300; + background-color: rgba(0, 0, 0, 0); + transition: background-color 0.3s ease-in-out; + } + + .overlay-visible { + background-color: rgba(0, 0, 0, 0.2); + } + .logo { font-family: Fredoka; } @@ -105,4 +118,12 @@ input[type='number'] { .shadow-noticeItem { box-shadow: 2px 8px 40px -3.034px rgba(50, 65, 96, 0.1); } + + .shadow-resultItem { + box-shadow: 8px 8px 30px 0px rgba(55, 127, 248, 0.16); + } + + .shadow-resultContent { + box-shadow: 11px 8px 30px rgba(55, 127, 248, 0.16); + } } diff --git a/src/app/stackflow/Stack.tsx b/src/app/stackflow/Stack.tsx index 932f1e7..53d923a 100644 --- a/src/app/stackflow/Stack.tsx +++ b/src/app/stackflow/Stack.tsx @@ -6,10 +6,19 @@ 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'; +import { VoteResultScreen } from '@/screen/vote-result/ui'; +import { VoteResultContentScreen } from '@/screen/vote-result-content/ui'; export const { Stack, useFlow } = stackflow({ transitionDuration: 350, - activities: { NoticeScreen, NoticeContentScreen, LoginScreen, HomeScreen }, + activities: { + NoticeScreen, + NoticeContentScreen, + VoteResultScreen, + VoteResultContentScreen, + LoginScreen, + HomeScreen, + }, plugins: [ basicRendererPlugin(), basicUIPlugin({ diff --git a/src/assets/icon/icon-vote.svg b/src/assets/icon/icon-vote.svg new file mode 100644 index 0000000..5cdfc3c --- /dev/null +++ b/src/assets/icon/icon-vote.svg @@ -0,0 +1,34 @@ + +
+ +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
diff --git a/src/assets/icon/index.ts b/src/assets/icon/index.ts index 197429c..0268af3 100644 --- a/src/assets/icon/index.ts +++ b/src/assets/icon/index.ts @@ -3,5 +3,13 @@ import ResultIcon from './icon-result.svg'; import NoticeIcon from './icon-notice.svg'; import NotificationIcon from './icon-notification.svg'; import MessageIcon from './icon-message.svg'; +import VoteIcon from './icon-vote.svg'; -export { UserIcon, ResultIcon, NoticeIcon, NotificationIcon, MessageIcon }; +export { + UserIcon, + ResultIcon, + NoticeIcon, + NotificationIcon, + MessageIcon, + VoteIcon, +}; diff --git a/src/features/notice/ui/NoticeItem.tsx b/src/features/notice/ui/NoticeItem.tsx index 04673a1..1c49f17 100644 --- a/src/features/notice/ui/NoticeItem.tsx +++ b/src/features/notice/ui/NoticeItem.tsx @@ -12,7 +12,7 @@ export default function NoticeItem({ id, title, type, date }: Notice) { return ( + ))} + + + )} + + ); +} diff --git a/src/widgets/vote-result/ui/VoteResultContainer.tsx b/src/widgets/vote-result/ui/VoteResultContainer.tsx new file mode 100644 index 0000000..4720879 --- /dev/null +++ b/src/widgets/vote-result/ui/VoteResultContainer.tsx @@ -0,0 +1,45 @@ +import { IoChevronDownSharp } from 'react-icons/io5'; + +import { BOTTOM_SHEET } from '@/shared/constants'; +import { useBottomSheet } from '@/shared/hook'; +import { cn } from '@/shared/utils'; + +import { VoteResultItem } from '@/widgets/vote-result/ui'; + +interface VoteResultContainerProps { + selectedYear: number; +} + +export default function VoteResultContainer({ + selectedYear, +}: VoteResultContainerProps) { + const { openBottomSheet, bottomSheetState } = useBottomSheet(); + const { isOpen } = bottomSheetState(BOTTOM_SHEET.VOTE_RESULT); + + return ( +
+
+ +
+
+ {selectedYear} +
+ + + + + +
+
+
+ ); +} diff --git a/src/widgets/vote-result/ui/VoteResultItem.tsx b/src/widgets/vote-result/ui/VoteResultItem.tsx new file mode 100644 index 0000000..75b7a25 --- /dev/null +++ b/src/widgets/vote-result/ui/VoteResultItem.tsx @@ -0,0 +1,24 @@ +import { useFlow } from '@/app/stackflow'; +import { PATH } from '@/shared/constants'; + +export default function VoteResultItem() { + const { push } = useFlow(); + + return ( + + ); +} diff --git a/src/widgets/vote-result/ui/index.ts b/src/widgets/vote-result/ui/index.ts new file mode 100644 index 0000000..1919793 --- /dev/null +++ b/src/widgets/vote-result/ui/index.ts @@ -0,0 +1,3 @@ +export { default as VoteResultContainer } from './VoteResultContainer'; +export { default as VoteResultBottomSheet } from './VoteResultBottomSheet'; +export { default as VoteResultItem } from './VoteResultItem';