Java Web – xây dựng trang bán hàng Ecomus.

A. Giới thiệu

Website Ecomus là một trang bán hàng thời trang như áo, quần, giày phụ kiện nam nữ… Với sứ mệnh mang đến cho khách hàng những bộ trang phục đẹp, chất lượng và phong cách.

Với giao diện bắt mắt, dễ sử dụng và mang lại trải nghiệp tốt cho người dùng.

B. Giao diện

TRANG CHỦ – HOME

Mô tả:

  • Thanh hiện menu
  • Sản phẩm đề xuất
  • Sản phẩm mới
  • Danh mục từng loại sản phẩm
  • Dịch vụ cửa hàng
  • Thông tin cửa hàng
  • Và các dịch vụ khác

Kết quả:

Trang danh mục – Category

Mô tả:

  • Trang danh mục là trang phân loại riêng từng thể loại sản phẩm.
  • Mục đích là để giúp người dùng dễ dàng tìm kiếm danh mục sản phẩm phù hợp với nhu cầu của bản thân.

Kết quả:

<section id="prodetails" class="section-p1" >
    <div class="container">
        <div class="row">
            <div class="col-md-6">
                <div class="single-pro-img">
                    <img src="${pageContext.request.contextPath}/storage/${product.thumbnail}" alt="" id="MainImg" width="85%" style="margin-left: 55px;">
                </div>
            </div>
            <div class="col-md-6">
                <form action="CartServlet" method="post" class="single-pro-details">
                    <div class="tf-product-info-wrap sticky-top">
                        <div class="tf-zoom-main"></div>
                        <div class="tf-product-info-list other-image-zoom">
                            <form action="CartServlet" method="post" class="single-pro-details">
                                <input type="hidden" name="action" value="create">
                                <input type="hidden" name="productId" value="${product.id}">
                                <input type="hidden" name="price" value="${product.price}">
                                <div class="tf-product-info mt-3 d-flex justify-content-between align-items-center">
                                    <div class="tf-product-info-title" style="font-size: 20px;">
                                        <strong style="margin-right: 10px">Name:</strong> ${product.name}</br>
                                        <strong style="margin-right: 10px">Price: $</strong>  ${product.price}
                                    </div> 
                                    <div class="text-center">

                                        <c:if test="${not empty qrCodeImage}">
                                            <img src="data:image/png;base64,${qrCodeImage}" alt="QR Code" class="img-fluid rounded" style="max-width: 75px;" />
                                        </c:if>
                                    </div>
                                </div>

                                <div style="margin-top: -50px; margin-bottom: 10px;">
                                    <strong>Description:</strong>
                                    <p>${product.description}</p>
                                </div>


                                <div class="d-flex align-items-center">
                                    <div class="tf-product-info-quantity me-3">
                                        <div class="quantity-title fw-6">Quantity</div>
                                        <div class="wg-quantity d-flex align-items-center">
                                            <span class="btn-quantity minus-btn">-</span>
                                            <input type="text" name="quantity" value="1" class="form-control mx-2" style="width: 60px;">
                                            <span class="btn-quantity plus-btn">+</span>
                                        </div>
                                    </div>
                                    <div class="tf-product-info-buy-button " style="margin-top: 26px">
                                        <button href="#"
                                                class="tf-btn btn-fill justify-content-center fw-6 fs-16 animate-hover-btn">
                                            <span>Add to cart</span>
                                        </button>
                                    </div>
                                </div>
                            </form>

                            <div class="b1" ">
                                <a href="#" class="btns-full" style="">Buy with <img
                                        src="./assets/images/payments/paypal.png" alt=""></a>
                                <a href="#" class="payment-more-option">More payment options</a>

                            </div>
                            <div class="tf-pickup-availability">
                                <div>
                                    <svg width="18" height="18" viewBox="0 0 18 18" class="mt_3">
                                    <path
                                        d="M7.6 13.2L14.65 6.15L13.25 4.75L7.6 10.4L4.75 7.55L3.35 8.95L7.6 13.2ZM0 18V0H18V18H0ZM2 16H16V2H2V16Z"
                                        fill="#428445"></path>
                                    </svg>
                                </div>
                                <div>
                                    <p>Pickup available at <span class="fw-6">Toronto - Spadina Avenue</span>
                                        Usually ready in 24 hours</p>
                                    <a href="#pickup_available" data-bs-toggle="modal" class="">
                                        Check availability at other stores
                                    </a>
                                </div>
                            </div>
                            <div class="tf-product-info-extra-link">
                                <a href="#compare_color" data-bs-toggle="modal" class="tf-product-extra-icon">
                                    <div class="icon">
                                        <img src="images/item/compare.svg" alt="">
                                    </div>
                                    <div class="text fw-6">Compare color</div>
                                </a>
                                <a href="#ask_question" data-bs-toggle="modal" class="tf-product-extra-icon">
                                    <div class="icon">
                                        <i class="icon-question"></i>
                                    </div>
                                    <div class="text fw-6">Ask a question</div>
                                </a>
                                <a href="#delivery_return" data-bs-toggle="modal" class="tf-product-extra-icon">
                                    <div class="icon">
                                        <svg class="d-inline-block" xmlns="http://www.w3.org/2000/svg"
                                             width="22" height="18" viewBox="0 0 22 18" fill="currentColor">
                                        <path
                                            d="M21.7872 10.4724C21.7872 9.73685 21.5432 9.00864 21.1002 8.4217L18.7221 5.27043C18.2421 4.63481 17.4804 4.25532 16.684 4.25532H14.9787V2.54885C14.9787 1.14111 13.8334 0 12.4255 0H9.95745V1.69779H12.4255C12.8948 1.69779 13.2766 2.07962 13.2766 2.54885V14.5957H8.15145C7.80021 13.6052 6.85421 12.8936 5.74468 12.8936C4.63515 12.8936 3.68915 13.6052 3.33792 14.5957H2.55319C2.08396 14.5957 1.70213 14.2139 1.70213 13.7447V2.54885C1.70213 2.07962 2.08396 1.69779 2.55319 1.69779H9.95745V0H2.55319C1.14528 0 0 1.14111 0 2.54885V13.7447C0 15.1526 1.14528 16.2979 2.55319 16.2979H3.33792C3.68915 17.2884 4.63515 18 5.74468 18C6.85421 18 7.80021 17.2884 8.15145 16.2979H13.423C13.7742 17.2884 14.7202 18 15.8297 18C16.9393 18 17.8853 17.2884 18.2365 16.2979H21.7872V10.4724ZM16.684 5.95745C16.9494 5.95745 17.2034 6.08396 17.3634 6.29574L19.5166 9.14894H14.9787V5.95745H16.684ZM5.74468 16.2979C5.27545 16.2979 4.89362 15.916 4.89362 15.4468C4.89362 14.9776 5.27545 14.5957 5.74468 14.5957C6.21392 14.5957 6.59575 14.9776 6.59575 15.4468C6.59575 15.916 6.21392 16.2979 5.74468 16.2979ZM15.8298 16.2979C15.3606 16.2979 14.9787 15.916 14.9787 15.4468C14.9787 14.9776 15.3606 14.5957 15.8298 14.5957C16.299 14.5957 16.6809 14.9776 16.6809 15.4468C16.6809 15.916 16.299 16.2979 15.8298 16.2979ZM18.2366 14.5957C17.8853 13.6052 16.9393 12.8936 15.8298 12.8936C15.5398 12.8935 15.252 12.943 14.9787 13.04V10.8511H20.0851V14.5957H18.2366Z">
                                        </path>
                                        </svg>
                                    </div>
                                    <div class="text fw-6">Delivery & Return</div>
                                </a>
                                <a href="#share_social" data-bs-toggle="modal" class="tf-product-extra-icon">
                                    <div class="icon">
                                        <i class="icon-share"></i>
                                    </div>
                                    <div class="text fw-6">Share</div>
                                </a>
                            </div>
                            <div class="tf-product-info-delivery-return">
                                <div class="row">
                                    <div class="col-xl-6 col-12">
                                        <div class="tf-product-delivery">
                                            <div class="icon">
                                                <i class="icon-delivery-time"></i>
                                            </div>
                                            <p>Estimate delivery times: <span class="fw-7">12-26 days</span>
                                                (International), <span class="fw-7">3-6 days</span> (United
                                                States).</p>
                                        </div>
                                    </div>
                                    <div class="col-xl-6 col-12">
                                        <div class="tf-product-delivery mb-0">
                                            <div class="icon">
                                                <i class="icon-return-order"></i>
                                            </div>
                                            <p>Return within <span class="fw-7">30 days</span> of purchase.
                                                Duties & taxes are non-refundable.</p>
                                        </div>
                                    </div>
                                </div>
                                <div class="tf-product-info-trust-seal mt-4">
                                    <div class="tf-product-trust-mess">
                                        <i class="icon-safe"></i>
                                        <p class="fw-6">Guarantee Safe <br> Checkout</p>
                                    </div>
                                    <div class="tf-payment">
                                        <img src="./assets/images/payments/visa.png" alt="">
                                        <img src="./assets/images/payments/img-1.png" alt="">
                                        <img src="./assets/images/payments/img-2.png" alt="">
                                        <img src="./assets/images/payments/img-3.png" alt="">
                                        <img src="./assets/images/payments/img-4.png" alt="">
                                    </div>
                                </div>
                            </div>
                        </div>
                    </div>
                </form>
            </div>
        </div>
    </div>
</section>

Kết quả:

Trang chi tiết sản phẩm – Detail

Mô tả:

  • Trang chi tiết sản phẩm dùng để hiển thị thông tin chi tiết của sản phẩm đó.
  • Có thể hiển thị tên, giá, mô tả, mã QR của sản phẩm.
  • Thêm vào giỏ hàng.
<section id="prodetails" class="section-p1" >
    <div class="container">
        <div class="row">
            <div class="col-md-6">
                <div class="single-pro-img">
                    <img src="${pageContext.request.contextPath}/storage/${product.thumbnail}" alt="" id="MainImg" width="85%" style="margin-left: 55px;">
                </div>
            </div>
            <div class="col-md-6">
                <form action="CartServlet" method="post" class="single-pro-details">
                    <div class="tf-product-info-wrap sticky-top">
                        <div class="tf-zoom-main"></div>
                        <div class="tf-product-info-list other-image-zoom">
                            <form action="CartServlet" method="post" class="single-pro-details">
                                <input type="hidden" name="action" value="create">
                                <input type="hidden" name="productId" value="${product.id}">
                                <input type="hidden" name="price" value="${product.price}">
                                <div class="tf-product-info mt-3 d-flex justify-content-between align-items-center">
                                    <div class="tf-product-info-title" style="font-size: 20px;">
                                        <strong style="margin-right: 10px">Name:</strong> ${product.name}</br>
                                        <strong style="margin-right: 10px">Price: $</strong>  ${product.price}
                                    </div> 
                                    <div class="text-center">

                                        <c:if test="${not empty qrCodeImage}">
                                            <img src="data:image/png;base64,${qrCodeImage}" alt="QR Code" class="img-fluid rounded" style="max-width: 75px;" />
                                        </c:if>
                                    </div>
                                </div>

                                <div style="margin-top: -50px; margin-bottom: 10px;">
                                    <strong>Description:</strong>
                                    <p>${product.description}</p>
                                </div>


                                <div class="d-flex align-items-center">
                                    <div class="tf-product-info-quantity me-3">
                                        <div class="quantity-title fw-6">Quantity</div>
                                        <div class="wg-quantity d-flex align-items-center">
                                            <span class="btn-quantity minus-btn">-</span>
                                            <input type="text" name="quantity" value="1" class="form-control mx-2" style="width: 60px;">
                                            <span class="btn-quantity plus-btn">+</span>
                                        </div>
                                    </div>
                                    <div class="tf-product-info-buy-button " style="margin-top: 26px">
                                        <button href="#"
                                                class="tf-btn btn-fill justify-content-center fw-6 fs-16 animate-hover-btn">
                                            <span>Add to cart</span>
                                        </button>
                                    </div>
                                </div>
                            </form>

                            <div class="b1" ">
                                <a href="#" class="btns-full" style="">Buy with <img
                                        src="./assets/images/payments/paypal.png" alt=""></a>
                                <a href="#" class="payment-more-option">More payment options</a>

                            </div>
                            <div class="tf-pickup-availability">
                                <div>
                                    <svg width="18" height="18" viewBox="0 0 18 18" class="mt_3">
                                    <path
                                        d="M7.6 13.2L14.65 6.15L13.25 4.75L7.6 10.4L4.75 7.55L3.35 8.95L7.6 13.2ZM0 18V0H18V18H0ZM2 16H16V2H2V16Z"
                                        fill="#428445"></path>
                                    </svg>
                                </div>
                                <div>
                                    <p>Pickup available at <span class="fw-6">Toronto - Spadina Avenue</span>
                                        Usually ready in 24 hours</p>
                                    <a href="#pickup_available" data-bs-toggle="modal" class="">
                                        Check availability at other stores
                                    </a>
                                </div>
                            </div>
                            <div class="tf-product-info-extra-link">
                                <a href="#compare_color" data-bs-toggle="modal" class="tf-product-extra-icon">
                                    <div class="icon">
                                        <img src="images/item/compare.svg" alt="">
                                    </div>
                                    <div class="text fw-6">Compare color</div>
                                </a>
                                <a href="#ask_question" data-bs-toggle="modal" class="tf-product-extra-icon">
                                    <div class="icon">
                                        <i class="icon-question"></i>
                                    </div>
                                    <div class="text fw-6">Ask a question</div>
                                </a>
                                <a href="#delivery_return" data-bs-toggle="modal" class="tf-product-extra-icon">
                                    <div class="icon">
                                        <svg class="d-inline-block" xmlns="http://www.w3.org/2000/svg"
                                             width="22" height="18" viewBox="0 0 22 18" fill="currentColor">
                                        <path
                                            d="M21.7872 10.4724C21.7872 9.73685 21.5432 9.00864 21.1002 8.4217L18.7221 5.27043C18.2421 4.63481 17.4804 4.25532 16.684 4.25532H14.9787V2.54885C14.9787 1.14111 13.8334 0 12.4255 0H9.95745V1.69779H12.4255C12.8948 1.69779 13.2766 2.07962 13.2766 2.54885V14.5957H8.15145C7.80021 13.6052 6.85421 12.8936 5.74468 12.8936C4.63515 12.8936 3.68915 13.6052 3.33792 14.5957H2.55319C2.08396 14.5957 1.70213 14.2139 1.70213 13.7447V2.54885C1.70213 2.07962 2.08396 1.69779 2.55319 1.69779H9.95745V0H2.55319C1.14528 0 0 1.14111 0 2.54885V13.7447C0 15.1526 1.14528 16.2979 2.55319 16.2979H3.33792C3.68915 17.2884 4.63515 18 5.74468 18C6.85421 18 7.80021 17.2884 8.15145 16.2979H13.423C13.7742 17.2884 14.7202 18 15.8297 18C16.9393 18 17.8853 17.2884 18.2365 16.2979H21.7872V10.4724ZM16.684 5.95745C16.9494 5.95745 17.2034 6.08396 17.3634 6.29574L19.5166 9.14894H14.9787V5.95745H16.684ZM5.74468 16.2979C5.27545 16.2979 4.89362 15.916 4.89362 15.4468C4.89362 14.9776 5.27545 14.5957 5.74468 14.5957C6.21392 14.5957 6.59575 14.9776 6.59575 15.4468C6.59575 15.916 6.21392 16.2979 5.74468 16.2979ZM15.8298 16.2979C15.3606 16.2979 14.9787 15.916 14.9787 15.4468C14.9787 14.9776 15.3606 14.5957 15.8298 14.5957C16.299 14.5957 16.6809 14.9776 16.6809 15.4468C16.6809 15.916 16.299 16.2979 15.8298 16.2979ZM18.2366 14.5957C17.8853 13.6052 16.9393 12.8936 15.8298 12.8936C15.5398 12.8935 15.252 12.943 14.9787 13.04V10.8511H20.0851V14.5957H18.2366Z">
                                        </path>
                                        </svg>
                                    </div>
                                    <div class="text fw-6">Delivery & Return</div>
                                </a>
                                <a href="#share_social" data-bs-toggle="modal" class="tf-product-extra-icon">
                                    <div class="icon">
                                        <i class="icon-share"></i>
                                    </div>
                                    <div class="text fw-6">Share</div>
                                </a>
                            </div>
                            <div class="tf-product-info-delivery-return">
                                <div class="row">
                                    <div class="col-xl-6 col-12">
                                        <div class="tf-product-delivery">
                                            <div class="icon">
                                                <i class="icon-delivery-time"></i>
                                            </div>
                                            <p>Estimate delivery times: <span class="fw-7">12-26 days</span>
                                                (International), <span class="fw-7">3-6 days</span> (United
                                                States).</p>
                                        </div>
                                    </div>
                                    <div class="col-xl-6 col-12">
                                        <div class="tf-product-delivery mb-0">
                                            <div class="icon">
                                                <i class="icon-return-order"></i>
                                            </div>
                                            <p>Return within <span class="fw-7">30 days</span> of purchase.
                                                Duties & taxes are non-refundable.</p>
                                        </div>
                                    </div>
                                </div>
                                <div class="tf-product-info-trust-seal mt-4">
                                    <div class="tf-product-trust-mess">
                                        <i class="icon-safe"></i>
                                        <p class="fw-6">Guarantee Safe <br> Checkout</p>
                                    </div>
                                    <div class="tf-payment">
                                        <img src="./assets/images/payments/visa.png" alt="">
                                        <img src="./assets/images/payments/img-1.png" alt="">
                                        <img src="./assets/images/payments/img-2.png" alt="">
                                        <img src="./assets/images/payments/img-3.png" alt="">
                                        <img src="./assets/images/payments/img-4.png" alt="">
                                    </div>
                                </div>
                            </div>
                        </div>
                    </div>
                </form>
            </div>
        </div>
    </div>
</section>

Kết quả:

Trang tìm kiếm – Search

Mô tả:

  • Giúp người dùng có thể nhanh chóng tìm kiếm các sản phẩm.
  <div class="grid-layout wrapper-shop" data-grid="grid-4">
            <!-- Loop through product list -->
            <c:forEach items="${productList}" var="product">
                <div class="card-product">
                    <div class="card-product-wrapper">
                        <a href="ProductServlet?productId=${product.id}" class="product-img">
                            <img class="lazyload img-product" data-src="${pageContext.request.contextPath}/storage/${product.thumbnail}" src="${pageContext.request.contextPath}/storage/${product.thumbnail}" alt="product image" 
                                 style="height: 500px; object-fit: cover; width: 100%;">
                            <img class="lazyload img-hover" data-src="${pageContext.request.contextPath}/storage/${product.thumbnail}" src="${pageContext.request.contextPath}/storage/${product.thumbnail} " alt="product image hover" 
                                 style="height: 500px; object-fit: cover; width: 100%;">
                        </a>
                        <div class="list-product-btn">
                            <a href="#quick_view" data-bs-toggle="modal" class="box-icon bg_white quickview tf-btn-loading">
                                <span class="icon icon-view"></span>
                                <span class="tooltip">Quick View</span>
                            </a>
                        </div>
                    </div>
                    <div class="card-product-info">
                        <div class="d-flex justify-content-between align-items-center">
                            <a href="ProductServlet?productId=${product.id}" class="title link ms-3">${product.name}</a>
                            <span class="price me-3">Price: $${product.price}</span>
                        </div>
                        <div class="d-block text-center">
                            <span class="text-truncate d-inline-block" style="max-width: 200px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;">
                                ${product.description}
                            </span>
                        </div>
                    </div>
                </div>
            </c:forEach>
        </div>

Kết quả:

Trang About

Mô tả:

  • Giới thiệu về cửa hàng

Kết quả:

Trang liên hệ – Contact

Mô tả:

  • Thông tin chi tiết về địa điểm.
  • Thông tin về quản lý và gửi yêu cầu hỗ trợ.

Kết quả:

Trang giỏ hàng – Cart

Mô tả:

  • Danh mục các sản phẩm đã thêm vào.
  • Chi tiết số tiền cần thanh toán.
  • Thêm, sữa, xoá sản phẩm có trong giỏ hàng.
  • Hiển thị mã QR thanh toán.
   <section class="flat-spacing-11">
            <div class="container">
                <c:if test="${message != null}">
                    <div class="alert alert-success" role="alert">
                        ${message}
                    </div>
                    <c:remove var="error" scope="session"/>
                </c:if>

                <div class="tf-cart-countdown">
                    <div class="title-left">
                        <svg class="d-inline-block" xmlns="http://www.w3.org/2000/svg" width="16" height="24" viewBox="0 0 16 24" fill="rgb(219 18 21)">
                            <path fill-rule="evenodd" clip-rule="evenodd" d="M10.0899 24C11.3119 22.1928 11.4245 20.2409 10.4277 18.1443C10.1505 19.2691 9.64344 19.9518 8.90645 20.1924C9.59084 18.2379 9.01896 16.1263 7.19079 13.8576C7.15133 16.2007 6.58824 17.9076 5.50148 18.9782C4.00436 20.4517 4.02197 22.1146 5.55428 23.9669C-0.806588 20.5819 -1.70399 16.0418 2.86196 10.347C3.14516 11.7228 3.83141 12.5674 4.92082 12.8809C3.73335 7.84186 4.98274 3.54821 8.66895 0C8.6916 7.87426 11.1062 8.57414 14.1592 12.089C17.4554 16.3071 15.5184 21.1748 10.0899 24Z"></path>
                        </svg>
                        <p>These products are limited, checkout within </p>
                    </div>
                    <div class="js-countdown timer-count" data-timer="600" data-labels="d:,h:,m:,s"></div>
                </div>
                <div class="tf-page-cart-wrap">
                    <div class="tf-page-cart-item">
                        <c:forEach items="${cart}" var="orderItem">
                            <table class="tf-table-page-cart">
                                <thead>
                                    <tr>
                                        <th>Product</th>
                                        <th>Price</th>
                                        <th>Quantity</th>
                                        <th>Total</th>
                                    </tr>
                                </thead>
                                <tbody>
                                    <tr class="tf-cart-item file-delete">
                                        <td class="tf-cart-item_product">
                                            <form action="CartServlet" method="post" style="display:inline;">
                                                <input type="hidden" name="action" value="delete">
                                                    <input type="hidden" name="productId" value="${orderItem.productId}">
                                                        <button type="submit" class="fa-regular fa-circle-xmark" style="border: solid white"></button>
                                                        </form>
                                                        <a href="" class="img-box">
                                                            <img src="${pageContext.request.contextPath}/storage/${orderItem.product.thumbnail}" alt="img-product">
                                                        </a>

                                                        <div class="cart-info">
                                                            <a href="" class="cart-title link">${orderItem.product.name}</a>
                                                            <div class="cart-meta-variant">${orderItem.product.description}</div>
                                                            <form action="CartServlet" method="post" style="display:inline;">
                                                                <input type="hidden" name="action" value="delete">
                                                                    <input type="hidden" name="productId" value="${orderItem.productId}">
                                                                        <button type="submit" class="remove-cart link" style="border: none; background: none; cursor: pointer;">
                                                                            <span class="fa-regular fa-circle-xmark">Remove</span>
                                                                        </button>
                                                                        </form>
                                                                        </div>

                                                                        </td>
                                                                        <td class="tf-cart-item_price" cart-data-title="Price">
                                                                            <div class="cart-price">$${orderItem.product.price}</div>
                                                                        </td>
                                                                        <td class="tf-cart-item_quantity d-flex justify-content-center">
                                                                            <form action="CartServlet" method="post">
                                                                                <input type="hidden" name="action" value="update">
                                                                                    <input type="hidden" name="productId" value="${orderItem.productId}">
                                                                                        <input name="quantity" onChange="this.form.submit()" type="number" min="1" value="${orderItem.quantity}" style="width: 50%;">
                                                                                            </form>
                                                                                            </td>
                                                                                            <td class="tf-cart-item_total" cart-data-title="Total">
                                                                                                <div class="cart-total">$${orderItem.price * orderItem.quantity}</div>
                                                                                            </td>
                                                                                            </tr>
                                </tbody>
                            </table>
                        </c:forEach>
                    </div>
                    <div class="tf-page-cart-footer">
                        <div class="tf-cart-footer-inner">
                            <div class="tf-free-shipping-bar">
                                <div class="tf-progress-bar">
                                    <span style="width: 50%;">
                                        <div class="progress-car">
                                            <svg xmlns="http://www.w3.org/2000/svg" width="21" height="14" viewBox="0 0 21 14" fill="currentColor">
                                                <path fill-rule="evenodd" clip-rule="evenodd" d="M0 0.875C0 0.391751 0.391751 0 0.875 0H13.5625C14.0457 0 14.4375 0.391751 14.4375 0.875V3.0625H17.3125C17.5867 3.0625 17.845 3.19101 18.0104 3.40969L20.8229 7.12844C20.9378 7.2804 21 7.46572 21 7.65625V11.375C21 11.8582 20.6082 12.25 20.125 12.25H17.7881C17.4278 13.2695 16.4554 14 15.3125 14C14.1696 14 13.1972 13.2695 12.8369 12.25H7.72563C7.36527 13.2695 6.39293 14 5.25 14C4.10706 14 3.13473 13.2695 2.77437 12.25H0.875C0.391751 12.25 0 11.8582 0 11.375V0.875ZM2.77437 10.5C3.13473 9.48047 4.10706 8.75 5.25 8.75C6.39293 8.75 7.36527 9.48046 7.72563 10.5H12.6875V1.75H1.75V10.5H2.77437ZM14.4375 8.89937V4.8125H16.8772L19.25 7.94987V10.5H17.7881C17.4278 9.48046 16.4554 8.75 15.3125 8.75C15.0057 8.75 14.7112 8.80264 14.4375 8.89937ZM5.25 10.5C4.76676 10.5 4.375 10.8918 4.375 11.375C4.375 11.8582 4.76676 12.25 5.25 12.25C5.73323 12.25 6.125 11.8582 6.125 11.375C6.125 10.8918 5.73323 10.5 5.25 10.5ZM15.3125 10.5C14.8293 10.5 14.4375 10.8918 14.4375 11.375C14.4375 11.8582 14.8293 12.25 15.3125 12.25C15.7957 12.25 16.1875 11.8582 16.1875 11.375C16.1875 10.8918 15.7957 10.5 15.3125 10.5Z"></path>
                                            </svg>
                                        </div>
                                    </span>
                                </div>
                                <div class="tf-progress-msg">
                                    Buy <span class="price fw-6">$75.00</span> more to enjoy <span class="fw-6">Free Shipping</span>
                                </div>
                            </div>
                            <div class="tf-page-cart-checkout">
                                <div class="shipping-calculator">
                                    <summary class="accordion-shipping-header d-flex justify-content-between align-items-center collapsed" data-bs-target="#shipping" data-bs-toggle="collapse" aria-controls="shipping">
                                        <h3 class="shipping-calculator-title">Estimate Shipping</h3>
                                        <span class="shipping-calculator_accordion-icon"></span>
                                    </summary>

                                </div>
                                <div class="cart-checkbox">
                                    <input type="checkbox" class="tf-check" id="cart-gift-checkbox">
                                        <label for="cart-gift-checkbox" class="fw-4">
                                            <span>Do you want a gift wrap?</span> Only <span class="fw-5">$5.00</span>
                                        </label>
                                </div>
                                <div class="tf-cart-totals-discounts">
                                    <h3>Subtotal</h3>
                                    <span class="total-value">${total} USD</span>
                                </div>
                                <p class="tf-cart-tax">
                                    Taxes and <a href="shipping-delivery.html">shipping</a>  calculated at checkout
                                </p>
                                <div class="cart-checkbox">
                                    <input type="checkbox" class="tf-check" id="check-agree">
                                        <label for="check-agree" class="fw-4">
                                            I agree with the <a href="terms-conditions.html">terms and conditions</a>
                                        </label>
                                </div>
                                <c:if test="${not empty sessionScope.qrCodeImage}">
                                    <h3 style="font-size: 20px; color: rgb(0, 0, 0);">Payment QR Code</h3>
                                    <div class="d-flex justify-content-center">
                                        <img src="data:image/png;base64,${sessionScope.qrCodeImage}" alt="QR Code" class="qr-code" style="width: 100px; height: 100px" />
                                    </div>
                                </c:if>
                                <div class="cart-checkout-btn">
                                    <a href="CheckoutServlet" style="width: 100%;">
                                        <button class="tf-btn w-100 btn-fill animate-hover-btn radius-3 justify-content-center">
                                            <span>Check out</span>
                                        </button>
                                    </a>
                                </div>
                                <div class="tf-page-cart_imgtrust">
                                    <p class="text-center fw-6">Guarantee Safe Checkout</p>
                                    <div class="cart-list-social">
                                        <div class="payment-item">
                                            <svg viewBox="0 0 38 24" xmlns="http://www.w3.org/2000/svg" role="img" width="38" height="24" aria-labelledby="pi-visa"><title id="pi-visa">Visa</title><path opacity=".07" d="M35 0H3C1.3 0 0 1.3 0 3v18c0 1.7 1.4 3 3 3h32c1.7 0 3-1.3 3-3V3c0-1.7-1.4-3-3-3z"></path><path fill="#fff" d="M35 1c1.1 0 2 .9 2 2v18c0 1.1-.9 2-2 2H3c-1.1 0-2-.9-2-2V3c0-1.1.9-2 2-2h32"></path><path d="M28.3 10.1H28c-.4 1-.7 1.5-1 3h1.9c-.3-1.5-.3-2.2-.6-3zm2.9 5.9h-1.7c-.1 0-.1 0-.2-.1l-.2-.9-.1-.2h-2.4c-.1 0-.2 0-.2.2l-.3.9c0 .1-.1.1-.1.1h-2.1l.2-.5L27 8.7c0-.5.3-.7.8-.7h1.5c.1 0 .2 0 .2.2l1.4 6.5c.1.4.2.7.2 1.1.1.1.1.1.1.2zm-13.4-.3l.4-1.8c.1 0 .2.1.2.1.7.3 1.4.5 2.1.4.2 0 .5-.1.7-.2.5-.2.5-.7.1-1.1-.2-.2-.5-.3-.8-.5-.4-.2-.8-.4-1.1-.7-1.2-1-.8-2.4-.1-3.1.6-.4.9-.8 1.7-.8 1.2 0 2.5 0 3.1.2h.1c-.1.6-.2 1.1-.4 1.7-.5-.2-1-.4-1.5-.4-.3 0-.6 0-.9.1-.2 0-.3.1-.4.2-.2.2-.2.5 0 .7l.5.4c.4.2.8.4 1.1.6.5.3 1 .8 1.1 1.4.2.9-.1 1.7-.9 2.3-.5.4-.7.6-1.4.6-1.4 0-2.5.1-3.4-.2-.1.2-.1.2-.2.1zm-3.5.3c.1-.7.1-.7.2-1 .5-2.2 1-4.5 1.4-6.7.1-.2.1-.3.3-.3H18c-.2 1.2-.4 2.1-.7 3.2-.3 1.5-.6 3-1 4.5 0 .2-.1.2-.3.2M5 8.2c0-.1.2-.2.3-.2h3.4c.5 0 .9.3 1 .8l.9 4.4c0 .1 0 .1.1.2 0-.1.1-.1.1-.1l2.1-5.1c-.1-.1 0-.2.1-.2h2.1c0 .1 0 .1-.1.2l-3.1 7.3c-.1.2-.1.3-.2.4-.1.1-.3 0-.5 0H9.7c-.1 0-.2 0-.2-.2L7.9 9.5c-.2-.2-.5-.5-.9-.6-.6-.3-1.7-.5-1.9-.5L5 8.2z" fill="#142688"></path></svg>
                                        </div>
                                        <div class="payment-item">
                                            <svg viewBox="0 0 38 24" xmlns="http://www.w3.org/2000/svg" width="38" height="24" role="img" aria-labelledby="pi-paypal"><title id="pi-paypal">PayPal</title><path opacity=".07" d="M35 0H3C1.3 0 0 1.3 0 3v18c0 1.7 1.4 3 3 3h32c1.7 0 3-1.3 3-3V3c0-1.7-1.4-3-3-3z"></path><path fill="#fff" d="M35 1c1.1 0 2 .9 2 2v18c0 1.1-.9 2-2 2H3c-1.1 0-2-.9-2-2V3c0-1.1.9-2 2-2h32"></path><path fill="#003087" d="M23.9 8.3c.2-1 0-1.7-.6-2.3-.6-.7-1.7-1-3.1-1h-4.1c-.3 0-.5.2-.6.5L14 15.6c0 .2.1.4.3.4H17l.4-3.4 1.8-2.2 4.7-2.1z"></path><path fill="#3086C8" d="M23.9 8.3l-.2.2c-.5 2.8-2.2 3.8-4.6 3.8H18c-.3 0-.5.2-.6.5l-.6 3.9-.2 1c0 .2.1.4.3.4H19c.3 0 .5-.2.5-.4v-.1l.4-2.4v-.1c0-.2.3-.4.5-.4h.3c2.1 0 3.7-.8 4.1-3.2.2-1 .1-1.8-.4-2.4-.1-.5-.3-.7-.5-.8z"></path><path fill="#012169" d="M23.3 8.1c-.1-.1-.2-.1-.3-.1-.1 0-.2 0-.3-.1-.3-.1-.7-.1-1.1-.1h-3c-.1 0-.2 0-.2.1-.2.1-.3.2-.3.4l-.7 4.4v.1c0-.3.3-.5.6-.5h1.3c2.5 0 4.1-1 4.6-3.8v-.2c-.1-.1-.3-.2-.5-.2h-.1z"></path></svg>
                                        </div>
                                        <div class="payment-item">
                                            <svg viewBox="0 0 38 24" xmlns="http://www.w3.org/2000/svg" role="img" width="38" height="24" aria-labelledby="pi-master"><title id="pi-master">Mastercard</title><path opacity=".07" d="M35 0H3C1.3 0 0 1.3 0 3v18c0 1.7 1.4 3 3 3h32c1.7 0 3-1.3 3-3V3c0-1.7-1.4-3-3-3z"></path><path fill="#fff" d="M35 1c1.1 0 2 .9 2 2v18c0 1.1-.9 2-2 2H3c-1.1 0-2-.9-2-2V3c0-1.1.9-2 2-2h32"></path><circle fill="#EB001B" cx="15" cy="12" r="7"></circle><circle fill="#F79E1B" cx="23" cy="12" r="7"></circle><path fill="#FF5F00" d="M22 12c0-2.4-1.2-4.5-3-5.7-1.8 1.3-3 3.4-3 5.7s1.2 4.5 3 5.7c1.8-1.2 3-3.3 3-5.7z"></path></svg>
                                        </div>
                                        <div class="payment-item">
                                            <svg xmlns="http://www.w3.org/2000/svg" role="img" aria-labelledby="pi-american_express" viewBox="0 0 38 24" width="38" height="24"><title id="pi-american_express">American Express</title><path fill="#000" d="M35 0H3C1.3 0 0 1.3 0 3v18c0 1.7 1.4 3 3 3h32c1.7 0 3-1.3 3-3V3c0-1.7-1.4-3-3-3Z" opacity=".07"></path><path fill="#006FCF" d="M35 1c1.1 0 2 .9 2 2v18c0 1.1-.9 2-2 2H3c-1.1 0-2-.9-2-2V3c0-1.1.9-2 2-2h32Z"></path><path fill="#FFF" d="M22.012 19.936v-8.421L37 11.528v2.326l-1.732 1.852L37 17.573v2.375h-2.766l-1.47-1.622-1.46 1.628-9.292-.02Z"></path><path fill="#006FCF" d="M23.013 19.012v-6.57h5.572v1.513h-3.768v1.028h3.678v1.488h-3.678v1.01h3.768v1.531h-5.572Z"></path><path fill="#006FCF" d="m28.557 19.012 3.083-3.289-3.083-3.282h2.386l1.884 2.083 1.89-2.082H37v.051l-3.017 3.23L37 18.92v.093h-2.307l-1.917-2.103-1.898 2.104h-2.321Z"></path><path fill="#FFF" d="M22.71 4.04h3.614l1.269 2.881V4.04h4.46l.77 2.159.771-2.159H37v8.421H19l3.71-8.421Z"></path><path fill="#006FCF" d="m23.395 4.955-2.916 6.566h2l.55-1.315h2.98l.55 1.315h2.05l-2.904-6.566h-2.31Zm.25 3.777.875-2.09.873 2.09h-1.748Z"></path><path fill="#006FCF" d="M28.581 11.52V4.953l2.811.01L32.84 9l1.456-4.046H37v6.565l-1.74.016v-4.51l-1.644 4.494h-1.59L30.35 7.01v4.51h-1.768Z"></path></svg>
                                        </div>
                                        <div class="payment-item">
                                            <svg xmlns="http://www.w3.org/2000/svg" role="img" viewBox="0 0 38 24" width="38" height="24" aria-labelledby="pi-amazon"><title id="pi-amazon">Amazon</title><path d="M35 0H3C1.3 0 0 1.3 0 3v18c0 1.7 1.4 3 3 3h32c1.7 0 3-1.3 3-3V3c0-1.7-1.4-3-3-3z" fill="#000" fill-rule="nonzero" opacity=".07"></path><path d="M35 1c1.1 0 2 .9 2 2v18c0 1.1-.9 2-2 2H3c-1.1 0-2-.9-2-2V3c0-1.1.9-2 2-2h32" fill="#FFF" fill-rule="nonzero"></path><path d="M25.26 16.23c-1.697 1.48-4.157 2.27-6.275 2.27-2.97 0-5.644-1.3-7.666-3.463-.16-.17-.018-.402.173-.27 2.183 1.504 4.882 2.408 7.67 2.408 1.88 0 3.95-.46 5.85-1.416.288-.145.53.222.248.47v.001zm.706-.957c-.216-.328-1.434-.155-1.98-.078-.167.024-.193-.148-.043-.27.97-.81 2.562-.576 2.748-.305.187.272-.047 2.16-.96 3.063-.14.138-.272.064-.21-.12.205-.604.664-1.96.446-2.29h-.001z" fill="#F90" fill-rule="nonzero"></path><path d="M21.814 15.291c-.574-.498-.676-.73-.993-1.205-.947 1.012-1.618 1.315-2.85 1.315-1.453 0-2.587-.938-2.587-2.818 0-1.467.762-2.467 1.844-2.955.94-.433 2.25-.51 3.25-.628v-.235c0-.43.033-.94-.208-1.31-.212-.333-.616-.47-.97-.47-.66 0-1.25.353-1.392 1.085-.03.163-.144.323-.3.33l-1.677-.187c-.14-.033-.296-.153-.257-.38.386-2.125 2.223-2.766 3.867-2.766.84 0 1.94.234 2.604.9.842.82.762 1.918.762 3.11v2.818c0 .847.335 1.22.65 1.676.113.164.138.36-.003.482-.353.308-.98.88-1.326 1.2a.367.367 0 0 1-.414.038zm-1.659-2.533c.34-.626.323-1.214.323-1.918v-.392c-1.25 0-2.57.28-2.57 1.82 0 .782.386 1.31 1.05 1.31.487 0 .922-.312 1.197-.82z" fill="#221F1F"></path></svg>
                                        </div>
                                    </div>
                                </div>
                            </div>
                        </div>
                    </div>                                                                  
                 </div>
            </div>
</section>

Kết quả:

Trang sản phẩm – Shop

Mô tả:

  • Hiển thị tất cả các phẩm có trong cửa hàng.
  • Chức năng lọc sản phẩm giúp người dùng dễ dàng tìm kiếm sản phẩm theo sở thích.
  <c:forEach items="${productList}" var="product">
                <!-- card product 1 -->
                <div class="card-product">
                    <div class="card-product-wrapper">
                        <a href="ProductServlet?productId=${product.id}" class="product-img">
                            <img class="lazyload img-product" data-src="${pageContext.request.contextPath}/storage/${product.thumbnail}" src="${pageContext.request.contextPath}/storage/${product.thumbnail}" alt="image-product" style="height: 500px; object-fit: cover; width: 100%;">
                            <img class="lazyload img-hover" data-src="${pageContext.request.contextPath}/storage/${product.thumbnail}" src="${pageContext.request.contextPath}/storage/${product.thumbnail}" alt="image-product" style="height: 500px; object-fit: cover; width: 100%;">
                        </a>
                        <div class="list-product-btn">
                            <a href="#quick_view" data-bs-toggle="modal" class="box-icon bg_white quickview tf-btn-loading">
                                <span class="icon icon-view"></span>
                                <span class="tooltip">Quick View</span>
                            </a>
                        </div>
                    </div>
                    <div class="card-product-info">
                        <div class="d-flex justify-content-between align-items-center">
                            <a href="ProductServlet?productId=${product.id}" class="title link ms-3">${product.name}</a>
                            <span class="price me-3">Price: $${product.price}</span>
                        </div>
                        <div class="d-block text-center">
                            <span class="text-truncate d-inline-block" style="max-width: 200px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;">
                                ${product.description}
                            </span>
                        </div>
                    </div>
                </div>
            </c:forEach>

Kết quả:

Trang đăng kí – Register

Mô tả:

  • Thực hiện các vấn đề về tài khoản: Tạo , xác minh tài khoản.
 <section class="flat-spacing-10">
        <div class="container">
            <div class="form-register-wrap">
                <div class="flat-title align-items-start gap-0 mb_30 px-0">
                    <h5 class="mb_18">Register</h5>
                    <p class="text_black-2">Sign up for early Sale access plus tailored new arrivals, trends and promotions. To opt out, click unsubscribe in our emails</p>
                </div>
                <div>
                    <form class="" id="register-form" action="RegisterServlet" method="post" accept-charset="utf-8" data-mailchimp="true">
                        <div class="tf-field style-1 mb_15">
                            <input class="tf-field-input tf-input" placeholder=" " type="email" id="property3" name="email">
                                <label class="tf-field-label fw-4 text_black-2" for="property3">Email *</label>
                        </div>
                        <div class="tf-field style-1 mb_30">
                            <input class="tf-field-input tf-input" placeholder=" " type="password" id="property4" name="password">
                                <label class="tf-field-label fw-4 text_black-2" for="property4">Password *</label>
                        </div>
                        <div class="mb_20">
                            <button type="submit" class="tf-btn w-100 radius-3 btn-fill animate-hover-btn justify-content-center">Register</button>
                        </div>
                        <div class="text-center">
                            <a href="LoginServlet" class="tf-btn btn-line">Already have an account? Log in here<i class="icon icon-arrow1-top-left"></i></a>
                        </div>
                    </form>
                   
                </div>
            </div>
        </div>
    </section>

Kết quả:

Trang đăng nhập – Login

Mô tả:

  • Thực hiện chức năng đăng nhập người dùng vào cửa hàng.
  <section class="flat-spacing-10">
        <div class="container">
            <div class="tf-grid-layout lg-col-2 tf-login-wrap">
                <div class="tf-login-form">
                    <div id="login">
                        <h5 class="mb_36">Log in</h5>
                        <div>
                            <form class="" id="login-form" action="LoginServlet" method="post" accept-charset="utf-8">
                                <div class="tf-field style-1 mb_15">
                                    <input class="tf-field-input tf-input" placeholder="" type="email" id="property3" name="email">
                                        <label class="tf-field-label fw-4 text_black-2" for="property3">Email *</label>
                                </div>
                                <div class="tf-field style-1 mb_30">
                                    <input class="tf-field-input tf-input" placeholder="" type="password" id="property4" name="password">
                                        <label class="tf-field-label fw-4 text_black-2" for="property4">Password *</label>
                                </div>
                                <div class="tf-field style-1 mb_30">
                                    <div class="d-flex gap-3 w-100">
                                        <a href="https://accounts.google.com/o/oauth2/auth?scope=email profile openid &redirect_uri=http://localhost:8080/Shop/login&response_type=code&client_id=800456180237-bflf1d7cqn8e4latcedb0s3mdlar3ccc.apps.googleusercontent.com&approval_prompt=force" class="btn btn-lg btn-danger d-flex align-items-center justify-content-center w-50">
                                            <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-google" viewBox="0 0 16 16">
                                                <path d="M15.545 6.558a9.42 9.42 0 0 1 .139 1.626c0 2.434-.87 4.492-2.384 5.885h.002C11.978 15.292 10.158 16 8 16A8 8 0 1 1 8 0a7.689 7.689 0 0 1 5.352 2.082l-2.284 2.284A4.347 4.347 0 0 0 8 3.166c-2.087 0-3.86 1.408-4.492 3.304a4.792 4.792 0 0 0 0 3.063h.003c.635 1.893 2.405 3.301 4.492 3.301 1.078 0 2.004-.276 2.722-.764h-.003a3.702 3.702 0 0 0 1.599-2.431H8v-3.08h7.545z" />
                                            </svg>
                                            <span class="ms-2 fs-6">Sign in with Google</span>
                                        </a>
                                        <a href="https://www.facebook.com/v19.0/dialog/oauth?client_id=417133904526343&redirect_uri=http://localhost:8080/Shop/Oauth2FacebookServlet" class="btn btn-lg btn-primary d-flex align-items-center justify-content-center w-50">
                                            <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-facebook" viewBox="0 0 16 16">
                                                <path d="M16 8.049c0-4.446-3.582-8.05-8-8.05C3.58 0-.002 3.603-.002 8.05c0 4.017 2.926 7.347 6.75 7.951v-5.625h-2.03V8.05H6.75V6.275c0-2.017 1.195-3.131 3.022-3.131.876 0 1.791.157 1.791.157v1.98h-1.009c-.993 0-1.303.621-1.303 1.258v1.51h2.218l-.354 2.326H9.25V16c3.824-.604 6.75-3.934 6.75-7.951z" />
                                            </svg>
                                            <span class="ms-2 fs-6">Sign in with Facebook</span>
                                        </a>
                                    </div>
                                </div>
                                <div class="mb_20">
                                    <a href="" class="tf-btn btn-line">Forgot your password?</a>
                                </div>
                                <div class="">
                                    <button type="submit" class="tf-btn w-100 radius-3 btn-fill animate-hover-btn justify-content-center">Log in</button>
                                </div>
                            </form>
                        </div>
                    </div>
                </div>
                <div class="tf-login-content">
                    <h5 class="mb_36">I'm new here</h5>
                    <p class="mb_20">Sign up for early Sale access plus tailored new arrivals, trends and promotions. To opt out, click unsubscribe in our emails.</p>
                    <a href="RegisterServlet" class="tf-btn btn-line">Register<i class="icon icon-arrow1-top-left"></i></a>
                </div>
            </div>
        </div>
    </section>

Kết quả:

Trang Dashboard

Mô tả:

  • Thống kê các thông số cửa hàng.
  • Chức năng thêm sửa xoá danh mục, sản phẩm, người dùng…

Kết quả:

Full sourcecode project:

Github: https://github.com/vietcuong090/JavaWeb.git

Author: Trần Viết Cường.