22일차
2024. 8. 28. 16:49ㆍFCB2O4
오늘도 합본 css 수정
메인페이지를 전반적으로 다시 다듬었다.
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="b2o4.mapper.MainPageMapper">
<!-- 평가받은 스타디움 가져오기 -->
<select id="getStadiumList" resultType="b2o4.dto.MainPage">
SELECT og.stadiumNo, og.stadiumName, og.stadiumAddress, og.stadiumPrice, og.stadiumCapacity, og.stadiumImage, (SUM(rv.likeCount) - SUM(rv.dislikeCount)) as totalLike
FROM stadium og
JOIN stadiumreview rv ON og.stadiumNo = rv.stadiumNo
GROUP BY og.stadiumNo, og.stadiumName, og.stadiumImage
ORDER BY totalLike DESC
</select>
<!-- 갤러리 게시판에서 게시물 6개 랜덤으로 가져오기 -->
<select id="getGalleryList" resultType="b2o4.dto.MainPage">
SELECT * FROM galleryboard ORDER BY RAND() LIMIT 6
</select>
<!-- 용품 장터에서 용품들 랜덤으로 가져오기 -->
<select id="getGoodsList" resultType="b2o4.dto.MainPage">
SELECT * FROM goodsshop ORDER BY RAND()
</select>
</mapper>
스타디움하고 용품들을 가져오는 것에 3개씩 제한을 뒀다가 갤러리 처럼 아예 캐러셀로 만들어버리자 해서 제한을 풀어버렸다.
그래서 RecommenedGear.js 와 MonthOfTheStadium.js를 수정. 특히 MonthOfTheStadium.js 에서는 추가로 인기 상위 3개에 하이라이트 서식을 하도록 수정했다
import { useEffect, useState, useRef } from "react";
import '../css/MainPage.css';
import { Link, useNavigate } from "react-router-dom";
import axios from "axios";
import Slider from "react-slick";
import "slick-carousel/slick/slick.css";
import "slick-carousel/slick/slick-theme.css";
const RecommendedGears = () => {
const [goodsList, setGoodsList] = useState([]);
const navigate = useNavigate();
const sliderRef = useRef(null);
const getRecommendedGears = () => {
axios.get("/main/goods")
.then(res => {
setGoodsList(res.data);
});
};
useEffect(() => {
getRecommendedGears();
}, []);
const settings = {
dots: true,
infinite: true,
speed: 400,
slidesToShow: 5,
slidesToScroll: 3,
responsive: [
{
breakpoint: 1024,
settings: {
slidesToShow: 2,
slidesToScroll: 1,
infinite: true,
dots: true
}
},
{
breakpoint: 600,
settings: {
slidesToShow: 1,
slidesToScroll: 1,
infinite: true,
dots: true
}
}
]
};
const handleNext = () => {
sliderRef.current.slickNext();
};
const handlePrev = () => {
sliderRef.current.slickPrev();
};
const handleRowClick = (goods) => {
navigate(`/goodsDetail/${goods.goodsNo}`, { state: { good: goods } });
};
return (
<div className='recommended-goods-container'>
<div className='section-title'>
<Link to="/goodsShop"><h1>Recommended Gears</h1></Link>
<hr />
</div>
<div className="slider-container">
<Slider {...settings} ref={sliderRef}>
{goodsList && goodsList.map(goods => (
<div key={goods.goodsNo} className="recommended-goods-card-body" onClick={() => handleRowClick(goods)}>
{goods.goodsImage ?
<img src={`/images/${goods.goodsImage}`} alt='기어 사진' />
: <img src="/images/defaultImage.png" alt="이미지 없음" />}
<div className="recommended-goods-desc">
<div className="recommended-goods-name-box">
<p className="recommended-goods-name">{goods.goodsName}</p>
</div>
<p className="recommended-goods-price">{goods.goodsPrice.toLocaleString()}원</p>
</div>
</div>
))}
</Slider>
<button className="slick-prev" onClick={handlePrev}>
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" className="bi bi-chevron-left" viewBox="0 0 16 16">
<path fillRule="evenodd" d="M11.354 1.646a.5.5 0 0 1 0 .708L5.707 8l5.647 5.646a.5.5 0 0 1-.708.708l-6-6a.5.5 0 0 1 0-.708l6-6a.5.5 0 0 1 .708 0" />
</svg>
</button>
<button className="slick-next" onClick={handleNext}>
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" className="bi bi-chevron-right" viewBox="0 0 16 16">
<path fillRule="evenodd" d="M4.646 1.646a.5.5 0 0 1 .708 0l6 6a.5.5 0 0 1 0 .708l-6 6a.5.5 0 0 1-.708-.708L10.293 8 4.646 2.354a.5.5 0 0 1 0-.708" />
</svg>
</button>
</div>
</div>
);
};
export default RecommendedGears;
import { useEffect, useState, useRef } from "react";
import axios from "axios";
import '../css/MainPage.css';
import { Link, useNavigate } from "react-router-dom";
import Slider from "react-slick";
import "slick-carousel/slick/slick.css";
import "slick-carousel/slick/slick-theme.css";
const MonthOfTheStadiumList = () => {
const [stadiumList, setStadiumList] = useState([]);
const [topStadiums, setTopStadiums] = useState([]);
const navigate = useNavigate();
const sliderRef = useRef(null);
const getStadiumList = () => {
axios.get("/main/stadium")
.then(res => {
setStadiumList(res.data);
});
};
useEffect(() => {
getStadiumList();
}, []);
useEffect(() => {
if (stadiumList.length > 0) {
//좋아요 - 싫어요가 가장 높은 3개 뽑기
const sortedStadiums = [...stadiumList].sort((a, b) => b.totalLike - a.totalLike);
const top3Stadiums = sortedStadiums.slice(0, 3);
setTopStadiums(top3Stadiums);
}
}, [stadiumList]);
const settings = {
dots: true,
infinite: true,
speed: 400,
slidesToShow: 4,
slidesToScroll: 3,
responsive: [
{
breakpoint: 1024,
settings: {
slidesToShow: 2,
slidesToScroll: 1,
infinite: true,
dots: true
}
},
{
breakpoint: 600,
settings: {
slidesToShow: 1,
slidesToScroll: 1,
infinite: true,
dots: true
}
}
]
};
const handleNext = () => {
sliderRef.current.slickNext();
};
const handlePrev = () => {
sliderRef.current.slickPrev();
};
const handleRowClick = (stadium) => {
navigate(`/stadiumDetail/${stadium.stadiumNo}`, { state: { stadium: stadium } });
};
return (
<div className='famous-stadium-list-container'>
<div className='section-title'>
<Link to="/StadiumList"><h1>Stadium of the Month</h1></Link>
<hr />
</div>
<div className="slider-container">
<Slider {...settings} ref={sliderRef}>
{stadiumList && stadiumList.map(stadium => (
<div key={stadium.stadiumNo} className={`stadium-card-body ${topStadiums.some(ts => ts.stadiumNo === stadium.stadiumNo) ? 'highlight' : ''}`} onClick={() => handleRowClick(stadium)}>
{topStadiums.some(famous => famous.stadiumNo === stadium.stadiumNo) &&
<img className="hot" src="/images/hotItem.jpg" alt="핫아이템"/>}
{stadium.stadiumImage ?
<img src={`/images/${stadium.stadiumImage}`} alt='스타디움 사진' className="stadium-image" />
: <img src="/images/defaultImage.png" alt="이미지 없음" />}
<div className="stadium-desc row">
<div className="col-10">
<p className="stadium-name">{stadium.stadiumName}</p>
<p className="stadium-address">{stadium.stadiumAddress}</p>
<p className="stadium-capacity">최대 수용 인원 : {stadium.stadiumCapacity} 명</p>
<p className="stadium-price">{stadium.stadiumPrice.toLocaleString()} 원(1인)</p>
</div>
<div className="col-2">
<p className="totalLike">
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" className="bi bi-heart" viewBox="0 0 16 16">
<path d="m8 2.748-.717-.737C5.6.281 2.514.878 1.4 3.053c-.523 1.023-.641 2.5.314 4.385.92 1.815 2.834 3.989 6.286 6.357 3.452-2.368 5.365-4.542 6.286-6.357.955-1.886.838-3.362.314-4.385C13.486.878 10.4.28 8.717 2.01zM8 15C-7.333 4.868 3.279-3.04 7.824 1.143q.09.083.176.171a3 3 0 0 1 .176-.17C12.72-3.042 23.333 4.867 8 15" />
</svg>
{stadium.totalLike}
</p>
</div>
</div>
</div>
))}
</Slider>
<button className="slick-prev" onClick={handlePrev}>
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" className="bi bi-chevron-left" viewBox="0 0 16 16">
<path fillRule="evenodd" d="M11.354 1.646a.5.5 0 0 1 0 .708L5.707 8l5.647 5.646a.5.5 0 0 1-.708.708l-6-6a.5.5 0 0 1 0-.708l6-6a.5.5 0 0 1 .708 0" />
</svg>
</button>
<button className="slick-next" onClick={handleNext}>
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" className="bi bi-chevron-right" viewBox="0 0 16 16">
<path fillRule="evenodd" d="M4.646 1.646a.5.5 0 0 1 .708 0l6 6a.5.5 0 0 1 0 .708l-6 6a.5.5 0 0 1-.708-.708L10.293 8 4.646 2.354a.5.5 0 0 1 0-.708" />
</svg>
</button>
</div>
</div>
);
};
export default MonthOfTheStadiumList;
그리고 둘 다 자세히 보기 버튼을 눌러야 상세페이지로 가는 게 아니라 그냥 카드를 눌러도 해당 상세페이지로 가도록 조정했다.
전체적으로 다듬은 메인페이지 콘텐츠들. 항목당 3개씩 나오게 하는 건 너무 심심했다.
라이브 페이지도 꾸밀까 했는데 딱히 꾸밀 아이디어가 생각나지 않아 오늘은 여기까지