어제 못한 유저 페이지 프론트 구현

main은 css 는 완료 했고 js도 버그를 제외한 기능 완료

info, cart, order, review의 html과 css 적용 완료

남은건 java script의 적용과 버그 수정과 더미 db 파일 적용

 

숫자 증감이나 별 클릭시 표시 

 

 

info.html - 숫자 증감과  체크 사용자 버튼 구현

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org" xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity5">
<head>
    <meta charset="UTF-8">
    <title></title>
    <link href="/css/style.css" rel="stylesheet">
    <link href="/css/user/info.css" rel="stylesheet" type="text/css">
    <script src="/js/user/info.js" type="text/javascript" defer></script>
</head>
<body>
<div class="innerBox">
    <header></header>
    <div class="container">
        <form action="/user/info" method="post" class="info-form">
            <div class="menu-image">
                <img src="/images/sample.png" alt="음식 이미지" class="menu-img">
            </div>
            <div class="info">
                <div class="title">짜파게티</div>
                <div class="contents">맛있는 짜파게티 김치 미포함</div>
                <div class="price">300원</div>
            </div>
            <div class="option">
                <div class="title">
                    <div class="text">매운맛</div>
                    <div class="select">필수</div>
                </div>
                <div class="contents">
                    <label class="select">
                        <input type="radio" name="spiciness" class="check" value="spicy">
                        <label></label>
                        <span class="content">맵게 해주세요</span>
                        <span class="price">+3000원</span>
                    </label>
                    <label class="select">
                        <input type="radio" name="spiciness" class="check" value="not-spicy">
                        <label></label>
                        <span class="content">안맵게 해주세요</span>
                        <span class="price">+4000원</span>
                    </label>
                </div>
            </div>
            <div class="option">
                <div class="title">
                    <div class="text">토핑</div>
                    <div class="select">선택</div>
                </div>
                <div class="contents">
                    <label class="select">
                        <input type="checkbox" class="check">
                        <label></label>
                        <span class="content">치즈</span>
                        <span class="price">1000원</span>
                    </label>
                    <label class="select">
                        <input type="checkbox" class="check">
                        <label></label>
                        <span class="content">감자</span>
                        <span class="price">1000원</span>
                    </label>
                </div>
            </div>
            <div class="count">
                <div class="inner">
                    <div class="text">수량</div>
                    <div class="num">
                        <input type="button" class="minus" value="-">
                        <div class="text">1</div>
                        <input type="button" class="plus" value="+">
                    </div>
                </div>
                <input type="button" class="submit button" value="300원 담기" onclick="infosubmit(form)">
            </div>
        </form>
    </div>
    <footer></footer>
</div>
</body>
</html>

 

info.css

@charset "UTF-8";

.container form{
    width: 100%;
    margin: 0;
    padding: 0;
    margin-bottom: var(--fixedBtn-height);
}
/* 메인 사진 */
.container .menu-image{
    width: 100%;
    height: 250px;
    overflow: hidden;
}

.container .menu-image img{
    width: 100%;
    height: auto;
    object-fit: cover;
    object-position: center top;
}

/* 음식 설명 */
.container .info{
    padding: var(--padding);
    margin: 0;
    display: flex;
    flex-direction: column;
    position: relative;
}

.container .info .title{
    font-size: var(--font-big);
    font-weight: bold;
    margin-bottom: 10px;
    color: var(--black);
}

.container .info .contents{
    font-size: var(--font-small);
    color: var(--light-gray);
}

.container .info .price{
    font-size: var(--font-middle);
    color: var(--black);
    text-align: right;
}
/* 옵션 사용자 버튼 */
.check{
    display: none;
}
/* 라벨의 가상 요소를 이용해 체크박스 스타일링 */
.select .check[type="checkbox"] + label::before {
    content: '\f0c8'; /* Font Awesome의 square 아이콘 */
    font-family: 'Font Awesome 5 Free';
    font-weight: 500;
    color: var(--light-gray);
    font-size: var(--font-middle);
    margin-right: var(--padding);
}

/* 체크된 체크박스의 스타일 */
.select .check[type="checkbox"]:checked + label::before {
    content: '\f14a'; /* Font Awesome의 check-square 아이콘 */
    color: var(--orange);
}

/* 라벨의 가상 요소를 이용해 라디오 버튼 스타일링 */
.select .check[type="radio"] + label::before {
    content: '\f111'; /* Font Awesome의 circle 아이콘 */
    font-family: 'Font Awesome 5 Free';
    font-weight: 500;
    color: var(--light-gray);
    font-size: var(--font-middle);
    margin-right: var(--padding);
}

/* 체크된 라디오 버튼의 스타일 */
.select .check[type="radio"]:checked + label::before {
    content: '\f058'; /* Font Awesome의 check-circle 아이콘 */
    color: var(--orange);
}

/* 옵션 */
.container .option{
    margin: 0;
    display: flex;
    flex-direction: column;
}

/* 옵션 이름 부분 */
.container .option .title{
    padding: var(--padding);
    width: 100%;
    display: flex;
    justify-content: space-between;
    background-color: var(--extra-light-gray);
    color: var(--light-gray);
}

.container .option .title .text{
    padding: 10px;
    color: var(--gray);
}

.container .option .title .select{
    padding: 10px;
    background-color: var(--light-gray);
    color: var(--gray);
}

/* 옵션 내용 선택 부분 */
.container .option .contents{
    padding: var(--padding);
    width: 100%;
    display: flex;
    flex-direction: column;
}

.container .option .contents .select{
    display: flex;
    padding: 10px 0;
}

.container .option .contents .select .content{
    flex: 1;
}

/* 수량 */
.container .count {
    position: fixed;
    left: 50%;
    bottom: 0;
    margin: 0;
    /* 자신의 너비의 반만큼 왼쪽으로 이동하여 정확히 중앙에 위치하도록 조정 */
    transform: translateX(-50%);
    width: var(--innerBox-width);
    background-color: white;
    z-index: 1; /* 필요에 따라 조정 */
    padding: var(--padding);
}
.container .count .inner{
    display: flex;
    justify-content: space-between; /* 내부 요소를 양 끝으로 정렬 */
    width: 100%; /* 부모 컨테이너의 전체 너비 사용 */
    padding: 0 20px; /* 좌우 패딩 추가로 내부 요소들 사이 간격 조정 */
    margin-bottom: 10px;
}
.container .count .inner .text {
    font-size: var(--font-content); /* 필요에 따라 조정 */
    color: var(--black);
    display: flex;
    justify-content: center;
    align-items: center;
}

.container .count .inner .num {
    padding: 5px;
    display: flex;
    justify-content: right;
    border: 2px solid var(--light-gray);
}

.container .count .inner .num .minus,
.container .count .inner .num .plus{
    padding: 0 15px;
    display: flex;
    justify-content: center;
    align-items: center;
    border: 0;
    background-color: var(--white);
    font-size: var(--font-content); /* 버튼 내 텍스트 크기 */
    cursor: pointer; /* 마우스 커서 변경 */
}
.container .count .inner .num .text{
    width: 40px;
    display: flex;
    justify-content: center;
    align-items: center;
    font-size: var(--font-content); /* 필요에 따라 조정 */
}

/* 버튼 */
.container .count .submit{
    width: calc(100% - 20px); /* 패딩 고려하여 너비 조정 */
}

 

info.js

/* form 하기 전에 체크 */

function infosubmit(form) {
    form.submit();
}

// 수량 증감 액션
const minus = document.querySelector('.minus');
const plus = document.querySelector('.plus');
const text = document.querySelector('.count .inner .num .text');

// 수량 증가 함수
function plusNum() {
    let num = parseInt(text.innerHTML);
    if (num < 100) {
        num += 1;
        text.innerHTML = num;
    }
}

// 수량 감소 함수
function minusNum() {
    let num = parseInt(text.innerHTML);
    if (num > 1) {
        num -= 1;
        text.innerHTML = num;
    }
}

// 마이너스 버튼 눌렀을 때
minus.addEventListener('mousedown', e => {
    minusNum(); // 수량 감소
});

// 플러스 버튼 눌렀을 때
plus.addEventListener('mousedown', e => {
    plusNum(); // 수량 증가
});

 

cart.html - 숫자 증감을 개별적으로 구현 메뉴추가 메인 링

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>장바구니</title>
    <link href="/css/style.css" rel="stylesheet">
    <link href="/css/user/cart.css" rel="stylesheet" type="text/css">
    <script src="/js/user/cart.js" type="text/javascript" defer></script>
</head>
<body>
<div class="innerBox">
    <header></header>
    <div class="container">
        <form action="/user/order" method="post">
            <div class="restaurant-name">더조은 식당</div>
            <div class="orders">
                <div class="menu">
                    <div class="text">
                        <div class="title">짜파게티</div>
                        <div class="menu-price">가격 : 5,000원</div>
                        <div class="option">옵션 : 안맵게 해주세요(-3000원)</div>
                        <div class="total-price">3000원</div>
                    </div>
                </div>
                <div class="etc">
                    <div class="image">
                        <img src="/images/sample.png" alt="음식 이미지" class="img">
                    </div>
                    <div class="num">
                        <input type="button" class="minus" value="-">
                        <div class="text">2</div>
                        <input type="button"  class="plus" value="+">
                    </div>
                </div>
            </div>
            <div class="orders">
                <div class="menu">
                    <div class="text">
                        <div class="title">짜파게티2</div>
                        <div class="menu-price">가격 : 4,000원</div>
                        <div class="option">옵션 : 맵게 해주세요(3000원)</div>
                        <div class="total-price">10000원</div>
                    </div>
                </div>
                <div class="etc">
                    <div class="image">
                        <img src="/images/sample.png" alt="음식 이미지" class="img">
                    </div>
                    <div class="num">
                        <input type="button" class="minus" value="-">
                        <div class="text">3</div>
                        <input type="button"  class="plus" value="+">
                    </div>
                </div>
            </div>
            <div class="menu-plus">
                +메뉴추가
            </div>
            <div class="request">
                <label for="contents" class="title">요청사항</label>
                <textarea class="contents" id="contents" name="contents" placeholder="내용을 입력하세요" rows="4"></textarea>
                <input type="button" class="submit button" onclick="cartsubmit(form)" value="3000원 주문하기">
            </div>
        </form>
    </div>
    <footer></footer>
</div>
</body>
</html>

 

cart.css

@charset "UTF-8";

.container form{
    margin: 0;
    width: 100%;
    padding: 0;
}

form>div{
    margin: 0;
    padding: 20px;
}

/* 식당 이름 */
.container form .restaurant-name{
    font-size: var(--font-middle);
    font-weight: bold;
    border-top: 1px solid var(--light-gray);
}

/* 주문 리스트 */
.container form .orders{
    width: 100%;
    display: flex;
    flex-direction: row;
    justify-content: space-between;
    border-top: 1px solid var(--light-gray);
}
.container form .orders .menu{}

.container form .orders .menu .text{
}
.container form .orders .menu .text .title,
.container form .orders .menu .text .total-price{
    font-size: var(--font-content);
    color: var(--black);
    padding-bottom: 10px;
}

.container form .orders .menu .text .menu-price,
.container form .orders .menu .text .option
{
    font-size: var(--font-small);
    color: var(--gray);
    padding-bottom: 10px;
}

.container form .orders .menu .text .total-price{
    padding-top: 10px;
}

.container form .orders .etc{
    display: flex;
    flex-direction: column;
    justify-content: space-between;
}
.container form .orders .etc .image{
    margin-left: auto; /* 오른쪽 정렬 */
    width: 90px;
    height: 90px;
    overflow: hidden;
}

.container form .orders .etc .image img{
    width: 100%;
    height: auto;
}

.container form .orders .etc .num{
    padding: 5px;
    display: flex;
    border: 1px solid var(--light-gray);
}
.container form .orders .etc .num .minus,
.container form .orders .etc .num .plus{
    padding: 0 15px;
    display: flex;
    justify-content: center;
    align-items: center;
    border: 0;
    background-color: var(--white);
    font-size: var(--font-content); /* 버튼 내 텍스트 크기 */
    cursor: pointer; /* 마우스 커서 변경 */
}
.container form .orders .etc .num .text{
    width: 40px;
    display: flex;
    justify-content: center;
    align-items: center;
    font-size: var(--font-content); /* 필요에 따라 조정 */
}

/* 새로운 매뉴 추가 */
.container form .menu-plus{
    background-color: var(--extra-light-gray);
    text-align: center;
    color: var(--gray);
}

/* 요청사항 */
.container form .request{
    
    padding-top: 40px;
}
.container form .request .title{
    font-weight: bold;
}
.container form .request .contents{
    border: 1px solid var(--light-gray);
}
.container form .request .submit{}

 

cart.js

// form 관련
function cartsubmit(form){
    form.submit();
}

// 숫자 증감

const minus = document.querySelectorAll('.minus');
const plus = document.querySelectorAll('.plus');

// 수량 증가 함수
function plusNum(text) {
    let num = parseInt(text.innerHTML);
    if (num < 100) {
        num += 1;
        text.innerHTML = num;
    }
}

// 수량 감소 함수
function minusNum(text) {
    let num = parseInt(text.innerHTML);
    if (num > 1) {
        num -= 1;
        text.innerHTML = num;
    }
}

minus.forEach( e =>{
    e.addEventListener('mousedown', () => {
        // 'text' 요소를 이 버튼과 가장 가까운 상위 요소에서 찾습니다.
        const text = e.closest('.num').querySelector('.text');
        minusNum(text); // 수량 감소
    });
});

plus.forEach( e =>{
    e.addEventListener('mousedown', () => {
        // 'text' 요소를 이 버튼과 가장 가까운 상위 요소에서 찾습니다.
        const text = e.closest('.num').querySelector('.text');
        plusNum(text); // 수량 증가
    });
});


// 메뉴 추가 버튼 클릭 시 메인으로
const menuPlus = document.querySelector(".menu-plus");

menuPlus.addEventListener('click', () =>{
    location.href = '/user/main';
});

 

order.html - 여긴 그냥 스타일 다듬기

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org" xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity5">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <link rel="stylesheet" href="/css/style.css" type="text/css">
    <link rel="stylesheet" href="/css/manager/order.css" type="text/css">
    <script src="/js/manager/order.js" defer type="text/javascript"></script>
</head>
<body>
    <div class="innerBox">
        <header>
            <div>
                <a href=""><i class="fas fa-home"></i></a>
            </div>
            <p>주문관리</p>
            <div>
                <a href="#"></a>
            </div>
        </header>
        <div class="container">
            <ul class="order-state-summary">
                <li class="call">
                    <p class="state-name">호출</p>
                    <p class="state-content"><span>9</span>건</p>
                </li>
                <li class="wait">
                    <p class="state-name">주문</p>
                    <p class="state-content"><span>3</span>건</p>
                </li>
                <li class="okay">
                    <p class="state-name">승인</p>
                    <p class="state-content"><span>1</span>건</p>
                </li>
            </ul>
            <button onclick="location.href='/manager/sales'">총 매출 확인하기 ></button>
            <ul class="list-select">
                <li class="on">전체</li>
                <li>호출</li>
                <li>대기</li>
                <li>승인</li>
            </ul>
            <ul class="order-list">
                <li>
                    <div class="content-summary">
                        <div class="left">
                            <p class="order-title call">호출</p>
                            <p class="order-subtitle">와주세요</p>
                            <span class="table-name">1번 테이블</span>
                        </div>
                        <div class="right">
                            <span class="time">13:00</span>
                        </div>
                    </div>
                </li>
                <li>
                    <div class="content-summary">
                        <div class="left">
                            <p class="order-title wait">주문</p>
                            <span class="table-name">1번 테이블</span>
                        </div>
                        <div class="right">
                            <span class="time">13:00</span>
                            <button><i class="fas fa-chevron-down"></i></button>
                        </div>
                    </div>
                    <table class="info">
                        <tr>
                            <th>상품이름</th>
                            <th>수량</th>
                            <th>금액</th>
                        </tr>
                        <tr>
                            <td>짜파게티</td>
                            <td>2</td>
                            <td>3,000</td>
                        </tr>
                        <tr>
                            <td>토마토 파스타</td>
                            <td>23</td>
                            <td>9,000</td>
                        </tr>
                        <tr>
                            <td>총 합계</td>
                            <td>25</td>
                            <td>267,000</td>
                        </tr>
                    </table>
                </li>
            </ul>
        </div>
    </div>
</body>
</html>

 

order.css

@charset "UTF-8";

.container>div{
    margin: 0;
    padding: 20px;
    border-bottom: 1px solid var(--light-gray);
}

/* 식당 이름 */
.container .restaurant-name{
    width: 100%;
    font-size: var(--font-middle);
    font-weight: bold;
    text-align: left;
}

/* 주문 목록 */
.container .order{
    width: 100%;
    display: flex;
    justify-content: space-between;
}
.container .order .content{}

.container .order .content .title{
    font-size: var(--font-content);
    color: var(--black);
    padding-bottom: 10px;
}
.container .order .content .before-price,
.container .order .content .option{
    font-size: var(--font-small);
    color: var(--gray);
    padding-bottom: 10px;
}

.container .order .content .option{
    padding-bottom: 0;
}
.container .order .after-price{
    display: flex;
    align-items: end;
}

/* 총 금액 */
.container .total-price{
    border-bottom: 0;
    width: 100%;
    display: flex;
    justify-content: space-between;
}
.container .total-price .title{}
.container .total-price .content{}

/* 요청사항 */
.container .request{
    border-bottom: 0;
    width: 100%;
    background-color: var(--extra-light-gray);
}
.container .request .title{
    padding-bottom: 20px;
}
.container .request .content{
    font-size: var(--font-small);
    color: var(--gray);
}
/* 기타? */
.container .etc{
    border-bottom: 0;
    width: 100%;
    padding: 20px;
}
/* 경고 문구 */
.container .etc .warning{
    font-size: var(--font-small);
    color: var(--red);
    padding-bottom: 20px;
    text-align: center;
}

/* 버튼 */
.container .etc .submit{
    width: 100%;
}

 

order.js

없음 나중에 백엔드 구현할때 할듯

 

review.html - 여긴 별 클릭 했을시 값변경과 별 색 변경

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>리뷰작성</title>
    <link href="/css/style.css" rel="stylesheet">
    <link href="/css/user/review.css" rel="stylesheet" type="text/css">
    <script src="/js/user/review.js" type="text/javascript" defer></script>
</head>
<body>
<div class="innerBox">
    <header></header>
    <div class="container">
        <form action="/user/review" method="post">
            <div class="restaurant-name">더조은 식당</div>
            <div class="stars">
                <div class="star-span">
                    <span><i class="fas fa-star"></i></span>
                    <span><i class="fas fa-star"></i></span>
                    <span><i class="fas fa-star"></i></span>
                    <span><i class="fas fa-star"></i></span>
                    <span><i class="fas fa-star"></i></span>
                    <input type="hidden" name="star" id="star" class="star">
                </div>
            </div>
            <div class="nickname">
                <label class="title">닉네임</label>
                <input type="text" class="contents" placeholder="닉네임을 입력해 주세요"></input>
            </div>
            <div class="review">
                <label class="title">리뷰 내용</label>
                <textarea class="contents" cols="3" rows="5"></textarea>
            </div>
            <div class="buttons">
                <input type="button" class="submit button" onclick="reviewCheck(form)" value="리뷰 작성">
            </div>
        </form>
    </div>
    <footer></footer>
</div>

</body>
</html>

 

review.css

@charset "UTF-8";

.container form{
    margin: 0;
    padding: 0;
}

form{
    width: 100%;
}

form>div{
    margin: 0;
    padding: 20px;
}

/* 식당 이름 */
.container form .restaurant-name{
    width: 100%;
    font-size: var(--font-middle);
    font-weight: bold;
    text-align: left;
}

/* 별 */
.container form .stars{
    width: 100%;
    padding: 0 20px;
}

.container form .stars .star-span{
    font-size: var(--font-big);
    color: var(--light-gray);
    cursor: default;
}

.container form .stars .star-span span{
    margin: -2px;
    cursor: pointer;
}

/* 닉네임 */
.container form .nickname{
    width: 100%;
}

.container form .nickname .title{
    margin-bottom: 10px;
}

.container form .nickname .contents{
    border: 1px solid var(--light-gray);
}

/* 리뷰 내용 */
.container form .review{
    width: 100%;
}

.container form .review .title{
    margin-bottom: 10px;
}

.container form .review .contents{
    margin: 0;
    border: 1px solid var(--light-gray);
}

/* 버튼 */
.container form .buttons{
    padding-top: 0;
}
.container form .buttons .submit{
    font-size: var(--font-middle);
}

 

review.js

function reviewCheck(form){
    form.submit();
}

// 별 클릭시 색 변하는 이벤트
const stars = document.querySelectorAll('.star-span span');
const text = document.querySelector('.star-span .star');

stars.forEach( (e, idx) =>{
    e.addEventListener('click', () =>{
        updateStars(idx);
    })
});

// 별을 i 번째 만큼 색 바꿈
function updateStars(idx){
    stars.forEach( (e, i) =>{
        text.value = idx+1;
        if(i <= idx){
            e.style.color = '#FFBE3F';
        }else{
            e.style.color = '#c2c2c2';
        }
    });
}

 

main구현할때 gpt 한테 다 해달래 했더니 너무 복잡해짐 
나머진 최대한 혼자서 해서 수정이 쉬웠는데
편한데 수정이 어렵다는 단점이 있음

'공부 > Ganju' 카테고리의 다른 글

[Spring/AWS] 팀프로젝트 9일차  (0) 2024.04.08
[Spring/AWS] 팀프로젝트 8일차  (0) 2024.04.06
[Spring/AWS] 팀프로젝트 6일차  (0) 2024.04.03
[Spring/AWS] 팀프로젝트 5일차  (0) 2024.04.02
[Spring/AWS] 팀프로젝트 4일차  (0) 2024.04.02

+ Recent posts