Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[FE] Feat/#592 핀 디테일의 핀 이미지 클릭 시 모달을 통해 크게 보이는 기능 구현 #595

Merged
merged 5 commits into from
Oct 19, 2023
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
71 changes: 37 additions & 34 deletions frontend/src/components/Layout/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import Map from '../Map';
import Toast from '../Toast';
import Logo from './Logo';
import Navbar from './Navbar';
import ImageModalContext from '../../context/ImageModalContext';

type LayoutProps = {
children: React.ReactNode;
Expand Down Expand Up @@ -43,44 +44,46 @@ function Layout({ children }: LayoutProps) {
return (
<ToastProvider>
<ModalProvider>
<CoordinatesProvider>
<MarkerProvider>
<SeeTogetherProvider>
<TagProvider>
<MediaWrapper
$isAddPage={navbarHighlights.addMapOrPin}
$layoutWidth={width}
>
<LayoutFlex
$flexDirection="column"
$minWidth={width}
height="calc(var(--vh, 1vh) * 100)"
$backgroundColor="white"
<ImageModalContext>
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

context가 또 생겼네여
이런건 zustand로는 무리?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

무리데스요 ~

<CoordinatesProvider>
<MarkerProvider>
<SeeTogetherProvider>
<TagProvider>
<MediaWrapper
$isAddPage={navbarHighlights.addMapOrPin}
$layoutWidth={width}
>
<LogoWrapper $layoutWidth={width}>
<Box>
<Logo />
<Space size={2} />
</Box>
</LogoWrapper>
<Flex
<LayoutFlex
$flexDirection="column"
height="inherit"
overflow="auto"
padding="0"
$minWidth={width}
height="calc(var(--vh, 1vh) * 100)"
$backgroundColor="white"
$layoutWidth={width}
Comment on lines +56 to +61
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이 부분 변동사항은 왜 생긴걸까요?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이 부분은 저도 만진적이 없어서 모르겠네요.. 흠 뭐지

>
{children}
</Flex>
<Navbar $layoutWidth={width} />
<Toast />
</LayoutFlex>
<Map />
</MediaWrapper>
</TagProvider>
</SeeTogetherProvider>
</MarkerProvider>
</CoordinatesProvider>
<LogoWrapper $layoutWidth={width}>
<Box>
<Logo />
<Space size={2} />
</Box>
</LogoWrapper>
<Flex
$flexDirection="column"
height="inherit"
overflow="auto"
padding="0"
>
{children}
</Flex>
<Navbar $layoutWidth={width} />
<Toast />
</LayoutFlex>
<Map />
</MediaWrapper>
</TagProvider>
</SeeTogetherProvider>
</MarkerProvider>
</CoordinatesProvider>
</ImageModalContext>
</ModalProvider>
</ToastProvider>
);
Expand Down
67 changes: 56 additions & 11 deletions frontend/src/components/PinImageContainer/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,23 @@ import Image from '../common/Image';
import RemoveImageButton from '../../assets/remove_image_icon.svg';
import useDelete from '../../apiHooks/useDelete';
import useToast from '../../hooks/useToast';
import { useModalContext, ImageModal } from '../../context/ImageModalContext';
import { useState } from 'react';
import Button from '../common/Button';
import Space from '../common/Space';

interface PinImageContainerProps {
images: ImageProps[];
getPinData: () => void;
}const NOT_FOUND_IMAGE =
'https://dr702blqc4x5d.cloudfront.net/2023-map-be-fine/icon/notFound_image.svg';
}
const NOT_FOUND_IMAGE =
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이 부분 공통 컴포넌트 Image랑 중복되는 것 같은데 constant에 빼주세요

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이 부분은 제가 착각했군여 무시하셔도 좋습니다.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

아하! 넹 ~!

'https://dr702blqc4x5d.cloudfront.net/2023-map-be-fine/icon/notFound_image.svg';

const PinImageContainer = ({ images, getPinData }: PinImageContainerProps) => {
const { fetchDelete } = useDelete();
const { showToast } = useToast();
const { isModalOpen, openModal, closeModal } = useModalContext();
const [modalImage, setModalImage] = useState<string>('');

const onRemovePinImage = (imageId: number) => {
const isRemoveImage = confirm('해당 이미지를 삭제하시겠습니까?');
Expand All @@ -24,28 +30,35 @@ const PinImageContainer = ({ images, getPinData }: PinImageContainerProps) => {
fetchDelete({
url: `/pins/images/${imageId}`,
errorMessage: '이미지 제거에 실패했습니다.',
isThrow: true,
onSuccess: () => {
showToast('info', '핀에서 이미지가 삭제 되었습니다.');
getPinData();
},
});
}
};

const onImageOpen = (imageUrl: string) => {
setModalImage(imageUrl);
openModal();
};

return (
<>
<FilmList>
{images.map(
(image, index) =>
index < 3 && (
<ImageWrapper>
<Image
key={image.id}
height="100px"
width="100px"
src={image.imageUrl}
$errorDefaultSrc={NOT_FOUND_IMAGE}
/>
<div onClick={() => onImageOpen(image.imageUrl)}>
<Image
key={image.id}
height="100px"
width="100px"
src={image.imageUrl}
$errorDefaultSrc={NOT_FOUND_IMAGE}
/>
</div>
<RemoveImageIconWrapper
onClick={() => onRemovePinImage(image.id)}
>
Expand All @@ -54,6 +67,17 @@ const PinImageContainer = ({ images, getPinData }: PinImageContainerProps) => {
</ImageWrapper>
),
)}
{isModalOpen && (
<ImageModal closeModalHandler={closeModal}>
<ModalImageWrapper>
<ModalImage src={modalImage} />
<Space size={3} />
<Button variant="custom" onClick={closeModal}>
닫기
</Button>
</ModalImageWrapper>
</ImageModal>
)}
</FilmList>
</>
);
Expand Down Expand Up @@ -84,4 +108,25 @@ const RemoveImageIconWrapper = styled.div`
}
`;

const ModalImageWrapper = styled.div`
width: 100%;
height: 100%;

display: flex;
flex-direction: column;
align-items: center;

margin: 0 auto;
overflow: hidden;
`;

const ModalImage = styled.img`
width: 100%;
height: 100%;
Comment on lines +124 to +125
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

결국 일괄 100%가 되었군요 ㅋㅋㅋㅋ


min-width: 360px;
min-height: 360px;

display: block;
`;
export default PinImageContainer;
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,12 @@ import React, {
import ReactDOM from 'react-dom';
import { styled } from 'styled-components';

interface ModalPortalProps {
interface ImageModalProps {
children: ReactChild;
closeModalHandler: () => void;
}

export const ModalPortal = (props: ModalPortalProps) => {
export const ImageModal = (props: ImageModalProps) => {
const $modalRoot = document.getElementById('modal-root') as HTMLElement;
const modalRef = useRef<HTMLDialogElement>(null);

Expand Down Expand Up @@ -54,8 +54,6 @@ export const ModalPortal = (props: ModalPortalProps) => {
};

const ModalContainer = styled.dialog`
width: 600px;
max-height: 600px;
padding: 32px 16px;

display: flex;
Expand Down Expand Up @@ -87,7 +85,7 @@ export const useModalContext = () => {

export const ModalContext = React.createContext<ModalContextType | null>(null);

function ModalContextProvider(props: { children: React.ReactNode }) {
function ImageModalContextProvider(props: { children: React.ReactNode }) {
const [isModalOpen, setIsModalOpen] = useState(false);

const openModal = () => {
Expand All @@ -111,4 +109,4 @@ function ModalContextProvider(props: { children: React.ReactNode }) {
);
}

export default ModalContextProvider;
export default ImageModalContextProvider;
Loading