diff --git a/src/assets/svg/space-register.svg b/src/assets/svg/space-register.svg
new file mode 100644
index 0000000..df8c037
--- /dev/null
+++ b/src/assets/svg/space-register.svg
@@ -0,0 +1,4 @@
+
diff --git a/src/pages/artwork-detail/components/MySpaceModal/index.style.ts b/src/pages/artwork-detail/components/MySpaceModal/index.style.ts
new file mode 100644
index 0000000..7d3f562
--- /dev/null
+++ b/src/pages/artwork-detail/components/MySpaceModal/index.style.ts
@@ -0,0 +1,157 @@
+import styled from '@emotion/styled';
+import theme from '@styles/theme.ts';
+
+interface ButtonProps {
+ $isCancle: boolean;
+}
+
+interface InputBoxProps {
+ $isName: boolean;
+}
+
+export const ModalWrap = styled.div`
+ width: 420px;
+ z-index: 2;
+ background-color: ${theme.colors.white};
+ box-shadow: 16px 16px 30px 0 rgba(0, 0, 0, 0.06);
+`;
+
+export const ModalSpace = styled.div`
+ width: 100vw;
+ height: 100vh;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ position: absolute;
+ top: 0;
+ left: 0;
+`;
+
+export const ModalBackground = styled.div`
+ position: fixed;
+ width: 100%;
+ height: 100%;
+ background-color: rgba(17, 17, 17, 0.6);
+ top: 0;
+ left: 0;
+ z-index: 1;
+`;
+
+export const ModalContent = styled.div`
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+`;
+
+export const TopContainer = styled.div`
+ width: 100%;
+ box-sizing: border-box;
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ padding: 17px 20px;
+`;
+
+export const EmptySpace = styled.div`
+ width: 24px;
+ height: 24px;
+`;
+
+export const CloseIcon = styled.img`
+ width: 24px;
+ height: 24px;
+ cursor: pointer;
+`;
+
+export const CenterContainer = styled.div`
+ width: 100%;
+ box-sizing: border-box;
+ display: flex;
+ flex-direction: column;
+ padding: 12px 32px 32px;
+ gap: 24px;
+`;
+
+export const InformContainer = styled.div`
+ display: flex;
+ flex-direction: column;
+ gap: 8px;
+`;
+
+export const InputContainer = styled.div`
+ width: 100%;
+ display: flex;
+ align-items: center;
+ gap: 8px;
+`;
+
+export const InputTitle = styled.div`
+ ${(theme) => theme.theme.typography['14']};
+ color: ${theme.colors.font03gray};
+ font-weight: 500;
+ width: 62px;
+`;
+
+export const InputBox = styled.input`
+ width: ${({ $isName }) => ($isName ? `250px` : `220px`)};
+ padding: 14px 16px;
+ border: 1px solid ${theme.colors.lightGray};
+ outline: none;
+ background-color: ${theme.colors.white};
+`;
+
+export const BottomContainer = styled.div`
+ width: 100%;
+ box-sizing: border-box;
+ display: flex;
+ justify-content: flex-end;
+ gap: 8px;
+ padding: 16px 32px 24px;
+`;
+
+export const CloseBtn = styled.div`
+ padding: 9px 38.5px;
+ background-color: ${({ $isCancle }) =>
+ $isCancle ? `${theme.colors.white}` : `${theme.colors.black}`};
+ border: ${({ $isCancle }) =>
+ $isCancle
+ ? `1px solid ${theme.colors.lightGray}`
+ : `1px solid ${theme.colors.black}`};
+ cursor: pointer;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+`;
+
+/* 이미지 업로드 스타일 */
+export const UploadContainer = styled.div`
+ width: 356px;
+ height: 215px;
+ position: relative;
+`;
+
+export const UploadLabel = styled.label`
+ position: absolute;
+ left: 50%;
+ transform: translateX(-50%);
+ cursor: pointer;
+ color: white;
+ font-size: 14px;
+`;
+
+export const UploadLabelImg = styled.img`
+ width: 356px;
+ height: 215px;
+`;
+
+export const FileInput = styled.input`
+ display: none;
+`;
+
+export const FilePreview = styled.img`
+ width: 356px;
+ height: 215px;
+ position: relative;
+ object-fit: cover;
+ z-index: 10;
+`;
diff --git a/src/pages/artwork-detail/components/MySpaceModal/index.tsx b/src/pages/artwork-detail/components/MySpaceModal/index.tsx
new file mode 100644
index 0000000..8ce37a3
--- /dev/null
+++ b/src/pages/artwork-detail/components/MySpaceModal/index.tsx
@@ -0,0 +1,111 @@
+import { useState } from 'react';
+import {
+ ModalBackground,
+ ModalSpace,
+ ModalWrap,
+ ModalContent,
+ TopContainer,
+ EmptySpace,
+ CloseIcon,
+ CenterContainer,
+ InformContainer,
+ InputContainer,
+ InputTitle,
+ InputBox,
+ BottomContainer,
+ CloseBtn,
+ UploadContainer,
+ UploadLabel,
+ UploadLabelImg,
+ FileInput,
+ FilePreview,
+} from './index.style.ts';
+import { Text } from '@/styles/text';
+import Close from '@/assets/svg/icon-close.svg';
+import Upload from '@/assets/svg/space-register.svg';
+
+interface MySpaceProps {
+ onClose: () => void;
+}
+
+export const MySpaceModal = ({ onClose }: MySpaceProps) => {
+ const [imagePreview, setImagePreview] = useState(null);
+
+ const handleProfileImageChange = (
+ event: React.ChangeEvent
+ ) => {
+ const imageFile = event.target.files?.[0];
+
+ if (!imageFile) return;
+
+ // 🔹 미리보기 이미지 URL 생성
+ const previewUrl = URL.createObjectURL(imageFile);
+ setImagePreview(previewUrl);
+ };
+
+ return (
+ <>
+
+
+
+
+
+
+
+ 내 공간 등록
+
+
+
+
+
+
+ 공간명
+
+
+
+ 공간넓이
+
+
+ m
+
+
+
+
+ {/* 이미지 업로드 */}
+
+
+
+
+
+ {imagePreview && (
+
+ )}
+
+
+
+
+
+ 취소
+
+
+
+
+ 확인
+
+
+
+
+
+
+ >
+ );
+};
diff --git a/src/pages/artwork-detail/index.tsx b/src/pages/artwork-detail/index.tsx
index 71b2487..8a52d26 100644
--- a/src/pages/artwork-detail/index.tsx
+++ b/src/pages/artwork-detail/index.tsx
@@ -31,14 +31,15 @@ import {
BigSpaceImg,
BigImageContainer,
SpaceArtwork,
- // SpaceButtonContainer,
- // ButtonContainer,
+ SpaceButtonContainer,
+ ButtonContainer,
} from './index.style.ts';
import { useHandleLink } from '@/hooks/common/useHandleLink.ts';
import { DetailInform } from '@/pages/artwork-detail/components/DetailInform/index.tsx';
import { ArtworkDetailCategory } from '@/pages/artwork-detail/components/ArtworkDetailCategory/index.tsx';
import { AuthorProfile } from '@/pages/artwork-detail/components/AuthorProfile/index.tsx';
import { MoreButton } from '@/pages/artwork-detail/components/MoreButton/index.tsx';
+import { MySpaceModal } from '@/pages/artwork-detail/components/MySpaceModal/index.tsx';
import { useParams } from 'react-router-dom';
import { useGetArtworkDetail } from '@/pages/artwork-detail/hooks/useGetArtworkDetail';
import { useToggleArtworkLike } from '@/pages/artwork-detail/hooks/useToggleArtworkLike';
@@ -64,6 +65,7 @@ export const ArtworkDetail = () => {
const [startIndex, setStartIndex] = useState(0);
const itemsPerPage = 5;
const [selectedSpaceIndex, setSelectedSpaceIndex] = useState(0);
+ const [isModalOpen, setIsModalOpen] = useState(false);
if (isLoading || !artworkData) {
return (
@@ -165,6 +167,23 @@ export const ArtworkDetail = () => {
const calculatedArtworkWidth =
(artworkWidth / 10) * (maxContainerWidth / userSpaceWidth);
+ const openModal = () => {
+ window.scrollTo({ top: 0, behavior: 'smooth' });
+
+ const handleScrollEnd = () => {
+ if (window.scrollY === 0) {
+ setIsModalOpen(true);
+ window.removeEventListener('scroll', handleScrollEnd);
+ }
+ };
+
+ window.addEventListener('scroll', handleScrollEnd);
+ };
+
+ const closeModal = () => {
+ setIsModalOpen(false);
+ };
+
return (
@@ -284,14 +303,14 @@ export const ArtworkDetail = () => {
{/* TODO[서윤] - 내 공간 등록 구현 */}
- {/*
-
+
+
내 공간 등록
- */}
+
{/* 작품 소개 섹션 */}
@@ -381,6 +400,7 @@ export const ArtworkDetail = () => {
+ {isModalOpen && }
);
};
diff --git a/src/pages/artwork/index.style.ts b/src/pages/artwork/index.style.ts
index 70ef31c..c65e94c 100644
--- a/src/pages/artwork/index.style.ts
+++ b/src/pages/artwork/index.style.ts
@@ -9,7 +9,7 @@ export const Container = styled.div`
`;
export const TextWrapper = styled.div`
- padding: 100px 0 64px;
+ padding: 70px 0;
width: 100%;
display: flex;
justify-content: flex-start;
diff --git a/src/pages/artwork/index.tsx b/src/pages/artwork/index.tsx
index aceab02..3be5646 100644
--- a/src/pages/artwork/index.tsx
+++ b/src/pages/artwork/index.tsx
@@ -86,7 +86,7 @@ export const ArtWork = () => {
-
+
Artwork