오전 9시에는 간단하게 머리 회전을 위해서 알고리즘 문제를 풀었다. 간단하게 Step2 3문제 정도 풀었다.
2025.02.18 - [코딩 공부/Baekjoon-Java] - [2480] 주사위 세개
2025.02.18 - [코딩 공부/Baekjoon-Java] - [2525] 오븐 시간
2025.02.18 - [코딩 공부/Baekjoon-Java] - [2884] 알람시계
✅ 프로젝트 회의
1. 오전 회의
하고자 했던 기능들 중 규현님은 기본 index.html 뼈대 완성, 채진님은 방명록 뼈대 완성, 나는 개인 상세 페이지를 완성했다.
그래서 오늘 해야하는 부분은 규현님과 채진님은 개인 상세페이지를 만드셔야하고, 나는 방명록 기능을 구현해야 한다.
방명록 기능은 이전에 내가 웹 페이지를 만들때 썼던 JS 코드를 수정하면 된다.
- CSS 고쳐야된다.
- 와이어 프레임도 그럴듯하게 제작.
2. 중간 회의
- Header(Nav) 만들기
- 새로운 기능 추가
- 아이디어 1. 구현된 기능 동적 추가를 해보자.
- 아이디어 2. 데일리 스크럼, 아예 화면에 작게 보여준다. > 데일리 스크럼 상세페이지를 만들자. ✅
- 추가된 기능: 스크럼을 추가, 변경, 삭제 하도록 해보자.
- 구현해야할 부분: 데일리 스크럼 상세페이지, Header
- 버튼 클릭으로 ? Nav- 메인 페이지, 따로 데일리스크럼, #id 값으로 접근 방명록
- 각자 쓰고 있는 상세페이지 Nav 바 height 80px, 바꾸기.
- btn id 조심하기
3. 오후 회의
- 내일 디테일을 잡자.
- 밥먹고와서 팀소개하: > / 토스트 메시지나 모달 메시지로 삭제할지 안할지 지정하는것도 해야함.
✅ 방명록 기능 구현하기
Firebase 는 안 쓰는 구글 계정으로 연동해서 쓸 것이다.
1. 방명록 삽입
// DB 에 보내기
$("#cardBtn").click(async function () {
let name = $('#name').val();
let content = $('#content').val();
let customId = Date.now().toString();
const docRef = doc(db, "Dotori", customId);
await setDoc(docRef, {
id: customId,
name: name,
coment: content
});
window.location.reload();
})
방명록에 이름, 컨텐트를 적으면 그 내용이 DB 로 전달된다.
나중에 데이터 삭제 시 편의성을 위해서 id 값을 customId로 설정했다.
(Firebase에서 자동으로 생성된 아이디가 아닌, 내가 아이디를 직접 설정해주겠다는 것이다.)
2. 방명록 조회
// 화면에 띄우기
let dotori = await getDocs(collection(db, "Dotori"));
dotori.forEach((coments) => {
let id = coments.data()['id'];
let name = coments.data()['name'];
let content = coments.data()['coment'];
let temp_html = ``
temp_html = `
<div class="col" id="${id}">
<div class="card h-100">
<div class="card-body">
<h5 class="card-title">${name}</h5>
<p class="card-text">${content}</p>
</div>
<div class="card-footer">
<small class="text-muted"><button id="guestDelete">삭제</button></small>
</div>
</div>
</div>`;
$('#guestBook').append(temp_html);
});
조회는 따로 함수로 구현하지 않고 forEach문을 통해 실제 화면에 띄우면 된다. (script 타입을 module로 해두었기 때문)
3. 방명록 삭제
// 방명록 삭제하기
$(document).on("click","#guestDelete", async function () {
let id = $(this).parent().parent().parent().parent().attr("id");
const docRef = doc(db, "Dotori", id);
await deleteDoc(docRef);
window.location.reload();
})
✅ 데일리 스크럼 HTML
<body>
<header>
<ul class="nav justify-content-center">
<li class="nav-item">
<a class="nav-link active" aria-current="page" href="./dailyScrum.html">데일리 스크럼</a>
</li>
<li class="nav-item">
<a class="nav-link" href="./index.html">메인 페이지</a>
</li>
<li class="nav-item">
<a class="nav-link" href="./index.html#guestBookse">방명록 작성</a>
</li>
</ul>
</header>
<!-- 스크럼 Form 부분 -->
<div class="mypostingbox">
<h3>오늘의 팀 목표</h3>
<div class="form-floating">
<textarea class="form-control" placeholder="Leave a comment here" id="teamAim"
style="height: 100px"></textarea>
<label for="teamAim">팀 목표</label>
</div>
<h3>팀원 개별 목표</h3>
<div class="form-floating">
<input class="form-control" id="ghGoal">
<label for="floatingInput">규현 목표</label>
</div>
<div class="form-floating">
<input class="form-control" id="cjGoal">
<label for="floatingInput">채진 목표</label>
</div>
<div class="form-floating">
<input class="form-control" id="syGoal">
<label for="floatingInput">신영 목표</label>
</div>
<br>
<div class="mybtn">
<button id="scrumBtn" type="button" class="btn btn-warning">기록하기</button>
</div>
</div>
<!-- 스크럼 쌓이는 부분 -->
<div id="stack_scrum">
<div class="accordion" id="accordionExample">
<!-- 여기에 쌓임. -->
</div>
</div>
</body>
- 간단하게 Input부분과 스크럼이 쌓이는 부분 두 가지를 만들었다.
✅ 데일리 스크럼 기능 구현
1. 스크럼 추가
// DB 에 보내기
$("#scrumBtn").click(async function () {
let teamAim = $('#teamAim').val();
let ghGoal = $('#ghGoal').val();
let cjGoal = $('#cjGoal').val();
let syGoal = $('#syGoal').val();
let customId = Date.now().toString();
let date = getTodayDate();
const docRef = doc(db, "Scrum", customId);
await setDoc(docRef, {
id: customId,
teamAim: teamAim,
ghGoal: ghGoal,
cjGoal:cjGoal,
syGoal:syGoal,
ghcheck:" ",
cjcheck:" ",
sycheck:" ",
date:date
});
window.location.reload();
})
- 다소 보내야 할 데이터가 많았다.
- 데이터로는 id, 팀목표, 팀원분들의 개인 목표, 개인목표 별 체크박스, 그리고 date 까지 필요하다.
- id 는 추후에 삭제 및 체크박스를 위해 만들어 둔 것이다.
- 개인 목표 별 체크박스는 html 의 input 끝란에 "" 공백으로 두고, check 할 경우 "checked"로 바꾸어 줄려고 추가한 데이터이다.
2. 스크럼 조회
// 데이터 띄우기
let scrums = await getDocs(collection(db,"Scrum"));
scrums.forEach(scrum=> {
let teamAim= scrum.data()['teamAim']
let ghGoal= scrum.data()['ghGoal']
let cjGoal= scrum.data()['cjGoal']
let syGoal= scrum.data()['syGoal']
let id= scrum.data()['id']
let date= scrum.data()['date']
let ghcheck = scrum.data()['ghcheck']
let cjcheck = scrum.data()['cjcheck']
let sycheck = scrum.data()['sycheck']
let temp_html = ``
temp_html=
` <div class="accordion-item" id="${id}">
<h2 class="accordion-header">
<button class="accordion-button collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#collapse${id}" aria-expanded="false" aria-controls="collapse${id}">
# ${date} ] 데일리 스크럼
</button>
</h2>
<div id="collapse${id}" class="accordion-collapse collapse" >
<div class="accordion-body">
<div>
<h5>오늘의 팀 목표</h5>
<p>${teamAim}</p>
</div>
<div>
<h5>개별 목표 달성 여부</h5>
<div class="form-check">
<input class="form-check-input ghcheckbox" type="checkbox" value="" id="flexCheckDefault" ${ghcheck}>
<label class="form-check-label" for="flexCheckDefault">
${ghGoal}
</label>
</div>
<div class="form-check">
<input class="form-check-input cjcheckbox" type="checkbox" value="" id="flexCheckDefault" ${cjcheck}>
<label class="form-check-label" for="flexCheckDefault">
${cjGoal}
</label>
</div>
<div class="form-check">
<input class="form-check-input sycheckbox" type="checkbox" value="" id="flexCheckDefault" ${sycheck}>
<label class="form-check-label" for="flexCheckDefault">
${syGoal}
</label>
</div>
</div>
<div class="d-grid gap-2 d-md-flex justify-content-md-end">
<button class="btn btn-warning" type="button">삭제하기</button>
</div>
</div>
</div>
</div>
`
$("#accordionExample").append(temp_html);
});
- 아래와 같이 구현이 될 것이다.
3. 스크럼 목표 체크박스
체크박스를 클릭할 경우 HTML의 input 요소 끝란에 "checked" 라는 문자열을 넣음으로 체크 박스가 전환되게끔 구현할 것이다.
// check 박스가 변경 되면 그걸 DB 에 연결해주어야함.
$('.ghcheckbox').change(async function () {
let id = $(this).parent().parent().parent().parent().parent().attr("id");
const docRef = doc(db, "Scrum", id);
if ($(this).is(':checked')) {
await updateDoc(docRef, {
ghcheck: "checked"
});
window.location.reload();
} else {
await updateDoc(docRef, {
ghcheck: " "
});
window.location.reload();
}
});
- checked 해야할 부분이 총 3개라(팀원3명) 어떻게 처리하지 고민했다.
- 근데 간단하게 각각의 id에 접근해서 처리하면 쉽게 해결 되었다. 너무 오래 코딩하다 보니 단순한 것도 생각하지 못했다..
✅ 오늘의 회고
- 오늘 생각보다 구현한 기능이 많다. 9 to 9 이라 그런가 생각보다 널널했던 것 같다.
- 오늘 한 것: 방명록 추가, 방명록 조회, 방명록 삭제, 스크럼 추가, 스크럼 조회, 스크럼 체크박스 구현, 기본 index.html css 수정 이렇게 나열 해보니 열심히 한것 같아 뿌듯하당 😎
- 하지만 중간 중간 머리를 너무 많이 쓰다보니 힐링이 필요했다.. 강아지를 자주 보았다 : >
- 나는 처음 프론트 배울 때, 애초에 LiveServer를 다운 받아라는 설명 아래 수업을 받았다. 그래서 LiveServer의 중요성을 잘 몰랐는데, 이번에 팀원들과 얘기하다가 알게된 점이 있다.
- 바로 로컬로 파일을 실행했을 때, Fetch API 와 Firebase 연동이 안되는 것이었다. 그래서 조금 더 찾아보니 아래와 같았다.
file:// (로컬파일) | Live server (HTTP) | |
Cors 문제 | 제한 많음 | 문제없음 |
Fetch() / AJAX 요청 | 차단됨 | 정상 작동 |
모듈 | 차단됨 | 정상 작동 |
자동 새로고침 | 없음 | 지원됨 |
실제 웹 환경과 유 | 아님 | 유사함 |
'백엔드 부트캠프 > TIL' 카테고리의 다른 글
[내일배움캠프Spring-5일차] 미니 프로젝트 Iteration[리터레이션] (0) | 2025.02.21 |
---|---|
[내일배움캠프Spring-4일차] 미니 프로젝트 4일차[최종] (3) | 2025.02.20 |
[내일배움캠프Spring-3일차] 미니 프로젝트 3일차 (4) | 2025.02.19 |
[내일배움캠프Spring-1일차] 미니 프로젝트 1일차 (0) | 2025.02.17 |