Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions src/assets/svg/space-register.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
157 changes: 157 additions & 0 deletions src/pages/artwork-detail/components/MySpaceModal/index.style.ts
Original file line number Diff line number Diff line change
@@ -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<InputBoxProps>`
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<ButtonProps>`
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;
`;
111 changes: 111 additions & 0 deletions src/pages/artwork-detail/components/MySpaceModal/index.tsx
Original file line number Diff line number Diff line change
@@ -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<string | null>(null);

const handleProfileImageChange = (
event: React.ChangeEvent<HTMLInputElement>
) => {
const imageFile = event.target.files?.[0];

if (!imageFile) return;

// 🔹 미리보기 이미지 URL 생성
const previewUrl = URL.createObjectURL(imageFile);
setImagePreview(previewUrl);
};

return (
<>
<ModalBackground onClick={onClose} />
<ModalSpace>
<ModalWrap>
<ModalContent>
<TopContainer>
<EmptySpace />
<Text size={20} color="black" weight="regular">
내 공간 등록
</Text>
<CloseIcon src={Close} onClick={onClose} alt="닫기" />
</TopContainer>
<CenterContainer>
<InformContainer>
<InputContainer>
<InputTitle>공간명</InputTitle>
<InputBox
placeholder="공간명을 입력해주세요"
$isName={true}
/>
</InputContainer>
<InputContainer>
<InputTitle>공간넓이</InputTitle>
<InputBox $isName={false} />
<Text size={14} color="font03gray" weight="medium">
m
</Text>
</InputContainer>
</InformContainer>

{/* 이미지 업로드 */}
<UploadContainer>
<UploadLabel htmlFor="file">
<UploadLabelImg src={Upload} alt="이미지 업로드" />
</UploadLabel>
<FileInput
type="file"
name="file"
id="file"
accept="image/*"
onChange={handleProfileImageChange}
/>
{imagePreview && (
<FilePreview src={imagePreview} alt="Preview" />
)}
</UploadContainer>
</CenterContainer>
<BottomContainer>
<CloseBtn onClick={onClose} $isCancle={true}>
<Text size={13} color="black" weight="regular">
취소
</Text>
</CloseBtn>
<CloseBtn onClick={onClose} $isCancle={false}>
<Text size={13} color="white" weight="regular">
확인
</Text>
</CloseBtn>
</BottomContainer>
</ModalContent>
</ModalWrap>
</ModalSpace>
</>
);
};
30 changes: 25 additions & 5 deletions src/pages/artwork-detail/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand All @@ -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 (
Expand Down Expand Up @@ -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 (
<PageLayout>
<Container>
Expand Down Expand Up @@ -284,14 +303,14 @@ export const ArtworkDetail = () => {
</BigSpaceContainer>

{/* TODO[서윤] - 내 공간 등록 구현 */}
{/* <SpaceButtonContainer>
<ButtonContainer>
<SpaceButtonContainer>
<ButtonContainer onClick={openModal}>
<Text size={14} color="black" weight="semibold">
내 공간 등록
</Text>
<Arrow $isBig={false} src={ArrowRight} alt="내 공간 등록" />
</ButtonContainer>
</SpaceButtonContainer> */}
</SpaceButtonContainer>
</CategoryContainer>

{/* 작품 소개 섹션 */}
Expand Down Expand Up @@ -381,6 +400,7 @@ export const ArtworkDetail = () => {
</CategoryContainer>
</BottomContainer>
</Container>
{isModalOpen && <MySpaceModal onClose={closeModal} />}
</PageLayout>
);
};
2 changes: 1 addition & 1 deletion src/pages/artwork/index.style.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
2 changes: 1 addition & 1 deletion src/pages/artwork/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ export const ArtWork = () => {
<PageLayout>
<Container>
<TextWrapper>
<Text size={48} color="black" weight="semibold">
<Text size={32} color="black" weight="semibold">
Artwork
</Text>
</TextWrapper>
Expand Down
Loading