Skip to content

Commit

Permalink
Merge pull request #378 from boostcampwm-2022/dev
Browse files Browse the repository at this point in the history
실서버에 0.3.0 버전을 배포합니다.
  • Loading branch information
shyuuuuni authored Dec 8, 2022
2 parents 9b2f22d + a2b2bcd commit f89219c
Show file tree
Hide file tree
Showing 78 changed files with 872 additions and 199 deletions.
1 change: 1 addition & 0 deletions client/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
</head>
<body>
<div id="root"></div>
<div id="modal"></div>
<script type="module" src="/src/main.tsx"></script>
</body>
</html>
2 changes: 2 additions & 0 deletions client/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { isEmpty } from "@/utils/typeCheck";
import ReactRouter from "@/ReactRouter";
import CommonModalWrapper from "@/components/main/Modal/ModalWrapper/CommonModalWrapper";
import { useRefreshInterceptor } from "@/hooks/useRefreshInterceptor";
import ModalProvider from "@/components/commons/Modal/ModalProvider/ModalProvider";

import "./App.scss";

Expand All @@ -21,6 +22,7 @@ function App(): JSX.Element {
<QueryClientProvider client={queryClient}>
<ReactRouter />
<CommonModalWrapper />
<ModalProvider />
<ReactQueryDevtools initialIsOpen={false} />
</QueryClientProvider>
);
Expand Down
5 changes: 5 additions & 0 deletions client/src/apis/post.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,11 @@ export const fetchBookmarkPost = async (
return data;
};

export const deletePost = async (postId: string): Promise<void> => {
const { data } = await axiosInstance.delete(`/posts/${postId}`);
return data;
};

export const uploadImage = async ({
preSignedData,
imageUri,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import React, { ReactPortal } from "react";
import { createPortal } from "react-dom";

import useModalStore from "@/store/useModalStore";
import PostMoreModal from "@/components/main/PostScroll/Post/PostFooter/RightBlockItems/PostMoreModal/PostMoreModal";
import { MODAL_KEY, ModalProps } from "@/types/modal";

const MODALS = new Map<MODAL_KEY, React.FC<ModalProps>>([
[MODAL_KEY.POST_MORE, PostMoreModal],
]);

const ModalProvider = (): ReactPortal => {
const modals = useModalStore((state) => state.modals);
const Modals = modals.map(({ key, props }) => {
const Modal = MODALS.get(key) as React.FC<ModalProps>;
return <Modal key={key} {...props} />;
});

return createPortal(
<>{Modals}</>,
document.getElementById("modal") as Element
);
};

export default ModalProvider;
35 changes: 35 additions & 0 deletions client/src/components/commons/Modal/core/Modal/Modal.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import React, { ReactNode, useRef } from "react";

import ModalContainer from "@/components/commons/Modal/core/ModalContainer/ModalContainer";
import ModalWrapper from "@/components/commons/Modal/core/ModalWrapper/ModalWrapper";
import ModalOverlay from "@/components/commons/Modal/core/ModalOverlay/ModalOverlay";
import useOutsideClickHandler from "@/hooks/useOutsideClickHandler";
import ModalTitle from "@/components/commons/Modal/core/ModalTitle/ModalTitle";
import ModalContents from "@/components/commons/Modal/core/ModalContents/ModalContents";

interface ModalProps {
title?: string;
onClose?: Function;
children?: ReactNode;
}

const Modal = ({ title, onClose, children }: ModalProps): JSX.Element => {
const modalRef = useRef<HTMLDivElement | null>(null);
const handleModalClose = (): void => {
onClose?.();
};
useOutsideClickHandler(modalRef, handleModalClose);

return (
<ModalContainer>
<ModalOverlay>
<ModalWrapper ref={modalRef}>
<ModalTitle title={title} />
<ModalContents>{children}</ModalContents>
</ModalWrapper>
</ModalOverlay>
</ModalContainer>
);
};

export default Modal;
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import React, { ReactNode, ReactPortal } from "react";
import { createPortal } from "react-dom";

interface ModalContainerProps {
children: ReactNode;
}

const ModalContainer = ({ children }: ModalContainerProps): ReactPortal => {
const modalElement = document.getElementById("modal") as HTMLElement;
const modalContents = <>{children}</>;

return createPortal(modalContents, modalElement);
};

export default ModalContainer;
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
@import "@/styles/_theme.scss";

.modal-contents {
font-size: $font-medium;
color: $text-color;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import React, { ReactNode } from "react";

import "./ModalContents.scss";

interface ModalContentsProps {
children?: ReactNode;
}

const ModalContents = ({ children }: ModalContentsProps): JSX.Element => {
return <div className="modal-contents">{children}</div>;
};

export default ModalContents;
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
$highest-z-index: 90000; // 가장 높은 z-index 값으로 설정

.modal-overlay {
position: fixed;
top: 0;
left: 0;
z-index: $highest-z-index;
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, 0.2); // 모달 배경 색
backdrop-filter: blur(2px);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import React, { ReactNode } from "react";

import "./ModalOverlay.scss";

interface ModalOverlayProps {
children: ReactNode;
}

const ModalOverlay = ({ children }: ModalOverlayProps): JSX.Element => {
return <div className="modal-overlay">{children}</div>;
};

export default ModalOverlay;
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
@import "@/styles/_theme.scss";

.modal-title {
width: 100%;
height: 5rem;
font-size: $font-large;
// div 텍스트 중앙 정렬
line-height: 5rem;
text-align: center;
border-bottom: $border-small $line-color;
}
13 changes: 13 additions & 0 deletions client/src/components/commons/Modal/core/ModalTitle/ModalTitle.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import React from "react";

import "./ModalTitle.scss";

interface ModalTitleProps {
title?: string;
}

const ModalTitle = ({ title }: ModalTitleProps): JSX.Element => {
return <div className="modal-title">{title ?? ""}</div>;
};

export default ModalTitle;
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
@import "@/styles/_theme.scss";

.modal-wrapper {
position: absolute;
// 좌측 상단 위치를 modal 중앙에 위치
top: 50%;
left: 50%;
box-sizing: border-box;
width: fit-content;
min-width: 20rem;
height: fit-content;
min-height: 5rem;
background-color: $weview-white;
border: $border-small $line-color;
border-radius: $radius-modal;
box-shadow: $shadow-box;
// wrapper 의 중앙을 modal 중앙에 위치
transform: translate(-50%, -50%);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import React, { forwardRef, ReactNode } from "react";

import "./ModalWrapper.scss";

interface ModalWrapperProps {
children: ReactNode;
}

const ModalWrapper = forwardRef<HTMLDivElement, ModalWrapperProps>(
({ children }, ref): JSX.Element => {
return (
<div className="modal-wrapper" ref={ref}>
{children}
</div>
);
}
);

export default ModalWrapper;
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ interface ProgressiveImageProps {
width: number | "100%";
height: number | "100%";
alt: string;
handleClickImage?: () => void;
}

const ProgressiveImage = ({
Expand All @@ -18,6 +19,7 @@ const ProgressiveImage = ({
width,
height,
alt,
handleClickImage,
}: ProgressiveImageProps): JSX.Element => {
const { observeImage } = useImageIntersect();

Expand All @@ -26,6 +28,7 @@ const ProgressiveImage = ({
ref={observeImage}
className={`progressive-image ${className}`}
src={placeholder}
onClick={handleClickImage}
data-lazysrc={src}
width={width}
height={height}
Expand Down
5 changes: 3 additions & 2 deletions client/src/components/main/CodeEditor/CodeEditor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@ import CodeViewer from "@/components/main/CodeViewer/CodeViewer";
import "./CodeEditor.scss";

const CodeEditor = (): JSX.Element => {
const { code, handleCodeChange, language, lineCount } = useCodeEditor();
const { lineRef, textRef, preRef, handleScrollChange } = useEditorScroll();

const { code, language, lineCount, handleCodeChange, handleKeyDown } =
useCodeEditor(textRef);
useEffect(() => {
textRef.current?.focus();
}, []);
Expand All @@ -25,6 +25,7 @@ const CodeEditor = (): JSX.Element => {
ref={textRef}
onScroll={handleScrollChange}
onChange={handleCodeChange}
onKeyDown={handleKeyDown}
value={code}
className="code__textarea"
autoComplete="false"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import ArrowDropDownCircleSharpIcon from "@mui/icons-material/ArrowDropDownCircl
import useLabel from "@/hooks/useLabel";
import { Label } from "@/types/search";
import SearchLabel from "@/components/commons/SearchLabel/SearchLabel";
import useNav from "@/hooks/useNav";

import DetailSearchForm from "./DetailSearchForm/DetailSearchForm";

Expand All @@ -20,6 +21,7 @@ const SearchContentHeader = (): JSX.Element => {
removeLabel,
handleSubmit,
} = useLabel();
const { handleNavClose } = useNav();
const [isDetailOpened, setIsDetailOpened] = useState(false);

return (
Expand All @@ -36,7 +38,9 @@ const SearchContentHeader = (): JSX.Element => {
/>
<SearchIcon
className="search-content__form__submit"
onClick={handleSubmit}
onClick={() => {
handleNavClose(() => handleSubmit());
}}
/>
</div>
<div className="search-content__filter__header">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,8 @@ const SearchHistoryView = (): JSX.Element => {
fetchSearchHistory,
{
suspense: true,
refetchOnMount: true, // 렌더 시 업데이트
staleTime: 2 * 1000, // 2초
}
);

Expand Down
Original file line number Diff line number Diff line change
@@ -1,21 +1,15 @@
@import "@/styles/theme";
@import "@/styles/responsive";
@import "@/styles/global-style";
@import "@/styles/animation";

.modal-container {
// root 의 가운데 정렬
position: absolute;
top: 0;
right: 0;
left: 0;
z-index: $modal-content-z-index;
z-index: $modal-content-z-index !important;
box-sizing: border-box;

display: flex;
width: 100%;
width: fit-content;
max-width: $desktop-main-width;
height: 100%;

height: 80%;
// 모달 내용들은 공통으로 2rem 패딩 내에 존재
padding: 2rem;
margin: 0 auto;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import React, { useCallback, MouseEvent } from "react";
import CloseIcon from "@mui/icons-material/Close";

import ModalContainer from "@/components/main/Modal/ModalContainer/ModalContainer";
import useCommonModalStore from "@/store/useCommonModalStore";
import { isCloseModalElement } from "@/utils/dom";

import "./ModalWrapper.scss";

Expand All @@ -12,16 +14,22 @@ const CommonModalWrapper = (): JSX.Element => {
]);

const clickWrapperBackGround = useCallback(
(e: MouseEvent<HTMLDivElement>) => {
(e: MouseEvent<HTMLDivElement | SVGSVGElement>) => {
if (!isCloseModalElement(e.target as HTMLElement)) return;
closeModal();
},
[]
);

return modalContent !== null ? (
<>
<div className="modal-background" onClick={clickWrapperBackGround} />
<ModalContainer content={modalContent} />
<div className="modal-background" onClick={clickWrapperBackGround}>
<CloseIcon
className="modal-close-button"
onClick={clickWrapperBackGround}
/>
<ModalContainer content={modalContent} />
</div>
</>
) : (
<></>
Expand Down
17 changes: 17 additions & 0 deletions client/src/components/main/Modal/ModalWrapper/ModalWrapper.scss
Original file line number Diff line number Diff line change
@@ -1,9 +1,26 @@
@import "@/styles/_global-style.scss";
@import "@/styles/theme.scss";
@import "@/styles/responsive";

.modal-background {
position: absolute;
top: 0;
z-index: $modal-background-z-index !important;
display: flex;
align-items: center;
width: 100vw;
height: 100vh;
min-height: 100vh;
background-color: rgba(0, 0, 0, 0.75);
}

.modal-close-button {
position: absolute;
top: 2rem;
right: 2rem;
z-index: $modal-content-z-index;
font-size: 2rem;
color: $line-color;
cursor: pointer;
transform: scale(2);
}
Loading

0 comments on commit f89219c

Please sign in to comment.