diff --git a/src/App.jsx b/src/App.jsx index c4a9821..7842901 100644 --- a/src/App.jsx +++ b/src/App.jsx @@ -1,21 +1,19 @@ 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 './menu/detail'; +import DetailPage from './pages/DetailPage'; import LoginPage from './pages/LoginPage'; import KakaoRedirection from './component/login/kakaoRedirection'; -import BranchSmall from './menu/small_club/branch/branch_small'; import HashTagPage from './pages/HashTag'; -import ReviewWrite from './menu/detail/review_write'; -import Search from './menu/search/search'; +import SearchPage from './pages/SearchPage'; import SummaryPage from './pages/Summary'; import BookMarkPage from './menu/bookmark'; import BranchCentralPage from './pages/BranchCentral'; +import BranchSmallPage from './pages/BranchSmall'; function App() { const isPc = useMediaQuery({ @@ -35,13 +33,12 @@ function App() { {/* } /> */} } /> } /> - } /> } /> } /> } /> - } /> + } /> } /> - } /> + } /> } /> } /> @@ -57,13 +54,12 @@ function App() { } /> } /> } /> - } /> } /> } /> } /> - } /> + } /> } /> - } /> + } /> } /> } /> diff --git a/src/component/hashtag/HashTagClub.jsx b/src/component/hashtag/HashTagClub.jsx index b4b66bb..f062f1a 100644 --- a/src/component/hashtag/HashTagClub.jsx +++ b/src/component/hashtag/HashTagClub.jsx @@ -1,6 +1,6 @@ import React from 'react'; import PropTypes from 'prop-types'; -import styles from '../branch/branchCentral.module.css'; +import styles from '../centralClub/centralClub.module.css'; import { LinkItem } from '../branch/BranchCentral'; function HashTagClub({ clubId, imageUrl, clubName, introduction }) { diff --git a/src/component/hashtag/TagScroll.jsx b/src/component/hashtag/TagScroll.jsx index cb73e07..38dd672 100644 --- a/src/component/hashtag/TagScroll.jsx +++ b/src/component/hashtag/TagScroll.jsx @@ -3,7 +3,7 @@ import HashTag from './HashTag'; export default function TagScroll() { return ( -
+
diff --git a/src/component/hashtag/branchHashtag.jsx b/src/component/hashtag/branchHashtag.jsx index 885aea5..f11040f 100644 --- a/src/component/hashtag/branchHashtag.jsx +++ b/src/component/hashtag/branchHashtag.jsx @@ -3,7 +3,7 @@ import { useEffect, useState } from 'react'; import axios from 'axios'; import { useLocation } from 'react-router-dom'; import HashTagClub from './HashTagClub'; -import styles from '../centralClub/centralClub.module.css'; +import styles from '../branch/branchCentral.module.css'; function BranchHashTag() { const [loading, setLoading] = useState(true); diff --git a/src/component/hashtag/tagScroll.css b/src/component/hashtag/tagScroll.css index df31bc8..d84c5e6 100644 --- a/src/component/hashtag/tagScroll.css +++ b/src/component/hashtag/tagScroll.css @@ -1,5 +1,5 @@ @media screen and (min-width: 769px) { - .wrapper { + .tagScroll_wrapper { padding: 0% 16%; padding-bottom: 3px; width: 100%; @@ -31,7 +31,7 @@ } @media screen and (max-width: 769px) { - .wrapper { + .tagScroll_wrapper { padding: 0% 10%; padding-bottom: 3px; width: 100%; diff --git a/src/component/layout/Header.jsx b/src/component/layout/Header.jsx index 01c61c0..fbd1dd1 100644 --- a/src/component/layout/Header.jsx +++ b/src/component/layout/Header.jsx @@ -142,7 +142,7 @@ export default function Header() { }; const handleSearch = () => { - navigate(`/menu/search?clubName=${searchTerm}`, { state: { clubName: searchTerm } }); + navigate(`/search?clubName=${searchTerm}`, { state: { clubName: searchTerm } }); }; const enterKeyDown = (event) => { diff --git a/src/menu/search/search.jsx b/src/component/search/search.jsx similarity index 98% rename from src/menu/search/search.jsx rename to src/component/search/search.jsx index aa11fd1..539325f 100644 --- a/src/menu/search/search.jsx +++ b/src/component/search/search.jsx @@ -2,7 +2,7 @@ import React, { useEffect, useState } from 'react'; import { useLocation } from 'react-router-dom'; import styles from './search.module.css'; import axios from 'axios'; -import SearchClub from './component/searchClub'; +import SearchClub from './searchClub'; function Search() { const [loading, setLoading] = useState(true); diff --git a/src/menu/search/search.module.css b/src/component/search/search.module.css similarity index 100% rename from src/menu/search/search.module.css rename to src/component/search/search.module.css diff --git a/src/menu/search/component/searchClub.jsx b/src/component/search/searchClub.jsx similarity index 94% rename from src/menu/search/component/searchClub.jsx rename to src/component/search/searchClub.jsx index 85b2c8b..5dc43e5 100644 --- a/src/menu/search/component/searchClub.jsx +++ b/src/component/search/searchClub.jsx @@ -1,7 +1,7 @@ import React from 'react'; import PropTypes from 'prop-types'; import styles from './searchClub.module.css'; -import { LinkItem } from '../../../component/branch/BranchCentral'; +import { LinkItem } from '../branch/BranchCentral'; //clubid페이지로 이동할 수 있게 수정 완료 function SearchClub({ clubId, clubName, introduction, imageUrl, division, department }) { diff --git a/src/menu/search/component/searchClub.module.css b/src/component/search/searchClub.module.css similarity index 100% rename from src/menu/search/component/searchClub.module.css rename to src/component/search/searchClub.module.css diff --git a/src/menu/small_club/branch/branch_small.jsx b/src/component/smallClub/BranchSmall.jsx similarity index 93% rename from src/menu/small_club/branch/branch_small.jsx rename to src/component/smallClub/BranchSmall.jsx index e6554cf..b910f29 100644 --- a/src/menu/small_club/branch/branch_small.jsx +++ b/src/component/smallClub/BranchSmall.jsx @@ -1,8 +1,8 @@ import React from 'react'; import { useEffect, useState } from 'react'; -import styles from './branch_small.module.css'; +import styles from './branchSmall.module.css'; import axios from 'axios'; -import SmallClub from './component/smallClub'; +import SmallClubProps from './SmallClubProps'; import { useLocation } from 'react-router-dom'; function BranchSmall() { @@ -37,7 +37,7 @@ function BranchSmall() { rows.push(
{rowItems.map((club) => ( - { - navigate('/menu/small_club/branch/branch_small', { state: { department: departmentValue } }); + navigate('/small/colleges', { state: { department: departmentValue } }); }; return ( diff --git a/src/menu/small_club/branch/component/smallClub.jsx b/src/component/smallClub/SmallClubProps.jsx similarity index 68% rename from src/menu/small_club/branch/component/smallClub.jsx rename to src/component/smallClub/SmallClubProps.jsx index 3bef59b..ebc377e 100644 --- a/src/menu/small_club/branch/component/smallClub.jsx +++ b/src/component/smallClub/SmallClubProps.jsx @@ -1,13 +1,13 @@ import React from 'react'; import PropTypes from 'prop-types'; -import styles from './smallClub.module.css'; -import { LinkItem } from '../../../../component/branch/BranchCentral'; +import styles from './smallClubProps.module.css'; +import { LinkItem } from '../branch/BranchCentral'; //clubid페이지로 이동할 수 있게 수정 완료 -function SmallClub({ clubId, clubName, introduction, imageUrl }) { +function SmallClubProps({ clubId, clubName, introduction, imageUrl }) { return (
- + {clubName}

{clubName}

@@ -17,11 +17,11 @@ function SmallClub({ clubId, clubName, introduction, imageUrl }) { ); } -SmallClub.propTypes = { +SmallClubProps.propTypes = { clubId: PropTypes.number.isRequired, imageUrl: PropTypes.string.isRequired, clubName: PropTypes.string.isRequired, introduction: PropTypes.string.isRequired, }; -export default SmallClub; +export default SmallClubProps; diff --git a/src/menu/small_club/branch/branch_small.module.css b/src/component/smallClub/branchSmall.module.css similarity index 100% rename from src/menu/small_club/branch/branch_small.module.css rename to src/component/smallClub/branchSmall.module.css diff --git a/src/menu/small_club/branch/component/smallClub.module.css b/src/component/smallClub/smallClubProps.module.css similarity index 100% rename from src/menu/small_club/branch/component/smallClub.module.css rename to src/component/smallClub/smallClubProps.module.css diff --git a/src/menu/summary/component/summary.jsx b/src/component/summary/summary.jsx similarity index 100% rename from src/menu/summary/component/summary.jsx rename to src/component/summary/summary.jsx diff --git a/src/menu/summary/component/summary.module.css b/src/component/summary/summary.module.css similarity index 100% rename from src/menu/summary/component/summary.module.css rename to src/component/summary/summary.module.css diff --git a/src/menu/detail/_component/IntroductionTab.jsx b/src/menu/detail/_component/IntroductionTab.jsx deleted file mode 100644 index 0744edb..0000000 --- a/src/menu/detail/_component/IntroductionTab.jsx +++ /dev/null @@ -1,65 +0,0 @@ -import React from 'react'; - -export default function IntroductionTab({ - clubName, - college, - department, - introduction, - instagram, - imgUrl, - leader, - activity, - room, - division, -}) { - // 컴포넌트 내부에서 줄바꿈 처리를 위한 함수 - const handleNewLines = (text) => { - if (!text) return null; - return text.split('\n').map((str, index) => ( - - {str} -
-
- )); - }; - - // 줄바꿈이 적용된 텍스트를 렌더링하는 컴포넌트 예시 - const NewLines = ({ text }) => { - return
{handleNewLines(text)}
; - }; - - return ( - <> -
-

{'<>'}

- {/* 타이틀이랑 내용이랑 css 차이를 어떻게 주면 좋을지 ? */} - {college === null ? '📌 소속분과' : '📌 단과대 / 학과'} -

- {college === null ? '중앙동아리' : college} / {department === null ? division : department} -

-

- 📌 소개 -

{introduction}

-

- 📌 인스타 - - instagram - -

- 📌 대표 활동 -

- -

-

- 📌 동아리장 -

{leader}

-

- 📌 동아리실 -

{room}

-
- - ); -} -/* -club detail image -*/ diff --git a/src/menu/detail/_component/ReviewBox.jsx b/src/menu/detail/_component/ReviewBox.jsx deleted file mode 100644 index 2217bae..0000000 --- a/src/menu/detail/_component/ReviewBox.jsx +++ /dev/null @@ -1,58 +0,0 @@ -import './reviewBox.css'; -import { useState, useEffect } from 'react'; -import axios from 'axios'; - -const KeywordBar = ({ text }) => { - if (text === 'CULTURE') { - text = '😃 "분위기가 좋아요"'; - } else if (text === 'FEE') { - text = '💵 "회비가 적당해요"'; - } else if (text === 'ACTIVITY') { - text = '🕺🏻 "활동 참여가 자유로워요"'; - } else if (text === 'CAREER') { - text = '🏆 "대외활동에 좋아요"'; - } else if (text === 'MANAGE') { - text = '👍🏻 "운영진이 일을 잘해요"'; - } - return
{text}
; -}; - -export default function ReviewBox({ clubId }) { - const [reviewData, setReviewData] = useState([]); - - useEffect(() => { - const fetchKeywordData = async () => { - try { - const res = await axios.get(`http://13.125.141.171:8080/v1/clubs/${clubId}/reviews`); - if (res.data.success) { - setReviewData(res.data.data.clubReviews); - console.log(reviewData); - } - } catch (error) { - console.error('Error fetching reviews:', error); - } - }; - - fetchKeywordData(); - }, [clubId]); - - return ( - <> - {reviewData.map((review) => ( -
-
-
-

익명 {review.reviewId}

- {review.dateTime} -
-
- {review.keywords.map((item, index) => ( - - ))} -
-
-
- ))} - - ); -} diff --git a/src/menu/detail/_component/ReviewStatics.jsx b/src/menu/detail/_component/ReviewStatics.jsx deleted file mode 100644 index 6751db0..0000000 --- a/src/menu/detail/_component/ReviewStatics.jsx +++ /dev/null @@ -1,79 +0,0 @@ -import React, { useState } from 'react'; -import './reviewStats.css'; -import axios from 'axios'; -import { useEffect } from 'react'; - -// 데이터 예시 -// 각 bar마다 color 다르게 -const labels = { - ACTIVITY: '🕺🏻 "활동 참여가 자유로워요"', - CAREER: '🏆 "대외활동에 좋아요"', - CULTURE: '😃 "분위기가 좋아요"', - FEE: '💵 "회비가 적당해요"', - MANAGE: '👍🏻 "운영진이 일을 잘해요"', -}; - -export default function ReviewStatics({ clubId }) { - const [reviews, setReviews] = useState([]); - - useEffect(() => { - const getReviewsSortedByCount = async () => { - try { - const res = await axios.get(`http://13.125.141.171:8080/v1/clubs/${clubId}/reviews/keyword-stats`); - if (res.data.success) { - //console.log(res.data.data); - const reviews = res.data.data.keywordStats; - - const sortedReviews = Object.entries(reviews) - .sort(([, countA], [, countB]) => countB - countA) // value 값 내림차순 - .reduce((acc, [key, value]) => ({ ...acc, [key]: value }), {}); // Convert back to object - console.log('sorted:', sortedReviews); - setReviews(sortedReviews); - } else { - console.error('Failed to fetch reviews'); - } - } catch (error) { - console.error('Error fetching reviews: ', error); - } - }; - - getReviewsSortedByCount(); - }, [clubId]); - - const sortedReviews = Object.entries(reviews); - console.log(sortedReviews); - const reviewsWithKoreanLabels = sortedReviews.map(([text, count]) => [labels[text], count]); - console.log(reviewsWithKoreanLabels); - - const PercentageBar = ({ text, count, total }) => { - const percentage = (count / total) * 100; - return ( -
-
- {text} -
-
- ); - }; - const ReviewStats = ({ data }) => { - // reduce -> acc + curr.count (누적값) , 0 (초기값) - const total = data.reduce((acc, curr) => acc + curr[1], 0); - - console.log('total: ', total); - console.log('data: ', data); - return ( -
- {data.map((item) => ( - - ))} -
- ); - }; - - return ( - <> - - - ); -} -// diff --git a/src/menu/detail/_component/ReviewTab.jsx b/src/menu/detail/_component/ReviewTab.jsx deleted file mode 100644 index 02bbf78..0000000 --- a/src/menu/detail/_component/ReviewTab.jsx +++ /dev/null @@ -1,29 +0,0 @@ -import { useNavigate } from 'react-router-dom'; -import ReviewStatics from './ReviewStatics'; -import './reviewTab.css'; -import ReviewBox from './ReviewBox'; - -export default function ReviewTab({ clubId, clubName }) { - const navigate = useNavigate(); - - const onClickReviewWrite = () => { - navigate('/menu/detail/review_write', { state: { clubId, clubName } }); - }; - - return ( -
-
-
-

이런 점이 좋았어요!

-
- write review -

리뷰쓰기

-
-
- -
-
- -
- ); -} diff --git a/src/menu/detail/_component/reviewBox.css b/src/menu/detail/_component/reviewBox.css deleted file mode 100644 index 1647bb0..0000000 --- a/src/menu/detail/_component/reviewBox.css +++ /dev/null @@ -1,97 +0,0 @@ -@media screen and (min-width: 768px) { - .review_box_container { - width: 125%; - background-color: white; - box-shadow: 0px 0px 4px 0px #0000004d; - border-radius: 15px; - margin-bottom: 15px; - padding: 16px 18px; - } - - .review_box_header { - display: flex; - flex-direction: row; - align-items: center; - } - - .review_box_header p { - font-size: 16px; - font-weight: 700; - margin-right: 7px; - } - - .review_box_header span { - font-size: 12px; - font-weight: 400; - color: gray; - } - - .review_box_contents { - display: grid; - /* 한 줄에 세개의 열 */ - grid-template-columns: repeat(3, 1fr); - gap: 5px; - margin-top: 7px; - /* width: 100%; */ - } - - .keyword_container { - background-color: #9c9c9c26; - border-radius: 5px; - border: none; - padding: 7px 10px; - font-size: 13px; - font-weight: 400; - /* width: 30%; - flex: 1; */ - } -} - -@media screen and (max-width: 768px) { - .review_box_container { - width: 125%; - background-color: white; - box-shadow: 0px 0px 4px 0px #0000004d; - border-radius: 15px; - margin-bottom: 15px; - padding: 16px 18px; - } - - .review_box_header { - display: flex; - flex-direction: row; - align-items: center; - } - - .review_box_header p { - font-size: 13px; - font-weight: 700; - margin-right: 7px; - } - - .review_box_header span { - font-size: 11px; - font-weight: 400; - color: gray; - } - - .review_box_contents { - display: grid; - /* 한 줄에 세개의 열 */ - /* grid-template-columns: repeat(3, 1fr);*/ - gap: 5px; - margin-top: 7px; - /* width: 100%; */ - } - - .keyword_container { - background-color: #9c9c9c26; - border-radius: 5px; - border: none; - padding: 7px 10px; - font-size: 13px; - font-weight: 400; - /* width: 30%; - flex: 1; */ - } -} diff --git a/src/menu/detail/_component/reviewStats.css b/src/menu/detail/_component/reviewStats.css deleted file mode 100644 index bf9724c..0000000 --- a/src/menu/detail/_component/reviewStats.css +++ /dev/null @@ -1,71 +0,0 @@ -@media screen and (min-width: 768px) { - .review-stats { - display: flex; - flex-direction: column; - gap: 8px; - } - - .bar-container { - /* width: 120%; */ - height: 35px; - background-color: #f2f2f2; - border-radius: 10px; - overflow: hidden; - /* position: relative; */ - } - - .bar { - height: 100%; - background-color: #9fd8ea; - display: flex; - align-items: center; - padding: 0 8px; - border-radius: 12px; - } - - .text { - color: #000; - font-size: 15px; - font-weight: 700; - white-space: nowrap; - overflow: visible; - padding-left: 7px; - /* text-overflow: ellipsis; */ - } -} - -@media screen and (max-width: 768px) { - .review-stats { - display: flex; - flex-direction: column; - gap: 8px; - } - - .bar-container { - /* width: 120%; */ - height: 35px; - background-color: #f2f2f2; - border-radius: 10px; - overflow: hidden; - /* position: relative; */ - } - - .bar { - height: 100%; - background-color: #9fd8ea; - display: flex; - align-items: center; - padding: 0 8px; - border-radius: 12px; - } - - .text { - color: #000; - font-size: 14px; - font-weight: 700; - white-space: nowrap; - overflow: visible; - padding-left: 7px; - /* text-overflow: ellipsis; */ - } -} diff --git a/src/menu/detail/_component/reviewTab.css b/src/menu/detail/_component/reviewTab.css deleted file mode 100644 index c98efcf..0000000 --- a/src/menu/detail/_component/reviewTab.css +++ /dev/null @@ -1,96 +0,0 @@ -@media screen and (min-width: 780px) { - .review_body { - width: 30%; - } - - .statics_container { - width: 120%; - } - - .divider { - width: 140%; - border: 0.2px solid #9c9c9c4d; - margin: 40px 0px 40px 0px; - } - - .statics_header { - display: flex; - flex-direction: row; - padding: 39px 0px 15px 0px; - justify-content: space-between; - } - - .review_write_btn { - display: flex; - flex-direction: row; - padding-left: 10%; - justify-items: space-between; - } - - .statics_header p { - background-color: transparent; - border: none; - cursor: pointer; - color: #1954b2; - font-size: 14px; - font-weight: 400; - display: flex; - flex-direction: row; - align-items: center; - } - - .statics_container img { - width: 21px; - height: 21px; - margin: 0px 0px 3px; - } -} - -@media screen and (max-width: 780px) { - .review_body { - width: 40%; - } - - .statics_container { - width: 120%; - } - - .divider { - width: 140%; - border: 0.2px solid #9c9c9c4d; - margin: 40px 0px 40px 0px; - } - - .statics_header { - display: flex; - flex-direction: row; - justify-content: space-between; - padding: 39px 0px 15px 0px; - font-size: 14px; - } - - .review_write_btn { - display: flex; - align-items: right; - flex-direction: row; - padding-left: 2%; - } - - .statics_header p { - background-color: transparent; - border: none; - cursor: pointer; - color: #1954b2; - font-size: 12px; - font-weight: 400; - display: flex; - flex-direction: row; - align-items: center; - } - - .statics_container img { - width: 21px; - height: 21px; - margin: 0px 0px 3px; - } -} diff --git a/src/menu/detail/component/clubDetail.jsx b/src/menu/detail/component/clubDetail.jsx deleted file mode 100644 index ab0bafa..0000000 --- a/src/menu/detail/component/clubDetail.jsx +++ /dev/null @@ -1,28 +0,0 @@ -import React from 'react'; -import PropTypes from 'prop-types'; -import styles from './clubDetail.module.css'; -import HashTag from '../../../components/hashtag/HashTag'; - -function ClubDetail({ clubId, clubName, introduction, imageUrl }) { - return ( -
- {clubName} -

{clubName}

-

{introduction}

-
- ); -} - -ClubDetail.propTypes = { - clubId: PropTypes.number.isRequired, - clubName: PropTypes.string.isRequired, - clubType: PropTypes.string.isRequired, - introduction: PropTypes.string.isRequired, - HashTag: PropTypes.number.isRequired, - division: PropTypes.string.isRequired, - //college : - department: PropTypes.number.isRequired, - imageUrl: PropTypes.string.isRequired, -}; - -export default ClubDetail; diff --git a/src/menu/detail/component/clubDetail.module.css b/src/menu/detail/component/clubDetail.module.css deleted file mode 100644 index e69de29..0000000 diff --git a/src/menu/detail/detailPage.css b/src/menu/detail/detailPage.css deleted file mode 100644 index 88c6350..0000000 --- a/src/menu/detail/detailPage.css +++ /dev/null @@ -1,258 +0,0 @@ -@media screen and (min-width: 768px) { - .detail_container { - display: flex; - flex-direction: column; - align-items: center; - } - - .detail_header_container { - display: flex; - flex-direction: row; - align-items: center; - width: 70%; - /* height: 40%; */ - } - - .detail_header_name { - display: flex; - flex-direction: row; - margin-bottom: 10px; - } - - .detail_header_name h3 { - display: flex; - flex-direction: row; - align-items: center; - font-size: 20px; - font-weight: 500; - /* line-height: 20px; */ - margin-top: 1px; - } - - .detail_logo { - width: 20%; - height: 60%; - margin: 12px 24px 20px 22px; - } - - .insta_icon { - margin-top: 1%; - margin-left: 3%; - width: 20px; - height: 20px; - } - - .star_icon { - width: 22px; - height: 21px; - margin-left: 7px; - } - - .association_btn { - width: 160px; - height: 30px; - background-color: #7BC8E0; - color: white; - font-size: 12.5px; - font-weight: 400; - border-radius: 5px; - /* text-align: center; */ - display: flex; - flex-direction: row; - align-items: center; - justify-content: space-evenly; - padding: 0px 6px 0px 6px; - } - - .detail_image { - width: 30%; - aspect-ratio: 1/1; - object-fit: cover; - margin-bottom: 2.5%; - } - - .detail_tab { - position: relative; - display: flex; - flex-direction: row; - align-items: center; - justify-content: space-evenly; - width: 70%; - height: 36px; - background-color: #7BC8E04D; - } - - .detail_body { - display: flex; - flex-direction: column; - align-items: left; - width: 70%; - margin: 2.5% 0 15% 0; - } - - .detail_body h3 { - width: fit-content; - margin: 2.5% 0 2.5% 0; - display: inline; - box-shadow: inset 0 -15px 0 #7BC8E04D; - } - - .detail_body p { - margin-top: 1%; - margin-left: 3%; - width: 50%; - text-align: left; - } - - .detail_tab button { - border: none; - background-color: transparent; - box-shadow: none; - cursor: pointer; - width: 10%; - height: 105%; - font-weight: 500; - text-align: center; - } - - .detail_tab button.active { - border-top: 2.5px solid #7BC8E0; - border-bottom: 2.5px solid #7BC8E0; - border-radius: 2px; - } - - .review_body { - display: flex; - flex-direction: column; - align-items: center; - } -} - -@media screen and (max-width: 768px) { - .detail_container { - display: flex; - flex-direction: column; - align-items: center; - } - - .detail_header_container { - display: flex; - flex-direction: row; - align-items: center; - width: 70%; - /* height: 40%; */ - } - - .detail_header_name { - display: flex; - flex-direction: row; - margin-bottom: 10px; - } - - .detail_header_name h3 { - font-size: 20px; - font-weight: 500; - line-height: 20px; - } - - .detail_logo { - width: 30%; - height: 60%; - margin: 12px 24px 20px 22px; - } - - .insta_icon { - margin-top: 1%; - margin-left: 5%; - width: 20px; - height: 20px; - } - - .star_icon { - width: 23px; - height: 23px; - margin-left: 2px; - padding: 2px; - } - - .association_btn { - width: 150px; - height: 30px; - background-color: #7BC8E0; - color: white; - font-size: 11px; - font-weight: 400; - border-radius: 5px; - /* text-align: center; */ - display: flex; - flex-direction: row; - align-items: center; - justify-content: space-evenly; - padding: 0px 6px 0px 6px; - } - - .detail_image { - width: 50%; - aspect-ratio: 1/1; - object-fit: cover; - margin-bottom: 2.5%; - align-items: left; - } - - .detail_tab { - position: relative; - display: flex; - flex-direction: row; - align-items: center; - justify-content: space-evenly; - width: 70%; - height: 36px; - background-color: #7BC8E04D; - } - - .detail_body { - display: flex; - flex-direction: column; - align-items: left; - width: 70%; - margin: 2.5% 0 15% 0; - } - - .detail_body h3 { - width: fit-content; - margin: 2.5% 0 2.5% 0; - display: inline; - box-shadow: inset 0px -15px 0 #7BC8E04D; - } - - .detail_body p { - margin-top: 1%; - margin-left: 5%; - width: 50%; - text-align: left; - font-size: 13px; - } - - .detail_tab button { - border: none; - background-color: transparent; - box-shadow: none; - cursor: pointer; - width: 10%; - height: 105%; - font-weight: 500; - text-align: center; - } - - .detail_tab button.active { - border-top: 2.5px solid #7BC8E0; - border-bottom: 2.5px solid #7BC8E0; - border-radius: 2px; - } - - .review_body { - display: flex; - flex-direction: column; - align-items: center; - } -} \ No newline at end of file diff --git a/src/menu/detail/index.jsx b/src/menu/detail/index.jsx deleted file mode 100644 index 409afde..0000000 --- a/src/menu/detail/index.jsx +++ /dev/null @@ -1,200 +0,0 @@ -import { useState, useEffect } from 'react'; -import axios from 'axios'; -import IntroductionTab from './_component/IntroductionTab'; -import ReviewTab from './_component/ReviewTab'; -import './detailPage.css'; -import { useLocation } from 'react-router-dom'; - -export default function DetailPage() { - const url = window.location.href; // 현재 URL 가져오기 - const urlParts = url.split('/'); // URL을 '/' 기준으로 분할 - const clubId = urlParts[urlParts.length - 1]; // 마지막 부분이 clubId - const intClubId = parseInt(clubId, 10); - - const location = useLocation(); - const tab = location.state || 'Introduction'; - console.log(tab); - const [whichTab, setWhichTab] = useState(tab); - const [detailData, setDetailData] = useState([]); - const [clubInfoData, setClubInfoData] = useState([]); - //즐겨찾기 기능 - const [favoriteId, setFavoriteId] = useState(null); - const [isFavorite, setIsFavorite] = useState(false); - const [isLoading, setIsLoading] = useState(false); - - //회원정보 조회 - const accessToken = localStorage.getItem('accessToken'); - - const getDetailData = async () => { - try { - console.log(intClubId); - const res = await axios.get(`http://13.125.141.171:8080/v1/clubs/${intClubId}`); - if (res.data.success) { - setDetailData(res.data.data); - setClubInfoData(res.data.data.clubInfo); - console.log(res.data.data); - console.log(res.data.data.clubInfo); - } - } catch (error) { - console.error('Error fetching data : ', error); - } - }; - - useEffect(() => { - getDetailData(); - getBookmarkData(); - }, [clubId]); - - const onClickIntroTab = () => { - setWhichTab('Introduction'); - console.log('동아리 상세 소개 탭뷰'); - }; - - const onClickReviewTab = () => { - setWhichTab('Review'); - console.log('동아리 상세 리뷰 탭뷰'); - }; - - //즐겨찾기 기능 - /* - const onClickFavorite = () => { - setIsFavorite((prev) => !prev); - }; - */ - - const getBookmarkData = async () => { - setIsLoading(true); - try { - const response = await axios.get('http://13.125.141.171:8080/v1/users/favorite', { - headers: { - Authorization: `Bearer ${accessToken}`, - }, - }); - if (response.data.success) { - setIsLoading(false); - const data = response.data.data.userFavorites; - console.log('Data: ', data); - const clubIds = data.map((item) => item.favoriteClub['clubId']); - //console.log(clubIds); - const isFavoriteClub = clubIds.some((id) => id === intClubId); - const favorite = data.find((item) => item.favoriteClub['clubId'] === intClubId); - console.log('isfavoriteClub: ', isFavoriteClub); - setIsFavorite(isFavoriteClub); - if (favorite) { - setFavoriteId(favorite.favoriteId); - } else { - setFavoriteId(null); - } - } else { - console.error('Failed to fetch bookmark data'); - } - } catch (error) { - console.error('Error fetching bookmark data : ', error); - } - }; - - const handleFavorite = async () => { - const favoriteData = { - clubId: clubId, - }; - - //if (!userId) return; //로그아웃 시 기능x - try { - if (isFavorite) { - const res = await axios.delete( - `http://13.125.141.171:8080/v1/clubs/${intClubId}/favorites/${favoriteId}`, - { - headers: { - 'Content-Type': 'application/json', - Authorization: `Bearer ${accessToken}`, - }, - } - ); - if (res.status == 200) { - console.log('delete res:', res); - setIsFavorite(false); - setFavoriteId(null); //즐겨찾기 ID 초기화 - } else { - console.error('Failed to delete favorite:', res); - return; // 실패 시 추가 요청을 하지 않음 - } - } - - if (!isFavorite) { - const addres = await axios.post( - `http://13.125.141.171:8080/v1/clubs/${intClubId}/favorites`, - favoriteData, - { - headers: { - 'Content-Type': 'application/json', - Authorization: `Bearer ${accessToken}`, - }, - } - ); - if (addres.data.success) { - console.log('add res : ', addres); - setIsFavorite(true); - setFavoriteId(addres.data.data.favoriteId); - } else { - console.error('Failed to add favorite:', addres); - } - } - getBookmarkData(); // 각 요청 후 즐겨찾기 리스트 업데이트 - } catch (error) { - console.error('Favorite error:', error); // 에러 로그 - getBookmarkData(); //에러 발생해도 업데이트 - } - }; - - return ( -
-
- {`${detailData.clubName} -
-
-

{detailData.clubName}

- - star -
-
- - {detailData.college === null || detailData.college === '' - ? '중앙동아리' - : detailData.college} - - | - {detailData.department || detailData.division} -
-
-
-
- - -
- {whichTab === 'Introduction' && ( - - )} - {whichTab === 'Review' && } -
- ); -} diff --git a/src/menu/detail/review_write/_component/reviewWrite.css b/src/menu/detail/review_write/_component/reviewWrite.css deleted file mode 100644 index ad833ee..0000000 --- a/src/menu/detail/review_write/_component/reviewWrite.css +++ /dev/null @@ -1,74 +0,0 @@ -.title { - width: 380px; - height: 40px; - text-align: center; - font-family: Noto Sans KR; - font-size: 24px; - font-weight: 600; - line-height: 34.75px; - margin: auto; - margin-bottom: 30px; - margin-top: 39px; -} -button { - width: 433px; - height: 50px; - border: 2px; - border-radius: 10px; - background: #ffffff; - box-shadow: 0px 0px 4px 0px #0000004d; - margin: 12px auto; - font-weight: 600; - font-family: Noto Sans KR; - display: block; - text-align: left; - padding: 0; -} - -.button-active { - background-color: #60c1c31a; - border: 1.5px solid #60c1c3; - color: #60c1c3; -} -.button_text { - display: inline-block; - vertical-align: middle; -} -.img { - width: 20px; - height: 20spx; - text-align: left; - margin-right: 9px; - margin-left: 21px; - vertical-align: middle; -} -.submit-active { - width: 90px; - height: 40px; - border-radius: 5px; - background: #60c1c3; - font-family: Noto Sans KR; - font-size: 16px; - font-weight: 700; - text-align: center; - color: #ffffff; - border-color: #60c1c3; - margin-top: 30px; -} -.submit { - width: 90px; - height: 40px; - border-radius: 5px; - font-family: Noto Sans KR; - font-size: 16px; - font-weight: 700; - text-align: center; - margin-top: 30px; - background: #9c9c9c4d; - color: #52555b; - border-color: #9c9c9c4d; -} - -.div_style { - display: inline-block; -} diff --git a/src/menu/detail/review_write/index.jsx b/src/menu/detail/review_write/index.jsx deleted file mode 100644 index bc4698e..0000000 --- a/src/menu/detail/review_write/index.jsx +++ /dev/null @@ -1,106 +0,0 @@ -import React from 'react'; -import './_component/reviewWrite.css'; -import { useState } from 'react'; -import { useNavigate, useLocation } from 'react-router-dom'; -import axios from 'axios'; - -function ReviewWrite() { - const btns = [ - { - type: 'CULTURE', - title: '"분위기가 좋아요"', - image: '/review/smile.png', - }, - { - type: 'FEE', - title: '"회비가 적당해요"', - image: '/review/money.png', - }, - { - type: 'ACTIVITY', - title: '"활동 참여가 자유로워요"', - image: '/review/people.png', - }, - { - type: 'CAREER', - title: '"대외활동에 좋아요"', - image: '/review/trophy.png', - }, - { - type: 'MANAGE', - title: '"운영진들이 일을 잘해요"', - image: '/review/good.png', - }, - ]; - - const navigate = useNavigate(); - const location = useLocation(); - - const clubId = location.state.clubId; - const clubName = location.state.clubName; - console.log(clubId); - console.log(clubName); - - const [btnActive, setBtnActive] = useState({}); - - const handleClick = (type) => { - setBtnActive((prevActive) => { - return { - ...prevActive, - [type]: !prevActive[type], - }; - }); - }; - //이전 버튼상태(prevActive)를 가져와 반전시켜 type값에 저장 후 리턴. - - const handleSubmit = async () => { - const tab = 'Review'; - const selectedKeywords = Object.keys(btnActive).filter((key) => btnActive[key]); - console.log(selectedKeywords); - - try { - const accessToken = localStorage.getItem('accessToken'); - const response = await axios.post( - `http://13.125.141.171:8080/v1/clubs/${clubId}/reviews`, - { - keywords: selectedKeywords, - }, - { - headers: { - Authorization: `Bearer ${accessToken}`, - }, - } - ); - console.log('리뷰 작성 성공:', response.data); - navigate(`/menu/detail/${clubId}`, { state: tab }); // 해당 동아리 상세 페이지로 이동 -> 폴더구조 정리해서 리뷰페이지로 이동하게 - setBtnActive({}); // 제출 후 버튼 상태를 초기화 - } catch (error) { - console.error('리뷰 작성 실패:', error); - } - }; - - const submitButtonClass = Object.values(btnActive).includes(true) ? 'submit-active' : 'submit'; - - return ( -
-

{clubName}에 대한 키워드를 골라주세요!

- - {btns.map((item) => ( - - ))} - -
- ); -} -export default ReviewWrite; diff --git a/src/pages/BranchSmall.jsx b/src/pages/BranchSmall.jsx new file mode 100644 index 0000000..e97ef56 --- /dev/null +++ b/src/pages/BranchSmall.jsx @@ -0,0 +1,9 @@ +import BranchSmall from '../component/smallClub/BranchSmall'; + +export default function BranchSmallPage() { + return ( + <> + + + ); +} diff --git a/src/pages/DetailPage.jsx b/src/pages/DetailPage.jsx index 8c32aa4..3e2450e 100644 --- a/src/pages/DetailPage.jsx +++ b/src/pages/DetailPage.jsx @@ -1,8 +1,8 @@ import { useState, useEffect } from 'react'; import axios from 'axios'; -import IntroductionPage from '../../components/clubs/introduction/IntroductionPage'; -import ReviewPage from '../../components/clubs/review/ReviewPage'; -import './clubsPage.css'; +import IntroductionPage from '../component/detail/introduction/IntroductionPage'; +import ReviewPage from '../component/detail/review/ReviewPage'; +import './detailPage.css'; import { useLocation } from 'react-router-dom'; export default function ClubsPage() { diff --git a/src/pages/SearchPage.jsx b/src/pages/SearchPage.jsx new file mode 100644 index 0000000..1d876a7 --- /dev/null +++ b/src/pages/SearchPage.jsx @@ -0,0 +1,9 @@ +import Search from '../component/search/search'; + +export default function SearchPage() { + return ( + <> + + + ); +} diff --git a/src/pages/Summary.jsx b/src/pages/Summary.jsx index 94b965e..9dd329a 100644 --- a/src/pages/Summary.jsx +++ b/src/pages/Summary.jsx @@ -1,4 +1,4 @@ -import Summary from '../menu/summary/component/summary'; +import Summary from '../component/summary/summary'; export default function SummaryPage() { return (