From 2f1946a834b89a40c6ba834c655aae049a68a249 Mon Sep 17 00:00:00 2001 From: kent Date: Tue, 13 Jan 2026 20:50:52 +0900 Subject: [PATCH] =?UTF-8?q?feat(SAM/WEB):=20=EC=88=98=EC=A3=BC=EA=B4=80?= =?UTF-8?q?=EB=A6=AC=20=ED=8E=98=EC=9D=B4=EC=A7=80=EC=97=90=20=EC=88=98?= =?UTF-8?q?=EC=A3=BC=EC=99=84=EB=A3=8C=20FCM=20=EC=95=8C=EB=A6=BC=20?= =?UTF-8?q?=EB=B2=84=ED=8A=BC=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - fcm.ts에 sendSalesOrderNotification 프리셋 함수 추가 - channel_id: push_sales_order, type: sales_order - order-management-sales 페이지에 수주완료 버튼 추가 --- .../sales/order-management-sales/page.tsx | 37 ++++++++++++++++--- src/lib/actions/fcm.ts | 15 ++++++++ 2 files changed, 47 insertions(+), 5 deletions(-) diff --git a/src/app/[locale]/(protected)/sales/order-management-sales/page.tsx b/src/app/[locale]/(protected)/sales/order-management-sales/page.tsx index f788b144..7de2188a 100644 --- a/src/app/[locale]/(protected)/sales/order-management-sales/page.tsx +++ b/src/app/[locale]/(protected)/sales/order-management-sales/page.tsx @@ -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>(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={ - +
+ + +
} stats={stats} searchValue={searchTerm} diff --git a/src/lib/actions/fcm.ts b/src/lib/actions/fcm.ts index 3f41ceea..352c178f 100644 --- a/src/lib/actions/fcm.ts +++ b/src/lib/actions/fcm.ts @@ -160,4 +160,19 @@ export async function sendNewClientNotification( channel_id: 'push_urgent', ...customParams, }); +} + +/** + * 수주 알림 발송 (프리셋) + */ +export async function sendSalesOrderNotification( + customParams?: Partial +): Promise { + return sendFcmNotification({ + title: '수주 알림', + body: '수주가 완료되었습니다.', + type: 'sales_order', + channel_id: 'push_sales_order', + ...customParams, + }); } \ No newline at end of file