feat(SAM/WEB): 거래처관리 페이지에 신규업체 FCM 알림 버튼 추가

- fcm.ts에 sendNewClientNotification 프리셋 함수 추가
  - channel_id: push_urgent (신규업체 알림용)
  - type: new_client
- 거래처관리 페이지에 "신규업체" 알림 버튼 추가
  - Bell 아이콘과 함께 헤더 액션에 배치
  - useTransition으로 로딩 상태 관리
This commit is contained in:
2026-01-13 20:42:43 +09:00
parent 60d42b2e2e
commit b30a51e84a
2 changed files with 47 additions and 5 deletions

View File

@@ -15,7 +15,7 @@
* - 페이지 기반 CRUD (등록/수정/상세 → 별도 페이지로 이동)
*/
import { useState, useRef, useEffect, useCallback } from "react";
import { useState, useRef, useEffect, useCallback, useTransition } from "react";
import { useRouter } from "next/navigation";
import { useClientList, Client } from "@/hooks/useClientList";
import {
@@ -28,6 +28,7 @@ import {
XCircle,
Eye,
Loader2,
Bell,
} from "lucide-react";
import { Button } from "@/components/ui/button";
import { Badge } from "@/components/ui/badge";
@@ -53,9 +54,12 @@ import {
AlertDialogHeader,
AlertDialogTitle,
} from "@/components/ui/alert-dialog";
import { sendNewClientNotification } from "@/lib/actions/fcm";
import { isNextRedirectError } from "@/lib/utils/redirect-error";
export default function CustomerAccountManagementPage() {
const router = useRouter();
const [isPending, startTransition] = useTransition();
// API 훅 사용
const {
@@ -336,6 +340,23 @@ export default function CustomerAccountManagementPage() {
}
};
// FCM 알림 발송 핸들러
const handleSendNotification = useCallback(async () => {
startTransition(async () => {
try {
const result = await sendNewClientNotification();
if (result.success) {
toast.success(`신규업체 알림을 발송했습니다. (${result.sentCount || 0}건)`);
} else {
toast.error(result.error || "알림 발송에 실패했습니다.");
}
} catch (error) {
if (isNextRedirectError(error)) throw error;
toast.error("알림 발송 중 오류가 발생했습니다.");
}
});
}, []);
// 상태 뱃지
const getStatusBadge = (status: "활성" | "비활성") => {
if (status === "활성") {
@@ -578,10 +599,16 @@ export default function CustomerAccountManagementPage() {
description="거래처 정보 및 계정을 관리합니다"
icon={Building2}
headerActions={
<Button className="ml-auto" onClick={handleAddNew}>
<Plus className="w-4 h-4 mr-2" />
</Button>
<div className="flex gap-2 ml-auto">
<Button variant="outline" onClick={handleSendNotification} disabled={isPending}>
<Bell className="w-4 h-4 mr-2" />
</Button>
<Button onClick={handleAddNew}>
<Plus className="w-4 h-4 mr-2" />
</Button>
</div>
}
stats={stats}
searchValue={searchTerm}

View File

@@ -145,4 +145,19 @@ export async function sendNoticeNotification(
channel_id: 'notice',
...customParams,
});
}
/**
* 신규업체 알림 발송 (프리셋)
*/
export async function sendNewClientNotification(
customParams?: Partial<FcmNotificationParams>
): Promise<FcmResult> {
return sendFcmNotification({
title: '신규업체 알림',
body: '새로운 업체가 등록되었습니다.',
type: 'new_client',
channel_id: 'push_urgent',
...customParams,
});
}