diff --git a/day10/app.js b/day10/app.js
index 97a1728..0ae488b 100644
--- a/day10/app.js
+++ b/day10/app.js
@@ -1,11 +1,12 @@
-var createError = require('http-errors');
-var express = require('express');
-var path = require('path');
-var cookieParser = require('cookie-parser');
-var logger = require('morgan');
+var createError = require("http-errors");
+var express = require("express");
+var path = require("path");
+var cookieParser = require("cookie-parser");
+var logger = require("morgan");
-var indexRouter = require('./routes/index');
-var usersRouter = require('./routes/users');
+var indexRouter = require("./routes/index");
+var usersRouter = require("./routes/users");
+const codeRouter = require("./routes/code");
const db = require("./models");
var cors = require("cors");
@@ -13,17 +14,18 @@ var cors = require("cors");
var app = express();
app.set("db", db);
// view engine setup
-app.set('views', path.join(__dirname, 'views'));
-app.set('view engine', 'jade');
+app.set("views", path.join(__dirname, "views"));
+app.set("view engine", "jade");
app.use(cors());
-app.use(logger('dev'));
+app.use(logger("dev"));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser());
-app.use(express.static(path.join(__dirname, 'public')));
+app.use(express.static(path.join(__dirname, "public")));
-app.use('/', indexRouter);
-app.use('/users', usersRouter);
+app.use("/", indexRouter);
+app.use("/users", usersRouter);
+app.use("/api/v1/code", codeRouter);
// catch 404 and forward to error handler
app.use(function (req, res, next) {
@@ -34,11 +36,11 @@ app.use(function (req, res, next) {
app.use(function (err, req, res, next) {
// set locals, only providing error in development
res.locals.message = err.message;
- res.locals.error = req.app.get('env') === 'development' ? err : {};
+ res.locals.error = req.app.get("env") === "development" ? err : {};
// render the error page
res.status(err.status || 500);
- res.render('error');
+ res.render("error");
});
module.exports = app;
diff --git a/day10/bin/www b/day10/bin/www
index cd1a62f..7742167 100755
--- a/day10/bin/www
+++ b/day10/bin/www
@@ -4,16 +4,16 @@
* Module dependencies.
*/
-var app = require('../app');
-var debug = require('debug')('day-1:server');
-var http = require('http');
+var app = require("../app");
+var debug = require("debug")("day-1:server");
+var http = require("http");
/**
* Get port from environment and store in Express.
*/
-var port = normalizePort(process.env.PORT || '3000');
-app.set('port', port);
+var port = normalizePort(process.env.PORT || "3000");
+app.set("port", port);
/**
* Create HTTP server.
@@ -26,8 +26,8 @@ var server = http.createServer(app);
*/
server.listen(port);
-server.on('error', onError);
-server.on('listening', onListening);
+server.on("error", onError);
+server.on("listening", onListening);
/**
* Normalize a port into a number, string, or false.
@@ -54,22 +54,20 @@ function normalizePort(val) {
*/
function onError(error) {
- if (error.syscall !== 'listen') {
+ if (error.syscall !== "listen") {
throw error;
}
- var bind = typeof port === 'string'
- ? 'Pipe ' + port
- : 'Port ' + port;
+ var bind = typeof port === "string" ? "Pipe " + port : "Port " + port;
// handle specific listen errors with friendly messages
switch (error.code) {
- case 'EACCES':
- console.error(bind + ' requires elevated privileges');
+ case "EACCES":
+ console.error(bind + " requires elevated privileges");
process.exit(1);
break;
- case 'EADDRINUSE':
- console.error(bind + ' is already in use');
+ case "EADDRINUSE":
+ console.error(bind + " is already in use");
process.exit(1);
break;
default:
@@ -83,8 +81,7 @@ function onError(error) {
function onListening() {
var addr = server.address();
- var bind = typeof addr === 'string'
- ? 'pipe ' + addr
- : 'port ' + addr.port;
- debug('Listening on ' + bind);
+ var bind = typeof addr === "string" ? "pipe " + addr : "port " + addr.port;
+ debug("Listening on " + bind);
+ console.log("Server listening on:", bind);
}
diff --git a/day10/invoice.html b/day10/invoice.html
new file mode 100644
index 0000000..0a9e163
--- /dev/null
+++ b/day10/invoice.html
@@ -0,0 +1,191 @@
+
+
+
+
+ A simple, clean, and responsive HTML invoice template
+
+
+
+
+
+
+
+
+
+
+
+
+
+ |
+
+
+ Invoice #: 123
+ Created: January 1, 2023
+ Due: February 1, 2023
+ |
+
+
+ |
+
+
+
+
+
+
+
+ Sparksuite, Inc.
+ 12345 Sunny Road
+ Sunnyville, CA 12345
+ |
+
+
+ Acme Corp.
+ John Doe
+ john@example.com
+ |
+
+
+ |
+
+
+
+ | Payment Method |
+
+ Check # |
+
+
+
+ | Check |
+
+ 1000 |
+
+
+
+ | Item |
+
+ Price |
+
+
+
+ | Website design |
+
+ $300.00 |
+
+
+
+
+
+ |
+
+ Total: $385.00 |
+
+
+
+
+
diff --git a/day10/package.json b/day10/package.json
index b96eef4..fe13f20 100644
--- a/day10/package.json
+++ b/day10/package.json
@@ -3,18 +3,22 @@
"version": "0.0.0",
"private": true,
"scripts": {
- "start": "node ./bin/www"
+ "start": "node ./bin/www",
+ "dev": "node --watch --env-file=.env ./bin/www"
},
"dependencies": {
"cookie-parser": "~1.4.4",
"cors": "^2.8.5",
"debug": "~2.6.9",
"express": "~4.16.1",
+ "html-pdf-node": "^1.0.8",
"http-errors": "~1.6.3",
"jade": "~1.11.0",
"jsonwebtoken": "^8.5.1",
"morgan": "~1.9.1",
"mysql2": "^2.3.3",
+ "node-input-validator": "^4.5.1",
+ "qrcode": "^1.5.4",
"sequelize": "^6.15.1"
}
}
diff --git a/day10/routes/code.js b/day10/routes/code.js
new file mode 100644
index 0000000..55bb79b
--- /dev/null
+++ b/day10/routes/code.js
@@ -0,0 +1,29 @@
+const express = require("express");
+const router = express.Router();
+const fs = require("fs");
+const path = require("path");
+const pdf = require("html-pdf-node");
+
+router.get("/:code", async (req, res) => {
+ const { amount = 1, service = "software service" } = req.query;
+
+ // Read the invoice template
+ const templatePath = path.join(__dirname, "../invoice.html");
+ let html = fs.readFileSync(templatePath, "utf8");
+
+ // Replace placeholders in the template
+ html = html
+ .replace("Website design", service)
+ .replace("$300.00", `$${amount}.00`)
+ .replace("Total: $385.00", `Total: $${amount}.00`);
+
+ // Generate PDF
+ let file = { content: html };
+ pdf.generatePdf(file, { format: "A4" }).then((pdfBuffer) => {
+ res.setHeader("Content-Type", "application/pdf");
+ res.setHeader("Content-Disposition", "attachment; filename=invoice.pdf");
+ res.send(pdfBuffer);
+ });
+});
+
+module.exports = router;
diff --git a/day10/routes/index.js b/day10/routes/index.js
index ecca96a..4ef9866 100644
--- a/day10/routes/index.js
+++ b/day10/routes/index.js
@@ -1,9 +1,22 @@
-var express = require('express');
+var express = require("express");
var router = express.Router();
+const QRCode = require("qrcode");
/* GET home page. */
-router.get('/', function(req, res, next) {
- res.render('index', { title: 'Express' });
+router.get("/", function (req, res, next) {
+ res.render("index", { title: "Express" });
+});
+
+router.get("/code", async function (req, res, next) {
+ const code = Math.random().toString(36).substring(2, 8); // random code
+ const qrUrl = `/api/v1/code/${code}?amount=1&service=software%20service`;
+ const qrData = await QRCode.toDataURL(
+ `http://localhost:${process.env.PORT || 3000}${qrUrl}`
+ );
+ res.render("code", {
+ qrData,
+ qrUrl: `http://localhost:${process.env.PORT || 3000}${qrUrl}`,
+ });
});
module.exports = router;
diff --git a/day10/views/code.jade b/day10/views/code.jade
new file mode 100644
index 0000000..3ff3419
--- /dev/null
+++ b/day10/views/code.jade
@@ -0,0 +1,6 @@
+extends layout
+
+block content
+ h1 QR Code
+ img(src=qrData)
+ p Link: #{qrUrl}
\ No newline at end of file