([]);
- // 알바님 알림: 승인/거절만 표시
- const alerts: Alert[] = useMemo(() => {
+ // 1) 서버 알림 불러오기 (사장님/알바 공통)
+ useEffect(() => {
+ if (!isLogin || !user?.id) {
+ setApiAlerts([]);
+ return;
+ }
+ (async () => {
+ try {
+ const res = await getUserAlerts(user.id, { offset: 0, limit: 50 });
+ const mapped: Alert[] = (res.items ?? []).map(({ item }) => ({
+ id: item.id,
+ createdAt: item.createdAt,
+ result: item.result,
+ read: item.read,
+ shop: { item: item.shop.item },
+ notice: { item: item.notice.item },
+ }));
+ setApiAlerts(mapped);
+ } catch {
+ setApiAlerts([]); // 실패해도 UI는 동작(직원 fallback)
+ }
+ })();
+ }, [isLogin, user?.id]);
+
+ // 2) (직원 전용) 지원내역 기반 fallback 알림
+ const fallbackAlertsForEmployee: Alert[] = useMemo(() => {
+ if (role !== 'employee') return [];
return applications
.filter(a => a.item.status !== 'pending')
.map(a => ({
id: a.item.id,
createdAt: a.item.createdAt ?? new Date().toISOString(),
result: a.item.status === 'accepted' ? 'accepted' : 'rejected',
- // ▶ 읽음: 사용자가 메시지를 클릭했을 때만 true
read: readIds.has(a.item.id),
shop: { item: a.item.shop.item, href: `/shops/${a.item.shop.item.id}` },
notice: { item: a.item.notice.item, href: `/notices/${a.item.notice.item.id}` },
}));
- }, [applications, readIds]);
+ }, [applications, role, readIds]);
+
+ // 3) 실제 표시할 알림: 서버 결과가 있으면 우선, 없으면(특히 직원) fallback
+ const alerts: Alert[] = useMemo(() => {
+ const base = apiAlerts.length > 0 ? apiAlerts : fallbackAlertsForEmployee;
+ return base.map(a => (readIds.has(a.id) ? { ...a, read: true } : a));
+ }, [apiAlerts, fallbackAlertsForEmployee, readIds]);
- const handleRead = (id: string) => {
- setReadIds(prev => {
- const next = new Set(prev);
- next.add(id);
- return next;
- });
+ const unreadCount = alerts.filter(a => !a.read).length;
+ const bellIcon: 'notificationOn' | 'notificationOff' =
+ open || unreadCount > 0 ? 'notificationOn' : 'notificationOff';
+ const bellColor = open || unreadCount > 0 ? 'bg-red-400' : 'bg-black';
+
+ // 알림 읽음 처리(서버 + 로컬 동기화)
+ const handleRead = async (id: string) => {
+ try {
+ if (user?.id) await markAlertRead(user.id, id);
+ } finally {
+ setReadIds(prev => {
+ const next = new Set(prev);
+ next.add(id);
+ return next;
+ });
+ setApiAlerts(prev => prev.map(a => (a.id === id ? { ...a, read: true } : a)));
+ }
};
- // role이 초기 undefined일 수 있어 방어
const currentRole: UserRole = (role ?? 'guest') as UserRole;
- // 아이콘은 "패널 열림 상태"로만 토글
- const bellIcon: 'notificationOn' | 'notificationOff' = open
- ? 'notificationOn'
- : 'notificationOff';
-
return (