화면관리ui수정

This commit is contained in:
kjs
2025-10-22 17:19:47 +09:00
parent 96df465a7d
commit 2dd96f5a74
16 changed files with 455 additions and 463 deletions

View File

@@ -10,8 +10,7 @@ import { useRouter } from "next/navigation";
import { toast } from "sonner";
import { initializeComponents } from "@/lib/registry/components";
import { EditModal } from "@/components/screen/EditModal";
import { ResponsiveLayoutEngine } from "@/components/screen/ResponsiveLayoutEngine";
import { useBreakpoint } from "@/hooks/useBreakpoint";
import { RealtimePreview } from "@/components/screen/RealtimePreviewDynamic";
export default function ScreenViewPage() {
const params = useParams();
@@ -22,13 +21,9 @@ export default function ScreenViewPage() {
const [layout, setLayout] = useState<LayoutData | null>(null);
const [loading, setLoading] = useState(true);
const [error, setError] = useState<string | null>(null);
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const [formData, setFormData] = useState<Record<string, unknown>>({});
// 화면 너비에 따라 Y좌표 유지 여부 결정
const [preserveYPosition, setPreserveYPosition] = useState(true);
const breakpoint = useBreakpoint();
// 편집 모달 상태
const [editModalOpen, setEditModalOpen] = useState(false);
const [editModalConfig, setEditModalConfig] = useState<{
@@ -124,24 +119,6 @@ export default function ScreenViewPage() {
}
}, [screenId]);
// 윈도우 크기 변경 감지 - layout이 로드된 후에만 실행
useEffect(() => {
if (!layout) return;
const screenWidth = layout?.screenResolution?.width || 1200;
const handleResize = () => {
const shouldPreserve = window.innerWidth >= screenWidth - 100;
setPreserveYPosition(shouldPreserve);
};
window.addEventListener("resize", handleResize);
// 초기 값도 설정
handleResize();
return () => window.removeEventListener("resize", handleResize);
}, [layout]);
if (loading) {
return (
<div className="flex h-full min-h-[400px] w-full items-center justify-center bg-gradient-to-br from-gray-50 to-slate-100">
@@ -172,39 +149,70 @@ export default function ScreenViewPage() {
// 화면 해상도 정보가 있으면 해당 크기로, 없으면 기본 크기 사용
const screenWidth = layout?.screenResolution?.width || 1200;
const screenHeight = layout?.screenResolution?.height || 800;
return (
<div className="h-full w-full bg-white">
<div style={{ padding: "16px 0" }}>
{/* 항상 반응형 모드로 렌더링 */}
{layout && layout.components.length > 0 ? (
<ResponsiveLayoutEngine
components={layout?.components || []}
breakpoint={breakpoint}
containerWidth={window.innerWidth}
screenWidth={screenWidth}
preserveYPosition={preserveYPosition}
isDesignMode={false}
formData={formData}
onFormDataChange={(fieldName: string, value: unknown) => {
console.log("📝 page.tsx formData 업데이트:", fieldName, value);
setFormData((prev) => ({ ...prev, [fieldName]: value }));
}}
screenInfo={{ id: screenId, tableName: screen?.tableName }}
/>
) : (
// 빈 화면일 때
<div className="flex items-center justify-center bg-white" style={{ minHeight: "600px" }}>
<div className="text-center">
<div className="mx-auto mb-4 flex h-16 w-16 items-center justify-center rounded-full bg-white shadow-sm">
<span className="text-2xl">📄</span>
</div>
<h2 className="mb-2 text-xl font-semibold text-gray-900"> </h2>
<p className="text-gray-600"> .</p>
<div className="bg-background h-full w-full">
{/* 절대 위치 기반 렌더링 */}
{layout && layout.components.length > 0 ? (
<div
className="bg-background relative mx-auto"
style={{
width: screenWidth,
minHeight: screenHeight,
}}
>
{/* 최상위 컴포넌트들 렌더링 */}
{layout.components
.filter((component) => !component.parentId)
.map((component) => (
<RealtimePreview
key={component.id}
component={component}
isSelected={false}
isDesignMode={false}
onClick={() => {}}
>
{/* 자식 컴포넌트들 */}
{(component.type === "group" || component.type === "container" || component.type === "area") &&
layout.components
.filter((child) => child.parentId === component.id)
.map((child) => {
// 자식 컴포넌트의 위치를 부모 기준 상대 좌표로 조정
const relativeChildComponent = {
...child,
position: {
x: child.position.x - component.position.x,
y: child.position.y - component.position.y,
z: child.position.z || 1,
},
};
return (
<RealtimePreview
key={child.id}
component={relativeChildComponent}
isSelected={false}
isDesignMode={false}
onClick={() => {}}
/>
);
})}
</RealtimePreview>
))}
</div>
) : (
// 빈 화면일 때
<div className="bg-background flex items-center justify-center" style={{ minHeight: screenHeight }}>
<div className="text-center">
<div className="bg-muted mx-auto mb-4 flex h-16 w-16 items-center justify-center rounded-full shadow-sm">
<span className="text-2xl">📄</span>
</div>
<h2 className="text-foreground mb-2 text-xl font-semibold"> </h2>
<p className="text-muted-foreground"> .</p>
</div>
)}
</div>
</div>
)}
{/* 편집 모달 */}
<EditModal