저번에 마이페이지 페이지를 만들고 내가 작성한 카페 목록을 보여주는 페이지를 만들었다.
오늘은 저번에 작업한 페이지에 + 즐겨찾기 목록과 마이페이지 디자인을 해보겠습니다.
CafeMypage.js코드
import React, { useState } from "react";
import { useNavigate } from "react-router-dom";
import styles from './CafeMypage.module.css';
const initialCafes = [
{ id: 1, name: "그릿비", region: "울산", category: "뷰맛집", description: "아름다운 바다를 볼 수 있는 카페", isFavorite: true },
{ id: 2, name: "롤링커피", region: "울산", category: "커피맛집", description: "신선한 커피를 제공하는 카페", isFavorite: false },
{ id: 3, name: "아베베베이커리", region: "서울", category: "빵맛집", description: "맛있는 빵과 디저트를 판매하는 카페", isFavorite: true },
];
export default function CafeMypage() {
const [cafes, setCafes] = useState(initialCafes);
const [editCafe, setEditCafe] = useState(null);
const [newName, setNewName] = useState('');
const [newRegion, setNewRegion] = useState('');
const [newCategory, setNewCategory] = useState('');
const [newDescription, setNewDescription] = useState('');
const navigate = useNavigate();
const handleEdit = (cafe) => {
setEditCafe(cafe.id);
setNewName(cafe.name);
setNewRegion(cafe.region);
setNewCategory(cafe.category);
setNewDescription(cafe.description);
};
const handleUpdate = () => {
setCafes(cafes.map(cafe =>
cafe.id === editCafe
? { ...cafe, name: newName, region: newRegion, category: newCategory, description: newDescription }
: cafe
));
setEditCafe(null);
setNewName('');
setNewRegion('');
setNewCategory('');
setNewDescription('');
};
const handleDelete = (id) => {
setCafes(cafes.filter(cafe => cafe.id !== id)); // 카페 삭제
};
const toggleFavorite = (cafeId) => {
setCafes(cafes.map(cafe => {
if (cafe.id === cafeId) {
return { ...cafe, isFavorite: !cafe.isFavorite }; // 즐겨찾기 상태 토글
}
return cafe;
}));
};
return (
<div className={styles.mypageBgimg}>
<div className={styles.mypageContainer}>
<div className={styles.mypageContent}>
<h1>내 카페 작성 목록</h1>
<ul className={styles.cafeList}>
{cafes.map(cafe => (
<li key={cafe.id} className={styles.cafeItem}>
<h2>{cafe.name}</h2>
<span>{cafe.region} | {cafe.category}</span>
<span>{cafe.description}</span>
<div className={styles.buttonGroup}>
<button onClick={() => handleEdit(cafe)}>수정</button>
<button onClick={() => handleDelete(cafe.id)}>삭제</button>
</div>
</li>
))}
</ul>
{editCafe && (
<div className={styles.editForm}>
<h2>카페 수정하기</h2>
<input
type="text"
value={newName}
onChange={(e) => setNewName(e.target.value)}
placeholder="카페 이름"
/>
<input
type="text"
value={newRegion}
onChange={(e) => setNewRegion(e.target.value)}
placeholder="지역"
/>
<input
type="text"
value={newCategory}
onChange={(e) => setNewCategory(e.target.value)}
placeholder="카테고리"
/>
<input
type="text"
value={newDescription}
onChange={(e) => setNewDescription(e.target.value)}
placeholder="설명"
/>
<button onClick={handleUpdate}>수정 완료</button>
<button onClick={() => setEditCafe(null)}>취소</button>
</div>
)}
</div>
<div className={styles.mypageFavoriteContent}>
<h2>즐겨찾기한 카페 목록</h2>
<ul className={styles.cafeList}>
{cafes.filter(cafe => cafe.isFavorite).map(cafe => (
<li key={cafe.id} className={styles.cafeItem}>
<h2>{cafe.name}</h2>
<button
className={cafe.isFavorite ? styles.favoriteButtonActive : styles.favoriteButton}
onClick={() => toggleFavorite(cafe.id)}
>
{cafe.isFavorite ? '❤️' : '♡'}
</button>
</li>
))}
</ul>
</div>
<button onClick={() => navigate('/cafeList')}>돌아가기</button>
</div>
</div>
);
}
CafeMypage.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%;
}
/* 배경 이미지 설정 */
.mypageBgimg {
display: flex;
flex-direction: column;
background-image: url('../img/main_bg.avif');
background-size: cover;
background-position: center;
background-repeat: no-repeat;
min-height: 100vh;
width: 100%;
}
/* 마이페이지 컨테이너 */
.mypageContainer {
width: 80%;
display: flex;
flex-direction: column; /* 세로 방향으로 정렬 */
padding: 20px;
background-color: #f9f9f9;
border-radius: 8px;
max-width: 800px;
margin: auto;
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1);
margin-top: 80px;
}
/* 카페 작성 목록 스타일 */
.mypageContent {
margin-bottom: 40px;
}
/* 카페 목록을 가로로 배치 */
.cafeList {
display: flex;
flex-wrap: wrap;
font-size: 14px;
}
/* 카페 아이템 스타일 */
.cafeItem {
border: 1px solid #ccc;
padding: 15px;
margin: 10px;
border-radius: 5px;
background-color: #ffffff;
transition: box-shadow 0.3s;
flex: 1 1 calc(30% - 20px); /* 3개 아이템 기준 */
max-width: calc(30% - 20px); /* 최대 너비 설정 */
min-height: 150px; /* 최소 높이 설정으로 빈 공간 방지 */
}
.cafeItem:hover {
box-shadow: 0 4px 10px rgba(0, 0, 0, 0.2);
}
/* 버튼 그룹 스타일 */
.buttonGroup {
display: flex;
justify-content: space-between;
margin-top: 10px; /* 버튼 간격 */
}
/* 즐겨찾기 목록 스타일 */
.mypageFavoriteContent {
padding: 20px;
border: 1px solid #007bff;
border-radius: 5px;
background-color: #eaf7ff;
}
/* 수정 폼 스타일 */
.editForm {
margin-top: 20px;
padding: 15px;
border: 1px solid #007bff;
border-radius: 5px;
background-color: #e7f1ff;
}
/* 입력 필드 스타일 */
.editForm input {
display: block;
margin-bottom: 10px;
padding: 10px;
border: 1px solid #ccc;
border-radius: 5px;
width: 100%;
font-size: 14px;
transition: border-color 0.3s;
}
.editForm input:focus {
border-color: #007bff;
outline: none;
}
/* 버튼 스타일 */
button {
padding: 10px 15px;
border: none;
border-radius: 5px;
background-color: #007bff;
color: white;
cursor: pointer;
transition: background-color 0.3s;
}
button:hover {
background-color: #0056b3;
}
button:focus {
outline: none;
}
결과 화면
- 작업 내용
- 마이페이지 디자인 수정
- 즐겨찾기한 카페 목록 추가
- 하트모양을 눌러서 채워진하트가 빈하트로바뀌면 즐겨찾기한 카페 목록에서 삭제 기능
- 내가 작성한 카페 목록 수정 및 삭제 기능
'사이드 프로젝트' 카테고리의 다른 글
카페 추천 웹사이트 (0) | 2024.12.07 |
---|---|
카페 추천 웹사이트(메인페이지 로그인 팝업, 비밀번호 재설정, 상세페이지 수정요청 버튼) (1) | 2024.12.04 |
카페 추천 웹사이트(카카오맵 API 환경변수 설정, 마이페이지 컴포넌트 생성 및 css) (0) | 2024.12.01 |
카페 추천 웹사이트(즐겨찾기 기능) (3) | 2024.12.01 |
카페 추천 웹사이트(카페추천리스트 페이지 수정, 메인페이지 수정) (4) | 2024.11.29 |