1. firebase를 사용하기 위한 기본 세팅을 직접 해보세요.
- https://firebase.google.com/?hl=ko
- firebase에 접속한 후 우측 상단의 콘솔로 이동 항목을 클릭합니다.
- 본인이 생성한 프로젝트를 클릭합니다.
- 프로젝트 개요 항목에서 본인이 생성한 웹 앱을 클릭하고, SDK 설정의 firebaseConfig의 설정 값을 복사합니다.
- food_5주차_실습.html 파일의 script 부분을 확인하여 본인이 등록한 firebase 프로젝트의 설정에 맞게 자신의 데이터베이스를 연결해줍니다.
- 참고 : 4주차 2강
파이어베이스의 설정을 완료해주었다.
단, 코드를 여기다가 적어놓으면, 내 api값이 누출되기에 적는 건 패스.
2. firebase 데이터 추가 코드를 완성해보세요.
- 가져온 값을 각각 image, title, star, comment 변수에 저장해 주세요.
- 각각 담은 변수를 컬렉션 필드에 image, title, star, comment에 각각 넣어주세요.
- 참고 : 4주차 5강
// 데이터 추가
$("#addBtn").click(async function () {
// title_input, comment_input, image_input id를 가진 HTML 요소에서 값을 가져와서 title, comment, image 변수에 저장해 주세요.
try {
const docRef = await addDoc(collection(db, "foods"), {
title: document.getElementById('title_input').value,
comment: document.getElementById('comment_input').value,
image: document.getElementById('image_input').value,
star: document.getElementById('star_id').value
});
alert("음식이 추가 되었습니다!");
window.location.reload();
} catch (e) {
console.error("Error adding document: ", e);
}
});
주의) addDoc 함수 안에서 변수를 선언할 때, 변수 선언 방식(let, const, var)을 사용하지 않고, 키-값 쌍의 형태로 정의해야 합니다. 즉 위에서처럼 딕셔너리 형태로 정의하지 않으면 제대로 작동하질 않는다.
3. firebase 데이터 읽기 및 카드 생성 코드를 완성해보세요.
- 문서의 image, title, star, comment 필드에서 추출한 데이터를 활용하, tempHtml 문자열에 각 데이터를 포함한 카드의 HTML 코드를 완성하세요.
- 참고 : 4주차 7강
당연하지만, 직접 코드를 짜는 일은 하지 않을 거다. 아래 미리 만들어진 카드의 html을 참고하자.
$(".row-cols-3").empty();
const querySnapshot = await getDocs(collection(db, "foods"));
querySnapshot.forEach((doc) => {
let title = doc.data().title;
let comment = doc.data().comment;
let star = "⭐".repeat(doc.data().star);
let image = doc.data().image;
// 문서의 title, comment, image, star 필드에서 데이터를 추출한 변수명을 갖고,
// tempHtml 문자열에 각 데이터를 포함한 카드의 HTML 코드를 생성하세요.
let tempHtml = `
<div class="card h-100">
<img src="${image}"
class="card-img-top" alt="...">
<div class="card-body">
<h4 class="card-title">${title}</h4>
<p class="card-text">${comment}</p>
<p>${star}</p>
<button class="card-button">주문하기</button>
</div>
</div>
</div > `
$(".row-cols-3").append(tempHtml);
});
주의) tempHtml을 만들 때, '를 쓰면 안 되고 `을 써야 한다. 이거 때문에 왜 안 되나 싶었다...
마지막으로 원래 아래에 추가되어 있던 카드들을 싹 지워주자.
완성된 코드
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<title>푸드파이터</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet"
integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous">
integrity="sha384-MrcW6ZMFYlzcLA8Nl+NtUVF0sA7MsXsP1UyJoMp4YLEuNSfAP+JcXn/tWtIaxVXM"
crossorigin="anonymous"></script>
<style>
@import url('https://fonts.googleapis.com/css2?family=Black+Han+Sans&family=Gowun+Dodum&display=swap');
* {
font-family: 'Gowun Dodum', sans-serif;
}
body {
background-color: white;
color: black;
}
.header {
background-size: cover;
background-image:
background-position: right;
height: 650px;
display: flex;
flex-direction: column;
}
.header>h1 {
margin: 0;
font-size: 40px;
}
.header>div {
font-size: 18px;
margin-top: 10px;
}
.form-button {
width: 150px;
height: 40px;
background-color: transparent;
border: 1px solid tr;
color: black;
font-size: 15px;
margin: 20px 10px 0px 0px;
}
.form-button:hover {
border: 2px solid black;
}
.info-button {
margin: 20px 0 0 15px;
height: 40px;
font-size: 14px;
}
.post {
width: 500px;
margin: 20px 0px 1px 20px;
padding: 20px;
box-shadow: 0px 0px 3px 0px transparent;
background-color: wheat;
}
.form-floating input,
.form-floating textarea {
color: black;
background-color: white;
}
.button2 {
display: flex;
justify-content: flex-end;
margin-top: 15px;
}
.button2>button {
margin-right: 10px;
}
.mycards {
width: 1600px;
margin: 30px auto;
flex-direction: row;
align-items: center;
}
.card {
border-radius: 30px;
background-color: white;
border: none;
color: black;
margin-left: 50px;
}
.card-img-top {
object-fit: cover;
height: 250px;
border-radius: 20px;
}
.card-title {
margin-top: 10px;
font-size: 18px;
}
.card-body {
border: blanchedalmond 2px solid;
border-radius: 20px;
}
.card-text {
color: black;
}
.comment {
color: black;
}
.play-button {
display: flex;
justify-content: flex-start;
margin-top: 15px;
}
a.nav-link {
color: #F17228;
font-size: large;
}
.icon {
height: 50px;
}
.card-button {
background-color: orange;
color: white;
text-align: center;
padding: 10px 15px;
border: none;
border-radius: 6px;
cursor: pointer;
}
.card-title {
font-weight: bold;
}
.card-button> :hover {
background-color: darkorange;
}
#input-card {
width: 500px;
margin: 0px 0px 0px 135px;
padding: 20px;
background-color: #f9f9f9;
border-radius: 10px;
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
float: left;
}
.form-floating input,
.form-floating textarea {
color: black;
background-color: #f9f9f9;
border: 1px solid #ccc;
border-radius: 5px;
margin-bottom: 10px;
padding: 10px;
width: 100%;
}
.form-floating label {
color: #333;
}
.input-group button,
.input-group select {
background-color: rgb(168, 161, 161);
color: white;
border: none;
border-radius: 5px;
cursor: pointer;
margin-top: 10px;
}
.input-group button:hover,
.input-group select:hover {
background-color: gray;
}
.button2 {
text-align: right;
}
.button2 button {
background-color: #F17228;
color: white;
border: none;
border-radius: 5px;
cursor: pointer;
}
.button2 button:hover {
background-color: #f3620f;
}
.jumbotron-message {
margin-left: 150px;
font-size: 1500px;
}
</style>
<script type="module">
import { collection, addDoc } from "https://www.gstatic.com/firebasejs/9.22.0/firebase-firestore.js";
const firebaseConfig = {
apiKey: "AIzaSyANfOa5DxeYY3wvB1gCLKPWVlqgE8pEDvg",
authDomain: "sparta-45b78.firebaseapp.com",
projectId: "sparta-45b78",
storageBucket: "sparta-45b78.appspot.com",
messagingSenderId: "1086011296968",
appId: "1:1086011296968:web:341a092fecd8dec42ce9fd",
measurementId: "G-F3QGKWWXCG"
};
const app = initializeApp(firebaseConfig);
const db = getFirestore(app);
// 데이터 추가
$("#addBtn").click(async function () {
// title_input, comment_input, image_input id를 가진 HTML 요소에서 값을 가져와서 title, comment, image 변수에 저장해 주세요.
try {
const docRef = await addDoc(collection(db, "foods"), {
title: document.getElementById('title_input').value,
comment: document.getElementById('comment_input').value,
image: document.getElementById('image_input').value,
star: document.getElementById('star_id').value
});
alert("음식이 추가 되었습니다!");
window.location.reload();
} catch (e) {
console.error("Error adding document: ", e);
}
});
// 데이터 읽기 및 카드 생성
$(".row-cols-3").empty();
const querySnapshot = await getDocs(collection(db, "foods"));
querySnapshot.forEach((doc) => {
let title = doc.data().title;
let comment = doc.data().comment;
let star = "⭐".repeat(doc.data().star);
let image = doc.data().image;
// 문서의 title, comment, image, star 필드에서 데이터를 추출한 변수명을 갖고,
// tempHtml 문자열에 각 데이터를 포함한 카드의 HTML 코드를 생성하세요.
let tempHtml = `
<div class="card h-100">
<img src="${image}"
class="card-img-top" alt="...">
<div class="card-body">
<h4 class="card-title">${title}</h4>
<p class="card-text">${comment}</p>
<p>${star}</p>
<button class="card-button">주문하기</button>
</div>
</div>
</div > `
$(".row-cols-3").append(tempHtml);
});
</script>
</head>
<body>
<!-- Navbar -->
<header class="p-3 text-bg-dark">
<div class="container">
<div class="d-flex flex-wrap align-items-center justify-content-center justify-content-lg-start">
<a href="/" class="d-flex align-items-center mb-2 mb-lg-0 text-white text-decoration-none">
<svg class="bi me-2" width="40" height="32" role="img" aria-label="Bootstrap">
<use xlink:href="#bootstrap"></use>
</svg>
</a>
<ul class="nav col-12 col-lg-auto me-lg-auto mb-2 justify-content-center mb-md-0">
class="icon"></li>
<li><a href="#" class="nav-link px-2 text-danger">Foodcourt</a></li>
<li><a href="#" class="nav-link px-2 ">홈</a></li>
<li><a href="#" class="nav-link px-2 ">한식</a></li>
<li><a href="#" class="nav-link px-2 ">일식</a></li>
<li><a href="#" class="nav-link px-2 ">중식</a></li>
<li><a href="#" class="nav-link px-2 ">양식</a></li>
</ul>
<form class="col-12 col-lg-auto mb-3 mb-lg-0 me-lg-3" role="search">
<input type="search" class="form-control form-control-dark text-bg-dark" placeholder="Search..."
aria-label="Search">
</form>
<div class="text-end">
<button type="button" class="btn btn-warning me-2">Login</button>
<button type="button" class="btn btn-warning">Sign-up</button>
</div>
</div>
</div>
</header>
<!-- 점보 트론 적용 jumbotron -->
<div class="header">
<div class="p-5 mb-4 bg-body-tertiary rounded-3">
<div class="container-fluid py-5">
<div class="jumbotron-message">
<h1 class="display-5 fw-bold" style="font-family: 'Black Han Sans', sans-serif; ">스파르타 푸드파이터
</h1>
<p class="col-md-8 fs-4"> 본인만의 맛집을 소개하는 사이트입니다.
<br>맛집을 소개해 주세요!
</p>
</div>
<!-- 부트스트랩 인풋 박스 적용-->
<div class="post" id="input-card">
<div class="form-floating mb-3">
<input type="email" class="form-control" id="image_input" placeholder="name@example.com">
<label for="floatingInput">음식 이미지 주소</label>
</div>
<div class="form-floating mb-3">
<input type="text" class="form-control" id="title_input" placeholder="영화 제목">
<label for="foodTitle">음식명</label>
</div>
<div class="input-group mb-3">
<button class="btn btn-outline-secondary" type="button">별점</button>
<select class="form-select" id="star_id"
aria-label="Example select with button addon">
<option selected>별점 선택</option>
<option value="1">⭐</option>
<option value="2">⭐⭐</option>
<option value="3">⭐⭐⭐</option>
<option value="4">⭐⭐⭐⭐</option>
<option value="5">⭐⭐⭐⭐⭐</option>
</select>
</div>
<div class="form-floating">
<textarea class="form-control" placeholder="Leave a comment here" id="comment_input"></textarea>
<label for="floatingTextarea">추천 이유</label>
</div>
<div class="button2">
<button type="button" class="btn btn-danger" id="addBtn"> 기록하기 </button>
</div>
</div>
</div>
</div>
</div>
<!-- 부트스트랩 카드 적용-->
<div class="mycards">
<div class="row row-cols-3 row-cols-md-3"></div>
</div>
</div>
<div class="container2">
<footer class="row row-cols-1 row-cols-sm-2 row-cols-md-5 py-5 my-5 border-top">
<div class="col mb-3">
<a href="/" class="d-flex align-items-center mb-3 link-body-emphasis text-decoration-none">
</a>
<p class="text-body-secondary">©Teamsparta 2024</p>
</div>
<div class="col mb-3">
</div>
<div class="col mb-3">
<h5>Section</h5>
<ul class="nav flex-column">
<li class="nav-item mb-2"><a href="#" class="nav-link p-0 text-body-secondary">Home</a></li>
<li class="nav-item mb-2"><a href="#" class="nav-link p-0 text-body-secondary">Features</a></li>
<li class="nav-item mb-2"><a href="#" class="nav-link p-0 text-body-secondary">Pricing</a></li>
<li class="nav-item mb-2"><a href="#" class="nav-link p-0 text-body-secondary">FAQs</a></li>
<li class="nav-item mb-2"><a href="#" class="nav-link p-0 text-body-secondary">About</a></li>
</ul>
</div>
<div class="col mb-3">
<h5>Section</h5>
<ul class="nav flex-column">
<li class="nav-item mb-2"><a href="#" class="nav-link p-0 text-body-secondary">Home</a></li>
<li class="nav-item mb-2"><a href="#" class="nav-link p-0 text-body-secondary">Features</a></li>
<li class="nav-item mb-2"><a href="#" class="nav-link p-0 text-body-secondary">Pricing</a></li>
<li class="nav-item mb-2"><a href="#" class="nav-link p-0 text-body-secondary">FAQs</a></li>
<li class="nav-item mb-2"><a href="#" class="nav-link p-0 text-body-secondary">About</a></li>
</ul>
</div>
<div class="col mb-3">
<h5>Section</h5>
<ul class="nav flex-column">
<li class="nav-item mb-2"><a href="#" class="nav-link p-0 text-body-secondary">Home</a></li>
<li class="nav-item mb-2"><a href="#" class="nav-link p-0 text-body-secondary">Features</a></li>
<li class="nav-item mb-2"><a href="#" class="nav-link p-0 text-body-secondary">Pricing</a></li>
<li class="nav-item mb-2"><a href="#" class="nav-link p-0 text-body-secondary">FAQs</a></li>
<li class="nav-item mb-2"><a href="#" class="nav-link p-0 text-body-secondary">About</a></li>
</ul>
</div>
</footer>
</div>
</body>
</html>
'사전 캠프 > 추가 과제' 카테고리의 다른 글
비밀의 사이트를 만드는 중이다. (1) (내용은 당연히 비밀.) (2) | 2024.09.25 |
---|---|
스타벅스 주문 시스템 만들기 (난이도 상) (완료) (2) | 2024.09.19 |
스타벅스 주문 시스템 만들기 (난이도 상) (2) (0) | 2024.09.19 |
스타벅스 주문 시스템 만들기 (난이도 상) (1) (1) | 2024.09.18 |
MBTI 테스트 (난이도 중) (2) | 2024.09.17 |