From 729272f44d87498b2ea23a11faa5a95e3494af48 Mon Sep 17 00:00:00 2001 From: DDD1542 Date: Sun, 29 Mar 2026 18:08:02 +0900 Subject: [PATCH] [agent-pipeline] pipe-20260329080516-zyud round-2 --- frontend/components/common/ScreenModal.tsx | 38 +++++++-------- .../widgets/VehicleMapOnlyWidget.tsx | 28 +++++------ frontend/components/layout/AppLayout.tsx | 26 +++++----- frontend/components/layout/ProfileModal.tsx | 16 +++---- frontend/components/layout/TabBar.tsx | 2 +- frontend/components/layout/TabContent.tsx | 7 +-- .../pop/management/PopDeployModal.tsx | 48 +++++++++---------- .../pop/management/PopScreenPreview.tsx | 4 +- .../pop/management/PopScreenSettingModal.tsx | 8 ++-- .../pop/viewer/PopViewerWithModals.tsx | 8 ++-- .../components/screen/CopyScreenModal.tsx | 32 ++++++------- .../components/screen/CreateScreenModal.tsx | 8 ++-- frontend/components/screen/EditModal.tsx | 12 +++-- .../screen/InteractiveDataTable.tsx | 4 +- .../screen/InteractiveScreenViewerDynamic.tsx | 8 ++-- frontend/hooks/useProfile.ts | 12 ++--- frontend/types/profile.ts | 4 +- 17 files changed, 135 insertions(+), 130 deletions(-) diff --git a/frontend/components/common/ScreenModal.tsx b/frontend/components/common/ScreenModal.tsx index 08b1c2d5..1d330d5b 100644 --- a/frontend/components/common/ScreenModal.tsx +++ b/frontend/components/common/ScreenModal.tsx @@ -32,7 +32,7 @@ import { useTabId } from "@/contexts/TabIdContext"; interface ScreenModalState { isOpen: boolean; - screenId: number | null; + screen_id: number | null; title: string; description?: string; size: "sm" | "md" | "lg" | "xl"; @@ -50,7 +50,7 @@ export const ScreenModal: React.FC = ({ className }) => { const [modalState, setModalState] = useState({ isOpen: false, - screenId: null, + screen_id: null, title: "", description: "", size: "md", @@ -417,7 +417,7 @@ export const ScreenModal: React.FC = ({ className }) => { setModalState({ isOpen: true, - screenId, + screen_id: screenId, title, description: description || "", size, @@ -435,7 +435,7 @@ export const ScreenModal: React.FC = ({ className }) => { setModalState({ isOpen: false, - screenId: null, + screen_id: null, title: "", description: "", size: "md", @@ -465,8 +465,8 @@ export const ScreenModal: React.FC = ({ className }) => { setResetKey((prev) => prev + 1); // 화면 데이터 다시 로드 (채번 규칙 새로 생성) - if (modalState.screenId) { - loadScreenData(modalState.screenId); + if (modalState.screen_id) { + loadScreenData(modalState.screen_id); } toast.success("저장되었습니다. 계속 입력하세요."); @@ -489,10 +489,10 @@ export const ScreenModal: React.FC = ({ className }) => { // 화면 데이터 로딩 useEffect(() => { - if (modalState.isOpen && modalState.screenId) { - loadScreenData(modalState.screenId); + if (modalState.isOpen && modalState.screen_id) { + loadScreenData(modalState.screen_id); } - }, [modalState.isOpen, modalState.screenId]); + }, [modalState.isOpen, modalState.screen_id]); const loadScreenData = async (screenId: number) => { try { @@ -921,7 +921,7 @@ export const ScreenModal: React.FC = ({ className }) => { setModalState({ isOpen: false, - screenId: null, + screen_id: null, title: "", size: "md", }); @@ -980,11 +980,11 @@ export const ScreenModal: React.FC = ({ className }) => { let newModalId: string | undefined; // 1순위: screenId (가장 안정적) - if (modalState.screenId) { - newModalId = `screen-modal-${modalState.screenId}`; + if (modalState.screen_id) { + newModalId = `screen-modal-${modalState.screen_id}`; // console.log("🔑 ScreenModal modalId 생성:", { // method: "screenId", - // screenId: modalState.screenId, + // screenId: modalState.screen_id, // result: newModalId, // }); } @@ -1022,7 +1022,7 @@ export const ScreenModal: React.FC = ({ className }) => { } }, [ modalState.isOpen, - modalState.screenId, + modalState.screen_id, modalState.title, screenData?.screenInfo?.tableName, screenData?.screenInfo?.screenName, @@ -1075,7 +1075,7 @@ export const ScreenModal: React.FC = ({ className }) => { ) : screenData ? ( @@ -1251,13 +1251,13 @@ export const ScreenModal: React.FC = ({ className }) => { window.dispatchEvent(new CustomEvent("refreshTable")); }} screenInfo={{ - id: modalState.screenId!, + id: modalState.screen_id!, tableName: screenData.screenInfo?.tableName, }} groupedData={selectedData} userId={userId} userName={userName} - companyCode={user?.company_code || user?.companyCode} + companyCode={user?.company_code} isInModal={true} /> ); @@ -1296,12 +1296,12 @@ export const ScreenModal: React.FC = ({ className }) => { window.dispatchEvent(new CustomEvent("refreshTable")); }} screenInfo={{ - id: modalState.screenId!, + id: modalState.screen_id!, tableName: screenData?.screenInfo?.tableName, }} userId={userId} userName={userName} - companyCode={user?.company_code || user?.companyCode} + companyCode={user?.company_code} isInModal={true} /> ); diff --git a/frontend/components/dashboard/widgets/VehicleMapOnlyWidget.tsx b/frontend/components/dashboard/widgets/VehicleMapOnlyWidget.tsx index 7b6dd1ae..266b8e5d 100644 --- a/frontend/components/dashboard/widgets/VehicleMapOnlyWidget.tsx +++ b/frontend/components/dashboard/widgets/VehicleMapOnlyWidget.tsx @@ -38,8 +38,8 @@ interface Vehicle { status: "active" | "inactive" | "maintenance" | "warning" | "off"; speed: number; destination: string; - userId?: string; // 이동경로 조회용 - tripId?: string; // 현재 운행 ID + user_id?: string; // 이동경로 조회용 + trip_id?: string; // 현재 운행 ID } // 이동경로 좌표 @@ -137,8 +137,8 @@ export default function VehicleMapOnlyWidget({ element, refreshInterval = 30000 : "inactive", speed: parseFloat(row.speed) || 0, destination: row.destination || "대기 중", - userId: row.user_id || undefined, - tripId: row.trip_id || undefined, + user_id: row.user_id || undefined, + trip_id: row.trip_id || undefined, }; }) // 유효한 위도/경도가 있는 차량만 필터링 @@ -160,7 +160,7 @@ export default function VehicleMapOnlyWidget({ element, refreshInterval = 30000 // 이동경로 로드 함수 const loadRoute = async (vehicle: Vehicle) => { - if (!vehicle.userId && !vehicle.tripId) { + if (!vehicle.user_id && !vehicle.trip_id) { console.log("🛣️ 이동경로 조회 불가: userId 또는 tripId 없음"); return; } @@ -175,15 +175,15 @@ export default function VehicleMapOnlyWidget({ element, refreshInterval = 30000 // trip_id가 있으면 해당 운행만, 없으면 user_id로 오늘 전체 조회 let query = ""; - if (vehicle.tripId) { - query = `SELECT latitude, longitude, speed, recorded_at - FROM vehicle_location_history - WHERE trip_id = '${vehicle.tripId}' + if (vehicle.trip_id) { + query = `SELECT latitude, longitude, speed, recorded_at + FROM vehicle_location_history + WHERE trip_id = '${vehicle.trip_id}' ORDER BY recorded_at ASC`; - } else if (vehicle.userId) { - query = `SELECT latitude, longitude, speed, recorded_at - FROM vehicle_location_history - WHERE user_id = '${vehicle.userId}' + } else if (vehicle.user_id) { + query = `SELECT latitude, longitude, speed, recorded_at + FROM vehicle_location_history + WHERE user_id = '${vehicle.user_id}' AND recorded_at >= '${startOfDay}' ORDER BY recorded_at ASC`; } @@ -352,7 +352,7 @@ export default function VehicleMapOnlyWidget({ element, refreshInterval = 30000 목적지: {vehicle.destination} {/* 이동경로 버튼 */} - {(vehicle.userId || vehicle.tripId) && ( + {(vehicle.user_id || vehicle.trip_id) && (
@@ -284,8 +284,8 @@ export function ProfileModal({ onFormChange("userName", e.target.value)} + value={formData.user_name} + onChange={(e) => onFormChange("user_name", e.target.value)} placeholder="이름을 입력하세요" /> @@ -305,15 +305,15 @@ export function ProfileModal({
- onFormChange("dept_name", value)}> {Array.isArray(departments) && departments.length > 0 ? ( departments.map((department) => ( - - {department.deptName} + + {department.dept_name} )) ) : ( diff --git a/frontend/components/layout/TabBar.tsx b/frontend/components/layout/TabBar.tsx index 1ac5144e..508fa641 100644 --- a/frontend/components/layout/TabBar.tsx +++ b/frontend/components/layout/TabBar.tsx @@ -183,7 +183,7 @@ export function TabBar() { const screens = await menuScreenApi.getScreensByMenu(numericObjid); if (screens.length > 0) { openTab( - { type: "screen", title: menuName, screenId: screens[0].screenId, menuObjid: numericObjid }, + { type: "screen", title: menuName, screenId: screens[0].screen_id, menuObjid: numericObjid }, insertIndex, ); return; diff --git a/frontend/components/layout/TabContent.tsx b/frontend/components/layout/TabContent.tsx index f2236b80..e0d90635 100644 --- a/frontend/components/layout/TabContent.tsx +++ b/frontend/components/layout/TabContent.tsx @@ -238,19 +238,20 @@ function TabPageRenderer({ tab: { id: string; type: string; screenId?: number; menuObjid?: number; adminUrl?: string }; refreshKey: number; }) { + const { screenId: tabScreenId } = tab; console.log("[TabPageRenderer] 탭 렌더링:", { tabId: tab.id, type: tab.type, - screenId: tab.screenId, + screenId: tabScreenId, adminUrl: tab.adminUrl, menuObjid: tab.menuObjid, }); - if (tab.type === "screen" && tab.screenId != null) { + if (tab.type === "screen" && tabScreenId != null) { return ( ); diff --git a/frontend/components/pop/management/PopDeployModal.tsx b/frontend/components/pop/management/PopDeployModal.tsx index edfd3044..91d390c9 100644 --- a/frontend/components/pop/management/PopDeployModal.tsx +++ b/frontend/components/pop/management/PopDeployModal.tsx @@ -29,7 +29,7 @@ import { import { toast } from "sonner"; interface LinkedScreenInfo { - screenId: number; + screen_id: number; screenName: string; screenCode: string; references: Array<{ @@ -42,7 +42,7 @@ interface LinkedScreenInfo { } interface ScreenEntry { - screenId: number; + screen_id: number; screenName: string; newScreenName: string; newScreenCode: string; @@ -107,7 +107,7 @@ export function PopDeployModal({ if (isGroupMode && groupScreens) { setGroupEntries( groupScreens.map((s) => ({ - screenId: s.screen_id ?? s.screenId, + screen_id: s.screen_id!, screenName: s.screen_name ?? s.screenName, newScreenName: s.screen_name ?? s.screenName, newScreenCode: "", @@ -120,7 +120,7 @@ export function PopDeployModal({ setScreenName(screen.screen_name ?? screen.screenName); setScreenCode(""); setGroupEntries([]); - analyzeLinks(screen.screen_id ?? screen.screenId); + analyzeLinks(screen.screen_id!); } }, [open, screen, groupScreens, isGroupMode]); @@ -169,13 +169,13 @@ export function PopDeployModal({ const linked: LinkedScreenInfo[] = result.linkedScreenIds.map( (linkedId) => { const linkedScreen = allScreens.find( - (s) => (s.screen_id ?? s.screenId) === linkedId, + (s) => s.screen_id === linkedId, ); const refs = result.references.filter( (r) => r.targetScreenId === linkedId, ); return { - screenId: linkedId, + screen_id: linkedId, screenName: (linkedScreen?.screen_name ?? linkedScreen?.screenName) || `화면 ${linkedId}`, screenCode: (linkedScreen?.screen_code ?? linkedScreen?.screenCode) || "", references: refs.map((r) => ({ @@ -211,7 +211,7 @@ export function PopDeployModal({ screensToSend = groupEntries .filter((e) => e.included && e.newScreenCode) .map((e) => ({ - sourceScreenId: e.screenId, + sourceScreenId: e.screen_id, screenName: e.newScreenName, screenCode: e.newScreenCode, })); @@ -219,14 +219,14 @@ export function PopDeployModal({ if (!screen || !screenName || !screenCode) return; screensToSend = [ { - sourceScreenId: screen.screen_id ?? screen.screenId, + sourceScreenId: screen.screen_id!, screenName, screenCode, }, ...linkedScreens .filter((ls) => ls.deploy) .map((ls) => ({ - sourceScreenId: ls.screenId, + sourceScreenId: ls.screen_id, screenName: ls.newScreenName, screenCode: ls.newScreenCode, })), @@ -283,7 +283,7 @@ export function PopDeployModal({ {isGroupMode ? `"${groupName}" 카테고리의 화면 ${groupScreens!.length}개를 다른 회사로 복사합니다.` : screen - ? `"${screen.screen_name ?? screen.screenName}" (ID: ${screen.screen_id ?? screen.screenId}) 화면을 다른 회사로 복사합니다.` + ? `"${screen.screen_name ?? screen.screenName}" (ID: ${screen.screen_id}) 화면을 다른 회사로 복사합니다.` : "화면을 선택해주세요."} @@ -340,10 +340,10 @@ export function PopDeployModal({
{/* 메인 카테고리의 직접 화면 */} {groupEntries - .filter((e) => groupInfo.screenIds.includes(e.screenId)) + .filter((e) => groupInfo.screenIds.includes(e.screen_id)) .map((entry) => (
{ setGroupEntries((prev) => prev.map((e) => - e.screenId === entry.screenId + e.screen_id === entry.screen_id ? { ...e, included: !!checked } : e, ), @@ -363,7 +363,7 @@ export function PopDeployModal({ {entry.screenName} - #{entry.screenId} + #{entry.screen_id}
))} @@ -376,11 +376,11 @@ export function PopDeployModal({
{groupEntries .filter((e) => - child.screenIds.includes(e.screenId), + child.screenIds.includes(e.screen_id), ) .map((entry) => (
{ setGroupEntries((prev) => prev.map((e) => - e.screenId === entry.screenId + e.screen_id === entry.screen_id ? { ...e, included: !!checked } : e, ), @@ -400,7 +400,7 @@ export function PopDeployModal({ {entry.screenName} - #{entry.screenId} + #{entry.screen_id}
))} @@ -411,7 +411,7 @@ export function PopDeployModal({
{groupEntries.map((entry) => (
{ setGroupEntries((prev) => prev.map((e) => - e.screenId === entry.screenId + e.screen_id === entry.screen_id ? { ...e, included: !!checked } : e, ), @@ -431,7 +431,7 @@ export function PopDeployModal({ {entry.screenName} - #{entry.screenId} + #{entry.screen_id}
))} @@ -484,13 +484,13 @@ export function PopDeployModal({
{linkedScreens.map((ls) => (
{ls.screenName}
- ID: {ls.screenId} |{" "} + ID: {ls.screen_id} |{" "} {ls.references .map((r) => r.referenceType) .join(", ")} @@ -502,7 +502,7 @@ export function PopDeployModal({ onCheckedChange={(checked) => { setLinkedScreens((prev) => prev.map((item) => - item.screenId === ls.screenId + item.screen_id === ls.screen_id ? { ...item, deploy: !!checked } : item, ), diff --git a/frontend/components/pop/management/PopScreenPreview.tsx b/frontend/components/pop/management/PopScreenPreview.tsx index 8a3b4302..cf0a16af 100644 --- a/frontend/components/pop/management/PopScreenPreview.tsx +++ b/frontend/components/pop/management/PopScreenPreview.tsx @@ -46,7 +46,7 @@ export function PopScreenPreview({ screen, className }: PopScreenPreviewProps) { const checkLayout = async () => { try { setLoading(true); - const layout = await screenApi.getLayoutPop(screen.screen_id ?? screen.screenId); + const layout = await screenApi.getLayoutPop(screen.screen_id); // v2 레이아웃: sections는 객체 (Record) // v1 레이아웃: sections는 배열 @@ -71,7 +71,7 @@ export function PopScreenPreview({ screen, className }: PopScreenPreviewProps) { }, [screen]); // 미리보기 URL - const previewUrl = screen ? `/pop/screens/${screen.screen_id ?? screen.screenId}?preview=true&device=${deviceType}` : null; + const previewUrl = screen ? `/pop/screens/${screen.screen_id}?preview=true&device=${deviceType}` : null; // 새 탭에서 열기 const openInNewTab = () => { diff --git a/frontend/components/pop/management/PopScreenSettingModal.tsx b/frontend/components/pop/management/PopScreenSettingModal.tsx index ada3b14e..86f63c7d 100644 --- a/frontend/components/pop/management/PopScreenSettingModal.tsx +++ b/frontend/components/pop/management/PopScreenSettingModal.tsx @@ -114,7 +114,7 @@ export function PopScreenSettingModal({ try { setLoading(true); - const layout = await screenApi.getLayoutPop(screen.screen_id ?? screen.screenId); + const layout = await screenApi.getLayoutPop(screen.screen_id); if (layout && layout.subScreens) { setSubScreens( @@ -173,7 +173,7 @@ export function PopScreenSettingModal({ // screen_definitions 테이블에 화면명/설명 업데이트 if (screenName !== (screen.screen_name ?? screen.screenName) || screenDescription !== (screen.description || "")) { - await screenApi.updateScreenInfo(screen.screen_id ?? screen.screenId, { + await screenApi.updateScreenInfo(screen.screen_id, { screenName, description: screenDescription, isActive: "Y", @@ -181,7 +181,7 @@ export function PopScreenSettingModal({ } // 레이아웃에 하위 화면 정보 저장 - const currentLayout = await screenApi.getLayoutPop(screen.screen_id ?? screen.screenId); + const currentLayout = await screenApi.getLayoutPop(screen.screen_id); const updatedLayout = { ...currentLayout, version: "pop-1.0", @@ -192,7 +192,7 @@ export function PopScreenSettingModal({ })), }; - await screenApi.saveLayoutPop(screen.screen_id ?? screen.screenId, updatedLayout); + await screenApi.saveLayoutPop(screen.screen_id, updatedLayout); toast.success("화면 설정이 저장되었습니다."); onSave?.(screenUpdate); diff --git a/frontend/components/pop/viewer/PopViewerWithModals.tsx b/frontend/components/pop/viewer/PopViewerWithModals.tsx index cc29697b..c6ad9f24 100644 --- a/frontend/components/pop/viewer/PopViewerWithModals.tsx +++ b/frontend/components/pop/viewer/PopViewerWithModals.tsx @@ -142,19 +142,19 @@ export default function PopViewerWithModals({ const unsubNavigate = subscribe("__pop_navigate__", (payload: unknown) => { const data = payload as { - screenId?: string; + screen_id?: string; params?: Record; }; - if (!data?.screenId) return; + if (!data?.screen_id) return; - if (data.screenId === "back") { + if (data.screen_id === "back") { router.back(); } else { const query = data.params ? "?" + new URLSearchParams(data.params).toString() : ""; - window.location.href = `/pop/screens/${data.screenId}${query}`; + window.location.href = `/pop/screens/${data.screen_id}${query}`; } }); diff --git a/frontend/components/screen/CopyScreenModal.tsx b/frontend/components/screen/CopyScreenModal.tsx index 7403b6d7..085a858c 100644 --- a/frontend/components/screen/CopyScreenModal.tsx +++ b/frontend/components/screen/CopyScreenModal.tsx @@ -59,7 +59,7 @@ interface LinkedModalScreen { } interface CompanyInfo { - companyCode: string; + company_code: string; companyName: string; } @@ -263,10 +263,10 @@ export default function CopyScreenModal({ // 원본 회사와 같은 회사가 선택되어 있으면 다른 회사로 변경 if (sourceCompanyCode && targetCompanyCode === sourceCompanyCode) { - const otherCompany = companies.find(c => c.companyCode !== sourceCompanyCode); + const otherCompany = companies.find(c => c.company_code !== sourceCompanyCode); if (otherCompany) { - console.log("🔄 원본 회사 선택됨 → 다른 회사로 자동 변경:", otherCompany.companyCode); - setTargetCompanyCode(otherCompany.companyCode); + console.log("🔄 원본 회사 선택됨 → 다른 회사로 자동 변경:", otherCompany.company_code); + setTargetCompanyCode(otherCompany.company_code); } } }, [companies, isOpen, mode, sourceGroup, sourceScreen, targetCompanyCode]); @@ -317,7 +317,7 @@ export default function CopyScreenModal({ const data = response.data.data || response.data || []; console.log("📋 회사 목록 데이터:", data); const mappedCompanies = data.map((c: any) => ({ - companyCode: c.company_code, + company_code: c.company_code, companyName: c.company_name, })); console.log("📋 매핑된 회사 목록:", mappedCompanies); @@ -783,8 +783,8 @@ export default function CopyScreenModal({ company_code: sourceGroupData.company_code || '', } as any; } - return { screenId, displayOrder, screenRole, screenData }; - }).filter(item => item.screenData && item.screenId); // screenId가 유효한 것만 + return { screen_id: screenId, displayOrder, screenRole, screenData }; + }).filter(item => item.screenData && item.screen_id); // screen_id가 유효한 것만 // display_order 순으로 정렬 screensWithOrder.sort((a, b) => (a.displayOrder || 0) - (b.displayOrder || 0)); @@ -970,11 +970,11 @@ export default function CopyScreenModal({ } else { console.log(` ❌ 화면 정보 없음: screenId=${screenId}, screenName=${screenName}`); } - return { screenId, displayOrder, screenRole, screenData }; - }).filter(item => item.screenData && item.screenId); // screenId가 유효한 것만 - + return { screen_id: screenId, displayOrder, screenRole, screenData }; + }).filter(item => item.screenData && item.screen_id); // screen_id가 유효한 것만 + console.log(`🔍 매핑 완료: ${screensWithOrder.length}개 화면 복사 예정`); - screensWithOrder.forEach(item => console.log(` - ${item.screenId}: ${item.screenData?.screen_name}`)); + screensWithOrder.forEach(item => console.log(` - ${item.screen_id}: ${item.screenData?.screen_name}`)); // display_order 순으로 정렬 screensWithOrder.sort((a, b) => (a.displayOrder || 0) - (b.displayOrder || 0)); @@ -1532,10 +1532,10 @@ export default function CopyScreenModal({ className="mt-1 flex h-8 w-full items-center justify-between rounded-md border border-input bg-background px-3 py-2 text-xs ring-offset-background placeholder:text-muted-foreground focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 sm:h-10 sm:text-sm" > {companies - .filter((company) => company.companyCode !== sourceGroup?.company_code) + .filter((company) => company.company_code !== sourceGroup?.company_code) .map((company) => ( - ))} @@ -1758,9 +1758,9 @@ export default function CopyScreenModal({ {companies - .filter((company) => company.companyCode !== sourceScreen?.company_code) + .filter((company) => company.company_code !== sourceScreen?.company_code) .map((company) => ( - + {company.companyName} ))} diff --git a/frontend/components/screen/CreateScreenModal.tsx b/frontend/components/screen/CreateScreenModal.tsx index fc463273..a7232b7d 100644 --- a/frontend/components/screen/CreateScreenModal.tsx +++ b/frontend/components/screen/CreateScreenModal.tsx @@ -60,7 +60,7 @@ export default function CreateScreenModal({ open, onOpenChange, onCreated, isPop // 화면 코드 자동 생성 const generateCode = async () => { try { - const companyCode = (user as any)?.company_code || (user as any)?.companyCode || "*"; + const companyCode = (user as any)?.company_code || "*"; const generatedCode = await screenApi.generateScreenCode(companyCode); setScreenCode(generatedCode); } catch (e) { @@ -220,7 +220,7 @@ export default function CreateScreenModal({ open, onOpenChange, onCreated, isPop if (!isValid || submitting) return; try { setSubmitting(true); - const companyCode = (user as any)?.company_code || (user as any)?.companyCode || "*"; + const companyCode = (user as any)?.company_code || "*"; // 데이터 소스 타입에 따라 다른 정보 전달 const createData: any = { @@ -248,9 +248,9 @@ export default function CreateScreenModal({ open, onOpenChange, onCreated, isPop const created = await screenApi.createScreen(createData); // POP 모드일 경우 빈 POP 레이아웃 자동 생성 - if (isPop && created.screenId) { + if (isPop && created.screen_id) { try { - await screenApi.saveLayoutPop(created.screenId, { + await screenApi.saveLayoutPop(created.screen_id, { version: "2.0", components: [], }); diff --git a/frontend/components/screen/EditModal.tsx b/frontend/components/screen/EditModal.tsx index 70b57e3f..04189725 100644 --- a/frontend/components/screen/EditModal.tsx +++ b/frontend/components/screen/EditModal.tsx @@ -62,7 +62,8 @@ const findSaveButtonInComponents = (components: any[]): any | null => { // conditional-container의 sections 내부 탐색 if (comp.componentType === "conditional-container" && comp.componentConfig?.sections) { for (const section of comp.componentConfig.sections) { - if (section.screenId) { + const { screenId: sectionScreenId } = section; + if (sectionScreenId) { // 조건부 컨테이너의 내부 화면은 별도로 로드해야 함 // 여기서는 null 반환하고, loadSaveButtonConfig에서 처리 continue; @@ -203,19 +204,20 @@ export const EditModal: React.FC = ({ className }) => { for (const comp of layoutData.components) { if (comp.componentType === "conditional-container" && comp.componentConfig?.sections) { for (const section of comp.componentConfig.sections) { - if (section.screenId) { + const { screenId: sectionScreenId } = section; + if (sectionScreenId) { try { - const innerLayoutData = await screenApi.getLayout(section.screenId); + const innerLayoutData = await screenApi.getLayout(sectionScreenId); saveButton = findSaveButtonInComponents(innerLayoutData?.components || []); if (saveButton) { // console.log("[EditModal] 조건부 컨테이너 내부에서 저장 버튼 발견:", { - // sectionScreenId: section.screenId, + // sectionScreenId: sectionScreenId, // sectionLabel: section.label, // }); break; } } catch (innerError) { - // console.warn("[EditModal] 내부 화면 레이아웃 조회 실패:", section.screenId); + // console.warn("[EditModal] 내부 화면 레이아웃 조회 실패:", sectionScreenId); } } } diff --git a/frontend/components/screen/InteractiveDataTable.tsx b/frontend/components/screen/InteractiveDataTable.tsx index 60d6d0e1..5fa07581 100644 --- a/frontend/components/screen/InteractiveDataTable.tsx +++ b/frontend/components/screen/InteractiveDataTable.tsx @@ -1205,7 +1205,7 @@ export const InteractiveDataTable: React.FC = ({ }); // SaveModal 열기 (등록 모드) - const screenId = component.addModalConfig?.screenId; + const screenId = component.addModalConfig?.screen_id; if (!screenId) { toast.error("화면 설정이 필요합니다. 테이블 설정에서 추가 모달 화면을 지정해주세요."); @@ -1227,7 +1227,7 @@ export const InteractiveDataTable: React.FC = ({ if (!selectedRowData) return; - const screenId = component.addModalConfig?.screenId; + const screenId = component.addModalConfig?.screen_id; if (!screenId) { toast.error("화면 설정이 필요합니다. 테이블 설정에서 수정 모달 화면을 지정해주세요."); diff --git a/frontend/components/screen/InteractiveScreenViewerDynamic.tsx b/frontend/components/screen/InteractiveScreenViewerDynamic.tsx index db75b754..afa04dfa 100644 --- a/frontend/components/screen/InteractiveScreenViewerDynamic.tsx +++ b/frontend/components/screen/InteractiveScreenViewerDynamic.tsx @@ -103,11 +103,11 @@ export const InteractiveScreenViewerDynamic: React.FC Promise, refr const [modalState, setModalState] = useState({ isOpen: false, formData: { - userName: "", + user_name: "", email: "", - deptName: "", + dept_name: "", positionName: "", locale: "", }, @@ -155,9 +155,9 @@ export const useProfile = (user: any, refreshUserData: () => Promise, refr ...prev, isOpen: true, formData: { - userName: user.user_name || "", + user_name: user.user_name || "", email: user.email || "", - deptName: user.dept_name || "", + dept_name: user.dept_name || "", positionName: user.position_name || "", locale: user.locale || "KR", // 기본값을 KR로 설정 }, @@ -416,7 +416,7 @@ export const useProfile = (user: any, refreshUserData: () => Promise, refr // 사용자 정보 저장 데이터 준비 const updateData: any = { - userName: modalState.formData.userName, + userName: modalState.formData.user_name, email: modalState.formData.email, locale: modalState.formData.locale, }; @@ -432,7 +432,7 @@ export const useProfile = (user: any, refreshUserData: () => Promise, refr // 운전자 정보도 저장 (운전자인 경우) if (isDriver) { const driverResponse = await updateDriverProfile({ - userName: modalState.formData.userName, + userName: modalState.formData.user_name, phoneNumber: driverFormData.phoneNumber, licenseNumber: driverFormData.licenseNumber, vehicleNumber: driverFormData.vehicleNumber, diff --git a/frontend/types/profile.ts b/frontend/types/profile.ts index 57816a0c..bdc63c9e 100644 --- a/frontend/types/profile.ts +++ b/frontend/types/profile.ts @@ -3,9 +3,9 @@ */ export interface ProfileFormData { - userName: string; + user_name: string; email: string; - deptName: string; + dept_name: string; positionName: string; locale: string; }