Make everything templates; confirm uploads
This commit is contained in:
parent
464535b6ad
commit
f0656d7d15
|
@ -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');
|
||||
})
|
||||
});
|
71
server.js
71
server.js
|
@ -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);
|
||||
}
|
||||
});
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
<article class="message {{style}}">
|
||||
<div class="message-header">
|
||||
<p>{{header}}</p>
|
||||
</div>
|
||||
<div class="message-body">
|
||||
{{message}}
|
||||
</div>
|
||||
</article>
|
|
@ -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>
|
|
@ -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>
|
|
@ -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>
|
Loading…
Reference in New Issue