From 14c0dddf93be40a8c3bbcdb1eb2a8e12fb36bf51 Mon Sep 17 00:00:00 2001 From: Robbie Antenesse Date: Thu, 27 Dec 2018 10:55:59 -0700 Subject: [PATCH] Improve templates; Add navbar; Show book details --- package.json | 2 +- public/js/little-library.js | 14 +++---- server.js | 64 ++++++++++++++++++++----------- settings.json | 2 + templates/elements/book.html | 2 +- templates/elements/modalCard.html | 15 ++++++++ templates/htmlContainer.html | 54 ++++++++++++++++++++++++-- templates/pages/uploadForm.html | 22 ++++++++--- yarn.lock | 8 ++-- 9 files changed, 139 insertions(+), 44 deletions(-) create mode 100644 templates/elements/modalCard.html diff --git a/package.json b/package.json index 2d714e1..8e978db 100644 --- a/package.json +++ b/package.json @@ -17,7 +17,7 @@ "filenamify": "^2.1.0", "helmet": "^3.15.0", "jquery": "^3.3.1", - "slugify": "^1.3.4", + "snarkdown": "^1.2.2", "socket.io": "^2.2.0", "socket.io-client": "^2.2.0", "unused-filename": "^1.0.0" diff --git a/public/js/little-library.js b/public/js/little-library.js index a5aa418..66cc445 100644 --- a/public/js/little-library.js +++ b/public/js/little-library.js @@ -1,8 +1,13 @@ $(document).ready(function() { var socket = io(); - $('.modal-background, .modal-close').click(function() { - $(this).parent('.modal').removeClass('is-active'); + $('.modal-background, .modal-close, .modal-card-head .delete, .modal-card-foot .close').click(function() { + $(this).closest('.modal').removeClass('is-active'); + }); + + $('.modal-button').click(function() { + var modal = $(this).data('modal'); + $('#' + modal).addClass('is-active'); }); $('#book').change(function() { @@ -16,9 +21,4 @@ $(document).ready(function() { } $('#bookFileName').text(fileName ? fileName : 'None Selected'); }); - - $('.book').click(function() { - var modal = $(this).data('modal'); - $('#' + modal).addClass('is-active'); - }); }); \ No newline at end of file diff --git a/server.js b/server.js index d234a06..7935097 100644 --- a/server.js +++ b/server.js @@ -8,6 +8,7 @@ const bodyParser = require('body-parser'); const fileUpload = require('express-fileupload'); const filenamify = require('filenamify'); const unusedFilename = require('unused-filename'); +const snarkdown = require('snarkdown'); const settings = require('./settings.json'); @@ -44,21 +45,7 @@ function Server () { this.server.use('/css', express.static(path.join(__dirname, './public/css/'))); this.server.get('/', (req, res) => { - const files = fs.readdirSync(this.fileLocation).filter(fileName => fileName.includes('.json')); - const books = files.map(fileName => { - const bookData = JSON.parse(fs.readFileSync(path.resolve(this.fileLocation, fileName), 'utf8')); - const id = fileName.replace('.json', ''); - const content = '
' + bookData.summary + '
'; - const modal = this.fillTemplate('./templates/elements/modal.html', { content, id }); - return this.fillTemplate('./templates/elements/book.html', { - id, - title: bookData.title, - author: bookData.author, - modal, - }) - }).join(''); - const body = this.fillTemplate('./templates/pages/booksList.html', { books }); - const html = this.fillTemplate('./templates/htmlContainer.html', { body }); + const html = this.generateHomePage(); if (html) { res.send(html); } else { @@ -66,14 +53,19 @@ function Server () { } }); + this.server.get('/give', (req, res) => { + const body = this.fillTemplate('./templates/pages/uploadForm.html'); + const html = this.fillTemplate('./templates/htmlContainer.html', { title: 'Give a Book', body }); + res.send(html); + }); this.server.post('/give', (req, res) => { if (Object.keys(req.files).length > 0 && req.body.hasOwnProperty('title') && req.body.title.trim() !== '' && req.body.hasOwnProperty('summary') && req.body.summary.trim() !== '') { const { book } = req.files; - const { title, author, summary } = req.body; + const { title, author, summary, contributor } = req.body; const fileType = book.name.substr(book.name.lastIndexOf('.')); - this.addBook({ book, title, author, summary, fileType }, () => { + this.addBook({ book, title, author, summary, contributor, fileType }, () => { const messageBox = this.fillTemplate('./templates/elements/messageBox.html', { style: 'is-success', header: 'Upload Successful', @@ -84,7 +76,7 @@ function Server () { content: messageBox, }); const body = this.fillTemplate('./templates/pages/uploadForm.html'); - const html = this.fillTemplate('./templates/htmlContainer.html', { body, modal }); + const html = this.fillTemplate('./templates/htmlContainer.html', { title: 'Give a Book', body, modal }); res.send(html); }, (err) => { const messageBox = this.fillTemplate('./templates/elements/messageBox.html', { @@ -97,7 +89,7 @@ function Server () { content: messageBox, }); const body = this.fillTemplate('./templates/pages/uploadForm.html'); - const html = this.fillTemplate('./templates/htmlContainer.html', { body, modal }); + const html = this.fillTemplate('./templates/htmlContainer.html', { title: 'Give a Book', body, modal }); res.send(html); }); } else { @@ -117,7 +109,7 @@ function Server () { message: errorMessage, }); const body = this.fillTemplate('./templates/pages/uploadForm.html'); - const html = this.fillTemplate('./templates/htmlContainer.html', { body, message }); + const html = this.fillTemplate('./templates/htmlContainer.html', { title: 'Give a Book', body, message }); res.send(html); } }); @@ -130,7 +122,7 @@ function Server () { if (fileLocation) { console.log(socket.id + ' removed ' + bookId); const downloadLocation = fileLocation.substr(fileLocation.lastIndexOf('/')); - socket.emit('./files' + downloadLocation); + socket.emit('get book', './files' + downloadLocation); } }); @@ -153,7 +145,9 @@ Server.prototype.fillTemplate = function (file, templateVars = {}) { this.templateCache[file] = data; } - let filledTemplate = data.replace(/\{\{allowedFormats\}\}/g, settings.allowedFormats.join(',')) + let filledTemplate = data.replace(/\{\{siteTitle\}\}/g, settings.siteTitle) + .replace(/\{\{titleSeparator\}\}/g, settings.titleSeparator) + .replace(/\{\{allowedFormats\}\}/g, settings.allowedFormats.join(',')) .replace(/\{\{maxFileSize\}\}/g, (settings.maxFileSize > 0 ? settings.maxFileSize + 'MB' : 'no')); for (let templateVar in templateVars) { @@ -170,6 +164,31 @@ Server.prototype.fillTemplate = function (file, templateVars = {}) { return data; } +Server.prototype.generateHomePage = function () { + const files = fs.readdirSync(this.fileLocation).filter(fileName => fileName.includes('.json')); + const books = files.map(fileName => { + const bookData = JSON.parse(fs.readFileSync(path.resolve(this.fileLocation, fileName), 'utf8')); + const id = fileName.replace('.json', ''); + const header = '

' + bookData.title + '

' + bookData.author + '

'; + const content = '

Contributed by ' + bookData.contributor + '

' + snarkdown(bookData.summary) + '
'; + const footer = 'Close Take Book'; + const modal = this.fillTemplate('./templates/elements/modalCard.html', { + id, + header, + content, + footer, + }); + return this.fillTemplate('./templates/elements/book.html', { + id, + title: bookData.title, + author: bookData.author, + modal, + }); + }).join(''); + const body = this.fillTemplate('./templates/pages/booksList.html', { books }); + return this.fillTemplate('./templates/htmlContainer.html', { title: 'View', body }); +} + Server.prototype.broadcastVisitors = function () { const numberConnected = this.io.of('/').clients().connected.length; this.io.emit('connected', numberConnected); @@ -190,6 +209,7 @@ Server.prototype.addBook = function (uploadData = {}, success = () => {}, error title: uploadData.title.trim(), author: uploadData.author.trim(), summary: uploadData.summary.trim(), + contributor: uploadData.contributor.trim(), fileType: book.name.substr(book.name.lastIndexOf('.')), } diff --git a/settings.json b/settings.json index e3f4ae0..5bb9e41 100644 --- a/settings.json +++ b/settings.json @@ -1,5 +1,7 @@ { "port": 3000, + "siteTitle": "Little Library", + "titleSeparator": " | ", "fileLocation": "./public/files/", "historyLocation": "./public/history/", "maxLibrarySize": 0, diff --git a/templates/elements/book.html b/templates/elements/book.html index 595f23b..f830a05 100644 --- a/templates/elements/book.html +++ b/templates/elements/book.html @@ -1,5 +1,5 @@
-
+ diff --git a/templates/elements/modalCard.html b/templates/elements/modalCard.html new file mode 100644 index 0000000..7912cfa --- /dev/null +++ b/templates/elements/modalCard.html @@ -0,0 +1,15 @@ + \ No newline at end of file diff --git a/templates/htmlContainer.html b/templates/htmlContainer.html index 9b55f4b..7b80ea9 100644 --- a/templates/htmlContainer.html +++ b/templates/htmlContainer.html @@ -6,7 +6,7 @@ - {{title}}Little Library + {{title}}{{titleSeparator}}{{siteTitle}} @@ -17,9 +17,57 @@ - {{message}} + + +
+
+ + {{message}} + + {{body}} + +
+
+ + {{modal}} diff --git a/templates/pages/uploadForm.html b/templates/pages/uploadForm.html index d1b81f5..0f231f9 100644 --- a/templates/pages/uploadForm.html +++ b/templates/pages/uploadForm.html @@ -1,18 +1,28 @@
-
-
-
+
+ +
+ +
diff --git a/yarn.lock b/yarn.lock index d4ef301..3585035 100644 --- a/yarn.lock +++ b/yarn.lock @@ -690,10 +690,10 @@ setprototypeof@1.1.0: resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.1.0.tgz#d0bd85536887b6fe7c0d818cb962d9d91c54e656" integrity sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ== -slugify@^1.3.4: - version "1.3.4" - resolved "https://registry.yarnpkg.com/slugify/-/slugify-1.3.4.tgz#78d2792d7222b55cd9fc81fa018df99af779efeb" - integrity sha512-KP0ZYk5hJNBS8/eIjGkFDCzGQIoZ1mnfQRYS5WM3273z+fxGWXeN0fkwf2ebEweydv9tioZIHGZKoF21U07/nw== +snarkdown@^1.2.2: + version "1.2.2" + resolved "https://registry.yarnpkg.com/snarkdown/-/snarkdown-1.2.2.tgz#0cfe2f3012b804de120fc0c9f7791e869c59cc74" + integrity sha1-DP4vMBK4BN4SD8DJ93kehpxZzHQ= socket.io-adapter@~1.1.0: version "1.1.1"