feat(SAM/WEB): 수주관리 페이지에 수주완료 FCM 알림 버튼 추가

- fcm.ts에 sendSalesOrderNotification 프리셋 함수 추가
- channel_id: push_sales_order, type: sales_order
- order-management-sales 페이지에 수주완료 버튼 추가
This commit is contained in:
2026-01-13 20:50:52 +09:00
parent b30a51e84a
commit 2f1946a834
2 changed files with 47 additions and 5 deletions

View File

@@ -10,7 +10,7 @@
* - API 연동 완료 (2025-01-08)
*/
import { useState, useRef, useEffect, useCallback } from "react";
import { useState, useRef, useEffect, useCallback, useTransition } from "react";
import { useRouter } from "next/navigation";
import {
FileText,
@@ -22,6 +22,7 @@ import {
Truck,
Eye,
Loader2,
Bell,
} from "lucide-react";
import { Button } from "@/components/ui/button";
import { Badge } from "@/components/ui/badge";
@@ -58,6 +59,8 @@ import {
type OrderStatus,
type OrderStats,
} from "@/components/orders/actions";
import { sendSalesOrderNotification } from "@/lib/actions/fcm";
import { isNextRedirectError } from "@/lib/utils/redirect-error";
// 상태 뱃지 헬퍼 함수
@@ -83,6 +86,7 @@ function getOrderStatusBadge(status: OrderStatus) {
export default function OrderManagementSalesPage() {
const router = useRouter();
const [isPending, startTransition] = useTransition();
const [searchTerm, setSearchTerm] = useState("");
const [filterType, setFilterType] = useState("all");
const [selectedItems, setSelectedItems] = useState<Set<string>>(new Set());
@@ -390,6 +394,23 @@ export default function OrderManagementSalesPage() {
}
};
// FCM 알림 발송 핸들러
const handleSendNotification = useCallback(async () => {
startTransition(async () => {
try {
const result = await sendSalesOrderNotification();
if (result.success) {
toast.success(`수주완료 알림을 발송했습니다. (${result.sentCount || 0}건)`);
} else {
toast.error(result.error || "알림 발송에 실패했습니다.");
}
} catch (error) {
if (isNextRedirectError(error)) throw error;
toast.error("알림 발송 중 오류가 발생했습니다.");
}
});
}, []);
// 탭 구성
const tabs: TabOption[] = [
{
@@ -620,10 +641,16 @@ export default function OrderManagementSalesPage() {
description="수주 관리 및 생산지시 연동"
icon={FileText}
headerActions={
<Button className="ml-auto" onClick={() => router.push("/sales/order-management-sales/new")}>
<FileText 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={() => router.push("/sales/order-management-sales/new")}>
<FileText className="w-4 h-4 mr-2" />
</Button>
</div>
}
stats={stats}
searchValue={searchTerm}

View File

@@ -160,4 +160,19 @@ export async function sendNewClientNotification(
channel_id: 'push_urgent',
...customParams,
});
}
/**
* 수주 알림 발송 (프리셋)
*/
export async function sendSalesOrderNotification(
customParams?: Partial<FcmNotificationParams>
): Promise<FcmResult> {
return sendFcmNotification({
title: '수주 알림',
body: '수주가 완료되었습니다.',
type: 'sales_order',
channel_id: 'push_sales_order',
...customParams,
});
}