Hi, "+ user.getFirstName()+ ",
"+ + "You recently requested to reset your password,"+"" + + "Please, follow the link below to complete the action.
"+ + "Reset password"+ + "Users Registration Portal Service"; + emailMessage(subject, senderName, mailContent, user); + } + + public void sendVerificationEmail(User user,String url) throws MessagingException, UnsupportedEncodingException { + String subject = "Verify your account"; + String senderName = "Users Verification Service"; + String mailContent = "
Hi, "+ user.getFirstName()+ ",
"+ + "CLick follow link to verify your account,"+"" + + "Verify account"+ + "
Users Registration Portal Service"; + emailMessage(subject, senderName, mailContent, user); + } + + private void emailMessage(String subject, String senderName, + String mailContent, User theUser) + throws MessagingException, UnsupportedEncodingException { + MimeMessage message = mailSender.createMimeMessage(); + var messageHelper = new MimeMessageHelper(message); + messageHelper.setFrom("hoangquanph0204@gmail.com", senderName); + messageHelper.setTo(theUser.getEmail()); + messageHelper.setSubject(subject); + messageHelper.setText(mailContent, true); + mailSender.send(message); + } +} diff --git a/src/main/java/org/ecommerce/spring/boot/vegetable/project/utility/TokenExpirationTimeCalculus.java b/src/main/java/org/ecommerce/spring/boot/vegetable/project/utility/TokenExpirationTimeCalculus.java new file mode 100644 index 0000000..49ee997 --- /dev/null +++ b/src/main/java/org/ecommerce/spring/boot/vegetable/project/utility/TokenExpirationTimeCalculus.java @@ -0,0 +1,17 @@ +package org.ecommerce.spring.boot.vegetable.project.utility; + +import org.springframework.stereotype.Component; + +import java.util.Calendar; +import java.util.Date; + +public class TokenExpirationTimeCalculus { + private static int EXPIRATION_TIME = 10; + + public static Date getExpirationTime() { + Calendar calendar = Calendar.getInstance(); + calendar.setTimeInMillis(new Date().getTime()); + calendar.add(Calendar.MINUTE, EXPIRATION_TIME); + return new Date(calendar.getTime().getTime()); + } +} diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml new file mode 100644 index 0000000..915d787 --- /dev/null +++ b/src/main/resources/application.yml @@ -0,0 +1,24 @@ + +server: + port: 8080 +spring: + datasource: + url: jdbc:mysql://localhost:3306/vegetable-project + username: root + password: 01229050402a + driver-class-name: com.mysql.cj.jdbc.Driver + jpa: + hibernate: + ddl-auto: update + show-sql: true + mail: + host: smtp.gmail.com + port: 587 + username: hoangquanph0204@gmail.com + password: hspuorvvliiqgbgr + properties: + mail: + smtp: + auth: true + starttls: + enable: true diff --git a/src/main/resources/static/css/footer.css b/src/main/resources/static/css/footer.css new file mode 100644 index 0000000..c4f4dd0 --- /dev/null +++ b/src/main/resources/static/css/footer.css @@ -0,0 +1,57 @@ + +*, ::after, ::before { + box-sizing: border-box; + padding: 0; + margin: 0; +} + +.footer-wrapper { + background-color: rgb(243,246,250); + height: max-content; +} + +.footer-left-icon { + margin-bottom: 20px; +} + +.footer-left-information { + display: block; + font-size: 16px; + line-height: 25px; + margin: 5px 0; + color: #1c1c1c; +} + +.footer-left-contact { + font-weight: bold; + font-size: 16px; +} + +.footer-left-contact-item { + font-size: 22px; + color: black; + padding: 10px 15px; + border-radius: 40px; + background-color: white; + } + +.footer-left-contact-item:hover { + background-color: #7fad39; + color: white; +} + +.footer-right-description { + display: block; + margin: 8px 0 12px 0; + font-size: 13px; + color: #1c1c1c; +} + +.footer-right-email { + width: 120px; +} + +.footer-down-image { + display: flex; + margin-left: auto; +} \ No newline at end of file diff --git a/src/main/resources/static/css/header.css b/src/main/resources/static/css/header.css new file mode 100644 index 0000000..2cd20b9 --- /dev/null +++ b/src/main/resources/static/css/header.css @@ -0,0 +1,128 @@ + +* { + box-sizing: border-box; + padding: 0; + margin: 0; +} + +.header-top { + background-color: rgb(245,245,245); + height: 46px; + font-size: 14px; +} + +.header-top-left, .header-top-right { + margin: 0; + list-style-type: none; + padding: 12px 0 13px; +} + +.header-top-item { + display: inline-block; +} + +.header-top-left__mail { + margin-right: 40px ; +} + +.header-top-left__mail-icon { + margin-right: 3px; +} + +.header-top-left__mail::after, .header-top-item-separate::after { + position: absolute; + top: 12px; + margin: 0 20px; + width: 0.5px; + height: 20px; + background-color: black; + opacity: 0.1; + content: ""; +} + +.header-top-right { + width: max-content; + float: left; +} + +.header-top-right-icon { + color: black; + margin-right: 20px; +} + +.header-top-item-separate { + margin-right: 40px; + color: black; +} + +.header-top-login { + display: inline-block; + color: black; + text-decoration: none; +} + +.login-icon { + margin-right: 2px; +} + +.header-menu-nav { + background-color: white !important; +} + +.header-menu-item-btn { + color: black; + font-size: 14px; + font-weight: bold; + letter-spacing: 1px; +} + +.header-menu-item-btn:hover { + color: #7fad39; +} + +.active { + color: #7fad39; +} + +.header-menu-icon { + color: black; + font-size: 17px; + margin-right: 5px; +} + +.header-user-action, .header-menu-page { + background-color: black; + padding-bottom: 3px; + padding-top: 3px; + display: none; + border-radius: unset; + position: absolute; + box-shadow: 0 0 6px 1px rgba(0, 0, 0, 0.1); + z-index: 1; +} + +.header-top-item:hover .header-user-action { + display: block; +} + +.header-menu-page-wrapper:hover .header-menu-page { + display: block; +} + + +.header-user-action-item { + padding-top: 5px; + padding-bottom: 5px; + border: none; + line-height: 17px; + letter-spacing: 1px; + color: white; + background-color: black; + text-decoration: none; +} + +.header-user-action-item:hover { + color: #7fad39; + background-color: black; +} + diff --git a/src/main/resources/static/css/home.css b/src/main/resources/static/css/home.css new file mode 100644 index 0000000..eb58826 --- /dev/null +++ b/src/main/resources/static/css/home.css @@ -0,0 +1,410 @@ + + +*, ::after, ::before { + box-sizing: border-box; + padding: 0; + margin: 0; +} + +.mh-12 { + margin: 0 12px; +} + + +.search-content { + margin-top: 80px !important; +} + +.search-content-department-wrapper { +} + +.search-content-department { + font-weight: bold; + padding: 10px 30px; + font-size: 18px; + border-radius: unset; + background-color: #7fad39; + color: white; + border: none; +} + +.search-content-department:hover { + background-color: #7fad39; +} + +.search-content-department:visited { + background-color: #7fad39; +} + +.search-content-department:active { + background-color: #7fad39 !important; +} + +.dropdown-toggle::after { + display: inline-block; + margin-left: 20px; + vertical-align: .255em; + content: ""; + border: .3em solid; + border-right-color: transparent; + border-bottom: 0 none; + border-left-color: transparent; +} + +.search-content-dropdown-list { + padding: 10px 30px; + font-size: 16px; + border-radius: unset; + color: white; +} + +.search-content-dropdown-item { + padding: 8px 10px; + width: 202px; + border-bottom: none; + border-top: none; +} + +.search-bar { + height: 48px; +} + +.search-bar-input { + font-size: 14px; + border-radius: unset; + margin-right: 0 !important; + padding-left: 20px; + +} + +.search-bar-input::placeholder { + color: rgba(0, 0, 0, 0.4); + margin-left: 10px; +} + +.search-bar-input:focus { + outline: none !important; +} + +.search-bar-submit { + border-radius: unset; + width: 25%; + background-color: #7fad39; + color: white; + font-weight: bold; + font-size: 14px; + border: none; +} + +.search-bar-submit:hover { + background-color: #7fad39; + color: white; +} + +.phone-wrapper { + height: 48px; + padding-left: 50px; +} + +.phone-icon-wrapper { + content: ""; + padding: 10px 15px; + background-color: rgba(0,0,0,0.04); + border-radius: 50%; +} + +.phone-icon { + color: #7fad39; + font-size: 18px; + height: fit-content; +} + +.phone-number-wrapper { + padding-left: 20px; + font-size: 18px; +} + +.banner-img { + +} + +.banner-text { + position: absolute; + top: 90px; + left: 80px; +} + +.banner-text-category { + letter-spacing: 2px; + color: #7fad39; + line-height: 14px; + font-weight: bold; + font-size: 14px; +} + +.banner-text-title { + font-size: 46px; + font-weight: bold; + margin: 8px 0; +} + +.banner-text-description { + color: rgba(0, 0, 0, 0.5); + font-size: 16px; + margin-bottom: 40px; + display: block; +} + +.banner-text-btn { + padding: 8px 25px; + color: white; + font-weight: bold; + border-radius: unset; + font-size: 14px; + letter-spacing: 1px; + background-color: #7fad39; +} + +.banner-text-btn:hover { + background: #7fad39; + color: white; +} + +.category-bar { + flex-wrap: nowrap; + overflow: scroll; +} + +/* Hide scrollbar for Chrome, Safari and Opera */ +.category-bar::-webkit-scrollbar { + display: none; +} + + +.category-bar { + width: 100%; + display: flex; + overflow-x: auto; /* Use 'auto' to enable scrolling */ + scroll-behavior: smooth; /* Add smooth scrolling behavior */ + white-space: nowrap; + transition: all 0.5s ease-in-out; /* Apply transition effect to all properties */ +} + +.category-wrapper { + height: 270px; + position: relative; +} + +.category-bar-wrapper { + margin-bottom: 60px !important; +} + +.category-item-title-wrapper { + position: absolute; + bottom: 0; + right: 0; + left: 0; + margin: 0 auto; +} + +.category-item-title { + position: absolute; + bottom: 15px; + right: 27px; + left: 0; + margin: 0 auto; + width: fit-content; + background-color: white; + font-size: 18px; + letter-spacing: 1px; + font-weight: bold; + padding: 8px 40px; + text-decoration: unset; + color: black; + transform: translateX(6px); +} + +.category-item-img { + height: 100%; +} + +.category-bar-navigate-wrapper { + position: relative; + z-index: 1; +} + +.category-bar-navigate { + height: max-content; + width: max-content; + position: absolute; + top: 140px; + bottom: 0; + margin: auto 0; + z-index: 1; + padding: 23px 6px; + border: 1px solid rgba(0, 0, 0, 0.1); + background-color: white; +} + +.category-bar-navigate-left { + left: -60px; +} + +.category-bar-navigate-right { + right: -60px; +} + +.featured-product-title { + font-weight: bold; + font-size: 36px; +} + +.featured-product-title:after { + display: block; + height: 4px; + width: 80px; + background: #7fad39; + content: ""; + margin: 5px auto 0; +} + +.feature-product-navigate { + width: max-content; + margin: 0 auto; + margin-bottom: 10px; +} + +.feature-product-navigate-link { + font-size: 18px; + text-decoration: none; + color: black; + display: inline-block; + cursor: pointer; +} + +.choose::after { + content: ""; + display: block; + width: 100%; + height: 2px; + background-color: #7fad39; + margin-top: 2px; +} + +.feature-product-item-wrapper { + +} + +.feature-product-item { + margin-top: 35px; +} + +.feature-product-item-text { + line-height: 18px; + padding-top: 10px; +} + +.feature-product-item-title { + font-size: 16px; + font-weight: unset; + text-decoration: none; + color: black; + padding: 8px 0; +} + +.feature-product-item-img { + max-width: 100%; + height: 260px; +} + +.feature-product-item-cost { + font-size: 18px; + font-weight: bold; +} + +.product-page > .page-link { + color: rgba(0, 0, 0, 0.7); +} + +.active > .page-link { + background-color: #7fad39; + border: #7fad39; + color: white; +} + +.page-link { + cursor: pointer; +} + +.home_banner_wrapper { + height: 262px; +} + +.home_banner { + +} + +.home_banner_image { + width: 100%; + height: 100%; +} + +.blog-item { + +} + +.blog-item-image { + width: 100%; + height: 258px; +} + +.createDate { + +} + +.createDate-icon { + display: inline-block; + font-size: 16px; + color: rgba(0, 0, 0, 0.4); +} + +.createDate-time { + display: inline-block; + font-size: 16px; + color: rgba(0, 0, 0, 0.3); + margin: 3px 0 0 0; +} + +.blog-item-title { + display: -webkit-box; + line-height: 20px; + -webkit-line-clamp: 1; + -webkit-box-orient: vertical; + font-size: 20px; + font-weight: bold; + width: 100%; + clear: both; + color: black; + text-decoration: none; + overflow: hidden; + } + +.blog-item-content { + display: -webkit-box; + line-height: 18px; + -webkit-line-clamp: 2; + -webkit-box-orient: vertical; + font-size: 16px; + width: 100%; + clear: both; + color: rgba(0, 0, 0, 0.6); + overflow: hidden; +} + + + + + + + + diff --git a/src/main/resources/static/css/login.css b/src/main/resources/static/css/login.css new file mode 100644 index 0000000..5495fca --- /dev/null +++ b/src/main/resources/static/css/login.css @@ -0,0 +1,33 @@ + +.body-login { + width: 100vw; + height: 100vh; + background-color: #7fad39; +} + +.login-container-wrapper { + background-color: white; + width: 600px; + height: 300px; + border-radius: 30px; + box-shadow: 0 0 6px 1px rgba(0, 0, 0, 0.7); + position: absolute; + right: 0; + left: 0; + top: 0; + bottom: 0; + margin: auto; + display: flex; + align-items: center; + justify-content: center; +} + + +.login-container { + display: flex; + flex-direction: column; + justify-content: center; +} + + + diff --git a/src/main/resources/static/css/main.css b/src/main/resources/static/css/main.css new file mode 100644 index 0000000..48afefb --- /dev/null +++ b/src/main/resources/static/css/main.css @@ -0,0 +1,11 @@ + +* { + box-sizing: border-box; + padding: 0; + margin: 0; +} + +.bg-active { + background: rgb(127,173,57) !important; +} + diff --git a/src/main/resources/static/css/register.css b/src/main/resources/static/css/register.css new file mode 100644 index 0000000..d78fc3c --- /dev/null +++ b/src/main/resources/static/css/register.css @@ -0,0 +1,5 @@ + +.login-container-wrapper { + min-height: 440px; + width: 700px; +} \ No newline at end of file diff --git a/src/main/resources/static/img/banner.jpg b/src/main/resources/static/img/banner.jpg new file mode 100644 index 0000000..aa610d6 Binary files /dev/null and b/src/main/resources/static/img/banner.jpg differ diff --git a/src/main/resources/static/img/logo.png b/src/main/resources/static/img/logo.png new file mode 100644 index 0000000..23a55a8 Binary files /dev/null and b/src/main/resources/static/img/logo.png differ diff --git a/src/main/resources/static/img/payment-item.png.webp b/src/main/resources/static/img/payment-item.png.webp new file mode 100644 index 0000000..04491b0 Binary files /dev/null and b/src/main/resources/static/img/payment-item.png.webp differ diff --git a/src/main/resources/static/js/home.js b/src/main/resources/static/js/home.js new file mode 100644 index 0000000..8a71c4a --- /dev/null +++ b/src/main/resources/static/js/home.js @@ -0,0 +1,97 @@ +function getAllProductByCategory(categoryName, pageNumber) { + $.ajax({ + type: "GET", + url: "/getProductListByCategory/" + categoryName + "/" + pageNumber, + success: function (data) { + var productHTML = ""; + data.forEach(function (product) { + productHTML += "