본문 바로가기
TIL

팀 소개 페이지 미니 프로젝트(2)

by 스니펫 2023. 10. 10.

2023.10.06

방명록의 댓글을 시간순으로 내림차순 정렬하기 위해  timestamp를 new Date() 함수를 이용해 입력하여 파이어베이스의 데이터를 정렬했다.

let doc = {
                'user': user,
                'comment': comment,
                timestamp: new Date() // 시간 순 정렬하기 위해 추가
            };
            await addDoc(collection(db, "guestBook"), doc);

데이터 정렬을 위해 orderBy와 query를 import하고, getDocs부분에 query를 호출하는 방식으로 orderBy를 넣었다. 

import { query, orderBy } from "https://www.gstatic.com/firebasejs/9.22.0/firebase-firestore.js";

let guest_docs = await getDocs(query(collection(db, "guestBook"), orderBy("timestamp", "desc"))); // timestamp desc순으로 꺼내옴

 

마지막으로 팀원이 방명록에 댓글 삭제 버튼을 넣고 싶어 했는데, 이것을 위해서는 댓글마다 고유의 id값을 지정하여 삭제 버튼을 눌렀을 때 DB에서 해당 id를 가진 데이터만을 삭제하도록 해야 했다.

처음에는 단순하게 let comment_id = 0; 에서 DB guestBook에 방명록 데이터를 저장할 때 ++ 연산자를 이용해 comment_id 값을 1씩 증가시키려고 했는데, 방명록에 글이 작성될 때마다 window.location.reload(); 가 실행되어 comment_id 가 다시 초기값 0으로 돌아가는 문제가 생겼다.

더보기
        let comment_id = 0;

        // DB guestBook에 방명록 데이터 저장
        $("#inputBtn").click(async function () {
            let user = $('#selectName').val();
            let comment = $('#commentText').val();

            //둘중에 하나라도 선택 안되있으면
            if (user == "받는사람선택" || comment == "") {
                alert("받는 사람과 메시지를 입력하세요.");
                return;
            }
            else {
                comment_id++; // 윈도우 리로드 시 0으로 초기화되는 문제 생김
            }
            
            // 이하 생략
        })

이를 해결하기 위해 윈도우가 리로드 되기 전 데이터베이스에 저장된 가장 큰 comment_id 값을 가져와 maxCommentId에 대입한 후 반환해주는 함수 getCurrentCommentId()와, getCurrentCommentId() 함수에서 가져온 값에 1을 더하여 comment_id 에 대입해주는 함수 incrementCommentId()를 작성했다.

        let comment_id = 0;

        // 데이터베이스에서 현재 comment_id 값을 가져오는 함수
        async function getCurrentCommentId() {
            const querySnapshot = await getDocs(query(collection(db, "guestBook")));
            let maxCommentId = 0;

            querySnapshot.forEach((doc) => {
                const data = doc.data();
                if (data.comment_id > maxCommentId) {
                    maxCommentId = data.comment_id;
                }
            });

            return maxCommentId;
        }

        // getCurrentCommentId() 값을 가져와 증가시키는 함수
        async function incrementCommentId() {
            const currentCommentId = await getCurrentCommentId();
            comment_id = currentCommentId + 1;
        }
        
        // DB guestBook에 방명록 데이터 저장
        $("#inputBtn").click(async function () {
            let user = $('#selectName').val();
            let comment = $('#commentText').val();

            //둘중에 하나라도 선택 안되있으면
            if (user == "받는사람선택" || comment == "") {
                alert("받는 사람과 메시지를 입력하세요.");
                return;
            }
            else {
                // comment_id++; // 윈도우 리로드 시 0으로 초기화되는 문제 생김
                await incrementCommentId();
            }
            
            // 이하 생략
        })

2023.10.08

팀 소개 미니 프로젝트에서 내가 맡은 메인 페이지 기능은 끝이 났기 때문에 개인 페이지 구현으로 넘어갔다.

개인 페이지의 경우 메인 페이지에서 멤버카드 이미지를 클릭하면 a 태그를 통해 해당 멤버가 DB에 저장해 둔 URL로 이동하도록 되어있다.

          <a href="${url}?${name}" target="_self" title="${name}소개 페이지">
            <img
              src=${image}
              class="card-img-top" alt="...">
          </a>

이동한 개인페이지에서 location.href.split('?')[1]; 이용해 ?를 기준으로 url과 name 중 2번째 요소인 멤버명 name을 receivedData에 저장한다. receivedData 를 통해 받아온 name으로 쿼리함수를 활용해 'member' 테이블에서 이름이 같은 멤버의 데이터만을 가져온다.

        //이전페이지 데이터 받아오기(이름으로 받음)
        const receivedData = location.href.split('?')[1];
        let name = decodeURI(receivedData); // data

        $('#title').text(name + " 소개 페이지");
        //데이터 읽어서 개인 페이지 요소에 넣기
        const q = query(collection(db, "member"), where("name", "==", name));
        const mem = await getDocs(q);
        mem.forEach((doc) => {
            let row = doc.data();
            // ...
        });

게인 페이지에서 프로필 사진 아래 블로그와 sns 아이콘을 배치한 후, 그 아래에  부트 스트랩에서 가져온 코드를 이용하여 내비게이션을 구현하였다. 각각의 요소에 마우스를 올리면 hover 클래스를 이용하여 요소의 크기가 1.1배 커지도록 하였다.

    <style>
        .nav.justify-content-center :hover {
            /* 마우스 포인터가 올라가 있으면 */
            transform: scale(1.1);
            /* 1.1배 커지도록 */
            transition: transform .3s;
            /* 애니메이션 속도 */
        }
    </style>

배웠던 내용을 활용하여, 내비게이션 클릭 시 숨겨져 있던 소개글이 toggle() 함수를 통해 보이도록 만들었고, 동시에 다른 소개글이 열려있다면 다시 숨겨지도록 하였다.

        // 소개글
        $("#aboutme").click(async function () {
            $('.aboutme').toggle(); // 클릭하면 토글을 열고
            if ($('.more').css('display') != 'none') { // 열려있던 다른 토글은 닫기
                $('.more').hide();
            }
            if ($('.mbti').css('display') != 'none') {
                $('.mbti').hide();
            }
        })

mbti 소개글에서는 Math.random()과 Math.floor() 함수를 이용하여 mbti에 쓸 이미지의 경로 값을 랜덤하게 반환하여 매번 새로운 mbti 이미지가 뜨도록 했다. 또한 mbti 이미지 클릭 시  a 태그를 통해 해당 페이지로 이동한다.

  • Math.random()  : 0 이상 1 미만의 부동소수점 난수를 생성하는 함수. Math.random() * (max - min) + min; 에서 함수의 반환값은 min보다 크거나 같으며, max보다 작다.
  • Math.floor() : 소수점을 버림하여 정수를 반환하는 함수
        // mbti 이미지 랜덤 출력
        function mbti_img() {
            let img_num = Math.floor(Math.random() * 4 + 1); // Math.random()로 1~4의 숫자 반환, Marh.floor()로 소수점 버리기
            let mbti_src = "memLogo/img" + img_num + ".png";

            return mbti_src
        }
        
        $('#title').text(name + " 소개 페이지");
        //데이터 읽어서 개인 페이지 요소에 넣기
        const q = query(collection(db, "member"), where("name", "==", name));
        const mem = await getDocs(q);
        mem.forEach((doc) => {
            let row = doc.data();
            let mbti = row['mbti'];
            let link = "https://www.16personalities.com/ko/성격유형-" + mbti.toLowerCase();

            $('#mbti').attr("src", mbti_img());
            $('#mbti_link').attr("href", link);
        });


마지막으로 맨 아래에 페이지 윗 부분으로 하이퍼링크를 준 버튼을 넣어 클릭시 위로 이동하도록 만들었다.

 

'TIL' 카테고리의 다른 글

Patch & Put 차이점  (2) 2023.12.07
통합 테스트, 단위 테스트  (2) 2023.12.04
메뉴판 프로그램  (0) 2023.10.23
환경변수 Path 복구  (0) 2023.10.12
팀 소개 페이지 미니 프로젝트(1)  (0) 2023.10.10