diff --git a/src/components/common/Badge.tsx b/src/components/common/Badge.tsx index 4fbdf72..3be7909 100644 --- a/src/components/common/Badge.tsx +++ b/src/components/common/Badge.tsx @@ -9,7 +9,11 @@ interface BadgeProps { | 'lightPink' | 'lightYellow' | 'outlineGray' - | 'outlineBlue'; + | 'outlineBlue' + | 'lightRed' + | 'grayOutline' + | 'bluesolid' + | 'lightBlueOutline'; className?: string; // 추가적인 여백(ml-2) 등을 줄 때 사용 } @@ -21,12 +25,13 @@ const badgeVariants = { lightYellow: 'bg-yellow-main text-[#CA8A04] border border-[#FEF08A]', // 연노랑 바탕 + 노랑 글씨 (교양필수) outlineBlue: 'bg-white border border-brand-lightBlue text-brand-lightBlue', // 흰 바탕 + 파란 테두리 + 파란 글씨 (요청받은 게시글) outlineGray: 'bg-white border border-gray-300 text-gray-600', // 흰 바탕 + 회색 테두리 - lightRed: 'bg-red-100 text-red-100 border text-gray-600', - grayOutline: 'bg-gray-200 text-zinc-900 text-xs border border-slate-400 ', // 교양필수 + lightRed: + 'bg-red-100 text-zinc-900 border text-gray-600 border-neutral-400 font-normal ', + grayOutline: 'bg-gray-200 text-zinc-900 text-sm border border-slate-400 ', // 교양필수 bluesolid: 'bg-brand-lightBlue text-white text-xs font-light border border-slate-500 font-normal', // 졸업요건 lightBlueOutline: - 'bg-blue-100 text-zinc-900 border text-xs border-brand-lightBlue ', //전공필수 + 'bg-brand-soft text-zinc-900 border text-gray-600 text-xs border-neutral-400 font-normal', //전공필수 }; export const Badge = ({ diff --git a/src/components/common/NotificationBell.tsx b/src/components/common/NotificationBell.tsx new file mode 100644 index 0000000..6bdb7b1 --- /dev/null +++ b/src/components/common/NotificationBell.tsx @@ -0,0 +1,58 @@ +import { useEffect, useState } from 'react'; +import { useNavigate } from 'react-router-dom'; +import { ICONS } from '@/constants/icons'; +import { IconButton } from '@/components/common/IconButton'; + +export const NotificationBell = () => { + const navigate = useNavigate(); + const [unreadCount, setUnreadCount] = useState(0); + + useEffect(() => { + const fetchUnreadCount = async () => { + try { + const token = localStorage.getItem('accessToken'); + const response = await fetch( + 'https://swapclass.duckdns.org/api/notifications/unread-count', + { + method: 'GET', + headers: { + 'Content-Type': 'application/json', + Authorization: `Bearer ${token}`, + }, + }, + ); + + const result = await response.json(); + + // 💡 백엔드 응답(result.success)이 성공이고, data 객체가 존재할 때 + if (result.success && result.data) { + // result.data가 { "typeA": 1, "typeB": 2 } 형태이므로, + // Object.values로 숫자 배열([1, 2])만 뽑아낸 뒤 모두 더해줍니다. + const totalCount = Object.values(result.data).reduce( + (sum: number, current: any) => sum + (Number(current) || 0), + 0, + ); + + setUnreadCount(totalCount); + } + } catch (error) { + console.error('알림 개수 조회 실패:', error); + } + }; + + fetchUnreadCount(); + }, []); + + return ( +
navigate('/alert')} + > + + + {unreadCount > 0 && ( +
+ )} +
+ ); +};