Make everything templates; confirm uploads

This commit is contained in:
Robbie Antenesse 2018-12-26 16:36:35 -07:00
parent 464535b6ad
commit f0656d7d15
6 changed files with 137 additions and 39 deletions

View File

@ -0,0 +1,17 @@
$(document).ready(function() {
$('.modal-background, .modal-close').click(function() {
$(this).parent('.modal').removeClass('is-active');
});
$('#book').change(function() {
var fileName = $(this).val();
if (fileName) {
const lastIndexOfSlash = fileName.lastIndexOf('\\');
if (lastIndexOfSlash < 0) {
lastIndexOfSlash = fileName.lastIndexOf('/');
}
fileName = fileName.substr(lastIndexOfSlash + 1);
}
$('#bookFileName').text(fileName ? fileName : 'None Selected');
})
});

View File

@ -42,7 +42,8 @@ function Server () {
this.server.use('/css', express.static(path.join(__dirname, './public/css/')));
this.server.get('/', (req, res) => {
const html = this.fillTemplate('./public/index.html');
const body = this.fillTemplate('./templates/pages/uploadForm.html');
const html = this.fillTemplate('./templates/htmlContainer.html', { body });
if (html) {
res.send(html);
} else {
@ -56,16 +57,57 @@ function Server () {
let success = false;
if (Object.keys(req.files).length > 0 && req.body.hasOwnProperty('title') && req.body.hasOwnProperty('summary')) {
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 fileType = book.name.substr(book.name.lastIndexOf('.'));
success = this.addBook({ book, title, author, summary, fileType }, () => {
res.send()
this.addBook({ book, title, author, summary, fileType }, () => {
const messageBox = this.fillTemplate('./templates/elements/messageBox.html', {
style: 'is-success',
header: 'Upload Successful',
message: 'Thank you for your contribution!'
});
const modal = this.fillTemplate('./templates/elements/modal.html', {
content: messageBox,
});
const body = this.fillTemplate('./templates/pages/uploadForm.html');
const html = this.fillTemplate('./templates/htmlContainer.html', { body, modal });
res.send(html);
}, (err) => {
const messageBox = this.fillTemplate('./templates/elements/messageBox.html', {
style: 'is-danger',
header: 'Upload Failed',
message: err,
});
const modal = this.fillTemplate('./templates/elements/modal.html', {
content: messageBox,
});
const body = this.fillTemplate('./templates/pages/uploadForm.html');
const html = this.fillTemplate('./templates/htmlContainer.html', { body, modal });
res.send(html);
});
} else {
let errorMessage = '';
if (Object.keys(req.files).length <= 0) {
errorMessage += 'You have not selected a file.';
}
if (!req.body.hasOwnProperty('title') || req.body.title.trim() === '') {
errorMessage += (errorMessage.length > 0 ? '<br>' : '') + 'You have not written a title.';
}
if (!req.body.hasOwnProperty('summary') || req.body.summary.trim() === '') {
errorMessage += (errorMessage.length > 0 ? '<br>' : '') + 'You have not written a summary.';
}
const message = this.fillTemplate('./templates/elements/messageBox.html', {
style: 'is-danger',
header: 'Missing Required Fields',
message: errorMessage,
});
const body = this.fillTemplate('./templates/pages/uploadForm.html');
const html = this.fillTemplate('./templates/htmlContainer.html', { body, message });
res.send(html);
}
res.send(success);
});
this.io.on('connection', socket => {
@ -96,9 +138,12 @@ Server.prototype.fillTemplate = function (file, templateVars = {}) {
for (let templateVar in templateVars) {
const regExp = new RegExp('\{\{' + templateVar + '\}\}', 'g')
filledTemplate = filledTemplate.replace(regexp, templateVars[templateVar]);
filledTemplate = filledTemplate.replace(regExp, templateVars[templateVar]);
}
// If any template variable is not provided, don't even render them.
filledTemplate = filledTemplate.replace(/\{\{[a-zA-Z0-9\-_]+\}\}/g, '');
return filledTemplate;
}
@ -116,27 +161,27 @@ Server.prototype.start = function () {
});
}
Server.prototype.addBook = function (uploadData = {}) {
Server.prototype.addBook = function (uploadData = {}, success = () => {}, error = () => {}) {
const { book } = uploadData;
const bookId = this.uuid4();
const bookPath = path.resolve(this.fileLocation, bookId);
const bookData = {
title: uploadData.title,
author: uploadData.author,
summary: uploadData.summary,
title: uploadData.title.trim(),
author: uploadData.author.trim(),
summary: uploadData.summary.trim(),
fileType: book.name.substr(book.name.lastIndexOf('.')),
}
console.log('moving the book');
const bookFilePath = unusedFilename.sync(path.resolve(bookPath + bookData.fileType));
return book.mv(bookFilePath, function (err) {
if (err) {
success = err;
console.log(err);
error(err);
} else {
const bookDataPath = unusedFilename.sync(path.resolve(bookPath + '.json'));
fs.writeFileSync(bookDataPath, JSON.stringify(bookData));
success();
console.log('uploaded ' + bookData.title + ' to ' + bookFilePath + ', and saved metadata to ' + bookDataPath);
}
});

View File

@ -0,0 +1,8 @@
<article class="message {{style}}">
<div class="message-header">
<p>{{header}}</p>
</div>
<div class="message-body">
{{message}}
</div>
</article>

View File

@ -0,0 +1,7 @@
<div class="modal is-active">
<div class="modal-background"></div>
<div class="modal-content">
{{content}}
</div>
<button class="modal-close is-large" aria-label="close"></button>
</div>

View File

@ -0,0 +1,28 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>{{title}}Little Library</title>
<meta name="description" content="A digital give-a-book, take-a-book library for ebooks">
<link rel="stylesheet" href="./css/bulma.min.css?v=1.0">
<link rel="stylesheet" href="./css/styles.css?v=1.0">
<script src="./js/jquery.min.js"></script>
<script src="./js/socket.io.js"></script>
</head>
<body>
{{message}}
{{body}}
{{modal}}
<script src="./js/little-library.js"></script>
</body>
</html>

View File

@ -1,47 +1,40 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Little Library</title>
<meta name="description" content="The HTML5 Herald">
<link rel="stylesheet" href="./css/bulma.min.css?v=1.0">
<link rel="stylesheet" href="./css/styles.css?v=1.0">
<script src="./js/jquery.min.js"></script>
<script src="./js/socket.io.js"></script>
</head>
<body>
<form action="./give" method="post" enctype="multipart/form-data">
<form action="./give" method="post" enctype="multipart/form-data">
<div class="field">
<label class="label">Book Title:
<input type="text" class="input" name="title" id="title">
</label>
</div>
<div class="field">
<label class="label">Book Author:
<input type="text" class="input" name="author" id="author">
</label>
</div>
<div class="field">
<label class="label">Why you're sharing it:<br>
<textarea class="textarea" name="summary" id="summary"></textarea>
</label>
</div>
<div class="file is-boxed">
<div class="field">
<div class="file is-boxed has-name">
<label class="file-label">
<input class="file-input" type="file" name="book" id="book" accept="{{allowedFormats}}">
<span class="file-cta">
<span class="file-icon">
<i class="fas fa-upload"></i>
</span>
<span class="file-label">
Choose a Book File <code>{{allowedFormats}}</code> ({{maxFileSize}} maximum)
<span class="file-label has-text-centered">
Choose a Book File <code>{{allowedFormats}}</code> ({{maxFileSize}} maximum size)
</span>
</span>
<span class="file-name has-text-centered" id="bookFileName">
None Selected
</span>
</label>
</div>
</div>
<div class="field">
<input class="button" type="submit" value="Give Book" name="submit">
</form>
<script src="./js/little-library.js"></script>
</body>
</html>
</div>
</form>