Skip to content

Commit

Permalink
Receipts + Order History
Browse files Browse the repository at this point in the history
  • Loading branch information
sethwalker1 committed Jul 26, 2021
1 parent ba86cd0 commit 40ac174
Show file tree
Hide file tree
Showing 12 changed files with 425 additions and 9 deletions.
16 changes: 16 additions & 0 deletions routes/authenticate.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,22 @@ const bcrypt = require('bcryptjs')
const express = require('express')
const router = express.Router();

router.post('/verifyIntegrity', async (req, res) => {
const {
body: { token },
method,
} = req

let user = await sql.query(`
SELECT id
FROM users
WHERE token = ?
LIMIT 1`, [token]);

if (!user) return res.json({ error: 'Invalid token. Try logging back in.' })
res.status(200).end();
})

router.post('/login', async (req, res) => {
const {
body: { email, password },
Expand Down
155 changes: 155 additions & 0 deletions routes/cart.js
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,129 @@ router.post('/fetch', async (req, res) => {
res.json({ data: Object.values(result) });
});

router.post('/fetchall', async (req, res) => {
const {
body: { token },
method,
} = req

let user = await sql.query(`
SELECT id
FROM users
WHERE token = ?
LIMIT 1`, [token]);
if (!user) return res.json({ error: 'Invalid token. Try logging back in.' })
user = user.id

let orders = await sql.query(`
SELECT id, time FROM orders
WHERE user_id = ? AND status = 1
ORDER BY time DESC`,
[user])
if (!orders || !orders.length) return res.json({ data: [] })

let result = {};
for (let order of orders) {
let { time } = order;
order = order.id;
result[order] = { id: order, time, items: []};

let items = await sql.query(`
SELECT items.id, items.product_id, items.quantity, products.name, products.cost as price FROM orders
INNER JOIN order_items as items
ON orders.id = items.order_id
JOIN products
ON items.product_id = products.id
WHERE orders.id = ?
ORDER BY time DESC`,
[order])
if (!items) return res.json({ data: [] })

let temp = {};
items.map(item => {
let { id, name, price, quantity } = item;
return temp[id] = { id, name, price, quantity };
});

let toppings = await sql.query(`
SELECT orders.order_item, toppings.name, toppings.price FROM order_modifications as orders
JOIN toppings
ON orders.topping_id = toppings.id
WHERE order_id = ?`, [order]);

if (toppings) {
for (let topping of toppings) {
if (!temp[topping.order_item].toppings)
temp[topping.order_item].toppings = [];
let { name, price } = topping;
temp[topping.order_item].toppings.push({ name, price });
}
}

result[order].items = Object.values(temp);
}

res.json({ data: Object.values(result) });
});

router.post('/receipt', async (req, res) => {
const {
body: { token },
method,
} = req

let user = await sql.query(`
SELECT id
FROM users
WHERE token = ?
LIMIT 1`, [token]);
if (!user) return res.json({ error: 'Invalid token. Try logging back in.' })
user = user.id

let order = await sql.query(`
SELECT id, time FROM orders
WHERE user_id = ? AND status = 1
ORDER BY time DESC LIMIT 1`,
[user])
if (!order) return res.json({ data: [] })
let { time } = order;
order = order.id

let items = await sql.query(`
SELECT items.id, items.product_id, items.quantity, products.name, products.cost as price FROM orders
INNER JOIN order_items as items
ON orders.id = items.order_id
JOIN products
ON items.product_id = products.id
WHERE orders.id = ?
ORDER BY time DESC`,
[order])
if (!items) return res.json({ data: [] })

let result = {};
items.map(item => {
let { id, name, price, quantity } = item;
return result[id] = { id, name, price, quantity };
});

let toppings = await sql.query(`
SELECT orders.order_item, toppings.name, toppings.price FROM order_modifications as orders
JOIN toppings
ON orders.topping_id = toppings.id
WHERE order_id = ?`, [order]);

if (toppings) {
for (let topping of toppings) {
if (!result[topping.order_item].toppings)
result[topping.order_item].toppings = [];
let { name, price } = topping;
result[topping.order_item].toppings.push({ name, price });
}
}

res.json({ data: { id: order, time, items: Object.values(result) }});
});

router.post('/add', async (req, res) => {
const {
body: { token, product, quantity, toppings },
Expand Down Expand Up @@ -154,4 +277,36 @@ router.post('/remove', async (req, res) => {
res.status(200).end();
})

router.post('/checkout', async (req, res) => {
const {
body: { token, type },
method,
} = req

let user = await sql.query(`
SELECT id
FROM users
WHERE token = ?
LIMIT 1`, [token]);
if (!user) return res.json({ error: 'Invalid token. Try logging back in.' })
user = user.id

let order = await sql.query(`
SELECT id FROM orders
WHERE user_id = ? AND status = 0
ORDER BY time DESC LIMIT 1`,
[user])
if (!order) return res.json({ data: [] })
order = order.id

let r = await sql.query(`
UPDATE orders
SET status = 1,
type = ?,
time = ?
WHERE id = ?`, [type, ~~(Date.now() / 1000), order]);

res.status(200).end();
});

module.exports = router
1 change: 1 addition & 0 deletions www/404.html
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
---
permalink: /404
title: 404
layout: default
---

Expand Down
7 changes: 5 additions & 2 deletions www/_includes/navbar.html
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@
<li id="login" class="nav-item me-3 me-lg-0" style="display: none">
<a class="nav-link" href="/login"><i class="fas fa-user-alt"></i></a>
</li>
<li id="history" class="nav-item me-3 me-lg-0" style="display: none">
<a class="nav-link" href="/history"><i class="fas fa-list-ol"></i></a>
</li>
<li id="logout" class="nav-item me-3 me-lg-0" style="display: none">
<a class="nav-link" href="/logout"><i class="fas fa-sign-out-alt"></i></a>
</li>
Expand All @@ -36,6 +39,6 @@

<script>
let token = localStorage.getItem('loginToken'), btn;
btn = token ? document.querySelector('#logout') : document.querySelector('#login');
btn.style.display = 'block';
btn = token ? $('#logout, #history') : $('#login');
btn.css('display', 'block')
</script>
11 changes: 11 additions & 0 deletions www/_layouts/default.html
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,17 @@
type="text/javascript"
src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"
></script>
<script>
(async () => {
let token = localStorage.getItem('loginToken');
if (token) {
let res = await $.post('{{ site.api }}/auth/verifyIntegrity', { token });
if (!res || !res.error) return;
localStorage.removeItem('loginToken');
window.location.reload();
}
})();
</script>
{% include navbar.html %}
<div class="container-fluid {% if page.container_class %}{{ page.container_class }}{% endif %}">
{{ content }}
Expand Down
30 changes: 23 additions & 7 deletions www/cart.html
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
layout: default
title: Login
title: Cart
container_class: col-xl-5 col-lg-6 col-sm-8 d-flex flex-column justify-content-center flex-grow-1 mt-2
---

Expand All @@ -14,7 +14,7 @@
<!--Body-->
<div class="modal-body">
<form class="text-center border border-light p-3" action="#!">
<table class="table table-hover">
<table class="table table-hover m-0">
<thead>
<tr>
<th>#</th>
Expand All @@ -27,7 +27,13 @@
</table>
</form>

<p>Subtotal: <span id="subtotal">$0.00</span></p>
<div class="d-inline-flex pb-3">
<select id="type" class="browser-default custom-select m-2">
<option value="1" selected>Takeout</option>
<option value="2">Delivery</option>
</select>
<p class="mx-2 my-auto">Subtotal: <span id="subtotal">$0.00</span></p>
</div>

<button id="check_out" class="btn btn-secondary btn-block mb-4" type="submit">Check out</button>
</div>
Expand Down Expand Up @@ -63,7 +69,7 @@
// something in cart
let items = res.data;
let subtotal = 0;
items.map(item => {
items.map((item, i) => {
let price = item.price * item.quantity;
if (item.toppings) {
for (let topping of item.toppings)
Expand All @@ -74,7 +80,7 @@
subtotal += price;

$('#table').append(`<tr>
<th scope="row">1</th>
<th scope="row">${item.quantity}</th>
<td>${item.name}</td>
<td class="price">${item.price}</td>
<td><a href="#" onclick="removeItem(${item.id})" data-id="${item.id}" style="color: black"><i class="fas fa-times"></i></a></td>
Expand All @@ -87,8 +93,18 @@
}
})();

document.querySelector('#check_out').addEventListener('click', e => {
document.querySelector('#check_out').addEventListener('click', async e => {
e.preventDefault();
window.location.href = '/';
let token = localStorage.getItem('loginToken');
let res = await $.post('{{ site.api }}/cart/checkout', {
token,
type: document.querySelector('#type').value
});

if (typeof res === 'string') {
window.location.href = '/receipt';
} else if (!res || res.error) {
console.error(res.error);
}
});
</script>
8 changes: 8 additions & 0 deletions www/cdn/css/global.css
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,14 @@ html, body {
border: 0.125rem solid var(--danger-hover-color) !important;
}

.custom-select {
padding: .375rem 1.75rem .375rem .75rem;
color: #495057;
vertical-align: middle;
border: 1px solid #ced4da;
border-radius: .25rem;
}

/* Menu Items */
.menuItem > .row {
margin: 1rem 0.25rem 0.5rem 0;
Expand Down
1 change: 1 addition & 0 deletions www/cdn/img/invoice.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions www/cdn/img/receipt.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading

1 comment on commit 40ac174

@vercel
Copy link

@vercel vercel bot commented on 40ac174 Jul 26, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.