const express = require('express');
const router = express.Router();
const auth = require('../auth');
const sql = require('mssql');
const { getUser } = require('../util.js');
const multer = require('multer');
const storage = multer.memoryStorage();
const uploadFile = multer({ dest: 'public/img' });
const uploadDB = multer({ storage });
router.get('/', async function(req, res, next) {
res.setHeader('Content-Type', 'text/html');
if (!req.session.user.isAdmin) {
res.send(htmlPage(`
404: Not Found
`, `404: Not Found`));
return;
}
let pool;
try {
let pool = await sql.connect(dbConfig);
// TO/DO: Write SQL query that prints out total order amount by day
let results = await pool.request().query(`
select cast(orderDate as date) as dateOfOrder, sum(totalAmount) as valueOfOrders
from ordersummary
group by cast(orderDate as date)
`);
const chartData = JSON.stringify({
type: 'bar',
data: {
labels: results.recordset.map(r => r.dateOfOrder),
datasets: [{
label: 'Income',
data: results.recordset.map(r => r.valueOfOrders),
borderWidth: 1
}]
},
options: {
scales: {
y: {
beginAtZero: true
}
}
}
});
res.render('layouts/main', {
loggedIn: getUser(req) != null,
user: getUser(req),
spacer: true,
content: `
Sales By Day
Order Date |
Income |
${results.recordset.map(row =>`
${(new Date(row.dateOfOrder)).toDateString()} |
$${Number(row.valueOfOrders).toFixed(2)} |
`).join("\n")}
`,
});
} catch(err) {
console.dir(err);
res.write(err + "");
res.end();
} finally {
if (pool) pool.close();
}
});
router.get('/listCustomers', async (req, res) => {
let pool;
try {
let pool = await sql.connect(dbConfig);
let customers = (await pool.request().query(`
select * from customer
`)).recordset;
res.render('layouts/main', {
title: 'Registered Customers',
loggedIn: getUser(req) != null,
user: getUser(req),
spacer: true,
content: `
Customer Directory
Name |
Username |
Email |
${customers.map(customer =>`
${customer.firstName} ${customer.lastName}
|
${customer.userid}
|
${customer.email}
|
`).join("\n")}
`,
});
} catch (err) {
console.error(err);
res.send("Unable to retrieve customer list");
} finally {
if (pool) pool.close();
}
});
router.get('/productDirectory', async (req, res) => {
let pool;
try {
pool = await sql.connect(dbConfig);
const products = (await pool.request().query(`
select * from product
`)).recordset;
res.render('layouts/main', {
title: 'Admin Product Directory',
spacer: true,
loggedIn: true,
user: getUser(req),
content: `
Admin Product Directory
ID |
Name |
${products.map(p => `
${p.productId} |
${p.productName} |
Update
|
Add Image
|
X
|
`).join('\n')}
`,
});
} catch (err) {
res.send("Could not retrieve categories: " + err.toString());
console.error(err);
} finally {
if (pool) pool.close();
}
});
router.get('/productDelete', async (req, res) => {
let pool;
let stmt;
try {
pool = await sql.connect(dbConfig);
stmt = new sql.PreparedStatement(pool);
stmt.input('productId', sql.VarChar);
await stmt.prepare(`
delete from product where productId = @productId
`);
await stmt.execute({productId: req.query.id});
res.redirect('/admin/productDirectory');
} catch (err) {
res.send("Could not retrieve categories: " + err.toString());
console.error(err);
} finally {
if (stmt) stmt.unprepare();
if (pool) pool.close();
}
});
router.get('/productUpdate', async (req, res) => {
let pool;
let stmt;
try {
pool = await sql.connect(dbConfig);
stmt = new sql.PreparedStatement(pool);
stmt.input('productId', sql.VarChar);
await stmt.prepare(`
select * from product where productId = @productId
`);
const product = (await stmt.execute({productId: req.query.id})).recordset[0];
const categories = (await pool.request().query(`
select * from category
`)).recordset;
res.render('layouts/main', {
title: 'Add a New Product',
loggedIn: true,
user: getUser(req),
spacer: true,
content: `
Update Product
`,
});
} catch (err) {
res.send("Could not retrieve data: " + err.toString());
console.error(err);
} finally {
if (stmt) stmt.unprepare();
if (pool) pool.close();
}
});
router.post('/productUpdate', async (req, res) => {
let pool;
let stmt;
try {
pool = await sql.connect(dbConfig);
stmt = new sql.PreparedStatement(pool);
stmt.input('productName', sql.VarChar);
stmt.input('productPrice', sql.Decimal(10, 2));
stmt.input('productDesc', sql.VarChar);
stmt.input('categoryId', sql.Int);
stmt.input('productId', sql.Int);
await stmt.prepare(`
update product set
productName = @productName,
productPrice = @productPrice,
productDesc = @productDesc,
categoryId = @categoryId
where productId = @productId
`);
console.log(req.query.id);
await stmt.execute({...req.body, productId: req.query.id});
res.redirect(`/admin/productDirectory`);
} catch (err) {
console.error(err);
res.send("Could not add product: " + err.toString());
} finally {
if (stmt) stmt.unprepare();
if (pool) pool.close();
}
});
router.get('/productAddImage', async (req, res) => {
res.render('layouts/main', {
title: 'Add a New Product',
loggedIn: true,
user: getUser(req),
spacer: true,
content: `
Add an image to this product
`,
});
});
router.post('/productAddFileImage', uploadFile.single('productImage'), async (req, res) => {
let pool;
let stmt;
try {
pool = await sql.connect(dbConfig);
stmt = new sql.PreparedStatement(pool);
stmt.input('productId', sql.Int);
stmt.input('productImageURL', sql.VarChar);
await stmt.prepare(`
update product set
productImageURL = @productImageURL
where productId = @productId
`);
await stmt.execute({productId: req.query.id, productImageURL: `img/${req.file.filename}`});
res.redirect('/admin/productDirectory');
} catch (err) {
res.send("Could not update product: " + err.toString());
console.error(err);
} finally {
if (stmt) stmt.unprepare();
if (pool) pool.close();
}
});
router.post('/productAddDBImage', uploadDB.single('productImage'), async (req, res) => {
let pool;
let stmt;
try {
pool = await sql.connect(dbConfig);
stmt = new sql.PreparedStatement(pool);
stmt.input('productId', sql.Int);
stmt.input('productImage', sql.VarBinary);
await stmt.prepare(`
update product set
productImage = @productImage
where productId = @productId
`);
await stmt.execute({productId: req.query.id, productImage: req.file.buffer});
res.redirect('/admin/productDirectory');
} catch (err) {
res.send("Could not update product: " + err.toString());
console.error(err);
} finally {
if (stmt) stmt.unprepare();
if (pool) pool.close();
}
});
router.get('/addProduct', async (req, res) => {
let pool;
try {
pool = await sql.connect(dbConfig);
const categories = (await pool.request().query(`
select * from category
`)).recordset;
res.render('layouts/main', {
title: 'Add a New Product',
loggedIn: true,
user: getUser(req),
spacer: true,
content: `
Add a New Product
`,
});
} catch (err) {
res.send("Could not retrieve categories: " + err.toString());
console.error(err);
} finally {
if (pool) pool.close();
}
});
router.post('/addProduct', uploadDB.single('productImage'), async (req, res) => {
let pool;
let stmt;
try {
pool = await sql.connect(dbConfig);
stmt = new sql.PreparedStatement(pool);
stmt.input('productName', sql.VarChar);
stmt.input('productPrice', sql.Decimal(10, 2));
stmt.input('productDesc', sql.VarChar);
stmt.input('categoryId', sql.Int);
stmt.input('image', sql.VarBinary);
await stmt.prepare(`
insert into product(productName, productPrice, productDesc, productImage, categoryId)
output inserted.productId
values (@productName, @productPrice, @productDesc, @image, @categoryId)
`);
const recordToInsert = {
...req.body,
image: req.body.storageLocation == "file" ? `img/${req.file.filename}` : req.file.buffer,
};
const stmtResults = await stmt.execute(recordToInsert);
res.redirect(`/product/?id=${stmtResults.recordset[0].productId}`);
} catch (err) {
console.error(err);
res.send("Could not add product: " + err.toString());
} finally {
if (stmt) stmt.unprepare();
if (pool) pool.close();
}
});
module.exports = router;