저번에 메인페이지 이미지 슬라이드까지 하고 마무리 했는데
이번엔 이미지 클릭시 카페 추천 리스트 이동과 카페 추천 리스트에 드롭박스를 넣어 카테고리를 선택하면 선택된 카테고리에 알맞는 카페가 뜨도록 구현 해보겠다.
App.js
import './App.css';
import CafeMain from './component/CafeMain';
import CafeList from './component/CafeList';
import { BrowserRouter, Route, Routes } from 'react-router-dom';
function App() {
return (
<BrowserRouter>
<div className="App">
<Routes>
<Route path='/' element={<CafeMain />} />
<Route path='/cafeList' element={<CafeList />} />
</Routes>
</div>
</BrowserRouter>
);
}
export default App;
CafeMain.js
import React, { useState, useEffect } from 'react';
import styles from './CafeMain.module.css';
import { Link, useNavigate } from 'react-router-dom';
const images = [
{ id: 1, url: require('../img/view1.jpg'), link: '/cafeList' },
{ id: 2, url: require('../img/view2.png'), link: '/cafeList' },
{ id: 3, url: require('../img/view3.jpg'), link: '/cafeList' },
];
export default function CafeMain() {
const [currentIndex, setCurrentIndex] = useState(0);
const navigate = useNavigate(); // useNavigate 훅 사용
useEffect(() => {
const interval = setInterval(() => {
setCurrentIndex((prevIndex) => (prevIndex + 1) % images.length);
}, 3000); // 3초마다 이미지 변경
return () => clearInterval(interval); //컴포넌트 언마운트 시 인터벌 정리
}, []);
const handleImageClick = (link) => {
navigate(link); // URL을 변경하면서 해당 링크로 이동
}
return (
<div className={styles.bgImg}>
<div className={styles.header}>
<h1>
<Link to="/">CAFE 추천</Link>
</h1>
<div className={styles.contentWrap}>
{images.map((image, index) => (
<div
key={image.id}
className={`${styles.contentImg} ${currentIndex === index ? styles.visible : styles.hidden}`}
style={{ backgroundImage: `url(${image.url})` }}
onClick={() => handleImageClick(image.link)} // 클릭 이벤트 핸들러 추가
>
</div>
))}
</div>
</div>
</div>
)
}
CafeMain.module.css
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
a {
text-decoration: none;
color: black;
}
li {
list-style: none;
}
img {
display: block;
width: 100%;
}
.header {
text-align: center;
margin-top: 40px;
}
.header > h1 > a{
color: white;
}
.bgImg {
display: flex;
justify-content: center; /* 수평 중앙 정렬 */
background-image: url('../img/main_bg.avif'); /* 배경 이미지 설정 */
background-size: cover; /* 배경 이미지 크기 조정 */
background-position: center; /* 배경 이미지 중앙 정렬 */
height: 100vh; /* 원하는 높이 설정 */
width: 100%; /* 전체 너비 */
position: relative;
}
.contentWrap{
margin-top: 20px;
position: relative; /* 자식 요소의 절대 위치 설정을 위해 필요 */
overflow: hidden; /* 자식 요소가 넘어가는 부분 숨기기 */
height: 700px; /* 슬라이드 높이 설정 */
width: 1420px;
}
.contentImg {
background-size: cover; /* 배경 이미지 크기 조정 */
background-position: center; /* 배경 이미지 중앙 정렬 */
width: 100%; /* 전체 너비 */
height: 100%; /* 부모 요소에 맞게 높이 설정 */
position: absolute; /* 절대 위치 */
transition: opacity 1s ease-in-out; /* 부드러운 전환 효과 */
opacity: 0;
}
.visible {
opacity: 1; /* 보이는 상태 */
}
.hidden{
opacity: 0; /* 숨겨진 상태 */
}
CafeList.js
import React, { useState } from "react";
import styles from './CafeList.module.css';
import { Link } from 'react-router-dom';
export default function CafeList() {
const [selectedRegion, setSelectedRegion] = useState();
const [selectedCategory, setSelectedCategory] = useState();
// 카페 데이터
const cafes = [
{ id : 1, name: "카페1", region: "서울", catergory: "커피맛집"},
{ id : 2, name: "카페2", region: "부산", catergory: "빵맛집"},
{ id : 3, name: "카페3", region: "서울", catergory: "뷰맛집"},
{ id : 4, name: "카페4", region: "제주", catergory: "커피맛집"},
{ id : 5, name: "카페5", region: "부산", catergory: "빵맛집"},
];
// 필터링 된 카페 목록
const filteredCafes = cafes.filter(cafe => {
const regionMatch = selectedRegion === "all" || cafe.region === selectedRegion;
const catergoryMatch = selectedCategory === "all" || cafe.catergory === selectedCategory;
return regionMatch && catergoryMatch;
});
return (
<div className={styles.bgImg}>
<h1 className={styles.header}>
<Link to="/" className={styles.title}>CAFE 추천 리스트</Link>
</h1>
<div className={styles.categorySelect}>
<label htmlFor="region">지역 선택:</label>
<select
id="region"
value={selectedRegion}
onChange={(e) => setSelectedRegion(e.target.value)}
>
<option value="all">모두 보기</option>
<option value="서울">서울</option>
<option value="부산">부산</option>
<option value="제주">제주</option>
</select>
</div>
<div className={styles.categorySelect}>
<label htmlFor="category">맛집 선택:</label>
<select
id="category"
value={selectedCategory}
onChange={(e) => setSelectedCategory(e.target.value)}
>
<option value="all">모두 보기</option>
<option value="뷰맛집">뷰 맛집</option>
<option value="빵맛집">빵 맛집</option>
<option value="커피맛집">커피 맛집</option>
</select>
</div>
<div className={styles.list_wrap}>
<ul className={styles.list_up}>
{filteredCafes.map(cafe => (
<li key={cafe.id} className={styles.list}>{cafe.name}</li>
))}
</ul>
</div>
</div>
);
}
CafeList.module.css
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
a {
text-decoration: none;
color: black;
}
li {
list-style: none;
}
img {
display: block;
width: 100%;
}
.bgImg {
display: flex;
flex-direction: column;
justify-content: flex-start; /* 수직 정렬을 상단으로 변경 */
background-image: url('../img/main_bg.avif'); /* 배경 이미지 설정 */
background-size: cover; /* 배경 이미지 크기 조정 */
background-position: center; /* 배경 이미지 중앙 정렬 */
height: 100vh; /* 원하는 높이 설정 */
width: 100%; /* 전체 너비 */
position: relative;
}
.header {
text-align: center;
margin-top: 20px; /* 상단 여백 추가 */
height: auto; /* 높이 자동 조정 */
}
.title{
text-align: center;
align-items: center;
color: white;
}
.list_wrap{
width: 80%;
text-align: center;
margin: 20px auto; /* 리스트와의 간격 추가 */
height: 80%;
background-color: white;
}
.list_up{
width: 100%;
display: flex;
justify-content: space-between;
align-items: center;
}
.list{
width: 30%;
border: 1px solid black;
}
.categorySelect {
margin: 20px auto; /* 위아래 여백 */
text-align: center; /* 중앙 정렬 */
}
.categorySelect label {
margin-right: 10px; /* 레이블과 드롭다운 사이 여백 */
}
기능은 얼추 해 뒀으니 이제 디자인을... 디자인이 제일 머리아픕니다 전 ㅎ...
모든 풀스택 개발자를 지향하시는 분들은 같은 고민이시려나요 ?
(풀스택 개발자를 꿈꾸는 분들 화이팅이고, 현직 풀스택 개발자 분들 존경합니다.)
'사이드 프로젝트' 카테고리의 다른 글
카페추천 웹사이트(카카오맵 API 연동) (1) | 2024.11.22 |
---|---|
카페추천 웹사이트(카페 리스트 디자인 및 상세 페이지 구현) (2) | 2024.11.20 |
카페추천 웹사이트 (메인페이지 이미지 슬라이드 효과 넣기) (1) | 2024.11.18 |
카페추천 웹사이트 디자인 (Figma) (1) | 2024.11.18 |
카페추천 웹사이트 프로젝트 개발 시작인데 (React와, Node.js를 곁들인) (3) | 2024.11.16 |