본문 바로가기

사이드 프로젝트

카페 추천 웹사이트(마이페이지 즐겨찾기한 목록 기능, 마이페이지 디자인)

저번에 마이페이지 페이지를 만들고 내가 작성한 카페 목록을 보여주는 페이지를 만들었다.

 

오늘은 저번에 작업한 페이지에 + 즐겨찾기 목록과 마이페이지 디자인을 해보겠습니다.

 

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;
}

 

결과 화면

결과 화면

 

 

  • 작업 내용
    • 마이페이지 디자인 수정
    • 즐겨찾기한 카페 목록 추가
    • 하트모양을 눌러서 채워진하트가 빈하트로바뀌면 즐겨찾기한 카페 목록에서 삭제 기능
    • 내가 작성한 카페 목록 수정 및 삭제 기능