diff --git a/src/app/team/[teamId]/study/[studyId]/page.tsx b/src/app/team/[teamId]/study/[studyId]/page.tsx index c6a284c0..d17a5a7b 100644 --- a/src/app/team/[teamId]/study/[studyId]/page.tsx +++ b/src/app/team/[teamId]/study/[studyId]/page.tsx @@ -1,12 +1,18 @@ +'use client'; + import { Flex, Grid, IconButton, Text, Link } from '@chakra-ui/react'; import NextLink from 'next/link'; +import { useState } from 'react'; import { MdOutlineArrowForwardIos } from 'react-icons/md'; import CurriculumCard from '@/components/CurriculumCard'; import StudyAssetCard from '@/components/StudyAssetCard'; import Title from '@/components/Title'; import Feed from '@/containers/study/Feed'; +import DeleteStudyModal from '@/containers/study/Modal/DeleteStudyModal'; +import TerminateStudyModal from '@/containers/study/Modal/TerminateStudyModal'; import Participant from '@/containers/study/Participant'; +import StudyControlPanel from '@/containers/study/StudyControlPanel'; import StudyInfoCard from '@/containers/study/StudyInfoCard'; import participantData from '@/mocks/participant'; import studyAssetCardData from '@/mocks/studyAssetCard'; @@ -15,51 +21,63 @@ import studyCardData from '@/mocks/studyCard'; const sampleStudy = studyCardData[0]; const Page = () => { + const [isDeleteModalOpen, setIsDeleteModalOpen] = useState(false); + const [isTerminateModalOpen, setIsTerminateModalOpen] = useState(false); + return ( - - - - <StudyInfoCard - progress={sampleStudy.percent} - startAt={new Date(sampleStudy.startDate)} - endAt={new Date(sampleStudy.endDate)} - /> - </Flex> - <Grid gap="4" templateColumns={{ base: '', xl: '2fr 1fr' }} w="100%"> - <Flex direction="column" rowGap={{ base: '6', '2xl': '12' }}> - <CurriculumCard /> - <Flex align="right" direction="column" rowGap="3"> - <Link as={NextLink} gap="3" display="flex" w="fit-content" ml="auto" href="/"> - <IconButton - fontSize="16px" - aria-label="" - icon={<MdOutlineArrowForwardIos />} - isRound - size="icon_sm" - variant="icon_orange" - /> - <Text>전체 보기</Text> - </Link> - <Grid gap="2" templateColumns={{ base: 'repeat(2, 1fr)', lg: 'repeat(4, 1fr)' }}> - {studyAssetCardData.map((data) => ( - <StudyAssetCard - key={data.title} - title={data.title} - content={data.content} - date={data.date} - bookmark={data.bookmark} - img={data.img} + <> + <Flex direction="column" gap="0" w="100%" p="8"> + <Flex justify="space-between" w="100%"> + <Title name={sampleStudy.name} description={sampleStudy.description} /> + <StudyInfoCard + progress={sampleStudy.percent} + startAt={new Date(sampleStudy.startDate)} + endAt={new Date(sampleStudy.endDate)} + /> + </Flex> + <StudyControlPanel terminateModalOpen={setIsTerminateModalOpen} deleteModalOpen={setIsDeleteModalOpen} /> + <Grid gap="4" templateColumns={{ base: '', xl: '2fr 1fr' }} w="100%"> + <Flex direction="column" rowGap={{ base: '6', '2xl': '12' }}> + <CurriculumCard /> + <Flex align="right" direction="column" rowGap="3"> + <Link as={NextLink} gap="3" display="flex" w="fit-content" ml="auto" href="/"> + <IconButton + fontSize="16px" + aria-label="" + icon={<MdOutlineArrowForwardIos />} + isRound + size="icon_sm" + variant="icon_orange" /> - ))} - </Grid> + <Text>전체 보기</Text> + </Link> + <Grid gap="2" templateColumns={{ base: 'repeat(2, 1fr)', lg: 'repeat(4, 1fr)' }}> + {studyAssetCardData.map((data) => ( + <StudyAssetCard + key={data.title} + title={data.title} + content={data.content} + date={data.date} + bookmark={data.bookmark} + img={data.img} + /> + ))} + </Grid> + </Flex> </Flex> - </Flex> - <Flex direction="column" rowGap={{ base: '6', '2xl': '12' }}> - <Feed /> - <Participant participantInfos={participantData} /> - </Flex> - </Grid> - </Flex> + <Flex direction="column" rowGap={{ base: '6', '2xl': '12' }}> + <Feed /> + <Participant participantInfos={participantData} /> + </Flex> + </Grid> + </Flex> + <TerminateStudyModal + studyName={sampleStudy.name} + isOpen={isTerminateModalOpen} + setIsOpen={setIsTerminateModalOpen} + /> + <DeleteStudyModal studyName={sampleStudy.name} isOpen={isDeleteModalOpen} setIsOpen={setIsDeleteModalOpen} /> + </> ); }; diff --git a/src/containers/study/Modal/DeleteStudyModal/index.tsx b/src/containers/study/Modal/DeleteStudyModal/index.tsx new file mode 100644 index 00000000..22440ab6 --- /dev/null +++ b/src/containers/study/Modal/DeleteStudyModal/index.tsx @@ -0,0 +1,30 @@ +import { Text } from '@chakra-ui/react'; + +import ConfirmModal from '@/components/Modal/ConfirmModal'; + +import { DeleteStudyModalProps } from '../types'; + +const DeleteStudyModal = ({ studyName, isOpen, setIsOpen }: DeleteStudyModalProps) => { + const handleClickDelete = () => { + // TODO - API 연결 + setIsOpen(false); + }; + + return ( + <ConfirmModal + isOpen={isOpen} + onClose={() => setIsOpen(false)} + title="스터디 삭제" + confirmButtonText="삭제" + onConfirmButtonClick={handleClickDelete} + > + <Text align="center"> + 삭제된 스터디는 되돌릴 수 없습니다. + <br /> + {`"${studyName}"을 삭제하시겠습니까?`} + </Text> + </ConfirmModal> + ); +}; + +export default DeleteStudyModal; diff --git a/src/containers/study/Modal/TerminateStudyModal/index.tsx b/src/containers/study/Modal/TerminateStudyModal/index.tsx new file mode 100644 index 00000000..1c2131a4 --- /dev/null +++ b/src/containers/study/Modal/TerminateStudyModal/index.tsx @@ -0,0 +1,32 @@ +import { Text } from '@chakra-ui/react'; + +import ConfirmModal from '@/components/Modal/ConfirmModal'; + +import { TerminateStudyModalProps } from '../types'; + +const TerminateStudyModal = ({ studyName, isOpen, setIsOpen }: TerminateStudyModalProps) => { + const handleClickTerminate = () => { + // TODO - API 연결 + setIsOpen(false); + }; + + return ( + <ConfirmModal + isOpen={isOpen} + onClose={() => setIsOpen(false)} + title="스터디 종료" + confirmButtonText="종료" + onConfirmButtonClick={handleClickTerminate} + > + <Text align="center"> + 스터디 종료시 수료증이 발급되며 + <br /> + 스터디 정보 수정 및 삭제가 불가능합니다. + <br /> + {`"${studyName}"을 종료하시겠습니까?`} + </Text> + </ConfirmModal> + ); +}; + +export default TerminateStudyModal; diff --git a/src/containers/study/Modal/types.ts b/src/containers/study/Modal/types.ts new file mode 100644 index 00000000..d8bdff37 --- /dev/null +++ b/src/containers/study/Modal/types.ts @@ -0,0 +1,11 @@ +export interface TerminateStudyModalProps { + studyName: string; + isOpen: boolean; + setIsOpen: React.Dispatch<React.SetStateAction<boolean>>; +} + +export interface DeleteStudyModalProps { + studyName: string; + isOpen: boolean; + setIsOpen: React.Dispatch<React.SetStateAction<boolean>>; +} diff --git a/src/containers/study/StudyControlPanel/index.tsx b/src/containers/study/StudyControlPanel/index.tsx new file mode 100644 index 00000000..ce723eb1 --- /dev/null +++ b/src/containers/study/StudyControlPanel/index.tsx @@ -0,0 +1,40 @@ +import { Button, Flex } from '@chakra-ui/react'; + +import { StudyControlPanelProps } from './types'; + +const StudyControlPanel = ({ terminateModalOpen, deleteModalOpen }: StudyControlPanelProps) => { + return ( + <Flex gap="2" mb="8"> + <Button + w="fit-content" + px="4" + py="1" + color="white" + bg="orange_dark" + shadow="md" + _hover={{ bg: 'orange_dark' }} + aria-label="" + onClick={() => terminateModalOpen(true)} + size="xs" + > + 종료 + </Button> + <Button + w="fit-content" + px="4" + py="1" + color="black" + bg="white" + shadow="md" + _hover={{ bg: 'white' }} + aria-label="" + onClick={() => deleteModalOpen(true)} + size="xs" + > + 삭제 + </Button> + </Flex> + ); +}; + +export default StudyControlPanel; diff --git a/src/containers/study/StudyControlPanel/types.ts b/src/containers/study/StudyControlPanel/types.ts new file mode 100644 index 00000000..6c8a4a24 --- /dev/null +++ b/src/containers/study/StudyControlPanel/types.ts @@ -0,0 +1,4 @@ +export interface StudyControlPanelProps { + terminateModalOpen: React.Dispatch<React.SetStateAction<boolean>>; + deleteModalOpen: React.Dispatch<React.SetStateAction<boolean>>; +}