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

Feature/#235 스터디 수정 모달 구현 #246

Merged
merged 2 commits into from
Jun 8, 2024
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
90 changes: 48 additions & 42 deletions src/app/team/[teamId]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import { StudyCardProps } from '@/components/StudyCard/types';
import TabButton from '@/components/TabButton';
import Title from '@/components/Title';
import { CARD_PER_PAGE, TEAM_CATEGORY_INFOS } from '@/constants/team';
import StudyModal from '@/containers/study/Modal/StudyModal';
import AssetGridView from '@/containers/team/AssetGridView';
import AttendanceRate from '@/containers/team/AttendanceRate';
import NavigationButton from '@/containers/team/NavigationButton';
Expand All @@ -21,7 +22,7 @@ import { gardenInfos1 } from '@/mocks/Garden3D';
import studyAssetCardData from '@/mocks/studyAssetCard';
import studyCardData from '@/mocks/studyCard';

const Page = () => {
const Page = ({ params }: { params: { teamId: number } }) => {
const [category, setCategory] = useState<string>(TEAM_CATEGORY_INFOS[0].name);
const [cardIdx, setCardIdx] = useState<number>(0);

Expand All @@ -30,6 +31,8 @@ const Page = () => {
const [assetArray, setAssetArray] = useState<StudyAssetCardProps[]>([]);
const [assetLength, setAssetLength] = useState<number>(0);

const [isCreateStudyModalOpen, setIsCreateStudyModalOpen] = useState<boolean>(false);

const getCardData = (start: number) => {
if (category === '스터디') {
// TODO: 스터디 목록 조회하기.
Expand Down Expand Up @@ -66,7 +69,7 @@ const Page = () => {

const handlePlusClick = () => {
if (category === '스터디') {
// TODO: create study modal 띄우기
setIsCreateStudyModalOpen(true);
} else if (category === '학습자료') {
// TODO: create study asset modal 띄우기
}
Expand All @@ -78,52 +81,55 @@ const Page = () => {
};

return (
<Flex direction="column" gap="8" w="100%" p="8">
<Flex justify="space-between">
<Title isTeam name="열사모" description="팀입니다" />
{/* TODO 팀원 목록, 초대링크 버튼 */}
<Flex align="center" gap={{ base: '2', lg: '8' }}>
<TeamMember />
<Button color="white" bg="orange_dark" rightIcon={<BsLink45Deg size="24px" />} rounded="full" size="sm">
초대
</Button>
<>
<Flex direction="column" gap="8" w="100%" p="8">
<Flex justify="space-between">
<Title isTeam name="열사모" description="팀입니다" />
{/* TODO 팀원 목록, 초대링크 버튼 */}
<Flex align="center" gap={{ base: '2', lg: '8' }}>
<TeamMember />
<Button color="white" bg="orange_dark" rightIcon={<BsLink45Deg size="24px" />} rounded="full" size="sm">
초대
</Button>
</Flex>
</Flex>
</Flex>

<Flex pos="relative" align="center" flex="1" gap="8">
{/* TODO 잔디 */}
<Box pos="relative" overflow="hidden" w="100%" h={{ base: '250px', md: '300px', xl: '320px' }}>
<Box pos="absolute" w="100%" h="100%">
<Garden3D
rotate
rotateY={0}
cubeGap={useBreakpointValue({ base: 3, xl: 4 }) || 3}
cubeSize={useBreakpointValue({ base: 20, md: 26, xl: 30 }) || 20}
gardenInfos={gardenInfos1}
/>
<Flex pos="relative" align="center" flex="1" gap="8">
{/* TODO 잔디 */}
<Box pos="relative" overflow="hidden" w="100%" h={{ base: '250px', md: '300px', xl: '320px' }}>
<Box pos="absolute" w="100%" h="100%">
<Garden3D
rotate
rotateY={0}
cubeGap={useBreakpointValue({ base: 3, xl: 4 }) || 3}
cubeSize={useBreakpointValue({ base: 20, md: 26, xl: 30 }) || 20}
gardenInfos={gardenInfos1}
/>
</Box>
</Box>
</Box>

{/* TODO 진행도 */}
<AttendanceRate attendanceRate={75} />
</Flex>
{/* TODO 진행도 */}
<AttendanceRate attendanceRate={75} />
</Flex>

<Flex direction="column" flex="1" gap="4">
{/* TODO 스터디, 학습자료, 작물창고 버튼 */}
<TabButton currentTab={category} changeTab={handleCategoryChange} categoryInfos={TEAM_CATEGORY_INFOS} />
{category !== '작물창고' && (
<NavigationButton
handlePrevClick={handlePrevClick}
handleNextClick={handleNextClick}
handlePlusClick={handlePlusClick}
/>
)}
{/* TODO 전체보기, 네비게이션 이동 버튼 */}
{/* TODO 스터디 카드 */}
{category === '스터디' && <StudyGridView studyArray={studyArray} />}
{category === '학습자료' && <AssetGridView assetArray={assetArray} />}
<Flex direction="column" flex="1" gap="4">
{/* TODO 스터디, 학습자료, 작물창고 버튼 */}
<TabButton currentTab={category} changeTab={handleCategoryChange} categoryInfos={TEAM_CATEGORY_INFOS} />
{category !== '작물창고' && (
<NavigationButton
handlePrevClick={handlePrevClick}
handleNextClick={handleNextClick}
handlePlusClick={handlePlusClick}
/>
)}
{/* TODO 전체보기, 네비게이션 이동 버튼 */}
{/* TODO 스터디 카드 */}
{category === '스터디' && <StudyGridView studyArray={studyArray} />}
{category === '학습자료' && <AssetGridView assetArray={assetArray} />}
</Flex>
</Flex>
</Flex>
<StudyModal teamId={params.teamId} isOpen={isCreateStudyModalOpen} setIsModalOpen={setIsCreateStudyModalOpen} />
</>
Copy link
Member

Choose a reason for hiding this comment

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

이건 배포 이후에 해도 될 것 같은데,

개인적으로 스터디 탭 버튼 + 스터디 카드 + 네비게이션 + 스터디 모달까지
해당 team page에서 말고, 아예 파일 빼서 하는것도 좋을 것 같습니다! 지금 봐서는 teamId만 props로 넘겨주면 될 것 같아서요!

Copy link
Member

Choose a reason for hiding this comment

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

그리고 저도 team 페이지 작업하고 있었기 때문에,, 조금 충돌이 날지두요 캬햐! 그치만 딱히 중요한건 안 겹쳐서 괜찮을 것 같습니당!

);
};

Expand Down
6 changes: 3 additions & 3 deletions src/app/team/[teamId]/study/[studyId]/page.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
/* eslint-disable @typescript-eslint/no-unused-vars */

'use client';

import { Flex, Grid, IconButton, Text, Link } from '@chakra-ui/react';
Expand All @@ -12,6 +10,7 @@ import Title from '@/components/Title';
import CurriculumCard from '@/containers/study/CurriculumCard';
import Feed from '@/containers/study/Feed';
import DeleteStudyModal from '@/containers/study/Modal/DeleteStudyModal';
import StudyModal from '@/containers/study/Modal/StudyModal';
import TerminateStudyModal from '@/containers/study/Modal/TerminateStudyModal';
import Participant from '@/containers/study/Participant';
import StudyControlPanel from '@/containers/study/StudyControlPanel';
Expand All @@ -22,7 +21,7 @@ import studyCardData from '@/mocks/studyCard';

const sampleStudy = studyCardData[0];

const Page = () => {
const Page = ({ params }: { params: { studyId: number } }) => {
const [isEditModalOpen, setIsEditModalOpen] = useState<boolean>(false);
const [isDeleteModalOpen, setIsDeleteModalOpen] = useState<boolean>(false);
const [isTerminateModalOpen, setIsTerminateModalOpen] = useState<boolean>(false);
Expand Down Expand Up @@ -79,6 +78,7 @@ const Page = () => {
</Flex>
</Grid>
</Flex>
<StudyModal studyId={params.studyId} isOpen={isEditModalOpen} setIsModalOpen={setIsEditModalOpen} />
<TerminateStudyModal
studyName={sampleStudy.name}
isOpen={isTerminateModalOpen}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import Selector from '@/components/Selector';
import StyledDatePicker from '@/components/StyledDatePicker';
import CROP from '@/constants/crop';

import { CreateStudyModalProps } from './types';
import { StudyModalProps } from './types';
Copy link
Member

Choose a reason for hiding this comment

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

지금 containers/study/study/Modal 폴더안에 비어있는 DeleteStudyModal, TerminateStudyModal 이 있는 것 같습니당!


const AlertContent = ({ message }: { message: string }) => {
return (
Expand All @@ -21,7 +21,8 @@ const AlertContent = ({ message }: { message: string }) => {
);
};

const CreateStudyModal = ({ isOpen, setIsModalOpen }: CreateStudyModalProps) => {
const StudyModal = ({ teamId, studyId, isOpen, setIsModalOpen }: StudyModalProps) => {
const isEditMode = Boolean(studyId);
Copy link
Member

Choose a reason for hiding this comment

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

스터디 수정 모달에서는, 맨처음에 원래 스터디 정보가 입력되서 나와야할 것 같아요!
그래서 스터디 정보 get api가 필요한데, 이 모달창이 어차피 스터디 페이지 -> 수정 버튼 눌렀을때 뜨는 모달이니까,
스터디 페이지에서 먼저 스터디 정보 get api가 쓰일거란 말이죠! 그래서 그 정보를 모달 props로 그대로 가져오는건 어떨까요? 사실 팀 페이지에서 해당 방식으로 사용했습니다! (팀 페이지 풀리퀘)

그렇게 되면 studyId말고 study 정보가 있는지 없는지로 구별하면 될 것 같아요!

Copy link
Member

Choose a reason for hiding this comment

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

만약 sutdy 정보 props명이 studyInfo라고 한다면,
스터디 생성 모달에서는 studyInfo가 어차피 null로 들어갈거니까, 지금 isEditModestudyInfo로 바꾸면 조건문 다 똑같이 동작할 것 같습니다!

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

오오 감사합니다! 참고해서 api 연결하겠습니다!

const [step, setStep] = useState<number>(1);
const [name, setName] = useState<string>('');
const [description, setDescription] = useState<string>('');
Expand All @@ -34,6 +35,21 @@ const CreateStudyModal = ({ isOpen, setIsModalOpen }: CreateStudyModalProps) =>
const [alertSelectedCropId, setAlertSelectedCropId] = useState<boolean>(false);
const [alertStartDate, setAlertStartDate] = useState<boolean>(false);

const onClose = () => {
setStep(1);
setName('');
setDescription('');
setCropName('');
setCropId(0);
setStartDate(null);
setEndDate(null);
setAlertName(false);
setAlertDescription(false);
setAlertSelectedCropId(false);
setAlertStartDate(false);
setIsModalOpen(false);
};

const handlePrevButtonClick = () => {
setStep(step - 1);
};
Expand All @@ -43,9 +59,14 @@ const CreateStudyModal = ({ isOpen, setIsModalOpen }: CreateStudyModalProps) =>
if (name !== '' && description !== '') setStep(step + 1);
};
const handleSaveButtonClick = () => {
if (cropName === '') setAlertSelectedCropId(true);
if (startDate === null) setAlertStartDate(true);
if (cropName !== '' && startDate !== null) setIsModalOpen(false);
if (isEditMode) {
if (startDate === null) setAlertStartDate(true);
else onClose();
} else {
if (cropName === '') setAlertSelectedCropId(true);
if (startDate === null) setAlertStartDate(true);
if (cropName !== '' && startDate !== null) onClose();
}
};
const handleNameChange = (e: React.ChangeEvent<HTMLTextAreaElement>) => {
setName(e.target.value);
Expand All @@ -69,11 +90,11 @@ const CreateStudyModal = ({ isOpen, setIsModalOpen }: CreateStudyModalProps) =>
return (
<ActionModal
isOpen={isOpen}
onClose={() => setIsModalOpen(false)}
title="스터디 생성"
onClose={onClose}
title={`스터디 ${isEditMode ? '수정' : '생성'}`}
subButtonText={step === 1 ? '취소' : '이전'}
mainButtonText={step === 1 ? '다음' : '저장'}
onSubButtonClick={step === 1 ? () => setIsModalOpen(false) : handlePrevButtonClick}
onSubButtonClick={step === 1 ? onClose : handlePrevButtonClick}
onMainButtonClick={step === 1 ? handleNextButtonClick : handleSaveButtonClick}
>
<Box overflowY="auto" minH="60vh" maxH="60vh">
Expand Down Expand Up @@ -113,7 +134,7 @@ const CreateStudyModal = ({ isOpen, setIsModalOpen }: CreateStudyModalProps) =>
/>
</>
)}
{step === 2 && (
{step === 2 && !isEditMode && (
<>
<Text textStyle="bold_xl" mt="4" mb="2">
작물 선택 *
Expand All @@ -133,6 +154,10 @@ const CreateStudyModal = ({ isOpen, setIsModalOpen }: CreateStudyModalProps) =>
else setAlertSelectedCropId(true);
}}
/>
</>
)}
{step === 2 && (
<>
<Text textStyle="bold_xl" mt="8" mb="2">
날짜 선택 *
</Text>
Expand All @@ -147,4 +172,4 @@ const CreateStudyModal = ({ isOpen, setIsModalOpen }: CreateStudyModalProps) =>
</ActionModal>
);
};
export default CreateStudyModal;
export default StudyModal;
6 changes: 6 additions & 0 deletions src/containers/study/Modal/StudyModal/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
export interface StudyModalProps {
teamId?: number;
Copy link
Member

Choose a reason for hiding this comment

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

혹시 teamId가 옵셔널인 이유가 있을까요? 스터디 생성/수정 모두 teamId는 들어가야하는거 아녔나용??

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

생성에만 teamId가 들어가고, 나머지는 모두 studyId만 필요로 하길래 옵션으로 걸어놨습니다!

studyId?: number;
isOpen: boolean;
setIsModalOpen: (isOpen: boolean) => void;
}
4 changes: 0 additions & 4 deletions src/containers/team/CreateStudyModal/types.ts

This file was deleted.