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

관리자 마이페이지 및 에러 처리 #76

Merged
merged 2 commits into from
Aug 7, 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
129 changes: 69 additions & 60 deletions src/App.jsx
Original file line number Diff line number Diff line change
@@ -1,26 +1,27 @@
import { useMediaQuery } from 'react-responsive';
import { BrowserRouter, Routes, Route } from 'react-router-dom';
import Header from './component/layout/Header';
import Footer from './component/layout/Footer';
import MainPage from './pages/Main';
import CentralClubPage from './pages/CentralClub';
import SmallClubPage from './pages/SmallClub';
import DetailPage from './pages/DetailPage';
import ReviewWrite from './component/detail/review/ReviewWrite';
import LoginPage from './pages/LoginPage';
import KakaoRedirection from './component/login/kakaoRedirection';
import HashTagPage from './pages/HashTag';
import SearchPage from './pages/SearchPage';
import SummaryPage from './pages/Summary';
import BookMarkPage from './pages/BookMarkPage';
import BranchCentralPage from './pages/BranchCentral';
import BranchSmallPage from './pages/BranchSmall';
import ReviewComment from './component/detail/review/ReviewComment';
import MyReview from './component/mypage/review/MyReview';
import AdminPage from './pages/AdminPage';
import EditPage from './component/admin/EditPage';
import PendingList from './component/admin/pending/PendingList';
import Layout from './component/admin/component/Layout';
import { useMediaQuery } from "react-responsive";
import { BrowserRouter, Routes, Route } from "react-router-dom";
import Header from "./component/layout/Header";
import Footer from "./component/layout/Footer";
import MainPage from "./pages/Main";
import CentralClubPage from "./pages/CentralClub";
import SmallClubPage from "./pages/SmallClub";
import DetailPage from "./pages/DetailPage";
import ReviewWrite from "./component/detail/review/ReviewWrite";
import LoginPage from "./pages/LoginPage";
import KakaoRedirection from "./component/login/kakaoRedirection";
import HashTagPage from "./pages/HashTag";
import SearchPage from "./pages/SearchPage";
import SummaryPage from "./pages/Summary";
import BookMarkPage from "./pages/BookMarkPage";
import BranchCentralPage from "./pages/BranchCentral";
import BranchSmallPage from "./pages/BranchSmall";
import ReviewComment from "./component/detail/review/ReviewComment";
import MyReview from "./component/mypage/review/MyReview";
import AdminPage from "./pages/AdminPage";
import EditPage from "./component/admin/EditPage";
import PendingList from "./component/admin/pending/PendingList";
import Layout from "./component/admin/component/Layout";
import ClubReviews from "./component/admin/ClubReviews";

function App() {
const isPc = useMediaQuery({
Expand Down Expand Up @@ -53,43 +54,51 @@ function App() {
<Route path="/bookmark" element={<BookMarkPage />} />
<Route path="/user/reviews" element={<MyReview />} />

<Route path="/admin" element={<Layout />}>
<Route index element={<AdminPage />} />
<Route path="/admin/edit/:clubId" element={<EditPage />} />
<Route path="/admin/mypage/pending" element={<PendingList />} />
</Route>
</Routes>
<Footer />
</BrowserRouter>
)}
<Route path="/admin" element={<Layout />}>
<Route index element={<AdminPage />} />
<Route path="/admin/edit/:clubId" element={<EditPage />} />
<Route path="/admin/mypage/reviews" element={<ClubReviews />} />
<Route path="/admin/mypage/pending" element={<PendingList />} />
</Route>
</Routes>
<Footer />
</BrowserRouter>
)}

{isMobile && (
<BrowserRouter>
<Header />
<Routes>
<Route path="/" element={<MainPage />} />
<Route path="/central" element={<CentralClubPage />} />
<Route path="/small" element={<SmallClubPage />} />
<Route path="/clubs/:clubId" element={<DetailPage />} />
<Route path="/clubs/:clubId/review" element={<ReviewWrite />} />
<Route path="/clubs/:clubId/review/comment" element={<ReviewComment />} />
<Route path="/central/divisions" element={<BranchCentralPage />} />
<Route path="/login" element={<LoginPage />} />
<Route path="/v1/auths/oauth/kakao" element={<KakaoRedirection />} />
<Route path="/small/colleges" element={<BranchSmallPage />} />
<Route path="/hashtag" element={<HashTagPage />} />
<Route path="/search" element={<SearchPage />} />
<Route path="/summary" element={<SummaryPage />} />
<Route path="/bookmark" element={<BookMarkPage />} />
<Route path="/user/reviews" element={<MyReview />} />
<Route path="/admin" element={<AdminPage />} />
<Route path="/admin/edit/:clubId" element={<EditPage />} />
<Route path="/admin/mypage/pending" element={<PendingList />} />
</Routes>
<Footer />
</BrowserRouter>
)}
</>
);
{isMobile && (
<BrowserRouter>
<Header />
<Routes>
<Route path="/" element={<MainPage />} />
<Route path="/central" element={<CentralClubPage />} />
<Route path="/small" element={<SmallClubPage />} />
<Route path="/clubs/:clubId" element={<DetailPage />} />
<Route path="/clubs/:clubId/review" element={<ReviewWrite />} />
<Route
path="/clubs/:clubId/review/comment"
element={<ReviewComment />}
/>
<Route path="/central/divisions" element={<BranchCentralPage />} />
<Route path="/login" element={<LoginPage />} />
<Route
path="/v1/auths/oauth/kakao"
element={<KakaoRedirection />}
/>
<Route path="/small/colleges" element={<BranchSmallPage />} />
<Route path="/hashtag" element={<HashTagPage />} />
<Route path="/search" element={<SearchPage />} />
<Route path="/summary" element={<SummaryPage />} />
<Route path="/bookmark" element={<BookMarkPage />} />
<Route path="/user/reviews" element={<MyReview />} />
<Route path="/admin" element={<AdminPage />} />
<Route path="/admin/edit/:clubId" element={<EditPage />} />
<Route path="/admin/mypage/reviews" element={<ClubReviews />} />
<Route path="/admin/mypage/pending" element={<PendingList />} />
</Routes>
<Footer />
</BrowserRouter>
)}
</>
);
}
export default App;
57 changes: 57 additions & 0 deletions src/component/admin/ClubReviews.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import '../mypage/review/myReview.css';
import '../detail/review/reviewBox.css';
import KeywordBar from '../detail/review/KeywordBar';
import { useEffect, useState } from 'react';
import { customAxios } from '../../config/axios-config';

export default function ClubReviews() {
const [clubReviewData, setClubReviewData] = useState([]);
const accessToken = localStorage.getItem('accessToken');

useEffect(() => {
const getMyReviews = async () => {
try {
const res = await customAxios.get(`/v1/admins/reviews`, {
headers: {
Authorization: `Bearer ${accessToken}`,
},
});
console.log(res);
if (res.data.success) {
setClubReviewData(res.data.data.clubReviews);
console.log(clubReviewData);
}
} catch (error) {
console.error('Error fetching my reviews : ', error);
}
};
getMyReviews();
}, [accessToken]);

return (
<div className="club_review_container">
<h2>동아리 리뷰 목록</h2>
{clubReviewData.map((cReview) => (
<div key={cReview.reviewId} className="my_review_box">
<div className="review_box_header">
<p className="club_name">익명 {cReview.reviewId}</p>
<span>{cReview.dateTime}</span>
{cReview.approvedStatus === 'APPROVED' ? (
<div className="review_approved">승인완료</div>
) : cReview.approvedStatus === 'PENDING' ? (
<div className="review_pending">승인대기</div>
) : cReview.approvedStatus === 'REJECTED' ? (
<div className="review_rejected">승인거절</div>
) : null}
</div>
<div className="review_box_contents">
{cReview.keywords.map((item, index) => (
<KeywordBar key={index} text={item} />
))}
</div>
<p className="review_comment">{cReview.content}</p>
</div>
))}
</div>
);
}
8 changes: 6 additions & 2 deletions src/component/admin/component/SideBar.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,12 @@ export default function SideBar() {
</NavLink>
<div className={styles.sideLine}></div>
<menu className={styles.sideTitle}>리뷰</menu>
<menu className={styles.sideText}>리뷰목록</menu>

<NavLink
to={`/admin/mypage/reviews`}
className={({ isActive }) => (isActive ? styles.activeMenu : styles.sideText)}
>
리뷰목록
</NavLink>
<NavLink
to={`/admin/mypage/pending`}
className={({ isActive }) => (isActive ? styles.activeMenu : styles.sideText)}
Expand Down
12 changes: 6 additions & 6 deletions src/component/admin/component/sideBar.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@
background: #d9d9d933;
border-radius: 2px;
flex: 1;
display: flex;
flex-direction: column;
gap: 3px;
}

.adminText {
Expand All @@ -36,7 +39,7 @@
line-height: 21.79px;
padding-top: 10%;
padding-left: 30px;
padding-bottom: 5%;
padding-bottom: 10px;
}

.sideTextWrite {
Expand All @@ -45,7 +48,6 @@
font-weight: 400;
line-height: 19.07px;
text-align: left;
margin-top: 5%;
padding-left: 30px;
padding-bottom: 3%;
color: #000;
Expand All @@ -58,9 +60,7 @@
font-weight: 400;
line-height: 19.07px;
text-align: left;
margin-top: 5%;
padding-left: 30px;
padding-bottom: 3%;
color: #000;
text-decoration: none;
}
Expand All @@ -78,9 +78,9 @@
}

.activeMenu {
margin-top: 10px;
/* margin-top: 10px; */
padding-left: 30px;
color: #7bc8e0;
text-decoration: none;
font-size: 14px;
font-size: 15px;
}
58 changes: 37 additions & 21 deletions src/component/admin/pending/PendingList.jsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,27 @@
import { useEffect, useState } from "react";
import SideBar from "../component/SideBar";
import "./pendingList.css";
import axios from "axios";
import { useNavigate } from "react-router-dom";
import ConfirmModal from "../../modal/ConfirmModal";

export default function PendingList() {
const navigate = useNavigate();
const [pendingData, setPendingData] = useState([]);
const accessToken = localStorage.getItem("accessToken");
const [checkedList, setCheckedList] = useState([]);
const [isAllChecked, setIsAllChecked] = useState(false);

// 승인 모달창
const [isModalOpen, setIsModalOpen] = useState(false);
const [modalMessage, setModalMessage] = useState("");
const [action, setAction] = useState("");

const closeModal = () => {
setIsModalOpen(false);
setModalMessage("");
navigate(`/admin/mypage/pending`);
};

// 전체선택
const handleAllCheck = (checked) => {
if (checked) {
Expand Down Expand Up @@ -52,32 +65,25 @@ export default function PendingList() {
}, [accessToken]);

const onClickApprove = () => {
try {
const res = axios.patch(
`http://13.125.141.171:8080/v1/admins/reviews/decision`,
{
reviewIds: checkedList,
approvedStatus: "APPROVED",
},
{
headers: {
Authorization: `Bearer ${accessToken}`,
},
}
);
console.log(res);
} catch (error) {
console.error("Error approving the review data : ", error);
}
};
setIsModalOpen(true);
setModalMessage("승인하시겠습니까?");
setAction("APPROVED");
}

const onClickReject = () => {
setIsModalOpen(true);
setModalMessage("거절하시겠습니까?");
setAction("REJECTED");
}

const onClickOk = () => {
console.log(action);
try {
const res = axios.patch(
`http://13.125.141.171:8080/v1/admins/reviews/decision`,
{
reviewIds: checkedList,
approvedStatus: "REJECTED",
approvedStatus: action,
},
{
headers: {
Expand All @@ -86,8 +92,17 @@ export default function PendingList() {
}
);
console.log(res);
// 승인 또는 거절된 리뷰를 pendingData에서 제거
setPendingData((prev) => prev.filter((item) => !checkedList.includes(item.reviewId)));
// 체크 리스트 초기화
setCheckedList([]);
setIsAllChecked(false);
// 모달 닫기
setIsModalOpen(false);
// 페이지 리다이렉트
navigate(`/admin/mypage/pending`, { replace: true });
} catch (error) {
console.error("Error rejecting the review data : ", error);
console.error("Error approving the review data : ", error);
}
};

Expand Down Expand Up @@ -133,6 +148,7 @@ export default function PendingList() {
</button>
</div>
</div>
<ConfirmModal isOpen={isModalOpen} message={modalMessage} onClickOk={onClickOk} onClose={closeModal} />
</div>
);
}
2 changes: 1 addition & 1 deletion src/component/admin/pending/pendingList.css
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@
}

.vertical_divider {
margin: 0px 5px;
margin: 3px 10px 0px 10px;
color: #9c9c9c80;
font-size: 24px;
font-weight: 100;
Expand Down
4 changes: 3 additions & 1 deletion src/component/detail/review/ReviewBox.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,9 @@ export default function ReviewBox({ clubId }) {
};

fetchKeywordData();
}, [clubId, reviewData]);
// useCallback 사용 . .
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);

return (
<div className="review_box_wrapper">
Expand Down
Loading
Loading