Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

6 feature/checkout page #11

Open
wants to merge 2 commits into
base: 5-feature/product-page
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions functions/index.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,27 @@
const functions = require('firebase-functions');
const admin = require('firebase-admin');

admin.initializeApp({
credential: admin.credential.applicationDefault()
});

// // Create and Deploy Your First Cloud Functions
// // https://firebase.google.com/docs/functions/write-firebase-functions
//
// exports.helloWorld = functions.https.onRequest((request, response) => {
// response.send("Hello from Firebase!");
// });

exports.processOrder = functions.firestore.document('orders/{orderId}').onCreate((snap, context) => {
var orderInfo = snap.data.data();
// do some server side code here, probably related to paypal
const r = Math.floor((Math.random() * 5) + 1);
if (r === 1) {
orderInfo.status = 'fail';
} else {
orderInfo.status = 'pending';
orderInfo.paypalRedirectUrl = 'https://github.com/emanlodovice/firebase-codelabs-bacolod/issues/10';
}

return snap.data.ref.set(orderInfo);
});
100 changes: 61 additions & 39 deletions public/checkout.html
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
<script src="https://www.gstatic.com/firebasejs/5.5.8/firebase.js"></script>
<script src="/js/firebase-config.js"></script>
</head>

<body class="row">
Expand All @@ -16,7 +18,7 @@
<a href="/" class="brand-logo left main-nav-content" style="padding-left: 20px"><i class="material-icons">store</i>My Shop</a>
<ul class="right main-nav-content">
<li><a href="" id="search-icon"><i class="material-icons">search</i></a></li>
<li><a href="/login.html"><i class="material-icons">account_circle</i></a></li>
<li><a href="/login.html" id="nav-user"><i class="material-icons">account_circle</i></a></li>
</ul>
<form id="search-form" class="hide">
<div class="input-field">
Expand All @@ -30,57 +32,77 @@
</div>
<!-- End Navbar -->

<div class="container col m6 offset-m3 s12 section">
<div class="container col m6 offset-m3 s12 section hide" id="product-detail">
<br>
<h4>Checkout</h4>
<!-- Start Product Info -->
<div class="row">
<div class="col m2 s4">
<img src="/images/g.jpg" width="100%">
<form id="checkout-form">
<div class="row">
<div class="col m2 s4">
<img src="/images/g.jpg" width="100%" id="image-preview">
</div>
<div class="col m8 s8">
<h5 id="name">Lorem ipsum dolor sit amet, consectetur adipisicing elit.</h5>
<h6><strong id="price">P 100.00</strong></h6>
</div>
<div class="col m2 s12">
<input type="number" name="quanity" min="1" value="1" id="quantity">
<input type="text" value="Total: P 2000.00" id="total" disabled>
</div>
</div>
<div class="col m8 s8">
<h5>Lorem ipsum dolor sit amet, consectetur adipisicing elit.</h5>
<h6><strong>P 100.00</strong></h6>
</div>
<div class="col m2 s12">
<input type="number" name="quanity" min="1" value="1">
<input type="text" value="Total: P 2000.00" disabled>
</div>
</div>
<!-- End Product Info -->
<!-- End Product Info -->

<!-- Start Delivery Address -->
<h5>Address and Contact Information</h5>
<div class="row">
<div class="input-field col s6">
<input placeholder="John" id="first_name" type="text" class="validate" name="first_name">
<label for="first_name">First Name</label>
<!-- Start Delivery Address -->
<h5>Address and Contact Information</h5>
<div class="row">
<div class="input-field col s6">
<input placeholder="John" id="first_name" type="text" class="validate" name="first_name">
<label for="first_name">First Name</label>
</div>
<div class="input-field col s6">
<input placeholder="Doe" id="last_name" type="text" class="validate" name="last_name">
<label for="last_name">Last Name</label>
</div>
<div class="input-field col s12">
<input placeholder="Address" id="address" type="text" class="validate" name="address">
<label for="address">Complete Address</label>
</div>
<div class="input-field col s12">
<input placeholder="+631234567890" id="contact" type="text" class="validate" name="contact">
<label for="contact">Contact Number</label>
</div>
</div>
<div class="input-field col s6">
<input placeholder="Doe" id="last_name" type="text" class="validate" name="last_name">
<label for="last_name">Last Name</label>
</div>
<div class="input-field col s12">
<input placeholder="Address" id="address" type="text" class="validate" name="address">
<label for="address">Complete Address</label>
</div>
<div class="input-field col s12">
<input placeholder="+631234567890" id="contact" type="text" class="validate" name="contact">
<label for="contact">Contact Number</label>
<!-- End Delivery Address -->

<!-- Start Pay Button -->
<div class="center-align">
<button class="waves-effect waves-light btn-large amber darken-4 valign-wrapper" id="pay"><i><img src="/images/ppcom.png" height="100%" alt=""></i></button>
</div>
</div>
<!-- End Delivery Address -->
<!-- End Pay Button -->
</form>

<!-- Start Pay Button -->
<div class="center-align">
<a class="waves-effect waves-light btn-large amber darken-4 valign-wrapper"><i><img src="/images/ppcom.png" height="100%" alt=""></i></a>
</div>
<!-- End Pay Button -->
</div>

<br>

<div class="center-align col s12" id="loader">
<div class="preloader-wrapper big active">
<div class="spinner-layer spinner-blue-only">
<div class="circle-clipper left">
<div class="circle"></div>
</div><div class="gap-patch">
<div class="circle"></div>
</div><div class="circle-clipper right">
<div class="circle"></div>
</div>
</div>
</div>
</div>

<script src="/js/jquery.js"></script>
<script src="/js/materialize.min.js"></script>
<script src="/js/nav.js"></script>
<script src="/js/firestore-config.js"></script>
<script src="/js/checkout.js"></script>
</body>
</html>
100 changes: 100 additions & 0 deletions public/js/checkout.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
function checkout() {
var url = new URL(window.location);
var urlParams = new URLSearchParams(url.search);
var productId = urlParams.get('product');

if (!productId) {
window.location = '/';
}

var product = null;

(function renderProduct() {
var productsCollection = firebase.firestore().collection('products');
productsCollection.doc(productId).get().then(function(snapshot) {
if(!snapshot.exists) {
window.location = '/';
}
product = snapshot.data();

$('#image-preview').attr('src', product.imageUrl);
$('#name').text(product.name);
$('#description').text(product.description);
$('#price').text('P ' + parseFloat(product.price).toFixed(2));
$('#checkout').attr('href', '/checkout.html?product=' + productId);

updateTotalCost();

$('#product-detail').removeClass('hide');
$('#loader').addClass('hide');
});
})();

function updateTotalCost() {
var quantity = $('#quantity').val();
var cost = parseFloat(product.price) * quantity;
$('#total').val('P ' + cost.toFixed(2));
}

(function enableQuantityChange() {
$('#quantity').on('change', updateTotalCost);
})();

(function enableCheckout() {
var ordersCollection = firebase.firestore().collection('orders');
var lock = false;

$('#checkout-form').on('submit', function(e) {
e.preventDefault();
if (lock) {
return;
}
lock = true;
$('#pay').addClass('hide');
$('#loader').removeClass('hide');

var quantity = $('#quantity').val();
var fname = $('#first_name').val();
var lname = $('#last_name').val();
var address = $('#address').val();
var contact = $('#contact').val();
var uid = firebase.auth().currentUser.uid;

ordersCollection.add({
product: productId,
uid: uid,
quantity: quantity,
firstName: fname,
lastName: lname,
address: address,
contact: contact,
timestamp: firebase.firestore.FieldValue.serverTimestamp()
}).then(function(order) {
order.onSnapshot(function(updatedOrder) {
var newOrderData = updatedOrder.data();
if (newOrderData.paypalRedirectUrl) {
window.location = newOrderData.paypalRedirectUrl;
} else if (newOrderData.status === 'fail') {
M.toast({html: 'Failed to process order.', classes: 'rounded'});
lock = false;
$('#pay').removeClass('hide');
$('#loader').addClass('hide');
}
});
}).catch(function(error) {
M.toast({html: error.message, classes: 'rounded'});
lock = false;
$('#pay').removeClass('hide');
$('#loader').addClass('hide');
});
});
})();;
}

$(document).ready(checkout);

$(window).on('auth', function(e, user) {
if (!user) {
window.location = '/login.html'
}
});