- updatePageSettings(currentPageId, {
- watermark: {
- ...currentPage.watermark!,
- text: e.target.value,
- },
+ updateWatermark({
+ ...layoutConfig.watermark!,
+ text: e.target.value,
})
}
placeholder="DRAFT, 대외비 등"
@@ -2765,13 +2759,11 @@ export function ReportDesignerRightPanel() {
- updatePageSettings(currentPageId, {
- watermark: {
- ...currentPage.watermark!,
- fontSize: Number(e.target.value),
- },
+ updateWatermark({
+ ...layoutConfig.watermark!,
+ fontSize: Number(e.target.value),
})
}
className="mt-1"
@@ -2784,26 +2776,22 @@ export function ReportDesignerRightPanel() {
- updatePageSettings(currentPageId, {
- watermark: {
- ...currentPage.watermark!,
- fontColor: e.target.value,
- },
+ updateWatermark({
+ ...layoutConfig.watermark!,
+ fontColor: e.target.value,
})
}
className="h-9 w-12 cursor-pointer p-1"
/>
- updatePageSettings(currentPageId, {
- watermark: {
- ...currentPage.watermark!,
- fontColor: e.target.value,
- },
+ updateWatermark({
+ ...layoutConfig.watermark!,
+ fontColor: e.target.value,
})
}
className="flex-1"
@@ -2815,7 +2803,7 @@ export function ReportDesignerRightPanel() {
)}
{/* 이미지 워터마크 설정 */}
- {currentPage.watermark?.type === "image" && (
+ {layoutConfig.watermark?.type === "image" && (
@@ -2843,21 +2831,19 @@ export function ReportDesignerRightPanel() {
) : (
<>
- {currentPage.watermark?.imageUrl ? "이미지 변경" : "이미지 선택"}
+ {layoutConfig.watermark?.imageUrl ? "이미지 변경" : "이미지 선택"}
>
)}
- {currentPage.watermark?.imageUrl && (
+ {layoutConfig.watermark?.imageUrl && (
@@ -2880,13 +2866,11 @@ export function ReportDesignerRightPanel() {
{/* 대각선/타일 회전 각도 */}
- {(currentPage.watermark?.style === "diagonal" ||
- currentPage.watermark?.style === "tile") && (
+ {(layoutConfig.watermark?.style === "diagonal" ||
+ layoutConfig.watermark?.style === "tile") && (
- updatePageSettings(currentPageId, {
- watermark: {
- ...currentPage.watermark!,
- rotation: Number(e.target.value),
- },
+ updateWatermark({
+ ...layoutConfig.watermark!,
+ rotation: Number(e.target.value),
})
}
className="mt-1"
@@ -2929,17 +2911,15 @@ export function ReportDesignerRightPanel() {
- {Math.round((currentPage.watermark?.opacity ?? 0.3) * 100)}%
+ {Math.round((layoutConfig.watermark?.opacity ?? 0.3) * 100)}%
- updatePageSettings(currentPageId, {
- watermark: {
- ...currentPage.watermark!,
- opacity: value[0] / 100,
- },
+ updateWatermark({
+ ...layoutConfig.watermark!,
+ opacity: value[0] / 100,
})
}
min={5}
@@ -2955,17 +2935,15 @@ export function ReportDesignerRightPanel() {
size="sm"
variant="outline"
onClick={() =>
- updatePageSettings(currentPageId, {
- watermark: {
- ...currentPage.watermark!,
- type: "text",
- text: "DRAFT",
- fontSize: 64,
- fontColor: "#cccccc",
- style: "diagonal",
- opacity: 0.2,
- rotation: -45,
- },
+ updateWatermark({
+ ...layoutConfig.watermark!,
+ type: "text",
+ text: "DRAFT",
+ fontSize: 64,
+ fontColor: "#cccccc",
+ style: "diagonal",
+ opacity: 0.2,
+ rotation: -45,
})
}
>
@@ -2975,17 +2953,15 @@ export function ReportDesignerRightPanel() {
size="sm"
variant="outline"
onClick={() =>
- updatePageSettings(currentPageId, {
- watermark: {
- ...currentPage.watermark!,
- type: "text",
- text: "대외비",
- fontSize: 64,
- fontColor: "#ff0000",
- style: "diagonal",
- opacity: 0.15,
- rotation: -45,
- },
+ updateWatermark({
+ ...layoutConfig.watermark!,
+ type: "text",
+ text: "대외비",
+ fontSize: 64,
+ fontColor: "#ff0000",
+ style: "diagonal",
+ opacity: 0.15,
+ rotation: -45,
})
}
>
@@ -2995,17 +2971,15 @@ export function ReportDesignerRightPanel() {
size="sm"
variant="outline"
onClick={() =>
- updatePageSettings(currentPageId, {
- watermark: {
- ...currentPage.watermark!,
- type: "text",
- text: "SAMPLE",
- fontSize: 48,
- fontColor: "#888888",
- style: "tile",
- opacity: 0.1,
- rotation: -30,
- },
+ updateWatermark({
+ ...layoutConfig.watermark!,
+ type: "text",
+ text: "SAMPLE",
+ fontSize: 48,
+ fontColor: "#888888",
+ style: "tile",
+ opacity: 0.1,
+ rotation: -30,
})
}
>
@@ -3015,16 +2989,14 @@ export function ReportDesignerRightPanel() {
size="sm"
variant="outline"
onClick={() =>
- updatePageSettings(currentPageId, {
- watermark: {
- ...currentPage.watermark!,
- type: "text",
- text: "COPY",
- fontSize: 56,
- fontColor: "#aaaaaa",
- style: "center",
- opacity: 0.25,
- },
+ updateWatermark({
+ ...layoutConfig.watermark!,
+ type: "text",
+ text: "COPY",
+ fontSize: 56,
+ fontColor: "#aaaaaa",
+ style: "center",
+ opacity: 0.25,
})
}
>
diff --git a/frontend/components/report/designer/ReportPreviewModal.tsx b/frontend/components/report/designer/ReportPreviewModal.tsx
index 92043666..b8fcb9ce 100644
--- a/frontend/components/report/designer/ReportPreviewModal.tsx
+++ b/frontend/components/report/designer/ReportPreviewModal.tsx
@@ -924,7 +924,7 @@ export function ReportPreviewModal({ isOpen, onClose }: ReportPreviewModalProps)
page.background_color,
pageIndex,
totalPages,
- page.watermark,
+ layoutConfig.watermark, // 전체 페이지 공유 워터마크
),
)
.join('');
@@ -1156,10 +1156,10 @@ export function ReportPreviewModal({ isOpen, onClose }: ReportPreviewModalProps)
backgroundColor: page.background_color,
}}
>
- {/* 워터마크 렌더링 */}
- {page.watermark?.enabled && (
+ {/* 워터마크 렌더링 (전체 페이지 공유) */}
+ {layoutConfig.watermark?.enabled && (
diff --git a/frontend/contexts/ReportDesignerContext.tsx b/frontend/contexts/ReportDesignerContext.tsx
index 206f56db..f8764d15 100644
--- a/frontend/contexts/ReportDesignerContext.tsx
+++ b/frontend/contexts/ReportDesignerContext.tsx
@@ -1,7 +1,7 @@
"use client";
import { createContext, useContext, useState, useCallback, ReactNode, useEffect, useRef } from "react";
-import { ComponentConfig, ReportDetail, ReportLayout, ReportPage, ReportLayoutConfig } from "@/types/report";
+import { ComponentConfig, ReportDetail, ReportLayout, ReportPage, ReportLayoutConfig, WatermarkConfig } from "@/types/report";
import { reportApi } from "@/lib/api/reportApi";
import { useToast } from "@/hooks/use-toast";
import { v4 as uuidv4 } from "uuid";
@@ -40,6 +40,7 @@ interface ReportDesignerContextType {
reorderPages: (sourceIndex: number, targetIndex: number) => void;
selectPage: (pageId: string) => void;
updatePageSettings: (pageId: string, settings: Partial) => void;
+ updateWatermark: (watermark: WatermarkConfig | undefined) => void; // 전체 페이지 공유 워터마크
// 컴포넌트 (현재 페이지)
components: ComponentConfig[]; // currentPage의 components (읽기 전용)
@@ -988,10 +989,19 @@ export function ReportDesignerProvider({ reportId, children }: { reportId: strin
const updatePageSettings = useCallback((pageId: string, settings: Partial) => {
setLayoutConfig((prev) => ({
+ ...prev,
pages: prev.pages.map((page) => (page.page_id === pageId ? { ...page, ...settings } : page)),
}));
}, []);
+ // 전체 페이지 공유 워터마크 업데이트
+ const updateWatermark = useCallback((watermark: WatermarkConfig | undefined) => {
+ setLayoutConfig((prev) => ({
+ ...prev,
+ watermark,
+ }));
+ }, []);
+
// 리포트 및 레이아웃 로드
const loadLayout = useCallback(async () => {
setIsLoading(true);
@@ -1471,6 +1481,7 @@ export function ReportDesignerProvider({ reportId, children }: { reportId: strin
reorderPages,
selectPage,
updatePageSettings,
+ updateWatermark,
// 컴포넌트 (현재 페이지)
components,
diff --git a/frontend/types/report.ts b/frontend/types/report.ts
index 6619b534..3631f831 100644
--- a/frontend/types/report.ts
+++ b/frontend/types/report.ts
@@ -113,12 +113,12 @@ export interface ReportPage {
};
background_color: string;
components: ComponentConfig[];
- watermark?: WatermarkConfig;
}
// 레이아웃 설정 (페이지 기반)
export interface ReportLayoutConfig {
pages: ReportPage[];
+ watermark?: WatermarkConfig; // 전체 페이지 공유 워터마크
}
// 컴포넌트 설정