Skip to content

Commit

Permalink
Merge pull request #374 from SejongPeer/feature/25
Browse files Browse the repository at this point in the history
feat : [25] 카테고리(교내) 선택
  • Loading branch information
AhnRian authored Aug 3, 2024
2 parents 3c5b95d + b76a480 commit 5bd0738
Show file tree
Hide file tree
Showing 9 changed files with 317 additions and 88 deletions.
Binary file added public/TimeTable.xlsx
Binary file not shown.
23 changes: 15 additions & 8 deletions src/components/modal/BottomModal.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import React, { useContext, useState, useEffect } from "react";
import { MyContext } from "../../App";
import React, { useContext, useState, useEffect } from 'react';
import { MyContext } from '../../App';

import style from './BottomModal.module.css';

const BottomModal = (props) => {
const BottomModal = ({ state = null, children }) => {
const [animate, setAnimate] = useState(false);
const { modalOpen, setModalOpen } = useContext(MyContext);

Expand All @@ -20,10 +20,17 @@ const BottomModal = (props) => {
// props.deleteHandler()
};

return <div className={style.modal}>
<div onClick={cancelHandler} className={style.backdrop} />
<div className={`${style.container} ${animate ? style.animate : ''}`}>{props.children}</div>
</div>;
return (
<div className={style.modal}>
<div
onClick={state === 'studyPostField' ? null : cancelHandler}
className={style.backdrop}
/>
<div className={`${style.container} ${animate ? style.animate : ''}`}>
{children}
</div>
</div>
);
};

export default BottomModal;
export default BottomModal;
63 changes: 32 additions & 31 deletions src/components/studyPostWrite/studyRequirement/Category.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,39 +2,40 @@ import { useEffect, useState } from 'react';
import usePostStore from '../../../pages/study/studyPostWrite/usePostStore';
import style from '../StudyRequirement.module.css';
import arrow from '../../../assets/image/down_black.png';

const Category = ({studyFilterHandler}) => {
const {category} = usePostStore();

const [isPost, setIsPost] = useState(true);
useEffect(() => {
if (window.location.pathname.startsWith('/study/modify')) {
setIsPost(false);
} else {
setIsPost(true);
}
}, [])
import useTimeTableStore from '../../../pages/study/timeTable/useTimeTableStore';
const Category = ({ studyFilterHandler }) => {
const { category } = usePostStore();
const { subjectName } = useTimeTableStore();

const modify = () => {
alert('카테고리는 수정할 수 없습니다!')
const [isPost, setIsPost] = useState(true);
useEffect(() => {
if (window.location.pathname.startsWith('/study/modify')) {
setIsPost(false);
} else {
setIsPost(true);
}
}, []);

return (
<div className={style.flexWrapper} onClick={isPost ? studyFilterHandler : modify}>
<label className={style.label}>
카테고리
</label>
const modify = () => {
alert('카테고리는 수정할 수 없습니다!');
};

{isPost ?
<img
src={arrow}
className={style.arrowImg}
alt="Arrow"
/>
:
<p>{category}</p>}
</div>
)
}
return (
<div
className={style.flexWrapper}
onClick={isPost ? studyFilterHandler : modify}
>
<label className={style.label}>
{subjectName === '' ? '카테고리' : subjectName}
</label>

export default Category;
{isPost ? (
<img src={arrow} className={style.arrowImg} alt="Arrow" />
) : (
<p>{category}</p>
)}
</div>
);
};

export default Category;
114 changes: 104 additions & 10 deletions src/pages/study/studyPostWrite/StudyPostWrite.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,14 @@ import Popup from '../../../components/studyPopup/Popup';
import usePostStore from './usePostStore';
import useStudyInfoStore from '../useStudyInfoStore';
import usePopupStroe from '../../../components/studyPopup/usePopupStore';
import useTimeTableStore from '../timeTable/useTimeTableStore';
import { format } from 'date-fns';
// import Category from '../../../components/studyPostWrite/studyRequirement/Category';

import { useNavigate } from 'react-router-dom';

//강의 시간표
import getTimeTable from '../timeTable/getTimeTable';
const StudyPostWrite = props => {
const {
title,
Expand All @@ -56,13 +60,24 @@ const StudyPostWrite = props => {
setPopupMessage,
} = usePopupStroe();
const { studyType } = useStudyInfoStore();
const { subjectName, setTableInfos, setShowData } = useTimeTableStore();

const navigate = useNavigate();

const handleDatePickerFocus = event => {
event.target.blur();
};

//강의 시간표 get
useEffect(() => {
const fetchAndSetTimeTable = async () => {
const data = await getTimeTable();
setTableInfos(data.tableInfos);
setShowData(data.showData);
};

fetchAndSetTimeTable();
}, []);
// 모달 오픈,
const [isClickedStudy, setIsClickedStudy] = useState(false);
const [isClickedMember, setIsClickedMember] = useState(false);
Expand Down Expand Up @@ -122,7 +137,7 @@ const StudyPostWrite = props => {
const newImgFiles = imgFiles.filter((_, i) => i !== index);
setImgFiles(newImgFiles);
};

//이미지 업로드 통신
const imgUpload = async id => {
const imgs = [...imgFiles];
Expand Down Expand Up @@ -174,10 +189,14 @@ const StudyPostWrite = props => {
const submitHandler = async e => {
//제목/모집기간/모집인원/내용/오픈채팅 링크/카테고리
const validation = (name, text) => {
if (text === '' || text === null) return `${name}을(를) 입력해주세요`;
if (text === '' || text === null) {
if (name === '카테고리') return `${name}를 선택해주세요`;
return `${name}을(를) 입력해주세요`;
}
};

const errorMessage =
validation('카테고리', category) ||
validation('제목', title) ||
validation('모집 시작일', startDate) ||
validation('모집 종료일', endDate) ||
Expand All @@ -191,6 +210,7 @@ const StudyPostWrite = props => {
}
const formStartDate = format(startDate, 'yyyy-MM-dd HH:mm:ss');
const formEndDate = format(endDate, 'yyyy-MM-dd HH:mm:ss');

const studyData =
studyType === 'lecture'
? {
Expand Down Expand Up @@ -247,17 +267,85 @@ const StudyPostWrite = props => {
throw new Error(data.message || 'Something went wrong');
}

// if (data.data !== null) {
// errorClassName = data.data.errorClassName;
// }
alert('게시글 작성 완료');
navigate(`/study/post/${studyId}`);
if (data.data !== null) {
errorClassName = data.data.errorClassName;
}
} catch (err) {
console.log('ErrorMessage : ', err.message);

e.preventDefault();
}
};

const modifyHandler = async e => {
//제목/모집기간/모집인원/내용/오픈채팅 링크/카테고리
const validation = (name, text) => {
if (text === '' || text === null) return `${name}을(를) 입력해주세요`;
};

const errorMessage =
validation('제목', title) ||
validation('모집 시작일', startDate) ||
validation('모집 종료일', endDate) ||
validation('내용', content) ||
validation('오픈채팅 링크', studyLink) ||
null;

if (errorMessage) {
togglePopup(errorMessage);
return;
}
const formStartDate = format(startDate, 'yyyy-MM-dd HH:mm:ss');
const formEndDate = format(endDate, 'yyyy-MM-dd HH:mm:ss');

const studyData = {
title: title,
content: content,
recruitmentCount: memberNum,
method: selectedWay,
frequency: selectedFrequency,
kakaoLink: studyLink,
questionLink: questionLink,
lectureId: category,
recruitmentStartAt: formStartDate,
recruitmentEndAt: formEndDate,
tags: tags,
images: null,
};
console.log(studyData);

try {
const response = await fetch(
`${process.env.REACT_APP_BACK_SERVER}/study/${props.studyId}`,
{
method: 'PATCH',
body: JSON.stringify(studyData),
headers: {
'Content-Type': 'application/json',
Authorization: `Bearer ${localStorage.getItem('accessToken')}`,
'Refresh-Token': localStorage.getItem('refreshToken'),
},
}
);

const text = await response.text();
const data = text ? JSON.parse(text) : {};

const studyId = data.data.id;
imgUpload(studyId);
if (!response.ok) {
throw new Error(data.message || 'Something went wrong');
}

if (data.data !== null) {
errorClassName = data.data.errorClassName;
}
} catch (err) {
console.log('ErrorMessage : ', err.message);

e.preventDefault();
}
};

const [isPost, setIsPost] = useState(true);
useEffect(() => {
Expand All @@ -266,7 +354,7 @@ const StudyPostWrite = props => {
} else {
setIsPost(true);
}
}, [])
}, []);
const btnOnclick = isPost ? submitHandler : modifyHandler;

return (
Expand Down Expand Up @@ -294,11 +382,17 @@ const StudyPostWrite = props => {
</div>

<div className={style.postConainer} onClick={submitHandler}>
<SubmitBtn name={'모집글 올리기'} ready={isFilled} />
<SubmitBtn
name={isPost ? '모집글 올리기' : '모집글 수정하기'}
ready={isFilled}
/>
</div>

{modalOpen && (
<BottomModal deleteHandler={deleteHandler}>
<BottomModal
deleteHandler={deleteHandler}
state={isClickedStudy ? 'studyPostField' : null}
>
{isClickedStudy && <StudyPostField />}
{isClickedMember && <StudyMember />}
</BottomModal>
Expand Down
72 changes: 71 additions & 1 deletion src/pages/study/studyPostWrite/studyPostField/StudyPostField.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,58 @@
import { useState, useEffect, useContext } from 'react';
import style from './StudyPostField.module.css';
import search from '../../../../assets/image/search_gray.png';

//zustand
import useTimeTableStore from '../../timeTable/useTimeTableStore';
import usePostStore from '../usePostStore';
import { MyContext } from '../../../../App';

import getTimeTable from '../../timeTable/getTimeTable';
const StudyPostField = () => {
const { tableInfos, setTableInfos, showData, setShowData, setSubjectName } =
useTimeTableStore();
const { setCategory } = usePostStore();
const [selectingState, setSelectingState] = useState('college');

//모달 닫기
const { setModalOpen } = useContext(MyContext);
const selectHandle = (item, state) => {
if (state === 'college') {
const newTableInfo = tableInfos.filter(row => row[1] === item);
setTableInfos(newTableInfo);
setShowData(
Array.from(new Set(newTableInfo.map(row => row[2]).filter(Boolean)))
);
setSelectingState('department');
} else if (state === 'department') {
const newTableInfo = tableInfos.filter(row => row[2] === item);
setTableInfos(newTableInfo);
setShowData(
Array.from(
new Set(newTableInfo.map(row => [row[3], row[4]]).filter(Boolean))
)
);
setSelectingState('subsProfs');
} else if (state === 'subsProfs') {
const newTableInfo = tableInfos.filter(row => {
if (row[3] === item[0] && row[4] === item[1]) {
return row;
}
});
setCategory(newTableInfo[0][0]);
setSubjectName(item[0]);
const fetchAndSetTimeTable = async () => {
const data = await getTimeTable();
setTableInfos(data.tableInfos);
setShowData(data.showData);
};

fetchAndSetTimeTable();
setSelectingState('college');
setModalOpen(false);
}
};

return (
<div className={style.container}>
<header className={style.header}>
Expand All @@ -17,7 +68,26 @@ const StudyPostField = () => {
/>
</div>
</div>
<div className={style.filter_study}></div>
<div className={style.filter_study}>
<div>
{showData.map((item, index) => (
<div
className={style.cateGoryItem}
key={index}
onClick={() => selectHandle(item, selectingState)}
>
{selectingState === 'subsProfs' ? (
<div className={style.subsProfsDiv}>
<span>{item[0]}</span>
<span>{item[1]}</span>
</div>
) : (
item
)}
</div>
))}
</div>
</div>
</div>
);
};
Expand Down
Loading

0 comments on commit 5bd0738

Please sign in to comment.