Skip to content

Commit

Permalink
♻️ refactor : Modify the layout used on the class list and class main…
Browse files Browse the repository at this point in the history
… page

- Change user's information to be passed in as props as well

Related Issue : YJU-OKURA#59 YJU-OKURA#77 YJU-OKURA#101
  • Loading branch information
Lainari committed May 8, 2024
1 parent d2825ee commit 76d09aa
Show file tree
Hide file tree
Showing 21 changed files with 450 additions and 404 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,12 @@ const ChatInput = ({setMsg}: inputProps) => {
setInputMsg(e.target.value);
};

const handleKeyPress = (e: React.KeyboardEvent) => {
if (e.key === 'Enter') {
handleClickButton();
}
};

const handleClickButton = () => {
console.log(inputMsg);
setMsg(inputMsg);
Expand All @@ -22,6 +28,7 @@ const ChatInput = ({setMsg}: inputProps) => {
className="w-full p-3 outline-none"
placeholder="Please enter your question"
onChange={handleInputMsg}
onKeyDown={handleKeyPress}
value={inputMsg}
/>
<div className="px-2" onClick={handleClickButton}>
Expand Down
127 changes: 49 additions & 78 deletions src/app/classes/[cId]/components/main/Main.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,100 +7,67 @@ import {
ClassCreatePost,
ClassCreateSchedule,
} from '@/src/app/classes/[cId]/components/modal';
import {RoleProps} from '@/src/interfaces/_class';
import {MainSectionProps, RoleProps} from '@/src/interfaces/_class';
import icons from '@/public/svgs/_class';

const Main = ({managerRole, classId}: RoleProps) => {
const Main = ({managerRole, classId, userInfo}: RoleProps) => {
const [showDropdown, setShowDropdown] = useState<Record<string, boolean>>({
공지사항: false,
일정: false,
게시글: false,
공지사항: true,
일정: true,
게시글: true,
});
const [modalState, setModalState] = useState({
schedule: false,
post: false,
});
const [showScheduleModal, setShowScheduleModal] = useState(false);
const [showPostModal, setShowPostModal] = useState(false);

const handleDropdown = (sectionTitle: string) => {
setShowDropdown(prevState => {
const newState = Object.assign({}, prevState);
newState[sectionTitle] = !prevState[sectionTitle];
return newState;
});
};

const handleOpenScheduleModal = () => {
setShowDropdown(prevState => ({...prevState, 일정: true}));
setShowScheduleModal(true);
};

const handleCloseScheduleModal = () => {
setShowDropdown(prevState => ({...prevState, 일정: false}));
setShowScheduleModal(false);
};

const handleOpenPostModal = () => {
setShowDropdown(prevState => ({
...prevState,
게시글: true,
일정: !prevState['일정'],
}));
setShowPostModal(true);
};

const handleClosePostModal = () => {
setShowDropdown(prevState => ({
...prevState,
게시글: false,
공지사항: !prevState['공지사항'],
}));
setShowPostModal(false);
const handleModal = (modalType: string, state: boolean) => {
setModalState(prevState => ({...prevState, [modalType]: state}));
setShowDropdown(prevState => ({...prevState, [modalType]: state}));
};
const createSection = (
title: string,
Component: React.ElementType,
ModalComponent: React.ElementType,
modalType: string
) => ({
title,
component: (
<>
<Component
managerRole={managerRole}
classId={classId}
userInfo={userInfo}
isOpen={showDropdown[title]}
/>
{modalState[modalType as keyof typeof modalState] && (
<ModalComponent
setShowModal={(state: boolean) => handleModal(modalType, state)}
classId={classId}
userInfo={userInfo}
/>
)}
</>
),
openModal: () => handleModal(modalType, true),
});

const mainSections = [
const mainSections: MainSectionProps[] = [
{
title: '공지사항',
component: (
<Notice
managerRole={managerRole}
classId={classId}
userInfo={userInfo}
isOpen={showDropdown['공지사항']}
/>
),
},
{
title: '일정',
component: (
<>
<Schedule
managerRole={managerRole}
classId={classId}
isOpen={showDropdown['일정']}
/>
{showScheduleModal && (
<ClassCreateSchedule
setShowScheduleModal={handleCloseScheduleModal}
/>
)}
</>
),
openModal: handleOpenScheduleModal,
},
{
title: '게시글',
component: (
<>
<Post
managerRole={managerRole}
classId={classId}
isOpen={showDropdown['게시글']}
/>
{showPostModal && (
<ClassCreatePost setShowPostModal={handleClosePostModal} />
)}
</>
),
openModal: handleOpenPostModal,
},
createSection('일정', Schedule, ClassCreateSchedule, 'schedule'),
createSection('게시글', Post, ClassCreatePost, 'post'),
];

return (
<>
<div className="mt-2 w-11/12">
Expand All @@ -115,12 +82,16 @@ const Main = ({managerRole, classId}: RoleProps) => {
className={`me-2 w-auto h-auto max-w-6 max-h-6 hover:cursor-pointer ${
showDropdown[section.title] ? '' : '-rotate-90'
}`}
onClick={() => handleDropdown(section.title)}
onClick={() =>
handleModal(section.title, !showDropdown[section.title])
}
/>
<div className="flex w-full mb-3 justify-between items-center">
<h3
className="text-xl font-bold hover:cursor-pointer"
onClick={() => handleDropdown(section.title)}
onClick={() =>
handleModal(section.title, !showDropdown[section.title])
}
>
{section.title}
</h3>
Expand Down
6 changes: 3 additions & 3 deletions src/app/classes/[cId]/components/main/Notice.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,13 @@ import {ClassEditPost} from '../modal';
import {Dropdown} from '@/src/app/classes/components/_class/dropdown';
import getClassAnnounced from '@/src/api/classBoard/getClassAnnounced';
import DeleteClassBoard from '@/src/api/classBoard/deleteClassBoard';
import User from '@/src/model/User';
import {RoleProps} from '@/src/interfaces/_class';
import icons from '@/public/svgs/_class';

const Notice = ({
managerRole,
classId,
userInfo,
isOpen,
}: RoleProps & {isOpen: boolean}) => {
const dropdownItems = [
Expand All @@ -36,10 +36,10 @@ const Notice = ({
const [selectedModalId, setSelectedModalId] = useState<string | null>(null);

const deleteNotice = async (postId: number) => {
if (classId !== undefined) {
if (classId !== undefined && userInfo) {
try {
if (confirm('정말로 공지사항을 삭제하시겠습니까?')) {
await DeleteClassBoard(postId, classId, User.uid);
await DeleteClassBoard(postId, classId, userInfo.id);
alert('Notice deleted successfully!');
}
const notices = await getClassAnnounced(classId);
Expand Down
91 changes: 37 additions & 54 deletions src/app/classes/[cId]/components/main/Post.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,13 @@
import {useState, useEffect} from 'react';
import {PostCard} from '../card';
import {ClassPost} from '../modal';
import getClassBoardList from '@/src/api/classBoard/getClassBoardList';
import getClassBoard from '@/src/api/classBoard/getClassBoard';
import DeleteClassBoard from '@/src/api/classBoard/deleteClassBoard';
import User from '@/src/model/User';
import classBoardAPI from '@/src/api/classBoard';
import {RoleProps} from '@/src/interfaces/_class';

const Post = ({
managerRole,
classId,
userInfo,
isOpen,
}: RoleProps & {isOpen: boolean}) => {
const [classPosts, setClassPosts] = useState<
Expand All @@ -33,22 +31,12 @@ const Post = ({

useEffect(() => {
if (classId !== undefined && isOpen) {
getClassBoardList(classId, 1, 99).then(posts => {
if (Array.isArray(posts.data)) {
setTotalPosts(posts.total);
} else {
console.error('getClassBoards did not return an array');
}
});
}
}, [classId, isOpen]);

useEffect(() => {
if (classId !== undefined && isOpen) {
getClassBoardList(classId, pageNum, 6).then(posts => {
console.log(posts.data);
classBoardAPI.getClassBoardList(classId, pageNum, 6).then(posts => {
if (Array.isArray(posts.data)) {
setClassPosts(posts.data);
if (pageNum === 1) {
setTotalPosts(posts.total);
}
} else {
console.error('getClassBoards did not return an array');
}
Expand All @@ -57,12 +45,16 @@ const Post = ({
}, [classId, isOpen, pageNum]);

const deletePost = async (postId: number) => {
if (classId !== undefined) {
if (classId !== undefined && userInfo) {
try {
if (confirm('정말로 게시글을 삭제하시겠습니까?')) {
await DeleteClassBoard(postId, classId, User.uid);
await classBoardAPI.deleteClassBoard(postId, classId, userInfo.id);
alert('Post deleted successfully!');
const posts = await getClassBoardList(classId, pageNum, 6);
const posts = await classBoardAPI.getClassBoardList(
classId,
pageNum,
6
);
if (Array.isArray(posts.data)) {
setClassPosts(posts.data);
} else {
Expand All @@ -78,27 +70,32 @@ const Post = ({
}
};

const handlePageChange = (page: number) => {
setPageNum(page);
setSelectedNum(page);
const calculateNewPageNum = (change: number) => {
const newPageNum = pageNum + change;
if (newPageNum < 1 || newPageNum > totalPages) {
return pageNum;
}
return newPageNum;
};

const handlePrevPage = () => {
if (pageNum > 1) {
setPageNum(pageNum - 1);
setSelectedNum(pageNum - 1);
}
const handlePageChange = (change: number) => {
const newPageNum = calculateNewPageNum(change);
setPageNum(newPageNum);
setSelectedNum(newPageNum);
};

const handleNextPage = () => {
if (pageNum < totalPages) {
setPageNum(pageNum + 1);
setSelectedNum(pageNum + 1);
}
const renderPageButton = (label: string, handler: () => void) => {
return totalPages === 0 ? null : (
<button className="border w-20 rounded-lg me-4 " onClick={handler}>
{label}
</button>
);
};

const renderPosts = () => {
if (classPosts.length === 0) {
const nonAnnouncedPosts = classPosts.filter(post => !post.IsAnnounced);

if (nonAnnouncedPosts.length === 0) {
return (
<div className="flex justify-center mt-2 w-full">
<div className="flex w-1/2 border-4 justify-center items-center h-20">
Expand All @@ -120,7 +117,7 @@ const Post = ({
key={post.ID}
onClick={async (event: React.MouseEvent) => {
event.stopPropagation();
setSelectedPost(await getClassBoard(post.ID));
setSelectedPost(await classBoardAPI.getClassBoard(post.ID));
setIsModalOpen(true);
}}
>
Expand Down Expand Up @@ -149,34 +146,20 @@ const Post = ({
return (
<>
{renderPosts()}
<div className="flex justify-center">
{totalPages === 0 ? null : (
<button
className="border w-20 rounded-lg me-4 "
onClick={handlePrevPage}
>
이전
</button>
)}
<div className="flex justify-center mt-10">
{renderPageButton('이전', () => handlePageChange(-1))}
{pages.map(page => (
<button
className={`border w-12 h-10 rounded-full me-2 ${
selectedNum === page ? 'bg-blue-300' : 'bg-[#DAEFFD]'
}`}
key={page}
onClick={() => handlePageChange(page)}
onClick={() => handlePageChange(page - pageNum)}
>
{page}
</button>
))}
{totalPages === 0 ? null : (
<button
className="border w-20 rounded-lg ms-2 "
onClick={handleNextPage}
>
다음
</button>
)}
{renderPageButton('다음', () => handlePageChange(1))}
</div>
</>
);
Expand Down
Loading

0 comments on commit 76d09aa

Please sign in to comment.