Merge branch 'main' of http://39.117.244.52:3000/kjs/ERP-node into feature/prisma-to-raw-query-phase1-complete
This commit is contained in:
@@ -2,6 +2,7 @@ import {
|
||||
Users, Shield, Settings, BarChart3, Palette, Layout, Database, Package
|
||||
} from "lucide-react";
|
||||
import Link from "next/link";
|
||||
import { GlobalFileViewer } from "@/components/GlobalFileViewer";
|
||||
|
||||
/**
|
||||
* 관리자 메인 페이지
|
||||
@@ -199,6 +200,16 @@ export default function AdminPage() {
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* 전역 파일 관리 */}
|
||||
<div className="mx-auto max-w-7xl space-y-6">
|
||||
<div className="text-center mb-6">
|
||||
<h2 className="text-2xl font-bold text-gray-900 mb-2">전역 파일 관리</h2>
|
||||
<p className="text-gray-600">모든 페이지에서 업로드된 파일들을 관리합니다</p>
|
||||
</div>
|
||||
<GlobalFileViewer />
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -13,6 +13,7 @@ import { useRouter } from "next/navigation";
|
||||
import { toast } from "sonner";
|
||||
import { initializeComponents } from "@/lib/registry/components";
|
||||
import { EditModal } from "@/components/screen/EditModal";
|
||||
import { isFileComponent, getComponentWebType } from "@/lib/utils/componentTypeUtils";
|
||||
// import { ResponsiveScreenContainer } from "@/components/screen/ResponsiveScreenContainer"; // 컨테이너 제거
|
||||
|
||||
export default function ScreenViewPage() {
|
||||
@@ -116,10 +117,10 @@ export default function ScreenViewPage() {
|
||||
|
||||
if (loading) {
|
||||
return (
|
||||
<div className="flex h-full min-h-[400px] w-full items-center justify-center bg-white">
|
||||
<div className="text-center">
|
||||
<Loader2 className="mx-auto h-8 w-8 animate-spin text-blue-600" />
|
||||
<p className="mt-2 text-gray-600">화면을 불러오는 중...</p>
|
||||
<div className="flex h-full min-h-[400px] w-full items-center justify-center bg-gradient-to-br from-gray-50 to-slate-100">
|
||||
<div className="text-center bg-white rounded-xl border border-gray-200/60 shadow-lg p-8">
|
||||
<Loader2 className="mx-auto h-10 w-10 animate-spin text-blue-600" />
|
||||
<p className="mt-4 text-gray-700 font-medium">화면을 불러오는 중...</p>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
@@ -127,14 +128,14 @@ export default function ScreenViewPage() {
|
||||
|
||||
if (error || !screen) {
|
||||
return (
|
||||
<div className="flex h-full min-h-[400px] w-full items-center justify-center bg-white">
|
||||
<div className="text-center">
|
||||
<div className="mx-auto mb-4 flex h-16 w-16 items-center justify-center rounded-full bg-red-100">
|
||||
<span className="text-2xl">⚠️</span>
|
||||
<div className="flex h-full min-h-[400px] w-full items-center justify-center bg-gradient-to-br from-gray-50 to-slate-100">
|
||||
<div className="text-center bg-white rounded-xl border border-gray-200/60 shadow-lg p-8 max-w-md">
|
||||
<div className="mx-auto mb-6 flex h-20 w-20 items-center justify-center rounded-full bg-gradient-to-br from-red-100 to-orange-100 shadow-sm">
|
||||
<span className="text-3xl">⚠️</span>
|
||||
</div>
|
||||
<h2 className="mb-2 text-xl font-semibold text-gray-900">화면을 찾을 수 없습니다</h2>
|
||||
<p className="mb-4 text-gray-600">{error || "요청하신 화면이 존재하지 않습니다."}</p>
|
||||
<Button onClick={() => router.back()} variant="outline">
|
||||
<h2 className="mb-3 text-xl font-bold text-gray-900">화면을 찾을 수 없습니다</h2>
|
||||
<p className="mb-6 text-gray-600 leading-relaxed">{error || "요청하신 화면이 존재하지 않습니다."}</p>
|
||||
<Button onClick={() => router.back()} variant="outline" className="rounded-lg">
|
||||
이전으로 돌아가기
|
||||
</Button>
|
||||
</div>
|
||||
@@ -147,17 +148,17 @@ export default function ScreenViewPage() {
|
||||
const screenHeight = layout?.screenResolution?.height || 800;
|
||||
|
||||
return (
|
||||
<div className="h-full w-full overflow-auto bg-white pt-10">
|
||||
<div className="h-full w-full overflow-auto bg-gradient-to-br from-gray-50 to-slate-100 pt-10">
|
||||
{layout && layout.components.length > 0 ? (
|
||||
// 캔버스 컴포넌트들을 정확한 해상도로 표시
|
||||
<div
|
||||
className="relative bg-white"
|
||||
className="relative bg-white rounded-xl border border-gray-200/60 shadow-lg shadow-gray-900/5 mx-auto"
|
||||
style={{
|
||||
width: `${screenWidth}px`,
|
||||
height: `${screenHeight}px`,
|
||||
minWidth: `${screenWidth}px`,
|
||||
minHeight: `${screenHeight}px`,
|
||||
margin: "0", // mx-auto 제거하여 사이드바 오프셋 방지
|
||||
margin: "0 auto 40px auto", // 하단 여백 추가
|
||||
}}
|
||||
>
|
||||
{layout.components
|
||||
@@ -177,15 +178,16 @@ export default function ScreenViewPage() {
|
||||
width: `${component.size.width}px`,
|
||||
height: `${component.size.height}px`,
|
||||
zIndex: component.position.z || 1,
|
||||
backgroundColor: (component as any).backgroundColor || "rgba(59, 130, 246, 0.1)",
|
||||
border: (component as any).border || "2px dashed #3b82f6",
|
||||
borderRadius: (component as any).borderRadius || "8px",
|
||||
padding: "16px",
|
||||
backgroundColor: (component as any).backgroundColor || "rgba(59, 130, 246, 0.05)",
|
||||
border: (component as any).border || "1px solid rgba(59, 130, 246, 0.2)",
|
||||
borderRadius: (component as any).borderRadius || "12px",
|
||||
padding: "20px",
|
||||
boxShadow: "0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06)",
|
||||
}}
|
||||
>
|
||||
{/* 그룹 제목 */}
|
||||
{(component as any).title && (
|
||||
<div className="mb-2 text-sm font-medium text-blue-700">{(component as any).title}</div>
|
||||
<div className="mb-3 text-sm font-semibold text-blue-700 bg-blue-50 px-3 py-1 rounded-lg inline-block">{(component as any).title}</div>
|
||||
)}
|
||||
|
||||
{/* 그룹 내 자식 컴포넌트들 렌더링 */}
|
||||
@@ -324,7 +326,19 @@ export default function ScreenViewPage() {
|
||||
/>
|
||||
) : (
|
||||
<DynamicWebTypeRenderer
|
||||
webType={component.webType || "text"}
|
||||
webType={(() => {
|
||||
// 유틸리티 함수로 파일 컴포넌트 감지
|
||||
if (isFileComponent(component)) {
|
||||
console.log(`🎯 page.tsx - 파일 컴포넌트 감지 → webType: "file"`, {
|
||||
componentId: component.id,
|
||||
componentType: component.type,
|
||||
originalWebType: component.webType
|
||||
});
|
||||
return "file";
|
||||
}
|
||||
// 다른 컴포넌트는 유틸리티 함수로 webType 결정
|
||||
return getComponentWebType(component) || "text";
|
||||
})()}
|
||||
config={component.webTypeConfig}
|
||||
props={{
|
||||
component: component,
|
||||
@@ -338,13 +352,13 @@ export default function ScreenViewPage() {
|
||||
},
|
||||
onFormDataChange: (fieldName, value) => {
|
||||
console.log(`🎯 page.tsx onFormDataChange 호출: ${fieldName} = "${value}"`);
|
||||
console.log(`📋 현재 formData:`, formData);
|
||||
console.log("📋 현재 formData:", formData);
|
||||
setFormData((prev) => {
|
||||
const newFormData = {
|
||||
...prev,
|
||||
[fieldName]: value,
|
||||
};
|
||||
console.log(`📝 업데이트된 formData:`, newFormData);
|
||||
console.log("📝 업데이트된 formData:", newFormData);
|
||||
return newFormData;
|
||||
});
|
||||
},
|
||||
|
||||
@@ -45,9 +45,9 @@ export default function RootLayout({
|
||||
<div id="root" className="h-full">
|
||||
<QueryProvider>
|
||||
<RegistryProvider>{children}</RegistryProvider>
|
||||
<Toaster position="top-right" richColors />
|
||||
<ScreenModal />
|
||||
</QueryProvider>
|
||||
<Toaster position="top-right" richColors />
|
||||
<ScreenModal />
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
Reference in New Issue
Block a user