기존의 디자인했던 것에 추가되는부분이 알람과 마이페이지부터 수정하겠습니다.
알림버튼은 아이콘을 사용할 예정이기 때문에
npm install react-icons --save
를 사용해서 설치를 해준다. 설치가 완료되면
React Icons 해당 사이트에서 사용할 아이콘을 골라준다.(저는 알림버튼을 대체할 종모양 => fa FaBell)
그 다음 해당 아이콘을 사용할 react파일에 import해준다.
import { FaBell } from "react-icons/fa";
여기서 주의할 점은 'react-icons/fi' 이 부분이다.
위의 사진을 자세히 보면 아이콘의 이름들이 파스칼 케이스로 되어 있는 것을 볼 수 있다.
(파스칼 케이스 : 첫 글자와 중간 글자가 모두 대문자)
여기서 파스칼 케이스 중 첫 번째 부분을 'react-icons/' 뒤에 소문자로 써야 한다. 내가 사용한 'FiMenu'를 예로 들면, 'FiMenu'의 첫 번째 부분인 'Fi'를 소문자 'fi'로 바꿔 'react-icons/fi' 이렇게 써야 정상적으로 작동이 된다.
import { FaBell } from "react-icons/fa";
<li>
<button onClick={handleAlertClick} className={styles.alram}>
<FaBell size={24} />
</button>
</li>
저는 이렇게 사용해줬습니다.
코드 작성후 결과물
그 다음 지역 선택과 맛집 선택(카테고리들)이 세로로 배치되어 있어서 가로로 배치되도록 수정합니다.
<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>
<option value="부산">부산</option>
<option value="대구">대구</option>
<option value="울산">울산</option>
<option value="세종">세종</option>
<option value="강원">강원</option>
<option value="경남">경남</option>
<option value="경북">경북</option>
<option value="전남">전남</option>
<option value="전북">전북</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를 하나 더 추가 하겠습니다.
<div className={styles.selectContainer}>
<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>
<option value="부산">부산</option>
<option value="대구">대구</option>
<option value="울산">울산</option>
<option value="세종">세종</option>
<option value="강원">강원</option>
<option value="경남">경남</option>
<option value="경북">경북</option>
<option value="전남">전남</option>
<option value="전북">전북</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>
그리고 css를 고칩니다.
.selectContainer {
display: flex; /* Flexbox 사용 */
justify-content: space-between; /* 공간을 균등하게 배분 */
align-items: center; /* 수직 정렬 */
margin: 20px auto; /* 상단 여백 및 중앙 정렬 */
width: 20%; /* 원하는 너비 설정 */
}
.categorySelect {
margin-right: 20px; /* 오른쪽 여백 추가 */
flex: 1; /* 각 선택 박스가 공간을 차지하도록 설정 */
}
수정 후 결과
메인페이지 수정
이미지 클릭시 회원가입 팝업 창 띄우기 계정 생성 후 => 로그인 팝업창 => 로그인 시 CafeList로 이동
import React, { useState, useEffect } from 'react';
import { useNavigate } from 'react-router-dom'; // useHistory 훅 임포트
import styles from './CafeMain.module.css';
import { Link } from 'react-router-dom';
const images = [
{ id: 1, url: require('../img/slide1.jpg'), link: '/cafeList' },
{ id: 2, url: require('../img/slide2.jpg'), link: '/cafeList' },
{ id: 3, url: require('../img/slide3.jpg'), link: '/cafeList' },
];
export default function CafeMain() {
const [currentIndex, setCurrentIndex] = useState(0);
const [showSignupPopup, setShowSignupPopup] = useState(false); // 회원가입 팝업 상태 추가
const [showLoginPopup, setShowLoginPopup] = useState(false); // 로그인 팝업 상태 추가
const [emailText, setEmailText] = useState(""); // 이메일 텍스트 상태 추가
const [emailDomain, setEmailDomain] = useState("gmail.com"); // 이메일 도메인 상태 추가
const [nickname, setNickname] = useState(""); // 닉네임 상태 추가
const navigate = useNavigate(); // useHistory 훅 사용
useEffect(() => {
const interval = setInterval(() => {
setCurrentIndex((prevIndex) => (prevIndex + 1) % images.length);
}, 3000); // 3초마다 이미지 변경
return () => clearInterval(interval); // 컴포넌트 언마운트 시 인터벌 정리
}, []);
const handleImageClick = () => {
setShowSignupPopup(true); // 회원가입 팝업 표시
}
const closeSignupPopup = () => {
setShowSignupPopup(false); // 회원가입 팝업 닫기
}
const handleEmailChange = (e) => {
setEmailText(e.target.value); // 이메일 텍스트 업데이트
}
const handleDomainChange = (e) => {
setEmailDomain(e.target.value); // 이메일 도메인 업데이트
}
const handleNicknameChange = (e) => {
setNickname(e.target.value); // 닉네임 업데이트
}
const handleSignupSubmit = (e) => {
e.preventDefault(); // 폼 제출 기본 동작 방지
// 여기서 회원가입 처리 로직을 추가하고 로그인 팝업 보여주기
console.log(`가입할 이메일: ${emailText}@${emailDomain}, 닉네임: ${nickname}`); // 가입할 정보 출력
setShowSignupPopup(false); // 회원가입 팝업 닫기
setShowLoginPopup(true); // 로그인 팝업 열기
};
const checkEmail = () => {
console.log(`Checking email: ${emailText}@${emailDomain}`);
// 실제 API 호출을 통해 이메일 중복을 확인하는 로직 추가
};
const checkNickname = () => {
console.log(`Checking nickname: ${nickname}`);
// 실제 API 호출을 통해 닉네임 중복을 확인하는 로직 추가
};
const closeLoginPopup = () => {
setShowLoginPopup(false); // 로그인 팝업 닫기
}
const handleLoginSubmit = (e) => {
e.preventDefault(); // 기본 폼 제출 방지
// 로그인 처리 로직이 여기에 추가
navigate('/cafeList'); // CafeList로 이동
}
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} // 클릭 이벤트 핸들러
>
</div>
))}
</div>
</div>
{/* 회원가입 팝업 */}
{showSignupPopup && (
<div className={styles.loginPopup}>
<div className={styles.popupContent}>
<span className={styles.closeButton} onClick={closeSignupPopup}>×</span>
<h2>회원가입</h2>
<form onSubmit={handleSignupSubmit}>
<div>
<label htmlFor="email">이메일:</label>
<div className={styles.emailContainer}>
<input
type="text"
id="email"
name="email"
value={emailText}
onChange={handleEmailChange}
required
placeholder="이메일 입력"
/>
<select
value={emailDomain}
onChange={handleDomainChange}
className={styles.emailSelect}
>
<option value="gmail.com">@gmail.com</option>
<option value="naver.com">@naver.com</option>
<option value="kakao.com">@kakao.com</option>
</select>
<button type="button" onClick={checkEmail} className={styles.checkButton}>중복 확인</button>
</div>
</div>
<div>
<label htmlFor="nickname">닉네임:</label>
<div className={styles.nicknameContainer}>
<input
type="text"
id="nickname"
name="nickname"
value={nickname}
onChange={handleNicknameChange}
required
/>
<button type="button" onClick={checkNickname} className={styles.checkButton}>중복 확인</button>
</div>
</div>
<div>
<label htmlFor="password">비밀번호:</label>
<input type="password" id="password" name="password" required />
</div>
<div>
<label htmlFor="confirmPassword">비밀번호 확인:</label>
<input type="password" id="confirmPassword" name="confirmPassword" required />
</div>
<button type="submit">계정 만들기</button>
</form>
</div>
</div>
)}
{/* 로그인 팝업 */}
{showLoginPopup && (
<div className={styles.loginPopup}>
<div className={styles.popupContent}>
<span className={styles.closeButton} onClick={closeLoginPopup}>×</span>
<h2>로그인</h2>
<form onSubmit={handleLoginSubmit}>
<div>
<label htmlFor="loginEmail">이메일:</label>
<input type="email" id="loginEmail" name="loginEmail" required placeholder="이메일 입력" />
</div>
<div>
<label htmlFor="loginPassword">비밀번호:</label>
<input type="password" id="loginPassword" name="loginPassword" required placeholder="비밀번호 입력" />
</div>
<button type="submit">로그인</button>
</form>
</div>
</div>
)}
</div>
)
}
CafeMain.js코드
* {
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: #001F3F;
}
.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; /* 숨겨진 상태 */
}
/* 로그인 및 회원가입 팝업 */
.loginPopup {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: rgba(0, 0, 0, 0.6); /* 반투명 배경 */
display: flex;
justify-content: center;
align-items: center;
z-index: 1000;
}
.popupContent {
background: white;
padding: 20px;
border-radius: 8px;
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);
width: 400px; /* 팝업 너비 조정 */
position: relative;
}
.closeButton {
position: absolute;
top: 10px;
right: 10px;
cursor: pointer;
font-size: 20px;
}
h2 {
margin-bottom: 15px;
}
form {
display: flex;
flex-direction: column;
}
label {
margin-bottom: 5px;
text-align: left; /* 레이블 왼쪽 정렬 */
}
input {
margin-bottom: 15px;
padding: 8px;
border: 1px solid #ccc;
border-radius: 4px;
width: 100%; /* 입력 필드 너비를 100%로 설정 */
box-sizing: border-box; /* 패딩과 보더를 포함하여 전체 너비 설정 */
}
button {
padding: 10px;
margin: 5px;
background-color: #007bff;
color: white;
border: none;
border-radius: 4px;
cursor: pointer;
}
button:hover {
background-color: #0056b3;
}
/* 이메일 입력 및 도메인 선택 */
.emailContainer {
display: flex; /* Flexbox를 사용하여 가로 배치 */
align-items: center; /* 수직 중앙 정렬 */
}
.emailContainer input {
margin-right: 10px; /* 오른쪽 여백 추가 */
}
.emailSelect {
padding: 10px; /* 패딩 추가 */
border: 1px solid #ccc; /* 테두리 설정 */
border-radius: 4px; /* 모서리 둥글게 */
margin: 0 10px 15px 0;
}
/* 닉네임 입력 및 중복 확인 버튼 */
.nicknameContainer {
display: flex; /* Flexbox를 사용하여 가로 배치 */
align-items: center; /* 수직 중앙 정렬 */
}
.checkButton {
padding: 8px 12px; /* 버튼 패딩 */
background-color: #007bff; /* 버튼 배경 색상 */
color: white; /* 버튼 텍스트 색상 */
border: none; /* 테두리 제거 */
border-radius: 4px; /* 모서리 둥글게 */
cursor: pointer; /* 커서 포인터 변경 */
margin-left: 10px; /* 버튼과 입력 필드 사이의 여백 */
width: 80px;
height: 37px;
font-size: 12px; /* 폰트 크기 조정 */
font-weight: bold;
}
.checkButton:hover {
background-color: #0056b3; /* 호버 시 배경 색상 변경 */
}
.emailCheckButton {
width: 120px; /* 이메일 중복 확인 버튼 너비 */
height: 37px;
font-size: 12px; /* 폰트 크기 조정 */
font-weight: bold;
}
CafeMain.module.css코드
실행 결과(영상)
오늘은 이렇게 마무리~
'사이드 프로젝트' 카테고리의 다른 글
카페 추천 웹사이트(카카오맵 API 환경변수 설정, 마이페이지 컴포넌트 생성 및 css) (0) | 2024.12.01 |
---|---|
카페 추천 웹사이트(즐겨찾기 기능) (3) | 2024.12.01 |
카페 추천 웹사이트(뭔가 찜찜해서 다시 되짚고 가는) (2) | 2024.11.29 |
카페추천 웹사이트(각 페이지 연결 및 DB 연동) (2) | 2024.11.25 |
카페추천 웹사이트(카페 작성 페이지 및 백엔드 설치) (1) | 2024.11.24 |