feat: [절곡] 우측 패널 sticky + 이미지 확대 모달 추가
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -84,6 +84,15 @@ export function BendingBaseForm({ id, mode }: BendingBaseFormProps) {
|
||||
const isView = mode === 'view';
|
||||
const isEdit = mode === 'edit';
|
||||
|
||||
// sticky를 위해 <main overflow-auto>를 일시적으로 visible로 변경
|
||||
useEffect(() => {
|
||||
const main = document.querySelector('main');
|
||||
if (!main) return;
|
||||
const prev = main.style.overflow;
|
||||
main.style.overflow = 'visible';
|
||||
return () => { main.style.overflow = prev; };
|
||||
}, []);
|
||||
|
||||
const [formData, setFormData] = useState<BendingItemFormData>(INITIAL_FORM);
|
||||
const [bendingData, setBendingData] = useState<BendingData[]>(INITIAL_FORM.bendingData);
|
||||
const [filters, setFilters] = useState<BendingItemFilters | null>(null);
|
||||
@@ -94,6 +103,7 @@ export function BendingBaseForm({ id, mode }: BendingBaseFormProps) {
|
||||
const [isDrawingOpen, setIsDrawingOpen] = useState(false);
|
||||
const [drawingImage, setDrawingImage] = useState<string | null>(null);
|
||||
const [isHistoryOpen, setIsHistoryOpen] = useState(false);
|
||||
const [isImageZoomOpen, setIsImageZoomOpen] = useState(false);
|
||||
const [originalItem, setOriginalItem] = useState<BendingItem | null>(null);
|
||||
const fileInputRef = useRef<HTMLInputElement>(null);
|
||||
|
||||
@@ -465,13 +475,17 @@ export function BendingBaseForm({ id, mode }: BendingBaseFormProps) {
|
||||
</Card>
|
||||
</div>
|
||||
|
||||
{/* 우측: 이미지 + 비고 + 저장 */}
|
||||
<div className="w-[280px] space-y-4">
|
||||
{/* 우측: 이미지 + 비고 (sticky) */}
|
||||
<div className="w-[280px] space-y-4 self-start sticky top-4">
|
||||
{/* 형상 이미지 */}
|
||||
<Card>
|
||||
<CardContent className="pt-6">
|
||||
<h3 className="text-sm font-semibold mb-3">형상 이미지</h3>
|
||||
<div className="w-full aspect-square bg-muted/30 border-2 border-dashed rounded-lg flex items-center justify-center mb-3 overflow-hidden">
|
||||
<div
|
||||
className="w-full aspect-square bg-muted/30 border-2 border-dashed rounded-lg flex items-center justify-center mb-3 overflow-hidden cursor-pointer"
|
||||
onClick={() => drawingImage && setIsImageZoomOpen(true)}
|
||||
title={drawingImage ? '클릭하여 확대' : undefined}
|
||||
>
|
||||
{drawingImage ? (
|
||||
<img src={drawingImage} alt="형상 이미지" className="w-full h-full object-contain" />
|
||||
) : (
|
||||
@@ -611,6 +625,18 @@ export function BendingBaseForm({ id, mode }: BendingBaseFormProps) {
|
||||
description="절곡 부품의 형상을 그리거나 편집합니다."
|
||||
/>
|
||||
|
||||
{/* 이미지 확대 */}
|
||||
<Dialog open={isImageZoomOpen} onOpenChange={setIsImageZoomOpen}>
|
||||
<DialogContent className="max-w-3xl max-h-[90vh] p-2">
|
||||
<DialogHeader>
|
||||
<DialogTitle className="text-sm">형상 이미지</DialogTitle>
|
||||
</DialogHeader>
|
||||
{drawingImage && (
|
||||
<img src={drawingImage} alt="형상 이미지 확대" className="w-full h-auto object-contain" />
|
||||
)}
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
|
||||
{/* 삭제 확인 */}
|
||||
<DeleteConfirmDialog
|
||||
open={isDeleteOpen}
|
||||
|
||||
@@ -168,6 +168,15 @@ export function BendingModelForm({ id, mode, category }: BendingModelFormProps)
|
||||
const disabled = isView;
|
||||
const sidebarCollapsed = useMenuStore((state) => state.sidebarCollapsed);
|
||||
|
||||
// sticky를 위해 <main overflow-auto>를 일시적으로 visible로 변경
|
||||
useEffect(() => {
|
||||
const main = document.querySelector('main');
|
||||
if (!main) return;
|
||||
const prev = main.style.overflow;
|
||||
main.style.overflow = 'visible';
|
||||
return () => { main.style.overflow = prev; };
|
||||
}, []);
|
||||
|
||||
const [form, setForm] = useState<FormState>(INITIAL_STATE);
|
||||
const [components, setComponents] = useState<ComponentData[]>([]);
|
||||
const [isLoading, setIsLoading] = useState(!isNew);
|
||||
@@ -179,6 +188,7 @@ export function BendingModelForm({ id, mode, category }: BendingModelFormProps)
|
||||
const [isWorkOrderOpen, setIsWorkOrderOpen] = useState(false);
|
||||
const [originalModel, setOriginalModel] = useState<GuiderailModelDetail | null>(null);
|
||||
const [isDrawingOpen, setIsDrawingOpen] = useState(false);
|
||||
const [isImageZoomOpen, setIsImageZoomOpen] = useState(false);
|
||||
const [drawingImage, setDrawingImage] = useState<string | null>(null);
|
||||
const fileInputRef = useRef<HTMLInputElement>(null);
|
||||
|
||||
@@ -480,12 +490,16 @@ export function BendingModelForm({ id, mode, category }: BendingModelFormProps)
|
||||
</Card>
|
||||
</div>
|
||||
|
||||
{/* 우측: 이미지 + 저장 */}
|
||||
<div className="w-[280px] space-y-4">
|
||||
{/* 우측: 이미지 (sticky) */}
|
||||
<div className="w-[280px] space-y-4 self-start sticky top-4">
|
||||
<Card>
|
||||
<CardContent className="pt-6">
|
||||
<h3 className="text-sm font-semibold mb-3">결합형태 이미지</h3>
|
||||
<div className="w-full aspect-square bg-muted/30 border-2 border-dashed rounded-lg flex items-center justify-center mb-3 overflow-hidden">
|
||||
<div
|
||||
className="w-full aspect-square bg-muted/30 border-2 border-dashed rounded-lg flex items-center justify-center mb-3 overflow-hidden cursor-pointer"
|
||||
onClick={() => drawingImage && setIsImageZoomOpen(true)}
|
||||
title={drawingImage ? '클릭하여 확대' : undefined}
|
||||
>
|
||||
{drawingImage ? (
|
||||
<img src={drawingImage} alt="결합형태 이미지" className="w-full h-full object-contain" />
|
||||
) : (
|
||||
@@ -734,6 +748,18 @@ export function BendingModelForm({ id, mode, category }: BendingModelFormProps)
|
||||
description="조립도 형상을 그리거나 편집합니다."
|
||||
/>
|
||||
|
||||
{/* 이미지 확대 */}
|
||||
<Dialog open={isImageZoomOpen} onOpenChange={setIsImageZoomOpen}>
|
||||
<DialogContent className="max-w-3xl max-h-[90vh] p-2">
|
||||
<DialogHeader>
|
||||
<DialogTitle className="text-sm">결합형태 이미지</DialogTitle>
|
||||
</DialogHeader>
|
||||
{drawingImage && (
|
||||
<img src={drawingImage} alt="결합형태 이미지 확대" className="w-full h-auto object-contain" />
|
||||
)}
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
|
||||
{/* 삭제 확인 */}
|
||||
<DeleteConfirmDialog
|
||||
open={isDeleteOpen}
|
||||
|
||||
Reference in New Issue
Block a user