Skip to content

Commit

Permalink
feat(preview) : #MAG-194 add arrows on preview to navigate between ca…
Browse files Browse the repository at this point in the history
…rds (#369)

---------

Co-authored-by: Florent Mariotti <florent.mariotti@cgi.com>
  • Loading branch information
FlorentMr and Florent Mariotti authored Jan 10, 2025
1 parent aca1eb3 commit ab3a461
Show file tree
Hide file tree
Showing 2 changed files with 153 additions and 40 deletions.
159 changes: 119 additions & 40 deletions frontend/src/components/Preview-modal/PreviewModal.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import { FC, useEffect, useState } from "react";
import { FC, useCallback, useEffect, useMemo, useState } from "react";

import ChevronLeftIcon from "@mui/icons-material/ChevronLeft";
import ChevronRightIcon from "@mui/icons-material/ChevronRight";
import CloseIcon from "@mui/icons-material/Close";
import ForumOutlinedIcon from "@mui/icons-material/ForumOutlined";
import { Box, IconButton, Modal, Typography } from "@mui/material";
Expand All @@ -11,22 +13,29 @@ import {
StyledContentBox,
modalBodyStyle,
ModalWrapper,
leftNavigationStyle,
rightNavigationStyle,
} from "./style";
import { CommentPanel } from "../comment-panel/CommentPanel";
import { PreviewContent } from "../preview-content/PreviewContent";
import { blackColor } from "../read-view/style";
import { BOARD_MODAL_TYPE } from "~/core/enums/board-modal-type";
import { useWindowResize } from "~/hooks/useWindowResize";
import { Card } from "~/models/card.model";
import { useBoard } from "~/providers/BoardProvider";

export const PreviewModal: FC = () => {
const {
board,
closeActiveCardAction,
displayModals: { CARD_PREVIEW, COMMENT_PANEL },
activeCard,
board: { canComment },
toggleBoardModals,
setActiveCard,
} = useBoard();
const [isRefReady, setIsRefReady] = useState(false);
const [cardIndex, setCardIndex] = useState<number>(0);
const commentDivRef = useWindowResize();

useEffect(() => {
Expand All @@ -37,50 +46,120 @@ export const PreviewModal: FC = () => {
}
}, [COMMENT_PANEL]);

const initialCards = useMemo(() => {
return board.isLayoutFree()
? board.cards
: board.sections.flatMap((section) => section.cards || []);
}, [board]);

useEffect(() => {
setCardIndex(
initialCards.findIndex(
(selectedCard: Card) => selectedCard.id === activeCard?.id,
),
);
}, [activeCard]);

const navigatePage = (direction: "next" | "prev") => {
const newIndex = direction === "next" ? cardIndex + 1 : cardIndex - 1;
const newCard = initialCards[newIndex];
setActiveCard(newCard);
};

const isLastCardInBoard = (): boolean => {
return activeCard === initialCards[initialCards.length - 1];
};

const handleKeyNavigation = useCallback(
(event: KeyboardEvent) => {
if (event.key === "ArrowLeft" && cardIndex > 0) {
navigatePage("prev");
} else if (event.key === "ArrowRight" && !isLastCardInBoard()) {
navigatePage("next");
}
},
[cardIndex, isLastCardInBoard, navigatePage],
);

useEffect(() => {
window.addEventListener("keydown", handleKeyNavigation);

return () => {
window.removeEventListener("keydown", handleKeyNavigation);
};
}, [handleKeyNavigation]);

return (
<Modal
open={CARD_PREVIEW}
onClose={() => closeActiveCardAction(BOARD_MODAL_TYPE.CARD_PREVIEW)}
aria-labelledby="modal-card-preview"
aria-describedby="modal-card-preview"
>
<ModalWrapper ref={commentDivRef} isCommentOpen={COMMENT_PANEL}>
<Box sx={modalBodyStyle}>
<IconButton
onClick={() => closeActiveCardAction(BOARD_MODAL_TYPE.CARD_PREVIEW)}
aria-label="close"
sx={closeButtonStyle}
>
<CloseIcon fontSize="inherit" />
</IconButton>
<StyledContentBox
isCommentOpen={COMMENT_PANEL}
data-scrollable="true"
>
{activeCard && <PreviewContent card={activeCard} />}
</StyledContentBox>
<CommentContainer isVisible={COMMENT_PANEL} />
{canComment && !COMMENT_PANEL && (
<Box sx={{ position: "relative" }}>
<Modal
open={CARD_PREVIEW}
onClose={() => closeActiveCardAction(BOARD_MODAL_TYPE.CARD_PREVIEW)}
aria-labelledby="modal-card-preview"
aria-describedby="modal-card-preview"
>
<ModalWrapper ref={commentDivRef} isCommentOpen={COMMENT_PANEL}>
<Box sx={modalBodyStyle}>
<IconButton
onClick={() => toggleBoardModals(BOARD_MODAL_TYPE.COMMENT_PANEL)}
onClick={() =>
closeActiveCardAction(BOARD_MODAL_TYPE.CARD_PREVIEW)
}
aria-label="close"
sx={commentButtonStyle}
sx={closeButtonStyle}
>
<CloseIcon fontSize="inherit" />
</IconButton>
<StyledContentBox
isCommentOpen={COMMENT_PANEL}
data-scrollable="true"
>
{activeCard && <PreviewContent card={activeCard} />}
</StyledContentBox>
<CommentContainer isVisible={COMMENT_PANEL} />
{canComment && !COMMENT_PANEL && (
<IconButton
onClick={() =>
toggleBoardModals(BOARD_MODAL_TYPE.COMMENT_PANEL)
}
aria-label="close"
sx={commentButtonStyle}
>
<Typography fontSize="inherit">
{activeCard?.nbOfComments}
</Typography>
<ForumOutlinedIcon fontSize="inherit" />
</IconButton>
)}
</Box>
{activeCard && COMMENT_PANEL && isRefReady && (
<CommentPanel
cardId={activeCard.id}
anchorEl={commentDivRef.current}
isInCardPreview
/>
)}
</ModalWrapper>
</Modal>

{CARD_PREVIEW && (
<>
{cardIndex > 0 && (
<IconButton
sx={leftNavigationStyle}
onClick={() => navigatePage("prev")}
>
<ChevronLeftIcon sx={blackColor} />
</IconButton>
)}
{!isLastCardInBoard() && (
<IconButton
sx={rightNavigationStyle}
onClick={() => navigatePage("next")}
>
<Typography fontSize="inherit">
{activeCard?.nbOfComments}
</Typography>
<ForumOutlinedIcon fontSize="inherit" />
<ChevronRightIcon sx={blackColor} />
</IconButton>
)}
</Box>
{activeCard && COMMENT_PANEL && isRefReady && (
<CommentPanel
cardId={activeCard.id}
anchorEl={commentDivRef.current}
isInCardPreview
/>
)}
</ModalWrapper>
</Modal>
</>
)}
</Box>
);
};
34 changes: 34 additions & 0 deletions frontend/src/components/Preview-modal/style.ts
Original file line number Diff line number Diff line change
Expand Up @@ -79,3 +79,37 @@ export const CommentContainer = styled(Box)<{ isVisible: boolean }>(
},
}),
);

export const leftNavigationStyle = {
position: "fixed",
left: "calc((100vw - 80vw)/2 - 3.5rem)",
top: "50%",
transform: "translateY(-50%)",
backgroundColor: "white",
border: "1px solid #e0e0e0",
"&:hover": { backgroundColor: "white" },
width: "7rem",
height: "7rem",
boxShadow: "0 3px 5px rgba(0,0,0,0.1)",
"& .MuiSvgIcon-root": {
fontSize: "5rem",
},
zIndex: 1500,
};

export const rightNavigationStyle = {
position: "fixed",
right: "calc((100vw - 80vw)/2 - 3.5rem)",
top: "50%",
transform: "translateY(-50%)",
backgroundColor: "white",
border: "1px solid #e0e0e0",
"&:hover": { backgroundColor: "white" },
width: "7rem",
height: "7rem",
boxShadow: "0 3px 5px rgba(0,0,0,0.1)",
"& .MuiSvgIcon-root": {
fontSize: "5rem",
},
zIndex: 1500,
};

0 comments on commit ab3a461

Please sign in to comment.