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

[Refactor] 모달 띄우는 로직, 데이터 상태 로직 리팩토링.. #197

Open
wants to merge 19 commits into
base: develop
Choose a base branch
from
Open
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
2 changes: 2 additions & 0 deletions src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { Outlet, useNavigate } from 'react-router-dom';
import { AxiosError } from 'axios';

import ErrorBoundary from '@/common/component/ErrorBoundary/ErrorBoundary';
import ModalContainer from '@/common/component/Modal/ModalContainer';
import { theme } from '@/common/style/theme/theme';

import LeftSidebar from '@/shared/component/LeftSidebar/LeftSidebar';
Expand Down Expand Up @@ -44,6 +45,7 @@ const App = () => {
<ErrorBoundary fallback={ErrorPage} onReset={handleResetError}>
<Login>
<div css={containerStyle}>
<ModalContainer />
<LeftSidebar />
<main css={layoutStyle}>
<Outlet />
Expand Down
4 changes: 2 additions & 2 deletions src/common/component/Modal/Modal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,14 @@
/* eslint-disable jsx-a11y/no-noninteractive-element-interactions */

/* eslint-disable jsx-a11y/click-events-have-key-events */
import { ReactElement, useCallback, useEffect } from 'react';
import { ReactNode, useCallback, useEffect } from 'react';
import { createPortal } from 'react-dom';

import { backgroundStyle, dialogStyle } from '@/common/component/Modal/Modal.style';

interface ModalProps {
isOpen: boolean;
children?: ReactElement;
children: ReactNode;
onClose?: () => void;
}

Expand Down
45 changes: 45 additions & 0 deletions src/common/component/Modal/ModalContainer.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import Modal from '@/common/component/Modal/Modal';

import DeleteModal from '@/shared/component/DeleteModal/DeleteModal';
import { BlockFlow } from '@/shared/component/ModalFlow/BlockFlow';
import { WorkSpaceFlow } from '@/shared/component/ModalFlow/WorkSpaceFlow';
import { BlockProvider } from '@/shared/hook/common/useBlockContext';
import { WorkSpaceProvider } from '@/shared/hook/common/useWorkSpaceContext';
import { useCloseModal, useModalContentType, useModalIsOpen } from '@/shared/store/modal';

const ModalContainer = () => {
const isOpen = useModalIsOpen();
const contentType = useModalContentType();
const closeModal = useCloseModal();

const renderContent = () => {
switch (contentType) {
case 'create-workspace':
return (
<WorkSpaceProvider>
<WorkSpaceFlow />
</WorkSpaceProvider>
);
case 'create-block':
return (
<BlockProvider>
<BlockFlow />
</BlockProvider>
);
case 'delete':
return <DeleteModal />;
default:
return null;
}
};

if (!isOpen || !contentType) return null;

return (
<Modal isOpen={isOpen} onClose={closeModal}>
{renderContent()}
</Modal>
);
};

export default ModalContainer;
33 changes: 12 additions & 21 deletions src/page/archiving/index/ArchivingPage.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
import BlockModal from '@/page/archiving/createTimeBlock/component/Block/BlockModal';
import UploadModal from '@/page/archiving/createTimeBlock/component/Upload/UploadModal';
import { buttonStyle, contentStyle, daySectionStyle, timelineStyle } from '@/page/archiving/index/ArchivingPage.style';
import DaySection from '@/page/archiving/index/component/DaySection/DaySection';
import DocumentBar from '@/page/archiving/index/component/DocumentBar/DocumentBar';
Expand All @@ -12,20 +10,22 @@ import { Block } from '@/page/archiving/index/type/blockType';
import { alignBlocks, getLastDayOfMonth } from '@/page/archiving/index/util/block';

import { useState } from 'react';
import { useLocation } from 'react-router-dom';

import AddIc from '@/common/asset/svg/add_btn.svg?react';
import Button from '@/common/component/Button/Button';
import Flex from '@/common/component/Flex/Flex';
import Modal from '@/common/component/Modal/Modal';
import { useModal, useOutsideClick } from '@/common/hook';
import { useOutsideClick } from '@/common/hook';
import { theme } from '@/common/style/theme/theme';

import { useTeamStore } from '@/shared/store/team';
import { useOpenModal } from '@/shared/store/modal';

const ArchivingPage = () => {
const [selectedId, setSelectedId] = useState('total');

const { teamId } = useTeamStore();
const location = useLocation();
const searchParams = new URLSearchParams(location.search);
const teamId = searchParams.get('teamId');

const handleClose = () => {
selectedBlock && setSelectedBlock(undefined);
Expand Down Expand Up @@ -59,22 +59,17 @@ const ArchivingPage = () => {

const selectedMonthNumber = parseInt(selectedMonth.split('월')[0]);

const { data } = useGetTimeBlockQuery(+teamId, 'executive', currentYear, selectedMonthNumber);
const { data } = useGetTimeBlockQuery(+teamId!, 'executive', currentYear, selectedMonthNumber);

const [selectedBlock, setSelectedBlock] = useState<Block>();
const timeBlocks: Block[] = data?.timeBlocks || [];
const blockFloors = alignBlocks(timeBlocks, endDay, selectedMonth, currentYear);

// 블록 생성 모달 관련 코드
const { isOpen, openModal, closeModal, setCurrentContent, currentContent } = useModal();

const handleNext = (blockData: {
blockName: string;
blockType: string;
dates: { startDate: string; endDate: string };
}) => {
const type = 'executive';
setCurrentContent(<UploadModal onClose={closeModal} teamId={+teamId} type={type} blockData={blockData} />);
const openModal = useOpenModal();

const handleOpenBlockModal = () => {
openModal('create-block');
};

return (
Expand Down Expand Up @@ -148,17 +143,13 @@ const ArchivingPage = () => {
</div>
</Flex>
<Flex css={{ zIndex: theme.zIndex.overlayTop, marginLeft: 'auto' }}>
<Button
variant="action"
css={buttonStyle(selectedBlock)}
onClick={() => openModal(<BlockModal onNext={handleNext} />)}>
<Button variant="action" css={buttonStyle(selectedBlock)} onClick={handleOpenBlockModal}>
<AddIc width={24} height={24} />
블록 생성
</Button>
</Flex>
</section>

<Modal isOpen={isOpen} children={currentContent} onClose={closeModal} />
<DocumentBar
selectedBlock={selectedBlock}
ref={sideBarRef}
Expand Down
45 changes: 20 additions & 25 deletions src/page/archiving/index/component/DocumentItem/DocumentItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,9 @@ import { ReactNode } from 'react';
import Download from '@/common/asset/svg/download.svg?react';
import TrashBox from '@/common/asset/svg/trash_box.svg?react';
import Flex from '@/common/component/Flex/Flex';
import Modal from '@/common/component/Modal/Modal';
import Text from '@/common/component/Text/Text';
import { useModal } from '@/common/hook';

import DeleteModal from '@/shared/component/DeleteModal/DeleteModal';
import { useOpenModal } from '@/shared/store/modal';
import { useTeamStore } from '@/shared/store/team';

interface DocumentItemProps {
Expand All @@ -28,11 +26,10 @@ interface DocumentItemProps {
}

const DocumentItem = ({ documentId, children, selectedId, blockName, fileUrl, color }: DocumentItemProps) => {
const { isOpen, openModal, closeModal, currentContent } = useModal();

const fileName = children?.toString();

const { teamId } = useTeamStore();
const openModal = useOpenModal();

//문서 클릭시 띄워주는 함수
const onClickDocumentItem = () => {
Expand All @@ -46,30 +43,28 @@ const DocumentItem = ({ documentId, children, selectedId, blockName, fileUrl, co

const handleTrashClick = (e: React.MouseEvent<SVGSVGElement, MouseEvent>) => {
e.stopPropagation();
openModal(<DeleteModal title="docs" detail="docs" onClose={closeModal} teamId={+teamId} id={documentId} />);
// 모달 띄우기
openModal('delete', { teamId: +teamId, itemId: documentId, itemType: 'docs' });
};

return (
<>
{/* eslint-disable-next-line jsx-a11y/no-noninteractive-element-interactions */}
<li css={containerStyle(selectedId)} onClick={onClickDocumentItem}>
{color && (
<div>
<Text tag="body8" css={blockNameTextStyle(color)}>
{blockName}
</Text>
</div>
)}
<Flex>
<Text tag="body6" css={fileNameStyle}>
{fileName}
/* eslint-disable-next-line jsx-a11y/no-noninteractive-element-interactions */
<li css={containerStyle(selectedId)} onClick={onClickDocumentItem}>
{color && (
<div>
<Text tag="body8" css={blockNameTextStyle(color)}>
{blockName}
</Text>
<Download width={20} height={20} css={{ cursor: 'pointer' }} onClick={handleDownloadClick} />
<TrashBox width={20} height={20} onClick={(e) => handleTrashClick(e)} css={{ cursor: 'pointer' }} />
</Flex>
</li>
<Modal isOpen={isOpen} children={currentContent} onClose={closeModal} />
Copy link
Contributor

Choose a reason for hiding this comment

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

오 요 modal 컴포넌트가 굉장히 애매했는데 이제 없앨수 있군요!
그러면 지금

  • 태그와 태그를 감싸고 있던 빈 <> 태그를 지워도 되겠네요~~!!

  • Copy link
    Contributor Author

    Choose a reason for hiding this comment

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

    맞아요! 빈태그도 지워줬습니다!!

    </>
    </div>
    )}
    <Flex>
    <Text tag="body6" css={fileNameStyle}>
    {fileName}
    </Text>
    <Download width={20} height={20} css={{ cursor: 'pointer' }} onClick={handleDownloadClick} />
    <TrashBox width={20} height={20} onClick={(e) => handleTrashClick(e)} css={{ cursor: 'pointer' }} />
    </Flex>
    </li>
    );
    };
    export default DocumentItem;
    39 changes: 11 additions & 28 deletions src/page/archiving/index/component/SelectedBlock/SelectedBlock.tsx
    Original file line number Diff line number Diff line change
    @@ -1,4 +1,9 @@
    import DocumentItem from '@/page/archiving/index/component/DocumentItem/DocumentItem';
    import {
    blockNameStyle,
    containerStyle,
    deleteBtnStyle,
    } from '@/page/archiving/index/component/SelectedBlock/SelectedBlock.style';
    import { documentListStyle } from '@/page/archiving/index/component/TotalDocument/TotalDocument.style';
    import { ICON_TYPE } from '@/page/archiving/index/constant/icon';
    import { Block } from '@/page/archiving/index/type/blockType';
    Expand All @@ -7,16 +12,12 @@ import { DocumentType } from '@/page/archiving/index/type/documentType';
    import Button from '@/common/component/Button/Button';
    import Flex from '@/common/component/Flex/Flex';
    import Heading from '@/common/component/Heading/Heading';
    import Modal from '@/common/component/Modal/Modal';
    import Text from '@/common/component/Text/Text';
    import { useModal } from '@/common/hook';
    import { theme } from '@/common/style/theme/theme';

    import DeleteModal from '@/shared/component/DeleteModal/DeleteModal';
    import { useOpenModal } from '@/shared/store/modal';
    import { useTeamStore } from '@/shared/store/team';

    import { blockNameStyle, containerStyle, deleteBtnStyle } from './SelectedBlock.style';

    interface DocumentBarInfoProps {
    selectedId: string;
    blockName: string;
    Expand All @@ -34,39 +35,22 @@ const SelectedBlock = ({
    endDate,
    documentList,
    selectedBlock,
    onClickClose,
    }: DocumentBarInfoProps) => {
    const { isOpen, openModal, closeModal, currentContent } = useModal();
    const { teamId } = useTeamStore();
    const openModal = useOpenModal();

    const handleCloseClick = () => {
    onClickClose();
    closeModal;
    const handleDeleteClick = () => {
    openModal('delete', { teamId: +teamId, itemId: selectedBlock.timeBlockId, itemType: 'block' }); // 데이터 전달
    };

    const { teamId } = useTeamStore();

    return (
    <Flex tag="section" css={containerStyle}>
    {ICON_TYPE.find((icon) => icon.name === selectedBlock.blockType)?.icon}
    <Flex styles={{ direction: 'row', justify: 'space-between', width: '24.8rem' }}>
    <Heading tag="H6" css={blockNameStyle}>
    {blockName}
    </Heading>
    <Button
    variant="text"
    size="small"
    css={deleteBtnStyle}
    onClick={() =>
    openModal(
    <DeleteModal
    title="block"
    detail="block"
    onClose={handleCloseClick}
    teamId={+teamId}
    id={selectedBlock.timeBlockId}
    />
    )
    }>
    <Button variant="text" size="small" css={deleteBtnStyle} onClick={handleDeleteClick}>
    블록삭제
    </Button>
    </Flex>
    Expand All @@ -86,7 +70,6 @@ const SelectedBlock = ({
    </DocumentItem>
    ))}
    </Flex>
    <Modal isOpen={isOpen} children={currentContent} onClose={closeModal} />
    </Flex>
    );
    };
    Expand Down
    Loading
    Loading