diff --git a/src/components/approval/DraftBox/actions.ts b/src/components/approval/DraftBox/actions.ts index 88bd718f..1e7c495d 100644 --- a/src/components/approval/DraftBox/actions.ts +++ b/src/components/approval/DraftBox/actions.ts @@ -457,4 +457,4 @@ export async function cancelDraft(id: string): Promise<{ success: boolean; error error: '서버 오류가 발생했습니다.', }; } -} \ No newline at end of file +} diff --git a/src/components/approval/DraftBox/index.tsx b/src/components/approval/DraftBox/index.tsx index 39fc90d4..21759ca9 100644 --- a/src/components/approval/DraftBox/index.tsx +++ b/src/components/approval/DraftBox/index.tsx @@ -8,6 +8,7 @@ import { Trash2, Plus, Pencil, + Bell, } from 'lucide-react'; import { toast } from 'sonner'; import { @@ -19,6 +20,7 @@ import { submitDraft, submitDrafts, } from './actions'; +import { sendApprovalNotification } from '@/lib/actions/fcm'; import { Button } from '@/components/ui/button'; import { Checkbox } from '@/components/ui/checkbox'; import { Badge } from '@/components/ui/badge'; @@ -243,6 +245,24 @@ export function DraftBox() { router.push('/ko/approval/draft/new'); }, [router]); + // ===== FCM 알림 발송 핸들러 ===== + const handleSendNotification = useCallback(async () => { + startTransition(async () => { + try { + const result = await sendApprovalNotification(); + if (result.success) { + toast.success(`결재 알림을 발송했습니다. (${result.sentCount || 0}건)`); + } else { + toast.error(result.error || '알림 발송에 실패했습니다.'); + } + } catch (error) { + if (isNextRedirectError(error)) throw error; + console.error('Notification error:', error); + toast.error('알림 발송 중 오류가 발생했습니다.'); + } + }); + }, []); + // ===== 문서 클릭/수정 핸들러 (조건부 로직) ===== // 임시저장 → 문서 작성 페이지 (수정 모드) // 그 외 → 문서 상세 모달 (상세 API 호출하여 content 포함된 데이터 가져옴) @@ -597,6 +617,10 @@ export function DraftBox() { )} +