diff --git a/src/APP/components/Footer/Footer.footer.jsx b/src/APP/components/Footer/Footer.footer.jsx index c3208a71..8f2d0698 100644 --- a/src/APP/components/Footer/Footer.footer.jsx +++ b/src/APP/components/Footer/Footer.footer.jsx @@ -1,23 +1,62 @@ -import React from 'react' -import * as itemS from "./Styled/Footer.footer.styles" +import React from 'react'; +import * as itemS from './Styled/Footer.footer.styles'; export default function footer() { + const currentYear = new Date().getFullYear(); return ( -
- KOALA(한국항공대학교 알고리즘 학회) +
+ KOALA + (한국항공대학교 알고리즘 학회)
- 문의처 : kau-koala@naver.com |업데이트 노트 링크 - Copyrightⓒ2024.KOALA. All rights reserved. + + 문의처 : kau-koala@naver.com | + + 업데이트 노트{' '} + 링크 + + + + Copyrightⓒ{currentYear}.KOALA. All rights reserved. + - - + + + + + + - ) + ); } diff --git a/src/APP/user-pages/Inquiry/Inquiry.inquiry.main.jsx b/src/APP/user-pages/Inquiry/Inquiry.inquiry.main.jsx index 9427d19a..e8f4555a 100644 --- a/src/APP/user-pages/Inquiry/Inquiry.inquiry.main.jsx +++ b/src/APP/user-pages/Inquiry/Inquiry.inquiry.main.jsx @@ -1,233 +1,256 @@ -import React, {useState, useEffect} from 'react'; +import React, { useState, useEffect } from 'react'; import request from '../../Api/request'; import * as itemS from './Styled/Inquiry.inquiry.main.styles'; import InquiryTable from './Inquiry.inquiry.table'; -import {useNavigate} from 'react-router-dom'; +import { useNavigate } from 'react-router-dom'; import useDebounce from '../../Common/useDebounce'; export default function Inquiry() { - const [isRegularMember, setIsRegularMember] = useState(false); - const navigate = useNavigate(); + const [isRegularMember, setIsRegularMember] = useState(false); + const navigate = useNavigate(); - const [posts, setPosts] = useState([]); - const [role, setRole] = useState(''); - const [categories, setCategories] = useState([{code: '', name: '전체'}]); // Default '전체' tab + const [posts, setPosts] = useState([]); + const [role, setRole] = useState(''); + const [categories, setCategories] = useState([{ code: '', name: '전체' }]); // Default '전체' tab - // api 요청 파라미터 - const [searchKeyword, setSearchKeyword] = useState(''); - const debouncedQuery = useDebounce(searchKeyword, 500); - const [sortType, setSortType] = useState('LATEST'); - const [selectedTab, setSelectedTab] = useState(''); + // api 요청 파라미터 + const [searchKeyword, setSearchKeyword] = useState(''); + const debouncedQuery = useDebounce(searchKeyword, 500); + const [sortType, setSortType] = useState('LATEST'); + const [selectedTab, setSelectedTab] = useState(''); - const [sortText, setSortText] = useState('최신순'); - const [isSortDropVisible, setIsSortDropVisible] = useState(false); // 정렬 드롭박스 열기/닫기 + const [sortText, setSortText] = useState('최신순'); + const [isSortDropVisible, setIsSortDropVisible] = useState(false); // 정렬 드롭박스 열기/닫기 - // 페이지 - const [currentPage, setCurrentPage] = useState(0); - const [totalPages, setTotalPages] = useState(0); //TODO - 임시 ) 전체 페이지 수 -> response 값으로 전체 개수 받아와야함 - const [currentPageGroup, setCurrentPageGroup] = useState(0); - const itemsPerPage = 10; // 페이지당 항목 수 + // 페이지 + const [currentPage, setCurrentPage] = useState(0); + const [totalPages, setTotalPages] = useState(0); //TODO - 임시 ) 전체 페이지 수 -> response 값으로 전체 개수 받아와야함 + const [currentPageGroup, setCurrentPageGroup] = useState(0); + const itemsPerPage = 10; // 페이지당 항목 수 - const [isTabClick, setIsTabClick] = useState(false); + const [isTabClick, setIsTabClick] = useState(false); - const pageNumbers = Array.from( - {length: Math.min(5, totalPages - currentPageGroup * 5)}, - (_, i) => currentPageGroup * 5 + i - ); + const pageNumbers = Array.from( + { length: Math.min(5, totalPages - currentPageGroup * 5) }, + (_, i) => currentPageGroup * 5 + i + ); + + useEffect(() => { + // Load `regularStudyMemberYn` from localStorage and set state + setIsRegularMember(localStorage.getItem('regularStudyMemberYn') === 'true'); + }, []); + + const fetchCategories = async () => { + try { + const response = await request.get('/inquiry/category'); + if (response.isSuccess) { + const apiCategories = response.result.categoryList; + setCategories([{ code: '', name: '전체' }, ...apiCategories]); // Add '전체' as the first tab + } else { + console.error('카테고리 목록 조회 실패:', response); + } + } catch (error) { + console.error('카테고리 목록 조회 오류', error); + } + }; + + const fetchInquiry = async () => { + try { + const response = await request.get( + `/inquiry?searchKeyword=${searchKeyword}&category=${selectedTab}&sort=${sortType}&page=${ + currentPage + 1 + }&size=${itemsPerPage}` + ); + if (response.isSuccess) { + // console.log('문의하기 목록 : ', response); + setPosts(response.result.inquiryList); + setTotalPages(Math.ceil(response.result.totalCount / itemsPerPage)); + } else { + console.error('문의하기 목록 조회 실패:', response); + } + } catch (error) { + console.error('문의하기 목록 조회 오류', error); + } + }; + + // "ROLE_ADMIN"인지 아닌지 확인하기 위해서 한번 더 api호출 + const fetchMyInfo = async () => { + try { + const response = await request.get(`/member/my-info`); + + if (response.isSuccess) { + setRole(response.result.role); + } else { + console.error('내 개인정보 조회 실패:', response); + } + } catch (error) { + console.error('내 개인정보 조회 오류', error); + } + }; + + useEffect(() => { + fetchMyInfo(); + }, []); + + useEffect(() => { + fetchCategories(); + }, []); + + useEffect(() => { + fetchInquiry(); + }, [selectedTab, sortType, currentPage, debouncedQuery]); + + const handleTabClick = (tab) => { + setSelectedTab(tab.code); + setIsTabClick(tab.code !== ''); + setCurrentPage(0); + setCurrentPageGroup(0); + }; - useEffect(() => { - // Load `regularStudyMemberYn` from localStorage and set state - setIsRegularMember(localStorage.getItem('regularStudyMemberYn') === 'true'); - }, []); - - const fetchCategories = async () => { - try { - const response = await request.get('/inquiry/category'); - if (response.isSuccess) { - const apiCategories = response.result.categoryList; - setCategories([{code: '', name: '전체'}, ...apiCategories]); // Add '전체' as the first tab - } else { - console.error('카테고리 목록 조회 실패:', response); - } - } catch (error) { - console.error('카테고리 목록 조회 오류', error); - } - }; - - const fetchInquiry = async () => { - try { - const response = await request.get( - `/inquiry?searchKeyword=${searchKeyword}&category=${selectedTab}&sort=${sortType}&page=${ - currentPage + 1 - }&size=${itemsPerPage}` - ); - if (response.isSuccess) { - // console.log('문의하기 목록 : ', response); - setPosts(response.result.inquiryList); - setTotalPages(Math.ceil(response.result.totalCount / itemsPerPage)); - } else { - console.error('문의하기 목록 조회 실패:', response); - } - } catch (error) { - console.error('문의하기 목록 조회 오류', error); - } - }; - - // "ROLE_ADMIN"인지 아닌지 확인하기 위해서 한번 더 api호출 - const fetchMyInfo = async () => { - try { - const response = await request.get(`/member/my-info`); - - if (response.isSuccess) { - setRole(response.result.role); - } else { - console.error('내 개인정보 조회 실패:', response); - } - } catch (error) { - console.error('내 개인정보 조회 오류', error); - } - }; - - useEffect(() => { - fetchMyInfo(); - }, []); - - useEffect(() => { - fetchCategories(); - }, []); - - useEffect(() => { - fetchInquiry(); - }, [selectedTab, sortType, currentPage, debouncedQuery]); - - const handleTabClick = (tab) => { - setSelectedTab(tab.code); - setIsTabClick(tab.code !== ''); - setCurrentPage(0); - setCurrentPageGroup(0); - }; - - const handleSearch = () => { - setCurrentPage(0); - setCurrentPageGroup(0); - }; - - const handlePageChange = (newPage) => { - if (newPage >= 0 && newPage < totalPages) { - setCurrentPage(newPage); - setCurrentPageGroup(Math.floor(newPage / 5)); // 페이지 그룹을 업데이트 - } - }; - - const handlePageGroupChange = (direction) => { - if (direction === 'next' && (currentPageGroup + 1) * 5 < totalPages) { - setCurrentPageGroup(currentPageGroup + 1); - setCurrentPage((currentPageGroup + 1) * 5); // 새로운 그룹의 첫 번째 페이지로 이동 - } else if (direction === 'prev' && currentPageGroup > 0) { - setCurrentPageGroup(currentPageGroup - 1); - setCurrentPage((currentPageGroup - 1) * 5); // 새로운 그룹의 첫 번째 페이지로 이동 - } - }; - - const toggleSortDrop = () => { - setIsSortDropVisible((prevState) => !prevState); - }; - - const onSortType = (type) => { - setIsSortDropVisible(false); - setSortType(type); - setSortText(type === 'LATEST' ? '최신순' : type === 'VIEW_COUNT' ? '조회수' : '좋아요'); - }; - - const handleWriteClick = () => { - navigate('/writeinquiry'); - }; - - return ( - - - - - - - 문의하기 >{' '} - {selectedTab ? categories.find((tab) => tab.code === selectedTab)?.name : '전체'} - - - - setSearchKeyword(e.target.value)} - placeholder="제목, 작성자 검색" - /> - handleSearch()} src="/img/search.svg" alt="돋보기" /> - - - - - {categories.map((tab) => - tab.code === selectedTab ? ( - handleTabClick(tab)}> - {tab.name} - - ) : ( - handleTabClick(tab)}> - {tab.name} - - ) - )} - - - - {sortText} - - {isSortDropVisible && ( - - onSortType('LATEST')}>최신순 - onSortType('VIEW_COUNT')}>조회수 - - )} - - - - - - - - handlePageGroupChange('prev')} - disabled={currentPageGroup === 0} - /> - {pageNumbers.map((pageNumber) => ( - handlePageChange(pageNumber)} - active={pageNumber === currentPage} - > - {pageNumber + 1} - - ))} - handlePageGroupChange('next')} - disabled={(currentPageGroup + 1) * 5 >= totalPages} - /> - - - {isRegularMember && role !== 'ROLE_ADMIN' ? ( - + 글쓰기 - ) : ( - - )} - - - - + const handleSearch = () => { + setCurrentPage(0); + setCurrentPageGroup(0); + }; + + const handlePageChange = (newPage) => { + if (newPage >= 0 && newPage < totalPages) { + setCurrentPage(newPage); + setCurrentPageGroup(Math.floor(newPage / 5)); // 페이지 그룹을 업데이트 + } + }; + + const handlePageGroupChange = (direction) => { + if (direction === 'next' && (currentPageGroup + 1) * 5 < totalPages) { + setCurrentPageGroup(currentPageGroup + 1); + setCurrentPage((currentPageGroup + 1) * 5); // 새로운 그룹의 첫 번째 페이지로 이동 + } else if (direction === 'prev' && currentPageGroup > 0) { + setCurrentPageGroup(currentPageGroup - 1); + setCurrentPage((currentPageGroup - 1) * 5); // 새로운 그룹의 첫 번째 페이지로 이동 + } + }; + + const toggleSortDrop = () => { + setIsSortDropVisible((prevState) => !prevState); + }; + + const onSortType = (type) => { + setIsSortDropVisible(false); + setSortType(type); + setSortText( + type === 'LATEST' ? '최신순' : type === 'VIEW_COUNT' ? '조회수' : '좋아요' ); + }; + + const handleWriteClick = () => { + navigate('/writeinquiry'); + }; + + return ( + + + + + + + 문의하기 >{' '} + {selectedTab + ? categories.find((tab) => tab.code === selectedTab)?.name + : '전체'} + + + + setSearchKeyword(e.target.value)} + placeholder="제목, 작성자 검색" + /> + handleSearch()} + src="/img/search.svg" + alt="돋보기" + /> + + + + + {categories.map((tab) => + tab.code === selectedTab ? ( + handleTabClick(tab)} + > + {tab.name} + + ) : ( + handleTabClick(tab)}> + {tab.name} + + ) + )} + + + + + {sortText} + + + {isSortDropVisible && ( + + onSortType('LATEST')}> + 최신순 + + onSortType('VIEW_COUNT')}> + 조회수 + + + )} + + + + + + + + handlePageGroupChange('prev')} + disabled={currentPageGroup === 0} + /> + {pageNumbers.map((pageNumber) => ( + handlePageChange(pageNumber)} + active={pageNumber === currentPage} + > + {pageNumber + 1} + + ))} + handlePageGroupChange('next')} + disabled={(currentPageGroup + 1) * 5 >= totalPages} + /> + + + {role !== 'ROLE_ADMIN' ? ( + + + 글쓰기 + + ) : ( + + )} + + + + + ); } diff --git a/src/APP/user-pages/RegularStudy/RegularStudy.regularstudy.attendance.jsx b/src/APP/user-pages/RegularStudy/RegularStudy.regularstudy.attendance.jsx index a5560808..a7cac79f 100644 --- a/src/APP/user-pages/RegularStudy/RegularStudy.regularstudy.attendance.jsx +++ b/src/APP/user-pages/RegularStudy/RegularStudy.regularstudy.attendance.jsx @@ -7,7 +7,7 @@ import AttendanceModal from './RegularStudy.regularstudy.modal'; import { AlertContext } from '../../Common/Alert/AlertContext'; import { ConfirmContext } from '../../Common/Confirm/ConfirmContext'; -export default function RegularStudyAttendance() { +export default function RegularStudyAttendance({ memberRole, endYn }) { const { id } = useParams(); const [currentTab, setCurrentTab] = useState('문제 인증'); const [data, setData] = useState({}); @@ -34,6 +34,7 @@ export default function RegularStudyAttendance() { try { const response = await request.get(`study/${id}/attendance`); if (response['isSuccess']) { + // console.log('출석 데이터 조회: ', response.result); setOriginalAttendanceData(response.result.attendanceList); const transformedData = transformData(response.result.attendanceList); setData(transformedData); @@ -560,20 +561,23 @@ export default function RegularStudyAttendance() { flexDirection: 'row', justifyContent: 'space-between', marginBottom: '0.167rem', + height: '1.75rem', }} > *이름을 클릭하면 주차별 출석 인증 내역을 확인할 수 있습니다. - - 챌린지 보상 사용하기 - + {!endYn && memberRole === 'MEMBER' && ( + + 챌린지 보상 사용하기 + + )}
)} diff --git a/src/APP/user-pages/RegularStudy/RegularStudy.regularstudy.main.jsx b/src/APP/user-pages/RegularStudy/RegularStudy.regularstudy.main.jsx index 4986f86f..6aea0c05 100644 --- a/src/APP/user-pages/RegularStudy/RegularStudy.regularstudy.main.jsx +++ b/src/APP/user-pages/RegularStudy/RegularStudy.regularstudy.main.jsx @@ -1,14 +1,30 @@ -import React, { useEffect, useState } from 'react' -import * as itemS from "./Styled/RegularStudy.regularstudy.main.styles"; -import RegularStudySideBar from "./RegularStudy.regularstudy.sidebar"; -import RegularStudyHome from "./RegularStudy.regularstudy.home" -import RegularStudyAttendance from "./RegularStudy.regularstudy.attendance" -import RegularStudyCurriculum from "./RegularStudy.regularstudy.curriculum" +import React, { useEffect, useState } from 'react'; +import * as itemS from './Styled/RegularStudy.regularstudy.main.styles'; +import RegularStudySideBar from './RegularStudy.regularstudy.sidebar'; +import RegularStudyHome from './RegularStudy.regularstudy.home'; +import RegularStudyAttendance from './RegularStudy.regularstudy.attendance'; +import RegularStudyCurriculum from './RegularStudy.regularstudy.curriculum'; import RegularStudyMocktest from './RegularStudy.regularstudy.mocktest'; import { useParams } from 'react-router-dom'; +import request from '../../Api/request'; export default function RegularStudyMain() { - const { id } = useParams(); // 정규스터디 ID 가져오기 + const { id } = useParams(); // 정규스터디 ID 가져오기 + const [regularStudyInfo, setRegularStudyInfo] = useState(null); + + const fetchRegularStudyInfo = async () => { + try { + const response = await request.get(`study/${id}/info`); + // console.log('정규 스터디 조회 정보: ', response); + if (response['isSuccess']) { + setRegularStudyInfo(response.result); + } else { + console.error('정규 스터디 조회 실패:', response); + } + } catch (err) { + console.error('정규스터디 정보 조회 오류', err); + } + }; const getInitialComponent = () => { const savedComponent = localStorage.getItem(`activeComponent_${id}`); @@ -18,15 +34,21 @@ export default function RegularStudyMain() { const [activeComponent, setActiveComponent] = useState(getInitialComponent); useEffect(() => { + fetchRegularStudyInfo(); localStorage.setItem(`activeComponent_${id}`, activeComponent); }, [activeComponent, id]); const renderComponent = () => { switch (activeComponent) { - case 'home': + case 'home': return ; case 'attendance': - return ; + return ( + + ); case 'curriculum': return ; case 'mocktest': @@ -34,13 +56,22 @@ export default function RegularStudyMain() { default: return ; } + }; + + if (!regularStudyInfo) { + return
Loading regular study info...
; } + return ( - + {renderComponent()} - ) + ); } diff --git a/src/APP/user-pages/RegularStudy/RegularStudy.regularstudy.sidebar.jsx b/src/APP/user-pages/RegularStudy/RegularStudy.regularstudy.sidebar.jsx index 835a1859..8b6dda82 100644 --- a/src/APP/user-pages/RegularStudy/RegularStudy.regularstudy.sidebar.jsx +++ b/src/APP/user-pages/RegularStudy/RegularStudy.regularstudy.sidebar.jsx @@ -6,28 +6,9 @@ import { useNavigate, useParams } from 'react-router-dom'; export default function RegularStudySideBar({ setActiveComponent, activeComponent, + regularStudyInfo, }) { - const { id } = useParams(); // 파라미터로 받는 해당 정규스터디의 studyId const navigate = useNavigate(); - const [regularStudyInfo, setRegularStudyInfo] = useState(null); - - useEffect(() => { - const fetchRegularStudyInfo = async () => { - try { - const response = await request.get(`study/${id}/info`); - // console.log("정규 스터디 사이드 바 조회 정보: ", response); - setRegularStudyInfo(response.result); - if (response['isSuccess']) { - console.log('정규 스터디 조회 성공'); - } else { - console.error('정규 스터디 조회 실패:', response); - } - } catch (err) { - console.error('정규스터디 정보 조회 오류', err); - } - }; - fetchRegularStudyInfo(); - }, [id]); const handleApplicationClick = () => { if (regularStudyInfo.answerYN) {