|
@@ -0,0 +1,91 @@
|
|
|
|
|
+import React, { useState } from 'react';
|
|
|
|
|
+import { MajorProject } from "@/data/project";
|
|
|
|
|
+import IndicatorDots from "@/components/common/IndicatorDots";
|
|
|
|
|
+
|
|
|
|
|
+interface CommonModalProps {
|
|
|
|
|
+ isOpen: boolean;
|
|
|
|
|
+ onClose: () => void;
|
|
|
|
|
+ item: MajorProject | null;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+export const ProjectModal: React.FC<CommonModalProps> = ({ isOpen, onClose, item }) => {
|
|
|
|
|
+ const [currentIndex, setCurrentIndex] = useState(0);
|
|
|
|
|
+
|
|
|
|
|
+ if (!isOpen || !item) return null;
|
|
|
|
|
+
|
|
|
|
|
+ const images = item.subImgUrl ?? [];
|
|
|
|
|
+
|
|
|
|
|
+ const handlePrev = () => {
|
|
|
|
|
+ if (images.length === 0) return;
|
|
|
|
|
+ setCurrentIndex((prev) => (prev === 0 ? images.length - 1 : prev - 1));
|
|
|
|
|
+ };
|
|
|
|
|
+
|
|
|
|
|
+ const handleNext = () => {
|
|
|
|
|
+ if (images.length === 0) return;
|
|
|
|
|
+ setCurrentIndex((prev) => (prev === images.length - 1 ? 0 : prev + 1));
|
|
|
|
|
+ };
|
|
|
|
|
+
|
|
|
|
|
+ return (
|
|
|
|
|
+ <div
|
|
|
|
|
+ className="fixed inset-0 z-50 flex items-center justify-center bg-black/70 backdrop-blur-sm"
|
|
|
|
|
+ onClick={onClose}
|
|
|
|
|
+ >
|
|
|
|
|
+ <div
|
|
|
|
|
+ className="relative bg-white w-[1222px] h-[901px] p-10 rounded-lg overflow-hidden"
|
|
|
|
|
+ onClick={(e) => e.stopPropagation()}
|
|
|
|
|
+ >
|
|
|
|
|
+ {/* 닫기 버튼 */}
|
|
|
|
|
+ <button
|
|
|
|
|
+ className="absolute top-6 right-6 text-black text-2xl font-light cursor-pointer"
|
|
|
|
|
+ onClick={onClose}
|
|
|
|
|
+ >
|
|
|
|
|
+ ×
|
|
|
|
|
+ </button>
|
|
|
|
|
+
|
|
|
|
|
+ {/* 제목 및 정보 */}
|
|
|
|
|
+ <div className="mb-6">
|
|
|
|
|
+ <h2 className="text-4xl font-extrabold mb-2">{item.title}</h2>
|
|
|
|
|
+ <div className="text-base font-light space-y-1">
|
|
|
|
|
+ <p>발주처 : {item.client}</p>
|
|
|
|
|
+ <p>계약금액 : {item.contractAmount}</p>
|
|
|
|
|
+ <p>공사기간 : {item.period}</p>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+
|
|
|
|
|
+ {/* 이미지 및 컨트롤 */}
|
|
|
|
|
+ <div className="relative w-full h-[578px] flex justify-center items-center">
|
|
|
|
|
+ {images.length > 0 && (
|
|
|
|
|
+ <img
|
|
|
|
|
+ src={images[currentIndex]}
|
|
|
|
|
+ alt={`image-${currentIndex}`}
|
|
|
|
|
+ className="rounded max-h-full object-contain"
|
|
|
|
|
+ />
|
|
|
|
|
+ )}
|
|
|
|
|
+ <button
|
|
|
|
|
+ onClick={handlePrev}
|
|
|
|
|
+ className="absolute left-4 top-1/2 -translate-y-1/2 bg-gray-300/75 w-14 h-14 text-2xl cursor-pointer"
|
|
|
|
|
+ >
|
|
|
|
|
+ {'<'}
|
|
|
|
|
+ </button>
|
|
|
|
|
+ <button
|
|
|
|
|
+ onClick={handleNext}
|
|
|
|
|
+ className="absolute right-4 top-1/2 -translate-y-1/2 bg-gray-300/75 w-14 h-14 text-2xl cursor-pointer"
|
|
|
|
|
+ >
|
|
|
|
|
+ {'>'}
|
|
|
|
|
+ </button>
|
|
|
|
|
+ </div>
|
|
|
|
|
+
|
|
|
|
|
+ {/* 페이지 인디케이터 */}
|
|
|
|
|
+ <div className="flex justify-center gap-2 mt-4">
|
|
|
|
|
+ <IndicatorDots
|
|
|
|
|
+ count={images.length}
|
|
|
|
|
+ activeIndex={currentIndex}
|
|
|
|
|
+ onClick={(index) => setCurrentIndex(index)}
|
|
|
|
|
+ activeColorClass="bg-blue-900"
|
|
|
|
|
+ inactiveColorClass="bg-blue-900/20"
|
|
|
|
|
+ />
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ );
|
|
|
|
|
+};
|