본문 바로가기
기타

[NBCamp | 미니 프로젝트] 팀 소개 페이지 만들기 Day3

by ㅇ달빛천사ㅇ 2024. 7. 18.
728x90

1일차 ~ 2일차는 사전교육 때, 못 들은 웹 개발 강의 완주 함.

오늘부터 본격적으로 미니프로젝트에 참가하게되었다.

내 담당은 Firebase의 "Firestore database 연동"

 


1. Cheers 버튼 구현

먼저 팀원이 이쁘게 cheers 버튼과 간단한 javascript 함수를 구현해 놓았길래

이걸 조금 더 근사하게 database에 연동해서 cheers 값이 저장되도록 만들어 보았다.

 

Firebase 인스턴스 초기화

웹 개발 강의를 들을 때, 실습했던 코드를 참고하여 database에서 값을 가져오고 업데이트 해야했다.

그런데 실습 때는 값을 저장 및 가져오기만 해서 업데이트는 어떻게 하는지 몰랐다.

 

Cloud Firestore에 데이터 추가  |  Firebase

의견 보내기 Cloud Firestore에 데이터 추가 컬렉션을 사용해 정리하기 내 환경설정을 기준으로 콘텐츠를 저장하고 분류하세요. 다음과 같은 몇 가지 방법으로 Cloud Firestore에 데이터를 쓸 수 있습니

firebase.google.com

Firebase 문서를 참고해서 업데이트를 하려고 했는데 도무지 안되어서

Chat GPT한테 이런 오류가 날 때, 어떻게 해야하는지 물어봄.

그래서 코드를

// Firebase 인스턴스 초기화

// 원래 코드
const app = initializeApp(firebaseConfig);
const db = getFirestore(app);
        
        
// 수정한 코드
firebase.initializeApp(firebaseConfig);
const db = firebase.firestore();

이렇게 수정하고 Firebase document가 있는 사이트에서 업데이트 코드를 가져와 사용함.


화면 처음에 cheer 횟수 뿌리기

데이터베이스에서 cheer 값을 가져와 id="cheer-count"인 태그 안에 넣어 줌.
// 응원 횟수 뿌리기
        const docRef = db.collection('cheer').doc('cheer');

        docRef.get().then(function (doc) {
            if (doc.exists) {
                const cheer = doc.data().cheer;
                $('#cheer-count').empty();
                $('#cheer-count').text(cheer);
            }
        }).catch(function (error) {
            alert('Error getting document: ' + error);
        });

 


Cheers 버튼 클릭 event 발생 처리

cheer + 1
데이터 베이스에 증가된 cheer 값 저장
toast 메세지 뿌리기

 

그런데 한 사람이 버튼을 여러번 클릭할 때에도 계속 응원 횟수가 오르는 것을 보고

한 사람이 1만큼만 응원 횟수를 올릴 수 있도록 만들고 싶었다.

 

그런데 회원 정보가 없다보니 이 사람이 응원 버튼을 눌렀는지 안 눌렀는지 알 방법이 없었다.

그래서 id="lover"라는 태그를 style="display:hidden;"으로 숨겨두고

그 안에 버튼 클릭을 하면 ❤️을 넣어두고

아직 클릭하지 않았으면 비워두도록 코드를 작성하고

id="lover"태그 안의 text값이 ""와 같으면 cheer++

그렇지 않으면 cheer--하여

응원 전의 값으로 cheer 값이 돌아오도록 만들었다.

toast 메세지도 이에 따라 다른 메세지가 보내지도록 코드를 작성하였다.

// 응원 버튼 클릭 이벤트
        $('.btn-cheer').click(function () {
        	// 버튼 클릭 여부 확인용
            let lover = $('#lover').text();
            
            //데이터베이스에서 cheer 콜렉션의 cheer 문서
            const docRef = db.collection('cheer').doc('cheer');
            // 현재 화면에 나온 cheer 값 정수로 가져오기
            let cheer = Number($('#cheer-count').text());
            
            if (lover == "") {
                cheer++;
                $('#lover').text('❤️');
                $('.toast-body').text('😍 응원해 주셔서 감사합니다! ❤️');
            } else {
                cheer--;
                $('#lover').empty();
                $('.toast-body').text('🥺 정말로 응원 취소하시나요? 💔');
            }
            let toast = new bootstrap.Toast($('#liveToast'));
            toast.show();
			
            // 데이터베이스에 +1 증가된 cheer 값 저장
            docRef.set({ 'cheer': cheer })
                .then(function () {
                    $('#cheer-count').text(cheer);

                })
                .catch(function (error) {
                    alert(error);
                });

        });

2. 모달창 CSS 변경

이전 모달창은

  • 카드 밖에 div 너비 및 높이가 카드보다 넓어서 카드만 깔끔하게 보이지 않음.
  • 닫기 버튼도 아래, 위에 2개가 있음.
  • 카드마다 너비가 제각각

CSS를 수정하고 싶었다.


닫기 버튼 단일화

일단 아래쪽 버튼으로 된 닫기 버튼을 없애주었고

div 너비와 높이를 카드에 맞게 변경했다.


닫기 버튼 위치 및 사진 넣는 태그 변경

처음에는 사진을 img태그에 그대로 두고 z-index를 주어 버튼 위치를 지정해 주려고 했는데

안되어서 다른 방법으로 구현해 보았다.

 

닫기 버튼이 사진 위에 보이도록 

img 태그로 들어가 있던 사진의 주소를

div의 background-image의 url()에 넣어 주었다.

 

닫기 버튼 사이즈 및 사진을 완전히 가리지 않도록 투명도 설정

닫기 버튼 아이콘 색상 white로 변경해 주었다.

 

닫기 버튼이 사진의 우측 상단에 위치하도록 CSS 변경해 주었다.


3. 동적 화면 구성

첫 화면에 이미지 뿌려주기

// 멤버 & 팀 이미지 setting
        for (let n = 0; n < 6; n++) {
            $(`img.member${n}`).attr("src", `./member${n}.jpg`);
            $(`div.member${n}`).css("background-image", `url(./member${n}.jpg)`);
        }

팀 및 팀원 정보 저장

팀 및 팀원 정보를 데이터베이스에 저장해 두고

화면 시작할 때, 뿌려주고 싶은데

일일이 손으로 적기 귀찮아서

버튼을 클릭하면 

팀원과 팀의 정보들이 저장되도록 하였다.

// 멤버 소개 정보 저장
        $("#save_btn").click(async function () {
            let modal = $('.modal');

            for (let i = 0; i < modal.length - 1; i++) {
                let doc = {};

                let card_body = modal.eq(i).find('.card-body');
                let title = card_body.find('.card-title').text();
                doc['name'] = title;

                let list_group = card_body.find('.list-group').find('.list-group-item');

                for (let j = 0; j < list_group.length - 1; j++) {
                    let li_i = list_group.eq(j);

                    doc[li_i.children().eq(0).text()] = li_i.children().eq(1).text();
                }

                doc['blog'] = list_group.find('a').attr('href');

                await db.collection("member_info").doc(`member${i + 1}`).set(doc);
                alert(`member${i + 1} 정보 저장 완료`);
            }

            let doc = {};
            let card_body = modal.eq(5).find('.card-body');
            let title = card_body.find('.card-title').text();
            doc['name'] = title;

            let list_group = card_body.find('.list-group').find('.list-group-item');
            let li = [];
            for (let j = 0; j < list_group.length; j++) {
                let li_i = list_group.eq(j);

                li[j] = li_i.children().last().text();
            }
            doc['info'] = li;

            await db.collection("team_info").doc(`team`).set(doc);
            alert(`team 정보 저장 완료`);



        })







728x90