initial commit

This commit is contained in:
Juthatip McDevitt 2024-07-12 22:02:32 -05:00
parent 2ae67844fd
commit 7fdb1633d6
16 changed files with 4474 additions and 0 deletions

4
bakery_website/.gitignore vendored Normal file
View file

@ -0,0 +1,4 @@
.env
node_modules/*
public/images/*
public/video/*

1881
bakery_website/package-lock.json generated Executable file

File diff suppressed because it is too large Load diff

21
bakery_website/package.json Executable file
View file

@ -0,0 +1,21 @@
{
"name": "bakery_website",
"version": "1.0.0",
"description": "",
"main": "index.js",
"type": "module",
"scripts": {
"start": "nodemon server.js"
},
"keywords": [],
"author": "",
"license": "ISC",
"dependencies": {
"dotenv": "^16.3.1",
"express.js": "^1.0.0",
"stripe": "^14.10.0"
},
"devDependencies": {
"nodemon": "^3.1.4"
}
}

View file

@ -0,0 +1,60 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>About | Sweet Bake - European style Bakery</title>
<link rel="stylesheet" href="style.css">
<link rel="shortcut icon" href="images/home-logo.png" type="image/x-icon">
<link href='https://unpkg.com/boxicons@2.1.4/css/boxicons.min.css' rel='stylesheet'>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.2.0/css/all.min.css">
</head>
<body>
<header>
<a href="index.html" class="brand" id="brand-1">Sweet Bake</a>
<div class="menu-btn"></div>
<div class="nav">
<div class="nav-items" id="nav-items-1">
<a href="menu.html">Order online</a>
<a href="gallery.html">Gallery</a>
<a href="about.html">About</a>
<a href="contact.html">Contact</a>
</div>
</div>
</header>
<!------------ about page ------------>
<div class="about">
<div class="main-about">
<img src="images/about.png" alt="">
<div class="all-text">
<h4>About</h4>
<h2>Sweet Bake</h2>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.
Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
</div>
</div>
</div>
<div class="content-4">
<h3>Sweet Bake</h3>
<div class="con-4-social">
<a href="#"><i class='bx bxl-facebook'></i></a>
<a href="#"><i class='bx bxl-instagram' ></i></a>
<a href="#"><i class='bx bx-mail-send'></i></a>
<a href="#"><i class='bx bx-phone' ></i></a>
</div>
<div class="con-text-4">
<a href="#">Policy</a>
<a href="#">FAQ</a>
</div>
</div>
<!------------ footer ------------>
<footer>
<p>&copy; 2023 All Right Reserved</p>
</footer>
<script src="main.js"></script>
</body>
</html>

17
bakery_website/public/cart.js Executable file
View file

@ -0,0 +1,17 @@
const payBtn = document.querySelector('.btn-buy');
payBtn.addEventListener('click',() => {
fetch('/stripe-checkout', {
method: 'post',
headers: new Headers({'Content-Type': 'application/Json'}),
body: JSON.stringify({
items: JSON.parse(localStorage.getItem('cartItems')),
}),
})
.then((res) => res.json())
.then((url) => {
location.href = url;
clearCart();
})
.catch((err) => console.log(err));
});

View file

@ -0,0 +1,111 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Contact Us | Sweet Bake - European style Bakery</title>
<link rel="stylesheet" href="style.css">
<link rel="shortcut icon" href="images/home-logo.png" type="image/x-icon">
<link href='https://unpkg.com/boxicons@2.1.4/css/boxicons.min.css' rel='stylesheet'>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.2.0/css/all.min.css">
</head>
<body>
<header>
<a href="index.html" class="brand" id="brand-1">Sweet Bake</a>
<div class="menu-btn"></div>
<div class="nav">
<div class="nav-items" id="nav-items-1">
<a href="menu.html">Order online</a>
<a href="gallery.html">Gallery</a>
<a href="about.html">About</a>
<a href="contact.html">Contact</a>
</div>
</div>
</header>
<!------------ contact page ------------>
<div class="contact-form">
<div class="contact-title">
<h2>Contact Us</h2>
</div>
<div class="contact-box">
<div class="contact form">
<p>Delivery: <span>We do not deliver, all order are in-house pickup.</span></p>
<p>Cake Design: <span>We can do color changes and topping changes for cakes, but we do not stray from our original cake designs</span></p>
<form>
<div class="formbox">
<div class="row">
<div class="inputbox">
<span>First Name</span>
<input type="text">
</div>
<div class="inputbox">
<span>Last Name</span>
<input type="text">
</div>
</div>
<div class="row">
<div class="inputbox">
<span>Email</span>
<input type="text">
</div>
<div class="inputbox">
<span>Phone Number</span>
<input type="text">
</div>
</div>
<div class="row1">
<div class="inputbox">
<span>Message</span>
<textarea></textarea>
</div>
</div>
<div class="row1">
<div class="inputbox">
<input type="submit" value="Send">
</div>
</div>
</div>
</form>
</div>
<div class="contact info">
<h3>Hours/Location/Number </h3>
<div class="infobox">
<div>
<p>Monday - Saturday 10:00am - 4:00pm</p>
<p>Sundays 11:00am - 4:00pm</p>
<p>1234 N Lincoln Park W <br>Chicago, IL 606060</p>
<p>(123) 456-7890</p>
</div>
</div>
</div>
<div class="contact map">
<iframe src="https://www.google.com/maps/embed?pb=!1m18!1m12!1m3!1d2968.658151457756!2d-87.63621522350827!3d41.921706962682066!2m3!1f0!2f0!3f0!3m2!1i1024!2i768!4f13.1!3m3!1m2!1s0x880fd36b093a9a07%3A0x940cc06f90294db!2sLincoln%20Park%20Zoo!5e0!3m2!1sth!2sus!4v1703708663155!5m2!1sth!2sus" style="border:0;" allowfullscreen="" loading="lazy" referrerpolicy="no-referrer-when-downgrade"></iframe>
</div>
</div>
</div>
<div class="content-4">
<h3>Sweet Bake</h3>
<div class="con-4-social">
<a href="#"><i class='bx bxl-facebook'></i></a>
<a href="#"><i class='bx bxl-instagram' ></i></a>
<a href="#"><i class='bx bx-mail-send'></i></a>
<a href="#"><i class='bx bx-phone' ></i></a>
</div>
<div class="con-text-4">
<a href="#">Policy</a>
<a href="#">FAQ</a>
</div>
</div>
<!------------ footer ------------>
<footer>
<p>&copy; 2023 All Right Reserved</p>
</footer>
<script src="main.js"></script>
</body>
</html>

View file

@ -0,0 +1,177 @@
//shopping-cart
let cartIcon = document.querySelector('#cart-icon');
let cart = document.querySelector('.cart');
let closeCart = document.querySelector('#close-cart');
cartIcon.onclick = () =>{
cart.classList.add("active");
};
closeCart.onclick = () =>{
cart.classList.remove("active");
};
//-------------------- add/remove items from the cart --------------------
if (document.readyState == 'loading'){
document.addEventListener('DOMContentLoaded', ready);
}
else{
ready();
}
function ready(){
//remove item from the cart
var removeCartBtn = document.getElementsByClassName('cart-remove');
for(var i = 0; i < removeCartBtn.length; i++){
var button = removeCartBtn[i];
button.addEventListener('click', removeCartItem);
}
//quantity
var quantityInput = document.getElementsByClassName('cart-quantity');
for(var i = 0; i < quantityInput.length; i++){
var input = quantityInput[i];
input.addEventListener('change', quantityChange);
}
//add cart
var addCart = document.getElementsByClassName('add-cart');
for(var i = 0; i < addCart.length; i++){
var button = addCart[i];
button.addEventListener('click', addCartClick);
}
loadCartItems();
}
//remove item
function removeCartItem(event){
var buttonClicked = event.target;
buttonClicked.parentElement.remove();
updateTotal();
saveCartItem();
}
//quantity change
function quantityChange(event){
var input = event.target;
if(isNaN(input.value) || input.value <= 0){
input.value = 1;
}
updateTotal();
saveCartItem();
updateCartIcon();
}
//add item to cart
function addCartClick(event){
var button = event.target;
var shopProduct = button.parentElement;
var title = shopProduct.getElementsByClassName('product-title')[0].innerText;
var price = shopProduct.getElementsByClassName('price')[0].innerText;
var productImg = shopProduct.getElementsByClassName('product-img')[0].src;
addProductToCart(title, price, productImg);
updateTotal();
saveCartItem();
updateCartIcon();
}
function addProductToCart(title, price, productImg){
var cartShopBox = document.createElement('div');
cartShopBox.classList.add('cart-box');
var cartItems = document.getElementsByClassName('cart-content')[0];
var cartItemName = cartItems.getElementsByClassName('cart-product-title');
for (var i = 0; i < cartItemName.length; i++){
if (cartItemName[i].innerText == title){
alert('You have already added this item to your cart');
return;
}
}
var cartBoxContent = ` <img src= "${productImg}" alt="" class="cart-img"/>
<div class="detail-box">
<div class="cart-product-title">${title}</div>
<div class="cart-price">${price}</div>
<input type="number" name="" id="" value="1" class="cart-quantity">
</div>
<i class='bx bxs-trash cart-remove'></i>`;
cartShopBox.innerHTML = cartBoxContent;
cartItems.append(cartShopBox);
cartShopBox.getElementsByClassName('cart-remove')[0].addEventListener('click', removeCartItem);
cartShopBox.getElementsByClassName('cart-quantity')[0].addEventListener('change', quantityChange);
saveCartItem();
updateCartIcon();
}
//price total
function updateTotal(){
var cartContent = document.getElementsByClassName('cart-content')[0];
var cartBoxes = cartContent.getElementsByClassName('cart-box');
var total =0;
for(var i = 0; i < cartBoxes.length; i++){
var cartBox = cartBoxes[i];
var priceElement = cartBox.getElementsByClassName('cart-price')[0];
var quantityElement = cartBox.getElementsByClassName('cart-quantity')[0];
var price = parseFloat(priceElement.innerText.replace('$', ''))
var quantity = quantityElement.value;
total += price*quantity;
}
total = Math.round(total * 100)/100;
document.getElementsByClassName('total-price')[0].innerText = '$' + total;
//save total
localStorage.setItem('cartTotal', total);
}
//item in cart
function saveCartItem(){
var cartContent = document.getElementsByClassName('cart-content')[0];
var cartBoxes = cartContent.getElementsByClassName('cart-box');
var cartItems = [];
for (var i = 0; i < cartBoxes.length; i++){
cartBox = cartBoxes[i];
var titleElement = cartBox.getElementsByClassName('cart-product-title')[0];
var priceElement = cart.getElementsByClassName('cart-price')[0];
var quantityElement = cartBox.getElementsByClassName('cart-quantity')[0];
var productImg = cartBox.getElementsByClassName('cart-img')[0].src;
var item = {
title: titleElement.innerText,
price: priceElement.innerText,
quantity: quantityElement.value,
productImg: productImg,
};
cartItems.push(item);
}
localStorage.setItem('cartItems', JSON.stringify(cartItems));
}
//load in cart
function loadCartItems(){
var cartItems = localStorage.getItem('cartItems');
if (cartItems){
cartItems = JSON.parse(cartItems);
for (var i = 0; i < cartItems.length; i++){
var item = cartItems[i];
addProductToCart(item.title, item.price, item.productImg);
var cartBoxes = document.getElementsByClassName('cart-box');
var cartBox = cartBoxes[cartBoxes.length - 1];
var quantityElement = cartBox.getElementsByClassName('cart-quantity')[0];
quantityElement.value = item.quantity;
}
}
var cartTotal = localStorage.getItem('cartTotal');
if(cartTotal){
document.getElementsByClassName('total-price')[0].innerText = '$' + cartTotal;
}
updateCartIcon();
}
//quantity in cart icon
function updateCartIcon(){
var cartBoxes = document.getElementsByClassName('cart-box');
var quantity = 0;
for (var i = 0; i < cartBoxes.length; i++){
var cartBox = cartBoxes[i];
var quantityElement = cartBox.getElementsByClassName('cart-quantity')[0];
quantity += parseInt(quantityElement.value);
}
var cartIcon = document.querySelector('#cart-icon');
cartIcon.setAttribute('data-quantity', quantity);
}
//clear cart after making a payment
function clearCart(){
var cartContent = document.getElementsByClassName('cart-content')[0];
cartContent.innerHTML = '';
updateTotal();
localStorage.removeItem('cartItems');
}

View file

@ -0,0 +1,123 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Home | Sweet Bake - European style Bakery</title>
<link rel="stylesheet" href="style.css">
<link rel="shortcut icon" href="images/home-logo.png" type="image/x-icon">
<link href='https://unpkg.com/boxicons@2.1.4/css/boxicons.min.css' rel='stylesheet'>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.2.0/css/all.min.css">
</head>
<body>
<header>
<a href="index.html" class="brand" id="brand-1">Sweet Bake</a>
<div class="menu-btn"></div>
<div class="nav">
<div class="nav-items" id="nav-items-1">
<a href="menu.html">Order online</a>
<a href="gallery.html">Gallery</a>
<a href="about.html">About</a>
<a href="contact.html">Contact</a>
</div>
</div>
</header>
<!------------ landing page ------------>
<div class="bakery">
<div class="wrapper">
<i id="left" class="fa-solid fa-angle-left"></i>
<div class="carousel">
<img src="images/gallery-1.jpg" alt="img" draggable="false">
<img src="images/gallery-2.jpg" alt="img" draggable="false">
<img src="images/gallery-3.jpg" alt="img" draggable="false">
<img src="images/gallery-4.jpg" alt="img" draggable="false">
<img src="images/gallery-5.jpg" alt="img" draggable="false">
</div>
<i id="right" class="fa-solid fa-angle-right"></i>
</div>
</div>
<div class="hour-bakery">
<div class="hour-baker-detail">
<h2>Business hours</h2>
<p>Mon - Sat 10:00am - 4:00pm</p>
<p>Sun 11:00am - 4:00pm</p>
</div>
</div>
<div class="line"></div>
<div class="wrapper-gallery">
<div class="our-gal">
<h2>Gallery</h2>
</div>
<nav>
<div class="gallery-items">
<span class="item-gallery active" data-name="all">All</span>
<span class="item-gallery" data-name="shop">Shop</span>
<span class="item-gallery" data-name="cake">Cake</span>
<span class="item-gallery" data-name="pastry">Pastry</span>
<span class="item-gallery" data-name="coffee">Coffee</span>
</div>
</nav>
<div class="gallery">
<div class="image-gal" data-name="shop"><span><img src="images/gal-1.jpg" alt=""></span></div>
<div class="image-gal" data-name="shop"><span><img src="images/gal-6.jpg" alt=""></span></div>
<div class="image-gal" data-name="shop"><span><img src="images/gal-7.jpg" alt=""></span></div>
<div class="image-gal" data-name="shop"><span><img src="images/gal-2.jpg" alt=""></span></div>
<div class="image-gal" data-name="shop"><span><img src="images/gal-3.jpg" alt=""></span></div>
<div class="image-gal" data-name="shop"><span><img src="images/gal-4.jpg" alt=""></span></div>
<div class="image-gal" data-name="coffee"><span><img src="images/gal-5.jpg" alt=""></span></div>
<div class="image-gal" data-name="coffee"><span><img src="images/gal-11.jpg" alt=""></span></div>
<div class="image-gal" data-name="coffee"><span><img src="images/gal-12.jpg" alt=""></span></div>
<div class="image-gal" data-name="coffee"><span><img src="images/gal-13.jpg" alt=""></span></div>
<div class="image-gal" data-name="coffee"><span><img src="images/gal-8.jpg" alt=""></span></div>
<div class="image-gal" data-name="coffee"><span><img src="images/gal-9.jpg" alt=""></span></div>
<div class="image-gal" data-name="coffee"><span><img src="images/gal-10.jpg" alt=""></span></div>
<div class="image-gal" data-name="coffee"><span><img src="images/gal-14.jpg" alt=""></span></div>
<div class="image-gal" data-name="pastry"><span><img src="images/gal-15.jpg" alt=""></span></div>
<div class="image-gal" data-name="pastry"><span><img src="images/gal-16.jpg" alt=""></span></div>
<div class="image-gal" data-name="pastry"><span><img src="images/gal-17.jpg" alt=""></span></div>
<div class="image-gal" data-name="pastry"><span><img src="images/gal-18.jpg" alt=""></span></div>
<div class="image-gal" data-name="pastry"><span><img src="images/gal-19.jpg" alt=""></span></div>
<div class="image-gal" data-name="pastry"><span><img src="images/gal-20.jpg" alt=""></span></div>
<div class="image-gal" data-name="cake"><span><img src="images/gal-21.jpg" alt=""></span></div>
<div class="image-gal" data-name="cake"><span><img src="images/gal-22.jpg" alt=""></span></div>
<div class="image-gal" data-name="cake"><span><img src="images/gal-23.jpg" alt=""></span></div>
<div class="image-gal" data-name="cake"><span><img src="images/gal-24.jpg" alt=""></span></div>
</div>
</div>
<div class="preview-box">
<div class="details-gal">
<span class="title-gal">Image Category: <p></p></span>
<span class="icon-gal fas fa-times"></span>
</div>
<div class="image-box-gal"><img src="" alt=""></div>
</div>
<div class="shadow"></div>
</div>
<div class="content-4">
<h3>Sweet Bake</h3>
<div class="con-4-social">
<a href="#"><i class='bx bxl-facebook'></i></a>
<a href="#"><i class='bx bxl-instagram' ></i></a>
<a href="#"><i class='bx bx-mail-send'></i></a>
<a href="#"><i class='bx bx-phone' ></i></a>
</div>
<div class="con-text-4">
<a href="#">Policy</a>
<a href="#">FAQ</a>
</div>
</div>
<!------------ footer ------------>
<footer>
<p>&copy; 2023 All Right Reserved</p>
</footer>
<script src="main.js"></script>
</body>
</html>

191
bakery_website/public/index.html Executable file
View file

@ -0,0 +1,191 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Home | Sweet Bake - European style Bakery</title>
<link rel="stylesheet" href="style.css">
<link rel="shortcut icon" href="images/home-logo.png" type="image/x-icon">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.14.0/css/all.min.css">
<link href='https://unpkg.com/boxicons@2.1.4/css/boxicons.min.css' rel='stylesheet'>
</head>
<body>
<header>
<a href="#" class="brand">Sweet Bake</a>
<div class="menu-btn"></div>
<div class="nav">
<div class="nav-items">
<a href="menu.html">Order online</a>
<a href="gallery.html">Gallery</a>
<a href="about.html">About</a>
<a href="contact.html">Contact</a>
</div>
</div>
</header>
<!------------ landing page ------------>
<section class="home">
<video src="video/home-1.mp4" class="video-slide active" autoplay muted loop></video>
<video src="video/home-2.mp4" class="video-slide" autoplay muted loop></video>
<div class="content active">
<h1>We bake the world a better place</h1>
<p>We are delighted to present to you daily, an irresistible selection of fresh ingredients</p>
<a href="./menu.html">Our Menu</a>
</div>
<div class="content">
<h1>Celebrate your holiday with us</h1>
<p>Enhance your holiday with our delightful array of freshly baked goods <br> and aromatic brewed beverages.</p>
<a href="./menu.html">Order Now</a>
</div>
<div class="slider-nav">
<div class="nav-btn active"></div>
<div class="nav-btn"></div>
</div>
</section>
<!------------ content-1 ------------>
<div class="gallery">
<div class="container">
<div class="tab">
<input type="radio" class="tab-radio" name="tab-example" id="tab1" checked>
<label for="tab1" class="tab-label"><img src="images/bakery.png" alt=""><br><br>pastry</label>
<div class="tab-content">
<div class="note">
<div class="container">
<div class="note-detail">
<div class="note-img">
<img src="images/hero-bakery.jpg" alt="">
</div>
<div class="note-text">
<div class="note-text-title">
<h2>Now</h2>
</div>
<h1>Fresh pastries available daily</h1>
<p>Check out fresh pastries selection for the very best in unique or custom, cookies, tarts, and more. Pre-orders are available</p>
<div class="order-btn"><a href="#">Order Now</a></div>
</div>
</div>
</div>
</div>
</div>
<input type="radio" class="tab-radio" name="tab-example" id="tab2">
<label for="tab2" class="tab-label"><img src="images/cake.png" alt=""><br><br> Cake</label>
<div class="tab-content">
<div class="note">
<div class="container">
<div class="note-detail">
<div class="note-img">
<img src="images/hero-cake.jpg" alt="">
</div>
<div class="note-text-1">
<div class="note-text-title-1">
<h2>Cheers</h2>
</div>
<h1>Wishing you a holly jolly <br><span>Christmas</span></h1>
<p>We would love to cater your holiday gathering! <br> Pre-orders are available</p>
<div class="order-btn-1"><a href="#">Order Now</a></div>
</div>
</div>
</div>
</div>
</div>
<input type="radio" class="tab-radio" name="tab-example" id="tab3">
<label for="tab3" class="tab-label"><img src="images/cup.png" alt=""><br><br> Coffee</label>
<div class="tab-content">
<div class="note">
<div class="container">
<div class="note-detail">
<div class="note-img">
<img src="images/hero-coffee.jpg" alt="">
</div>
<div class="note-text">
<div class="note-text-title">
<h2>New</h2>
</div>
<h1>Enjoy your Coffee</h1>
<p>A cup of coffee lasts only a moment, but it is that moment that makes your day better. <br> Discover you perfect cup with us</p>
<div class="order-btn"><a href="#">Try Now</a></div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<!------------ content-2 ------------>
<div class="content-2">
<h1>Best Selling</h1>
<div class="con-2">
<div class="container">
<div class="con-2-detail">
<div class="con-2-img">
<img src="images/best-selling-1.jpg" alt="">
<div class="con-2-text">
<h3>Macarons</h3>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. </p>
<button class="con-2-btn"><a href="#">Order Now</a></button>
</div>
</div>
<div class="con-2-img">
<img src="images/best-selling-2.jpg" alt="">
<div class="con-2-text">
<h3>Cream Puffs</h3>
<p>Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
<button class="con-2-btn"><a href="#">Order Now</a></button>
</div>
</div>
<div class="con-2-img">
<img src="images/best-selling-3.jpg" alt="">
<div class="con-2-text">
<h3>Cheesecake</h3>
<p>Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.</p>
<button class="con-2-btn"><a href="#">Order Now</a></button>
</div>
</div>
</div>
</div>
</div>
</div>
<!------------ content-3 ------------>
<div class="content-3">
<div class="con-3">
<div class="container">
<div class="con-3-detail">
<div class="con-3-text">
<h1>current hours</h1>
</div>
<div class="con-3-text-detail">
<h3>Business Hours</h3>
<p>Monday - Saturday 10:00am - 4:00pm</p>
<p>Sundays 11:00am - 4:00pm</p>
</div>
</div>
</div>
</div>
<div class="con-3-img"><img src="images/con-3.jpg" alt=""></div>
</div>
<!------------ content-4 ------------>
<div class="content-4">
<h2>Looking to inquire or ready to make an order?</h2>
<button class="con-2-btn"><a href="#">Contact Us</a></button>
<h3>Sweet Bake</h3>
<div class="con-4-social">
<a href="#"><i class='bx bxl-facebook'></i></a>
<a href="#"><i class='bx bxl-instagram' ></i></a>
<a href="#"><i class='bx bx-mail-send'></i></a>
<a href="#"><i class='bx bx-phone' ></i></a>
</div>
<div class="con-text-4">
<a href="#">Policy</a>
<a href="#">FAQ</a>
</div>
</div>
<!------------ footer ------------>
<footer>
<p>&copy; 2023 All Right Reserved</p>
</footer>
<script src="main.js"></script>
</body>
</html>

164
bakery_website/public/main.js Executable file
View file

@ -0,0 +1,164 @@
//navbar
const menuBtn = document.querySelector(".menu-btn");
const navi = document.querySelector(".nav");
menuBtn.addEventListener("click", ()=>{
menuBtn.classList.toggle("active");
navi.classList.toggle("active");
});
//video
const videoBtn = document.querySelectorAll(".nav-btn");
const slides = document.querySelectorAll(".video-slide");
const contents = document.querySelectorAll(".content");
var sliderNav = function(manual){
videoBtn.forEach((btn)=>{
btn.classList.remove("active");
});
slides.forEach((slide)=>{
slide.classList.remove("active");
});
contents.forEach((content)=>{
content.classList.remove("active");
});
videoBtn[manual].classList.add("active");
slides[manual].classList.add("active");
contents[manual].classList.add("active");
}
videoBtn.forEach((btn, i)=>{
btn.addEventListener("click", ()=>{
sliderNav(i);
});
});
//carousel
const carousel = document.querySelector(".carousel"),
firstImg = carousel.querySelectorAll("img")[0],
arrowIcons = document.querySelectorAll(".wrapper i");
let isDragStart = false, isDragging = false, prevPageX, prevScrollLeft, positionDiff;
const showHideIcons = () => {
// showing and hiding prev/next icon according to carousel scroll left value
let scrollWidth = carousel.scrollWidth - carousel.clientWidth; // getting max scrollable width
arrowIcons[0].style.display = carousel.scrollLeft == 0 ? "none" : "block";
arrowIcons[1].style.display = carousel.scrollLeft == scrollWidth ? "none" : "block";
}
arrowIcons.forEach(icon => {
icon.addEventListener("click", () => {
let firstImgWidth = firstImg.clientWidth + 14; // getting first img width & adding 14 margin value
// if clicked icon is left, reduce width value from the carousel scroll left else add to it
carousel.scrollLeft += icon.id == "left" ? -firstImgWidth : firstImgWidth;
setTimeout(() => showHideIcons(), 60); // calling showHideIcons after 60ms
});
});
const autoSlide = () => {
// if there is no image left to scroll then return from here
if(carousel.scrollLeft - (carousel.scrollWidth - carousel.clientWidth) > -1 || carousel.scrollLeft <= 0) return;
positionDiff = Math.abs(positionDiff); // making positionDiff value to positive
let firstImgWidth = firstImg.clientWidth + 14;
// getting difference value that needs to add or reduce from carousel left to take middle img center
let valDifference = firstImgWidth - positionDiff;
if(carousel.scrollLeft > prevScrollLeft) { // if user is scrolling to the right
return carousel.scrollLeft += positionDiff > firstImgWidth / 3 ? valDifference : -positionDiff;
}
// if user is scrolling to the left
carousel.scrollLeft -= positionDiff > firstImgWidth / 3 ? valDifference : -positionDiff;
}
const dragStart = (e) => {
// updatating global variables value on mouse down event
isDragStart = true;
prevPageX = e.pageX || e.touches[0].pageX;
prevScrollLeft = carousel.scrollLeft;
}
const dragging = (e) => {
// scrolling images/carousel to left according to mouse pointer
if(!isDragStart) return;
e.preventDefault();
isDragging = true;
carousel.classList.add("dragging");
positionDiff = (e.pageX || e.touches[0].pageX) - prevPageX;
carousel.scrollLeft = prevScrollLeft - positionDiff;
showHideIcons();
}
const dragStop = () => {
isDragStart = false;
carousel.classList.remove("dragging");
if(!isDragging) return;
isDragging = false;
autoSlide();
}
carousel.addEventListener("mousedown", dragStart);
carousel.addEventListener("touchstart", dragStart);
document.addEventListener("mousemove", dragging);
carousel.addEventListener("touchmove", dragging);
document.addEventListener("mouseup", dragStop);
carousel.addEventListener("touchend", dragStop);
//gallery-tab
//selecting all required elements
const filterItem = document.querySelector(".gallery-items");
const filterImg = document.querySelectorAll(".gallery .image-gal");
window.onload = ()=>{ //after window loaded
filterItem.onclick = (selectedItem)=>{ //if user click on filterItem div
if(selectedItem.target.classList.contains("item-gallery")){ //if user selected item has .item class
filterItem.querySelector(".active").classList.remove("active"); //remove the active class which is in first item
selectedItem.target.classList.add("active"); //add that active class on user selected item
let filterName = selectedItem.target.getAttribute("data-name"); //getting data-name value of user selected item and store in a filtername variable
filterImg.forEach((image) => {
let filterImges = image.getAttribute("data-name"); //getting image data-name value
//if user selected item data-name value is equal to images data-name value
//or user selected item data-name value is equal to "all"
if((filterImges == filterName) || (filterName == "all")){
image.classList.remove("hide"); //first remove the hide class from the image
image.classList.add("show"); //add show class in image
}else{
image.classList.add("hide"); //add hide class in image
image.classList.remove("show"); //remove show class from the image
}
});
}
}
for (let i = 0; i < filterImg.length; i++) {
filterImg[i].setAttribute("onclick", "preview(this)"); //adding onclick attribute in all available images
}
}
//fullscreen image preview function
//selecting all required elements
const previewBox = document.querySelector(".preview-box"),
categoryName = previewBox.querySelector(".title-gal p"),
previewImg = previewBox.querySelector("img"),
closeIcon = previewBox.querySelector(".icon-gal"),
shadow = document.querySelector(".shadow");
function preview(element){
//once user click on any image then remove the scroll bar of the body, so user can't scroll up or down
document.querySelector("body").style.overflow = "hidden";
let selectedPrevImg = element.querySelector("img").src; //getting user clicked image source link and stored in a variable
let selectedImgCategory = element.getAttribute("data-name"); //getting user clicked image data-name value
previewImg.src = selectedPrevImg; //passing the user clicked image source in preview image source
categoryName.textContent = selectedImgCategory; //passing user clicked data-name value in category name
previewBox.classList.add("show"); //show the preview image box
shadow.classList.add("show"); //show the light grey background
closeIcon.onclick = ()=>{ //if user click on close icon of preview box
previewBox.classList.remove("show"); //hide the preview box
shadow.classList.remove("show"); //hide the light grey background
document.querySelector("body").style.overflow = "auto"; //show the scroll bar on body
}
}

225
bakery_website/public/menu.html Executable file
View file

@ -0,0 +1,225 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Menu | Sweet Bake - European style Bakery</title>
<link rel="stylesheet" href="style_extension.css">
<link rel="shortcut icon" href="images/home-logo.png" type="image/x-icon">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.14.0/css/all.min.css">
<link href='https://unpkg.com/boxicons@2.1.4/css/boxicons.min.css' rel='stylesheet'>
</head>
<body>
<header>
<div class="nav-menu container-menu">
<a href="index.html" class="menu-logo">Sweet Bake</a>
<i class='bx bx-shopping-bag' id="cart-icon" data-quantity="0"></i>
<div class="cart">
<h2 class="cart-title">Your Cart</h2>
<div class="cart-content">
<!--<div class="cart-box">
<img src="images/cake-7.jpg" alt="" class="cart-img">
<div class="detail-box">
<div class="cart-product-title">Product</div>
<div class="cart-price">$24.99</div>
<input type="number" name="" id="" value="1" class="cart-quantity">
</div>
<i class='bx bxs-trash cart-remove'></i>
</div>-->
</div>
<div class="total">
<div class="total-title">Total</div>
<div class="total-price">$0</div>
</div>
<button type="button" class="btn-buy">Pay Now</button>
<i class='bx bx-x' id="close-cart"></i>
</div>
</div>
</header>
<!-- Product -->
<div class="shop container-shop">
<h2 class="section-title">Cakes</h2>
<div class="shop-content">
<div class="product-box">
<img src="https://lh3.googleusercontent.com/pw/ABLVV84qyExbv2N9cMSe2Ic9xyGZjUQayKOdEY8vJJvMZq4S8YNmz9gY4HsH_GLq86uejCEMuLC2C1nDsuVXeN6PSidKi4tNiYa9GWLyNGYw6d8qMh023TFd1SewhgBba-wscs_qIeYscukcr8rruhw5qOfO=w737-h921-s-no?authuser=0" alt="" class="product-img">
<h2 class="product-title">Ice cream cake</h2>
<span class="price">$24.99 (1 lb)</span>
<i class='bx bx-shopping-bag add-cart'></i>
</div>
<div class="product-box">
<img src="https://lh3.googleusercontent.com/pw/ABLVV87x_ZSDPdVoapBMy6cST_wOnKE_rFq17Ci0PZe9DsFYdzaBR8L4zoMDTvIrmDBvPgatymPmkJAQKsq0rLTq-qP1JYpRkfTno6k7KN1Zzh0TtNoM3vlZM-y4V8_pYGisURq5qziX6laMLOAmIcTt2XLj=w737-h921-s-no?authuser=0" alt="" class="product-img">
<h2 class="product-title">Chocolate cake</h2>
<span class="price">$19.99 (1 lb)</span>
<i class='bx bx-shopping-bag add-cart'></i>
</div>
<div class="product-box">
<img src="https://lh3.googleusercontent.com/pw/ABLVV84G2Iina5G4cdaRMxbOUCHuPxmS9sNjfguoGPkYpIVElFXNSFac-jBKUd25AePQ9lOOjRZbpfOUcI8l1SNxfBZ8tTJzPC2L3iv__uJ-qKGISYyeq_GC6Tk-BVDgW-pqwoXOhdHikAEcCxAk0OA6m8Uq=w737-h921-s-no?authuser=0" alt="" class="product-img">
<h2 class="product-title">Red velvet cake</h2>
<span class="price">$19.99 (1 lb)</span>
<i class='bx bx-shopping-bag add-cart'></i>
</div>
<div class="product-box">
<img src="https://lh3.googleusercontent.com/pw/ABLVV85gdwk9PCG1PfVTZ3gZWQAGBRDF5hxFIxVWC5xeqgUdPUlzgt4JLNThit2yVNj7caGCjOq5Z7KB6YmGTn7-UetJCMu2AbrVJT8h6behjT_l_z_0s0iFWFUIGxuyTpcx1mTERrsO42p2Ku4LzhCIfiKo=w737-h921-s-no?authuser=0" alt="" class="product-img">
<h2 class="product-title">Cheesecake</h2>
<span class="price">$19.99 (1 lb)</span>
<i class='bx bx-shopping-bag add-cart'></i>
</div>
<div class="product-box">
<img src="https://lh3.googleusercontent.com/pw/ABLVV8612BO4uuXv7D9ikXmzpTkGse3l_zT9nJN1Ou1NdMrc2mThfqeTn6VAgoAK4zTM8_4oY29OHrJY5v4dwz-iRxSA11wThWFvLPQxoCaN2djuppdaaocOJgZEQ_BQSalKJ93cGeDf2cvCOu05fYKKDpwy=w737-h921-s-no?authuser=0" alt="" class="product-img">
<h2 class="product-title">Orange Cake</h2>
<span class="price">$15.99 (1 lb)</span>
<i class='bx bx-shopping-bag add-cart'></i>
</div>
<div class="product-box">
<img src="https://lh3.googleusercontent.com/pw/ABLVV86-7Wr8jScKegTRMnd8jow--OG82smatMr0gOpl0J9IMqyrdokKsO2NybAOPUPjCrqYAUr8uMZuNQG59EFSnTE7dJMN-Z8UrnS7fMd4TEW3pbY7qEius5aU_EJBz0HpyVqfygS2T3o_VTzpBoncUxz3=w736-h921-s-no?authuser=0" alt="" class="product-img">
<h2 class="product-title">Carrot cake</h2>
<span class="price">$13.99 (1 lb)</span>
<i class='bx bx-shopping-bag add-cart'></i>
</div>
</div>
<h2 class="section-title"><br><br><br> Pastries</h2>
<div class="shop-content">
<div class="product-box">
<img src="https://lh3.googleusercontent.com/pw/ABLVV850i052hqLqrYOjnBmNDZyral0wu_RB2iAaJx-86vbWDlizTyUNEF_GLNeJgWm4WZYtU885CAM8tWQH620pGcSS9Ateo3M9OXAAck3XpzqaJtzqPzUPi69fictJ3auPeKtW5iQ9ZQ8UokcT0A-UKfSM=w575-h719-s-no?authuser=0" alt="" class="product-img">
<h2 class="product-title">Passion fruit panna cotta</h2>
<span class="price">$7.99 (1 ea)</span>
<i class='bx bx-shopping-bag add-cart'></i>
</div>
<div class="product-box">
<img src="https://lh3.googleusercontent.com/pw/ABLVV86us9gqzmEyQBn-OkDx9yBPEbQSkTcQiZQ1wHWuIEgL6ueqKHTBblnJp4IU0TSOfAjZM4KcVa5pvd-DQtAZaxnvIIdh4536sq36tZfA9zjVJSvw9IMM5YmsZ0aO-GrXwWyOnw_U_deD26agn5dIl1MM=w737-h921-s-no?authuser=0" alt="" class="product-img">
<h2 class="product-title">Tiramisu</h2>
<span class="price">$6.99 (1 ea)</span>
<i class='bx bx-shopping-bag add-cart'></i>
</div>
<div class="product-box">
<img src="https://lh3.googleusercontent.com/pw/ABLVV87QRkyYplULS1FoQqOAIcH8RGZj4WiEFiQRiIlcjZGPeteiVLqKw_bSFy1q5xMUeASNhkNJuFiI3fQErpNljTHD-ISFgD3-_sy0GRI-d40l3ol8pDmjUAVQh_o3_L-o4da7AOJnvq0jgfCvwXfVPlYF=w737-h921-s-no?authuser=0" alt="" class="product-img">
<h2 class="product-title">Cream puff</h2>
<span class="price">$6.99 (1 ea)</span>
<i class='bx bx-shopping-bag add-cart'></i>
</div>
<div class="product-box">
<img src="https://lh3.googleusercontent.com/pw/ABLVV87js0IKvFXjfukkhSDtwQQhapXQo6hTNU2nKWkdlpd4iOv8uDLYY5fF1NwvZyOUZXY08UXAXv-yNhzFF2dwFiKapTzYMSieXhFeCtETnYO68Ws9mfwgiDMvzFiwPascRCJj4--9zjBCyrI70bfAZLnp=w737-h921-s-no?authuser=0" alt="" class="product-img">
<h2 class="product-title">Matcha Swiss roll</h2>
<span class="price">$5.99 (1 ea)</span>
<i class='bx bx-shopping-bag add-cart'></i>
</div>
<div class="product-box">
<img src="https://lh3.googleusercontent.com/pw/ABLVV87XwyJUxBraV1GGoF_yr9EwsImNe07BH8d4CANayyVnMI9s9TgKvQOmaJKuCvxzkTAf5jN1jxMDY2F8ohjFBRyDcthcHxzAtItK1rQdZ0hCGiy6pVAUZ6LRAlPck8_-PAHdmg0CBKIYsmGRSA-n13VQ=w435-h543-s-no?authuser=0" alt="" class="product-img">
<h2 class="product-title">strawberry swiss roll</h2>
<span class="price">$5.99 (1 ea)</span>
<i class='bx bx-shopping-bag add-cart'></i>
</div>
<div class="product-box">
<img src="https://lh3.googleusercontent.com/pw/ABLVV86gTB3HVD8n1FZcgLh3IAJ-nf8YBqBPKsC5tmcHDrobPhLAuaAiYqsgOT40i_rs9hn9Qcy5-1N5xbTqjVlNhT1IRUkhbMliZ0BOnlJ8VvF9lLWhwE0X-7l9iSI2uCFOGrEMwb9Bc69QOnstGdWE2w4t=w737-h921-s-no?authuser=0" alt="" class="product-img">
<h2 class="product-title">Paris brest</h2>
<span class="price">$5.99 (1 ea)</span>
<i class='bx bx-shopping-bag add-cart'></i>
</div>
<div class="product-box">
<img src="https://lh3.googleusercontent.com/pw/ABLVV86kyMtuDCR-0BY3IS6unBqwuVXLHxlnja27siB2nFzrMsHTub79AyP-0bEk9LwzKpwcdTg5er-DX7_dNCIetnbv04amjcT2nUpok0n7FocgTYdECS7vdsW5DiPGAW-1VrBK66JAWyuf5vYAHSRt1eJl=w387-h483-s-no?authuser=0" alt="" class="product-img">
<h2 class="product-title">Crème brûlée</h2>
<span class="price">$5.99 (1 ea)</span>
<i class='bx bx-shopping-bag add-cart'></i>
</div>
<div class="product-box">
<img src="https://lh3.googleusercontent.com/pw/ABLVV87fvjSwuzadi5bumA0JzUZTvAFyWkQ6PXY0p8P1DoCzsvrdSjowfzF8Ql79ejyQ3N5GR5o_o0kzzPoojODseemw4S8zdbtdYtvV2eiVRHZEizoeCgxO07XumiN1YH0mJMVO8zgO1EiBpw1kOGOvZb8A=w455-h570-s-no?authuser=0" alt="" class="product-img">
<h2 class="product-title">Pastéis De Nata</h2>
<span class="price">$4.99 (1 ea)</span>
<i class='bx bx-shopping-bag add-cart'></i>
</div>
<div class="product-box">
<img src="https://lh3.googleusercontent.com/pw/ABLVV85YpNqyo0rhjU2ws7mffKic4shVssuNT4oUcqJnNwVbhFn1GRnhofWz3t0TNFrF6qPBnlsko5iTt1lLF3HBMe4JpBjxHE4XMGAQCalUsntFgEbEiSwbq1YcLKqISDbkSbgqY2KzQ3yVZFW437GmD4W-=w437-h546-s-no?authuser=0" alt="" class="product-img">
<h2 class="product-title">corissant</h2>
<span class="price">$3.99 (1 ea)</span>
<i class='bx bx-shopping-bag add-cart'></i>
</div>
<div class="product-box">
<img src="https://lh3.googleusercontent.com/pw/ABLVV85JO-EqQZPYeQA0OOFlWkF1lyxU6nXfnHI1fjtMatLiGXI9ldzqS4R2vv4LkavbpAjLf7ZLUYR17zfl6fDuf0G2ZDI0qHolYy2l5HYlWSj798e_07dXedt4Ajug6y3kefvag0byU1WYHbRLTYRyW7AL=w386-h482-s-no?authuser=0" alt="" class="product-img">
<h2 class="product-title">Nutella Puff</h2>
<span class="price">$2.99 (1 ea)</span>
<i class='bx bx-shopping-bag add-cart'></i>
</div>
</div>
<h2 class="section-title"><br><br><br> Macarons</h2>
<div class="shop-content">
<div class="product-box">
<img src="https://lh3.googleusercontent.com/pw/ABLVV85b1o-4GiiVdWDHzqxhI3UtUB5oQeeXS-7p8ZLTcs9CN4_9PDnt2lf8C_o6oNW72uGcmDxDcllMgV6CwcL3pUH7wtwUX6sSZZrMdNPERwWFvMZ3bGdHm9vp4O7tiVU_MMgoBtM_mwiXSGQNFD6V47xH=w499-h624-s-no?authuser=0" alt="" class="product-img">
<h2 class="product-title">Rose Lychee Macaron</h2>
<span class="price">$2.99 (1 ea)</span>
<i class='bx bx-shopping-bag add-cart'></i>
</div>
<div class="product-box">
<img src="https://lh3.googleusercontent.com/pw/ABLVV84xosF_PCdnSNfPB-bxAzrShDolJJ8HWRqAL7T9F-NTCzjJ68We6lshOEDpK9-p2l_0opZCZGiXuF5wsw1dPqav6esMk4BEMHfEEV6nGn95dAq3CikMaZEZ_xSH5_cjVaniqjwd6iZU8ghS-3PaL0sn=w535-h669-s-no?authuser=0" alt="" class="product-img">
<h2 class="product-title">Chocolate macaron</h2>
<span class="price">$2.99 (1 ea)</span>
<i class='bx bx-shopping-bag add-cart'></i>
</div>
<div class="product-box">
<img src="https://lh3.googleusercontent.com/pw/ABLVV85bCKXE14_lO-PQaCZa8EuUk1fO_H4NG_iZ_UC3zccD76XvPQy1HnPkCHkP7qYCNTgFQkd9Y68a9e0jMO7e769uDax9q_xYVaxgxQN6WmwV94okZQ4N5p_5lvjdgavxaXxjRYsbwrzaBsrl0POyWNFe=w529-h662-s-no?authuser=0" alt="" class="product-img">
<h2 class="product-title">Vanilla macaron</h2>
<span class="price">$2.99 (1 ea)</span>
<i class='bx bx-shopping-bag add-cart'></i>
</div>
<div class="product-box">
<img src="https://lh3.googleusercontent.com/pw/ABLVV84rHn4G_cynNv81Pyt21eHG5bjW3bgwbPPwwOSywinCLXGTtjLxnQbJBA5DymMYutmWRUvakd66b4bMuYDwN1cmHN_9XCsGAvLY2SXIS-nD4rL1kTblo_MDQhuC1TWntWk0A8IQRlhEAZNIweVnyztx=w523-h654-s-no?authuser=0" alt="" class="product-img">
<h2 class="product-title">Strawberry Macaron </h2>
<span class="price">$2.99 (1 ea)</span>
<i class='bx bx-shopping-bag add-cart'></i>
</div>
<div class="product-box">
<img src="https://lh3.googleusercontent.com/pw/ABLVV86P8pO8TZd1x6o_vG2_cI_mdnjxyTj2S49t8PTUXP_0Ya2z4_QtzzvokX7josntuUIdVuXst0Z7NJ8zO1Ly8Sqpku-rRaWnkwfpflE4EgR1XzGbZ9S3iHMs4ZMoxEfxbq3A-RLfbgBpvecVQhsqLqKb=w516-h645-s-no?authuser=0" alt="" class="product-img">
<h2 class="product-title">Lemon Macaron</h2>
<span class="price">$2.99 (1 ea)</span>
<i class='bx bx-shopping-bag add-cart'></i>
</div>
<div class="product-box">
<img src="https://lh3.googleusercontent.com/pw/ABLVV85Or0UR3A6sSHDwn9-pweQyp212gp1QYCXw1zUR0JUzCjMHu1SrzZTjZISx5bG38EQRZ9AYTCFlm8ctQMF0KhgWWFHcWpfxzDz5oetzQZur2kuBXZglbu6iiPapJcByDi70yepguvwlkKpTrSQlNI-r=w498-h623-s-no?authuser=0" alt="" class="product-img">
<h2 class="product-title">Pistachio Macaron </h2>
<span class="price">$2.99 (1 ea)</span>
<i class='bx bx-shopping-bag add-cart'></i>
</div>
<div class="product-box">
<img src="https://lh3.googleusercontent.com/pw/ABLVV85BDX2o0B1f_blBMEAvu4sUW1mb10dNNWs68QfIuM-9aNkBFIFenmpBVaufDisCMMSHmyuGMY3j9YiH44RYH53XK4i6S2bYTnXr7cPtz1P0LYH0P-q4CJsEsdb1UlU4uPCWJjQCjSOzIF7mIUZXhsbB=w518-h648-s-no?authuser=0" alt="" class="product-img">
<h2 class="product-title">Salted Caramel Macaron </h2>
<span class="price">$2.99 (1 ea)</span>
<i class='bx bx-shopping-bag add-cart'></i>
</div>
<div class="product-box">
<img src="https://lh3.googleusercontent.com/pw/ABLVV85iTP7g-myaZOGQ-LKlZkbxqQvoWHA1WDtYOcs1ERKNTS7wbXHV8RLVxKwXLRBEsAy-mRjkfhQQ67BiG--I9L25XifeLmsVTsKVgkFuk2eYsZjeZkMkl07yI9E7UiFJCwrPQFmg6qHSsVYnCSTu8-bo=w470-h588-s-no?authuser=0" alt="" class="product-img">
<h2 class="product-title">Hazelnut Praline Macaron </h2>
<span class="price">$2.99 (1 ea)</span>
<i class='bx bx-shopping-bag add-cart'></i>
</div>
</div>
</div>
<script src="extension.js"></script>
<script src="cart.js"></script>
</body>
</html>

1083
bakery_website/public/style.css Executable file

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,311 @@
@import url('https://fonts.googleapis.com/css2?family=Cormorant:wght@300;400;500;600;700&family=Waterfall&display=swap');
*{
margin: 0;
padding: 0;
box-sizing: border-box;
font-family: 'Cormorant', serif;
}
img{
width: 100%;
}
header{
position: fixed;
top: 0;
left: 0;
width: 100%;
z-index: 100;
background-color: white;
box-shadow: 0 1px 4px hsla(0, 0%, 98%, 0.3);
}
.nav-menu{
display: flex;
align-items: center;
justify-content: space-between;
padding: 20px 0;
}
.container-menu{
max-width: 80%;
margin: auto;
width: 100%;
}
.menu-logo{
color: black;
font-size: 66px;
font-weight: 500;
letter-spacing: 2px;
font-family: 'Waterfall';
text-decoration: none;
}
#cart-icon{
position: relative;
font-size: 26px;
color: black;
cursor: pointer;
}
#cart-icon[data-quantity='0']::after{
contain: '';
}
#cart-icon[data-quantity]::after{
content: attr(data-quantity);
position: absolute;
top: 0;
right: -12px;
width: 20px;
height: 20px;
background-color: white;
border: 1px solid black;
border-radius: 50%;
color: black;
font-size: 12px;
font-weight: 500;
display: flex;
justify-content: center;
align-items: center;
}
.cart{
position: fixed;
top: 0;
right: -100%;
width: 360px;
min-height: 100vh;
padding: 50px;
background-color: whitesmoke;
box-shadow: -2px 0 4px hsl(0, 4%, 15% / 10%);
transition: 0.3 cubic-bezier(0.075, 0.82, 0.165, 1);
}
.cart.active{
right: 0;
transition: 0.3 cubic-bezier(0.075, 0.82, 0.165, 1);
}
.cart-title{
text-align: center;
font-size: 24px;
margin-top: 20px;
}
.total{
display: flex;
justify-content: flex-end;
margin-top: 30px;
border-top: 1px solid #B0A695;
}
.total-title{
font-size: 18px;
margin-top: 22px;
}
.total-price{
font-size: 20px;
margin: 20px 0 0 20px;
}
.btn-buy{
display: flex;
justify-content: center;
margin: 30px auto 0 auto;
padding: 8px 10px;
width: 50%;
text-align: center;
border: 1px solid black;
background-color: transparent;
font-size: 18px;
font-weight: 500;
cursor: pointer;
}
#close-cart{
position: absolute;
top: 20px;
right: 20px;
font-size: 30px;
cursor: pointer;
}
.cart-box{
display: grid;
grid-template-columns: 35% 40% 15%;
align-items: center;
gap: 20px;
margin-top: 30px;
}
.cart-img{
width: 90px;
height: 90px;
object-fit: contain;
object-position: center;
padding: 10px;
}
.detail-box{
display: grid;
row-gap: 10px;
}
.cart-product-title{
font-size: 16px;
text-transform: capitalize;
}
.cart-price{
font-weight: 600;
}
.cart-quantity{
border: 1px solid black;
outline-color: black;
width: 50px;
text-align: center;
font-size: 18px;
border-radius: 5px;
}
.cart-remove{
font-size: 20px;
color: #6C5F5B;
cursor: pointer;
}
/*-------------------- product --------------------*/
.shop{
margin-top: 50px;
padding: 4rem 0 3rem ;
}
.container-shop{
max-width: 60%;
margin: auto;
width: 100%;
margin-top: 100px;
}
.section-title{
font-size: 26px;
font-weight: 600;
text-align: center;
text-transform: uppercase;
letter-spacing: 4px;
margin-bottom: 50px;
}
.shop-content{
display: grid;
grid-template-columns: repeat(auto-fit, minmax(220px, auto));
gap: 20px;
}
.product-box{
position: relative;
background-color: white;
padding: 10px;
border-radius: 5px;
transition: 0.4s cubic-bezier(0.075, 0.82, 0.165, 1);
}
.product-box:hover{
border: 1px solid black;
box-shadow: 0 8px 32px hsla(0.75, 0.82, 0.165, 1);
transition: 0.3s cubic-bezier(0.075, 0.82, 0.165, 1);
}
.product-img{
width: 100%;
height: 70%;
object-fit: cover;
margin-bottom: 10px;
}
.product-title{
font-size: 18px;
font-weight: 600;
text-transform: capitalize;
margin-bottom: 10px;
}
.price{
font-weight: 500;
}
.add-cart{
position: absolute;
bottom: 10px;
right: 10px;
background-color: white;
border: 1px solid black;
color: black;
padding: 10px;
font-size: 16px;
border-radius: 50%;
cursor: pointer;
}
.add-cart:hover{
background-color: black;
color: white;
}
/*-------------------- payment successful --------------------*/
.sc-container{
width: 100%;
height: 100vh;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
.sc-container img{
width: 200px;
margin: 50px 0;
}
.sc-container h1{
font-size: 38px;
margin-bottom: 20px;
}
.sc-container p{
font-size: 18px;
max-width: 600px;
text-align: center;
margin: 10px;
}
.sc-btn{
padding: 12px 20px;
background-color: lightgrey;
border: 1px solid grey;
font-size: 20px;
font-weight: 600;
text-transform: uppercase;
text-decoration: none;
color: black;
}
@media (width < 1380px) {
.container-shop{
max-width: 80%;
}
}
@media (width < 950px) {
.container-shop{
max-width: 70%;
}
}
@media (width < 750px) {
.container-shop{
max-width: 90%;
}
}
@media (width < 590px) {
.container-shop{
max-width: 50%;
}
.shop-content{
grid-template-columns: repeat(auto-fit, minmax(220px, auto));
}
.menu-logo{
font-size: 48px;
}
.cart{
width: 320px;
}
}
@media (width < 390px) {
.container-shop{
max-width: 60%;
}
.shop-content{
grid-template-columns: repeat(auto-fit, minmax(220px, auto));
}
.menu-logo{
font-size: 48px;
}
.cart{
width: 100%;
}
}

View file

@ -0,0 +1,20 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Payment Successful</title>
<link rel="stylesheet" href="style_extension.css">
<link rel="shortcut icon" href="images/home-logo.png" type="image/x-icon">
<link href='https://unpkg.com/boxicons@2.1.4/css/boxicons.min.css' rel='stylesheet'>
</head>
<body>
<div class="sc-container">
<h1>Payment Successful</h1>
<p>You have completed your payment</p>
<img src="images/success.png" alt="">
<a href="http://localhost:3000" class="sc-btn">Back</a>
</div>
</body>
</html>

View file

@ -0,0 +1,21 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Payment Unsuccessful</title>
<link rel="stylesheet" href="style_extension.css">
<link rel="shortcut icon" href="images/home-logo.png" type="image/x-icon">
<link href='https://unpkg.com/boxicons@2.1.4/css/boxicons.min.css' rel='stylesheet'>
</head>
<body>
<div class="sc-container">
<h1>Payment Unsuccessful</h1>
<p>Oops! Something went wrong. Please try again or contact us for any support at</p>
<p>help@example.com</p>
<img src="images/no.png" alt="">
<a href="http://localhost:3000" class="sc-btn">Back</a>
</div>
</body>
</html>

65
bakery_website/server.js Executable file
View file

@ -0,0 +1,65 @@
import express from 'express';
import dotenv from 'dotenv'
import stripe from 'stripe';
//load variable
dotenv.config();
//start server
const app = express();
app.use(express.static('public'));
app.use(express.json());
//Home Route
app.get('/', (req, res) => {
res.sendFile('menu.html', {root: 'public'});
});
//success
app.get('/success', (req, res) => {
res.sendFile('success.html', {root: 'public'});
});
//unsuccess
app.get('/unsuccess', (req, res) => {
res.sendFile('unsuccess.html', {root: 'public'});
});
//stripe
let stripeGateway = stripe(process.env.stripe_api);
let DOMAIN = process.env.DOMAIN;
app.post('/stripe-checkout', async (req, res) => {
const lineItems = req.body.items.map((item) => {
const unitAmount = parseInt(item.price.replace(/[^0-9.-]+/g, '') * 100);
console.log('item-price:', item.price);
console.log('unitAmount:', unitAmount);
return {
price_data:{
currency: 'usd',
product_data: {
name: item.title,
images: [item.productImg]
},
unit_amount: unitAmount,
},
quantity: item.quantity,
};
});
console.log('lineItems:', lineItems);
//craete checkout
const session = await stripeGateway.checkout.sessions.create({
payment_method_types: ['card'],
mode: 'payment',
success_url: `${DOMAIN}/success`,
cancel_url: `${DOMAIN}/unsuccess`,
line_items: lineItems,
//asking address in stripe checkout
billing_address_collection: 'required'
});
res.json(session.url);
});
app.listen(3005, ()=>{
console.log('listening on port 3005;');
});