본문 바로가기
Sparta 내일배움캠프 Java 5기/[사전캠프] mini_mini Team Project ✓ 2024. 4. 8.

(24.04.05) 기능 구현 코드 짜기

 

기능 구현 

더보기
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>배스킨라빈스(추후수정)</title>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet"
        integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous">
    <style>
        @import url('https://fonts.googleapis.com/css2?family=Noto+Sans+KR:wght@100..900&display=swap');

        * {
            font-family: "Noto Sans KR", sans-serif;
            font-optical-sizing: auto;
            font-weight: <weight>;
            font-style: normal;
        }

        body {
            background-size: cover;
            background-position: center;
            background-attachment: fixed;
        }



        .mytitle {
            background-color: transparent;
            height: 300px;
            color: black;
            display: flex;
            flex-direction: column;
            align-items: center;
            justify-content: center;

        }

        .mytitle>button {
            height: 50px;
            weight: 150px;
            background-color: #F986BD;
            color: white;
            border: 1px solid #F986BD;
            border-radius: 5px;
            margin-top: 20px;
        }

        .mycard {
            width: 1200px;
            margin: 30px auto 0px auto;
        }

        .mypostingbox {
            width: 500px;
            margin: 30px auto 0px auto;

            padding: 20px;
            box-shadow: 0px 0px 3px 0px blue;
            border-radius: 5px;
        }

        .mybtn {
            display: flex;
            flex-direction: row;
            align-items: center;
            justify-content: center;
        }

        .mybtn>button {
            margin-right: 5px;
        }

        /*모달에 관한 CSS */
        .modal-footer {
            display: flex;
            justify-content: center;
        }


        .modal-footer button {
            margin: 0 5px;
            width: 40%;
        }

        .btn-flavors {
            margin-bottom: 10px;
        }

        .btn-flavors .btn {
            margin: 5px;
        }

        /*등록 카드의 아이스크림 배치 등에 관한 */
        .card .row .col img {
            width: 120px;
        }

        .card .row {
            margin: -30px 0;
        }

        .card .col {
            margin-right: -150px;
        }

        .card {
            display: flex;
            justify-content: center;
            padding-top: 30px;
        }
    </style>

    <script type="module">
        import { initializeApp } from "https://www.gstatic.com/firebasejs/9.22.0/firebase-app.js";
        import { getFirestore } from "https://www.gstatic.com/firebasejs/9.22.0/firebase-firestore.js";
        import { collection, addDoc } from "https://www.gstatic.com/firebasejs/9.22.0/firebase-firestore.js";
        import { getDocs } from "https://www.gstatic.com/firebasejs/9.22.0/firebase-firestore.js";


        // Firebase 구성 정보 설정
        const firebaseConfig = {
            apiKey: "AIzaSyCGxdvDyVsYEfoEnitKaonaXjMaxpxUzDw",
            authDomain: "sparta-bee1a.firebaseapp.com",
            projectId: "sparta-bee1a",
            storageBucket: "sparta-bee1a.appspot.com",
            messagingSenderId: "354592468831",
            appId: "1:354592468831:web:86f959a0da2ff302d9d0ea",
            measurementId: "G-FW22WNY4XT"
        };

        const app = initializeApp(firebaseConfig);
        const db = getFirestore(app);

        $("#postingbtn").click(async function () {
            let title = $('#title').val();
            let name = $('#name').val();
            let recommend = $('#recommend').val();

            var selectedFlavors = [];

            // 선택한 맛에대한 이미지 URL을 baskin_DB=아이스크림 이미지 DB에서 불러서 저장하기
            $(".btn-flavors .btn").each(function () {
                if ($(this).hasClass('active')) {
                    selectedFlavors.push($(this).text());
                }
            });
            let flavorsString = selectedFlavors.join(', ');
            let imageURLs = [];
            // baskin_DB에는 flavor아이스크림 이름, imageURL 해당 이미지URL 필드로 자료저장되어있음
            for (let i = 0; i < selectedFlavors.length; i++) {
                let flavor = selectedFlavors[i];
                let querySnapshot = await getDocs(collection(db, "baskin_DB"));

                querySnapshot.forEach((doc) => {
                    if (doc.data().flavor === flavor) {
                        imageURLs.push(doc.data().imageURL);
                    }
                });
            }

            let doc = {
                'title': title,
                'name': name,
                'recommend': recommend,
                'imageURL': imageURLs,  // 가져온 imageURL들 배열
                'flavors': flavorsString
            };

            await addDoc(collection(db, "baskin_register"), doc);
            alert('등록되었습니다');
            window.location.reload();
        });

        $("#postingbtn-close").click(function () {
            $('#exampleModal').modal('hide');
        });



        // 등록된 imageURL들은 많아 배열로 만든 후, 반복문으로 2열로 만들어 카드에 넣기
        let docs = await getDocs(collection(db, "baskin_register"));
        docs.forEach((doc) => {
            let row = doc.data();
            let images = row['imageURL'];
            let title = row['title'];
            let name = row['name'];
            let recommend = row['recommend'];
            let flavors = row['flavors'];

            let temp_html = `
    <div class="col">
        <div class="card h-100">
            <div class="row flavor-table">`;

            images.forEach((image, index) => {
                temp_html += `
            <div class="col">
                <img src="${image}" class="card-img-top" alt="...">
            </div>`;
                if ((index + 1) % 2 === 0 && index !== images.length - 1) {
                    temp_html += `</div><div class="row flavor-table">`;
                }
            });

            temp_html += `
            </div> <!-- flavor-table 닫음 -->
            <div class="card-body">
                <h5 class="card-title" style="margin-top: 30px;">${title}</h5>
                <p class="card-text" style="color: gray;">${recommend}</p>
                <br>
                <p class="card-text" style="font-size: 13px;">by ${name}</p>
                
            </div>
            <div class="card-footer">
                <small class="text-body-secondary" style="color: gray;"">${flavors}</small>
            </div>
        </div>
    </div>`;

            $('#card').append(temp_html);
        });



        $('#postingbox').hide();
        $("#savebtn").click(async function () {
            $('#postingbox').toggle();

        })


    </script>


    <script>
        $(document).ready(function () {
            $('#modalbtn').click(function () {
                $('#exampleModal').modal('show');
            });
        });

    </script>

    <script>
        $(document).ready(function () {
            $('.btn').on('click', function () {
                $(this).toggleClass('active');
            });
        });
    </script>


</head>

<body>
    <div class="mytitle">
        <h1 style="font-size: 50px;">배스킨라빈스(추후수정)</h1>
        <button id="modalbtn" type="button" class="btn btn-info" data-bs-toggle="modal" data-bs-target="#exampleModal">
            등록하기
        </button>
    </div>



    <div class="mycard">
        <div id="card" class="row row-cols-1 row-cols-md-5 g-4">
        </div>
    </div>

    <!-- 아이스크림 선택 모달 -->
    <div class="modal fade" id="exampleModal" tabindex="-1" aria-labelledby="exampleModalLabel" aria-hidden="true">
        <div class="modal-dialog modal-dialog-centered">
            <div class="modal-content">
                <div class="modal-header">
                    <h5 class="modal-title" id="exampleModalLabel">정보 입력하기</h5>
                    <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
                </div>
                <div class="modal-body">
                    <!-- 아이스크림 선택 버튼들 -->
                    <div class="btn-flavors">
                        <input type="checkbox" class="btn-check" id="btn-check-1" autocomplete="off">
                        <label class="btn btn-outline-secondary" for="btn-check-1">아이스 도쿄바나나</label>
                        <input type="checkbox" class="btn-check" id="btn-check-2" autocomplete="off">
                        <label class="btn btn-outline-secondary" for="btn-check-2">와사비 아이스크림</label>
                        <input type="checkbox" class="btn-check" id="btn-check-3" autocomplete="off">
                        <label class="btn btn-outline-secondary" for="btn-check-3">팥있는 말차당</label>
                        <input type="checkbox" class="btn-check" id="btn-check-4" autocomplete="off">
                        <label class="btn btn-outline-secondary" for="btn-check-4">봉쥬르, 마카롱</label>
                        <input type="checkbox" class="btn-check" id="btn-check-5" autocomplete="off">
                        <label class="btn btn-outline-secondary" for="btn-check-5">피치 요거트</label>
                        <input type="checkbox" class="btn-check" id="btn-check-6" autocomplete="off">
                        <label class="btn btn-outline-secondary" for="btn-check-6">민트 초코 봉봉</label>
                        <input type="checkbox" class="btn-check" id="btn-check-7" autocomplete="off">
                        <label class="btn btn-outline-secondary" for="btn-check-7">망고 탱고</label>
                        <input type="checkbox" class="btn-check" id="btn-check-8" autocomplete="off">
                        <label class="btn btn-outline-secondary" for="btn-check-8">러브미</label>
                        <input type="checkbox" class="btn-check" id="btn-check-9" autocomplete="off">
                        <label class="btn btn-outline-secondary" for="btn-check-9">아빠는 딸바봉</label>
                        <input type="checkbox" class="btn-check" id="btn-check-10" autocomplete="off">
                        <label class="btn btn-outline-secondary" for="btn-check-10">엄마는 외계인</label>
                        <input type="checkbox" class="btn-check" id="btn-check-11" autocomplete="off">
                        <label class="btn btn-outline-secondary" for="btn-check-11">민트 초콜릿 칩</label>
                        <input type="checkbox" class="btn-check" id="btn-check-12" autocomplete="off">
                        <label class="btn btn-outline-secondary" for="btn-check-12">뉴욕 치즈케이크</label>
                        <input type="checkbox" class="btn-check" id="btn-check-13" autocomplete="off">
                        <label class="btn btn-outline-secondary" for="btn-check-13">레인보우 샤베트</label>
                        <input type="checkbox" class="btn-check" id="btn-check-14" autocomplete="off">
                        <label class="btn btn-outline-secondary" for="btn-check-14">체리쥬빌레</label>
                        <input type="checkbox" class="btn-check" id="btn-check-15" autocomplete="off">
                        <label class="btn btn-outline-secondary" for="btn-check-15">슈팅스타</label>
                        <input type="checkbox" class="btn-check" id="btn-check-16" autocomplete="off">
                        <label class="btn btn-outline-secondary" for="btn-check-16">사랑에 빠진 딸기</label>
                        <input type="checkbox" class="btn-check" id="btn-check-17" autocomplete="off">
                        <label class="btn btn-outline-secondary" for="btn-check-17">오레오 쿠키 앤 크림</label>
                        <input type="checkbox" class="btn-check" id="btn-check-18" autocomplete="off">
                        <label class="btn btn-outline-secondary" for="btn-check-18">베리베리 스트로베리</label>
                        <input type="checkbox" class="btn-check" id="btn-check-19" autocomplete="off">
                        <label class="btn btn-outline-secondary" for="btn-check-19">31요거트</label>
                        <input type="checkbox" class="btn-check" id="btn-check-20" autocomplete="off">
                        <label class="btn btn-outline-secondary" for="btn-check-20">바람과 함께 사라지다</label>
                        <input type="checkbox" class="btn-check" id="btn-check-21" autocomplete="off">
                        <label class="btn btn-outline-secondary" for="btn-check-21">바닐라</label>
                        <input type="checkbox" class="btn-check" id="btn-check-22" autocomplete="off">
                        <label class="btn btn-outline-secondary" for="btn-check-22">이상한 나라의 솜사탕</label>
                        <input type="checkbox" class="btn-check" id="btn-check-23" autocomplete="off">
                        <label class="btn btn-outline-secondary" for="btn-check-23">초콜릿 무스</label>
                        <input type="checkbox" class="btn-check" id="btn-check-24" autocomplete="off">
                        <label class="btn btn-outline-secondary" for="btn-check-24">그린티</label>
                        <input type="checkbox" class="btn-check" id="btn-check-25" autocomplete="off">
                        <label class="btn btn-outline-secondary" for="btn-check-25">피스타치오 아몬드</label>
                        <input type="checkbox" class="btn-check" id="btn-check-26" autocomplete="off">
                        <label class="btn btn-outline-secondary" for="btn-check-26">초콜릿</label>
                        <input type="checkbox" class="btn-check" id="btn-check-27" autocomplete="off">
                        <label class="btn btn-outline-secondary" for="btn-check-27">자모카 아몬드 훠지</label>
                        <input type="checkbox" class="btn-check" id="btn-check-28" autocomplete="off">
                        <label class="btn btn-outline-secondary" for="btn-check-28">월넛</label>
                        <input type="checkbox" class="btn-check" id="btn-check-29" autocomplete="off">
                        <label class="btn btn-outline-secondary" for="btn-check-29">아몬드 봉봉</label>
                        <input type="checkbox" class="btn-check" id="btn-check-30" autocomplete="off">
                        <label class="btn btn-outline-secondary" for="btn-check-30">애플 민트</label>

                    </div>
                    <div class="form-floating mb-3">
                        <input type="email" class="form-control" id="title" placeholder="name@example.com">
                        <label for="floatingInput">제목</label>
                    </div>
                    <div class="form-floating mb-3">
                        <input type="email" class="form-control" id="name" placeholder="name@example.com">
                        <label for="floatingInput">작성자 이름</label>
                    </div>

                    <div class="form-floating">
                        <textarea class="form-control" id="recommend" placeholder="Leave a comment here"
                            id="floatingTextarea"></textarea>
                        <label for="floatingTextarea">추천 이유</label>
                    </div>

                </div>
                <div class="modal-footer">
                    <!-- 모달 푸터 -->
                    <button id="postingbtn" type="button" class="btn btn-info">등록하기</button>
                    <button id="postingbtn-close" type="button" class="btn btn-secondary"
                        data-bs-dismiss="modal">닫기</button>
                </div>
            </div>
        </div>
    </div>


</body>

</html>

 

아이스크림 선택, 등록하기 모달

  • 모달에서 아이스크림 그림을 선택 계획 → 이름 선택으로 변경
    • 아이스크림 갯수가 너무 많아서 이름만 간단하게 선택할 수 있게

등록된 아이스크림 카드 불러와서 랜딩페이지에 보여주기

  • 카드6개 → 카드5개 변경 : 카드 내용이 너무 안보이고, 아이스크림 사진이 잘 구별이 안되어 변경
    • 등록한 아이스크림 이미지를 2열 배치 : 일단 FirebaseStore 에 따로 저장해놓은 이미지URL을 가져온 후, 배치