First iteration of PA 6 (UPDATE).
This commit is contained in:
parent
6203d762bb
commit
9fae467b25
10 changed files with 514 additions and 23 deletions
|
@ -156,12 +156,18 @@ input, select, textarea {
|
||||||
box-shadow: #000000 3px 3px 5px;
|
box-shadow: #000000 3px 3px 5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
#outputMessage {
|
#successMessage {
|
||||||
background-color: #4c6b22;
|
background-color: #4c6b22;
|
||||||
color: #b3d4fc;
|
color: #b3d4fc;
|
||||||
min-height: 50px;
|
min-height: 50px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#errorMessage {
|
||||||
|
background-color: darkred;
|
||||||
|
color: #b3d4fc;
|
||||||
|
min-height: 50px;
|
||||||
|
}
|
||||||
|
|
||||||
.tableCoverArt {
|
.tableCoverArt {
|
||||||
max-height: 50px;
|
max-height: 50px;
|
||||||
}
|
}
|
||||||
|
|
351
edit.html
351
edit.html
|
@ -1,10 +1,353 @@
|
||||||
<!DOCTYPE html>
|
<!doctype html>
|
||||||
<html lang="en">
|
<html>
|
||||||
|
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="utf-8">
|
||||||
<title>Edit Game</title>
|
<title>Edit Game</title>
|
||||||
|
<meta name="description" content="">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
|
||||||
|
<link rel="manifest" href="site.webmanifest">
|
||||||
|
<link rel="apple-touch-icon" href="icon.png">
|
||||||
|
|
||||||
|
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/css/bootstrap.min.css" rel="stylesheet"
|
||||||
|
integrity="sha384-rbsA2VBKQhggwzxH7pPCaAqO46MgnOM80zW1RWuH61DGLwZJEdK2Kadq2F9CUG65" crossorigin="anonymous">
|
||||||
|
<link rel="stylesheet" href="css/normalize.css">
|
||||||
|
<link rel="stylesheet" href="css/main.css">
|
||||||
|
|
||||||
|
<meta name="theme-color" content="#488ea7">
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
|
<div id="header" class="container">
|
||||||
|
<h1>Edit Game</h1>
|
||||||
|
<hr/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row mb-3">
|
||||||
|
<div class="col"></div>
|
||||||
|
<div class="col card" id="successMessage"></div>
|
||||||
|
<div class="col"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row mb-3">
|
||||||
|
<div class="col"></div>
|
||||||
|
<div class="col card" id="errorMessage"></div>
|
||||||
|
<div class="col"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="form">
|
||||||
|
<div class="container">
|
||||||
|
|
||||||
|
<div class="row mb-3">
|
||||||
|
<div class="col">
|
||||||
|
<label>Title</label>
|
||||||
|
</div>
|
||||||
|
<div class="col">
|
||||||
|
<input id="title" type="text"/>
|
||||||
|
</div>
|
||||||
|
<div class="col"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row mb-3">
|
||||||
|
<div class="col">
|
||||||
|
<label>
|
||||||
|
Developer
|
||||||
|
<br/>
|
||||||
|
(<a href="insertDeveloper.html">Add New Developer</a>)
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
<div class="col">
|
||||||
|
<select id="developer">
|
||||||
|
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div class="col"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row mb-3">
|
||||||
|
<div class="col">
|
||||||
|
<label>
|
||||||
|
Publisher
|
||||||
|
<br/>
|
||||||
|
(<a href="insertPublisher.html">Add New Publisher</a>)
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
<div class="col">
|
||||||
|
<select id="publisher">
|
||||||
|
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div class="col"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row mb-3">
|
||||||
|
<div class="col">
|
||||||
|
<label>Release Date</label>
|
||||||
|
</div>
|
||||||
|
<div class="col">
|
||||||
|
<input id="releaseDate" type="date"/>
|
||||||
|
</div>
|
||||||
|
<div class="col"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row mb-3">
|
||||||
|
<div class="col">
|
||||||
|
<label>Supported OSes</label>
|
||||||
|
</div>
|
||||||
|
<div class="col">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col">
|
||||||
|
<span>Windows</span>
|
||||||
|
<input id="win" type="checkbox"/>
|
||||||
|
</div>
|
||||||
|
<div class="col">
|
||||||
|
<span>MacOS</span>
|
||||||
|
<input id="mac" type="checkbox"/>
|
||||||
|
</div>
|
||||||
|
<div class="col">
|
||||||
|
<span>Linux</span>
|
||||||
|
<input id="linux" type="checkbox"/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row mb-3">
|
||||||
|
<div class="col">
|
||||||
|
<label>Cover Art</label>
|
||||||
|
</div>
|
||||||
|
<div class="col">
|
||||||
|
<div id="currentArt"></div>
|
||||||
|
<input id="coverArt" type="file"
|
||||||
|
accept="image/jpeg, image/png"/>
|
||||||
|
</div>
|
||||||
|
<div class="col"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row mb-3">
|
||||||
|
<div class="col">
|
||||||
|
<label>Short Description</label>
|
||||||
|
<p>(maximum 300 characters)</p>
|
||||||
|
</div>
|
||||||
|
<div class="col">
|
||||||
|
<textarea id="shortDescription" rows="5" cols="40" maxlength="300"></textarea>
|
||||||
|
</div>
|
||||||
|
<div class="col"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row mb-3">
|
||||||
|
<div class="col">
|
||||||
|
<label>Long Description</label>
|
||||||
|
<p>(supports <a href="https://www.markdownguide.org/">Markdown</a>) </p>
|
||||||
|
</div>
|
||||||
|
<div class="col">
|
||||||
|
<textarea id="longDescription" rows="15" cols="40"></textarea>
|
||||||
|
</div>
|
||||||
|
<div class="col"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row mb-3">
|
||||||
|
<div class="col align-content-center">
|
||||||
|
<button id="submitButton" type="submit">Submit</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<hr/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<footer id="footer">
|
||||||
|
<p>Page created by <a href="https://lunarpenguin.net/">Kaj Forney</a>, as work for class (GIMM 285).</p>
|
||||||
|
<p>All example data used is originally from <a href="https://store.steampowered.com/">Steam</a>.</p>
|
||||||
|
</footer>
|
||||||
|
|
||||||
|
<script src="js/vendor/modernizr-3.11.2.min.js"></script>
|
||||||
|
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/js/bootstrap.bundle.min.js"
|
||||||
|
integrity="sha384-kenU1KFdBIe4zVF0s0G1M5b4hcpxyD9F7jL+jjXkk+Q2h455rYXK/7HAuoJl+0I4"
|
||||||
|
crossorigin="anonymous" defer></script>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
const isEmpty = (obj) => Object.keys(obj).length === 0;
|
||||||
|
|
||||||
|
document.getElementById("successMessage").hidden = true;
|
||||||
|
document.getElementById("errorMessage").hidden = true;
|
||||||
|
|
||||||
|
fetch("http://localhost:8787/developers", { method: 'GET' })
|
||||||
|
.then((response) => {
|
||||||
|
return new Promise((resolve) => response.json()
|
||||||
|
.then((json) => resolve({
|
||||||
|
status: response.status,
|
||||||
|
json,
|
||||||
|
})
|
||||||
|
));
|
||||||
|
})
|
||||||
|
.then(({ status, json }) => {
|
||||||
|
if (200 === status) {
|
||||||
|
const developerSelect = document.getElementById('developer');
|
||||||
|
for (dev of json.data) {
|
||||||
|
let option = document.createElement("option");
|
||||||
|
option.value = dev.id;
|
||||||
|
option.text = dev.name;
|
||||||
|
developerSelect.add(option);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
console.error('Error:', error);
|
||||||
|
});
|
||||||
|
|
||||||
|
fetch("http://localhost:8787/publishers", { method: 'GET' })
|
||||||
|
.then((response) => {
|
||||||
|
return new Promise((resolve) => response.json()
|
||||||
|
.then((json) => resolve({
|
||||||
|
status: response.status,
|
||||||
|
json,
|
||||||
|
})
|
||||||
|
));
|
||||||
|
})
|
||||||
|
.then(({ status, json }) => {
|
||||||
|
if (200 === status) {
|
||||||
|
const publisherSelect = document.getElementById('publisher');
|
||||||
|
for (publisher of json.data) {
|
||||||
|
let option = document.createElement("option");
|
||||||
|
option.value = publisher.id;
|
||||||
|
option.text = publisher.name;
|
||||||
|
publisherSelect.add(option);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
console.error('Error:', error);
|
||||||
|
});
|
||||||
|
|
||||||
|
let urlParams = new URLSearchParams(window.location.search)
|
||||||
|
fetch("http://localhost:8787/games/" + urlParams.get("id"), {method: 'GET'})
|
||||||
|
.then((response) => {
|
||||||
|
return new Promise((resolve) => response.json()
|
||||||
|
.then((json) => resolve({
|
||||||
|
status: response.status,
|
||||||
|
json,
|
||||||
|
})
|
||||||
|
));
|
||||||
|
})
|
||||||
|
.then(({ status, json }) => {
|
||||||
|
if (200 === status) {
|
||||||
|
let gameData = json.data[0];
|
||||||
|
|
||||||
|
if(gameData !== undefined) {
|
||||||
|
document.getElementById("title").value = gameData.title;
|
||||||
|
|
||||||
|
let releaseDate = new Date(gameData.releaseDate);
|
||||||
|
document.getElementById("releaseDate").value = releaseDate.toISOString().split("T", 1);
|
||||||
|
|
||||||
|
document.getElementById("win").checked = Boolean(gameData.win);
|
||||||
|
document.getElementById("mac").checked = Boolean(gameData.mac);
|
||||||
|
document.getElementById("linux").checked = Boolean(gameData.linux);
|
||||||
|
|
||||||
|
let coverImg = document.createElement('img');
|
||||||
|
coverImg.src = "http://localhost:8787/images/" + gameData.coverArt;
|
||||||
|
document.getElementById("currentArt").appendChild(coverImg);
|
||||||
|
|
||||||
|
document.getElementById("shortDescription").value = gameData.shortDescription;
|
||||||
|
document.getElementById("longDescription").value = gameData.longDescription;
|
||||||
|
} else {
|
||||||
|
document.getElementById("errorMessage").innerHTML = "Invalid App ID!";
|
||||||
|
document.getElementById("errorMessage").hidden = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
console.error('Error:', error);
|
||||||
|
});
|
||||||
|
|
||||||
|
document.getElementById('submitButton').addEventListener('click', (event) => {
|
||||||
|
const parameters = {};
|
||||||
|
|
||||||
|
if(urlParams.get("id") !== undefined) {
|
||||||
|
parameters.id = urlParams.get("id");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (document.getElementById('title').value.length !== 0) {
|
||||||
|
//formData.append('title', document.getElementById('title').value);
|
||||||
|
parameters.title = document.getElementById('title').value;
|
||||||
|
}
|
||||||
|
if (document.getElementById('developer').value.length !== 0) {
|
||||||
|
//formData.append('developer', document.getElementById('developer').value);
|
||||||
|
parameters.developerID = document.getElementById('developer').value;
|
||||||
|
}
|
||||||
|
if (document.getElementById('publisher').value.length !== 0) {
|
||||||
|
//formData.append('publisher', document.getElementById('publisher').value);
|
||||||
|
parameters.publisherID = document.getElementById('publisher').value;
|
||||||
|
}
|
||||||
|
if (document.getElementById('releaseDate').value.length !== 0) {
|
||||||
|
//formData.append('releaseDate', document.getElementById('releaseDate').value);
|
||||||
|
parameters.releaseDate = document.getElementById('releaseDate').value;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (document.getElementById('win').checked) {
|
||||||
|
parameters.win = 1;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
parameters.win = 0;
|
||||||
|
}
|
||||||
|
if (document.getElementById('mac').checked) {
|
||||||
|
parameters.mac = 1;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
parameters.mac = 0;
|
||||||
|
}
|
||||||
|
if (document.getElementById('linux').checked) {
|
||||||
|
parameters.linux = 1;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
parameters.linux = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (document.getElementById('shortDescription').value.length !== 0) {
|
||||||
|
parameters.shortDescription = document.getElementById('shortDescription').value;
|
||||||
|
}
|
||||||
|
if (document.getElementById('longDescription').value.length !== 0) {
|
||||||
|
parameters.longDescription = document.getElementById('longDescription').value;
|
||||||
|
}
|
||||||
|
|
||||||
|
const formData = new FormData();
|
||||||
|
const coverField = document.querySelector('input[type="file"]');
|
||||||
|
formData.append("coverArt", coverField.files[0]);
|
||||||
|
|
||||||
|
|
||||||
|
//Settings for FETCH API request
|
||||||
|
let fetchSettings = {
|
||||||
|
method: 'PUT',
|
||||||
|
body: formData
|
||||||
|
};
|
||||||
|
|
||||||
|
//Send FETCH API request
|
||||||
|
fetch("http://localhost:8787/games/" + urlParams.get("id") + (!isEmpty(parameters) ? '?' + new URLSearchParams(parameters) : ''), fetchSettings)
|
||||||
|
.then((response) => {
|
||||||
|
return new Promise((resolve) => response.json()
|
||||||
|
.then((json) => resolve({
|
||||||
|
status: response.status,
|
||||||
|
json,
|
||||||
|
})
|
||||||
|
));
|
||||||
|
})
|
||||||
|
.then(({status, json}) => {
|
||||||
|
if (status === 200) {
|
||||||
|
let message = "Game submission successful!"
|
||||||
|
document.getElementById('outputMessage').hidden = false;
|
||||||
|
document.getElementById('outputMessage').innerHTML = message;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
console.error('Error:', error);
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
|
||||||
|
</html>
|
||||||
|
|
|
@ -58,7 +58,7 @@
|
||||||
document.title = "Pressurized Gas - " + json.data[0].title;
|
document.title = "Pressurized Gas - " + json.data[0].title;
|
||||||
document.getElementById("gameTitle").innerHTML = json.data[0].title;
|
document.getElementById("gameTitle").innerHTML = json.data[0].title;
|
||||||
document.getElementById("longDescription").innerHTML = json.data[0].longDescription;
|
document.getElementById("longDescription").innerHTML = json.data[0].longDescription;
|
||||||
var coverImg = document.createElement('img');
|
let coverImg = document.createElement('img');
|
||||||
coverImg.src = "http://localhost:8787/images/" + json.data[0].coverArt;
|
coverImg.src = "http://localhost:8787/images/" + json.data[0].coverArt;
|
||||||
document.getElementById("coverArt").appendChild(coverImg);
|
document.getElementById("coverArt").appendChild(coverImg);
|
||||||
}
|
}
|
||||||
|
|
|
@ -215,6 +215,7 @@
|
||||||
'<thead>' +
|
'<thead>' +
|
||||||
'<tr>' +
|
'<tr>' +
|
||||||
'<th>Edit Game</th>' +
|
'<th>Edit Game</th>' +
|
||||||
|
'<th>Delete Game</th>' +
|
||||||
'<th>AppID</th>' +
|
'<th>AppID</th>' +
|
||||||
'<th>Title</th>' +
|
'<th>Title</th>' +
|
||||||
'<th>Developer</th>' +
|
'<th>Developer</th>' +
|
||||||
|
@ -248,6 +249,7 @@
|
||||||
for (row of json.data) {
|
for (row of json.data) {
|
||||||
displayTable += '<tr>' +
|
displayTable += '<tr>' +
|
||||||
'<td> <a href="edit.html?id=' + row.appID.toString() + '">Edit</a></td>' +
|
'<td> <a href="edit.html?id=' + row.appID.toString() + '">Edit</a></td>' +
|
||||||
|
'<td> <a href="delete.html?id=' + row.appID.toString() + '">Edit</a></td>' +
|
||||||
'<td>' + row.appID + '</td>' +
|
'<td>' + row.appID + '</td>' +
|
||||||
'<td>' + row.title + '</td>' +
|
'<td>' + row.title + '</td>' +
|
||||||
'<td>' + row.developer + '</td>' +
|
'<td>' + row.developer + '</td>' +
|
||||||
|
|
21
insert.html
21
insert.html
|
@ -24,6 +24,18 @@
|
||||||
<hr/>
|
<hr/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="row mb-3">
|
||||||
|
<div class="col"></div>
|
||||||
|
<div class="col card" id="successMessage"></div>
|
||||||
|
<div class="col"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row mb-3">
|
||||||
|
<div class="col"></div>
|
||||||
|
<div class="col card" id="errorMessage"></div>
|
||||||
|
<div class="col"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div id="form">
|
<div id="form">
|
||||||
<div class="container">
|
<div class="container">
|
||||||
|
|
||||||
|
@ -143,12 +155,6 @@
|
||||||
<hr/>
|
<hr/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="row mb-3">
|
|
||||||
<div class="col"></div>
|
|
||||||
<div class="col card" id="outputMessage"></div>
|
|
||||||
<div class="col"></div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -165,7 +171,8 @@
|
||||||
<script>
|
<script>
|
||||||
const isEmpty = (obj) => Object.keys(obj).length === 0;
|
const isEmpty = (obj) => Object.keys(obj).length === 0;
|
||||||
|
|
||||||
document.getElementById("outputMessage").hidden = true;
|
document.getElementById("successMessage").hidden = true;
|
||||||
|
document.getElementById("errorMessage").hidden = true;
|
||||||
|
|
||||||
fetch("http://localhost:8787/developers", { method: 'GET' })
|
fetch("http://localhost:8787/developers", { method: 'GET' })
|
||||||
.then((response) => {
|
.then((response) => {
|
||||||
|
|
|
@ -7,11 +7,22 @@ const developers = require('./model/developers');
|
||||||
const publishers = require('./model/publishers');
|
const publishers = require('./model/publishers');
|
||||||
const {request, response} = require("express");
|
const {request, response} = require("express");
|
||||||
const {check, checkSchema, validationResult} = require("express-validator");
|
const {check, checkSchema, validationResult} = require("express-validator");
|
||||||
|
const path = require('path');
|
||||||
|
|
||||||
//Setup defaults for script
|
//Setup defaults for script
|
||||||
const app = express();
|
const app = express();
|
||||||
|
const storage = multer.diskStorage({
|
||||||
|
//Logic where to upload files
|
||||||
|
destination: function (request, file, callback) {
|
||||||
|
callback(null, 'public/images/')
|
||||||
|
},
|
||||||
|
//Logic to name the file when uploaded
|
||||||
|
filename: function (request, file, callback) {
|
||||||
|
callback(null, file.originalname + '-' + Date.now() + path.extname(file.originalname))
|
||||||
|
}
|
||||||
|
})
|
||||||
const upload = multer({
|
const upload = multer({
|
||||||
dest: 'public/images/',
|
storage: storage,
|
||||||
//Validation for file upload
|
//Validation for file upload
|
||||||
fileFilter: (request, file, callback) => {
|
fileFilter: (request, file, callback) => {
|
||||||
const allowedFileMimeTypes = ["image/png", "image/jpg", "image/jpeg"];
|
const allowedFileMimeTypes = ["image/png", "image/jpg", "image/jpeg"];
|
||||||
|
@ -134,15 +145,16 @@ app.post('/games', upload.single('coverArt'),
|
||||||
check('shortDescription', 'You must enter a description'),
|
check('shortDescription', 'You must enter a description'),
|
||||||
checkSchema({
|
checkSchema({
|
||||||
'coverArt': {
|
'coverArt': {
|
||||||
|
optional: true,
|
||||||
custom: {
|
custom: {
|
||||||
options: (value, {req, path}) => !!req.files[path],
|
options: (value, {req, path}) => !!req.file[path],
|
||||||
errorMessage: 'Please upload an image file.',
|
errorMessage: 'Please upload an image file.',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
|
|
||||||
async (request, response) => {
|
async (request, response) => {
|
||||||
|
console.log(request.file);
|
||||||
const errors = validationResult(request);
|
const errors = validationResult(request);
|
||||||
if(!errors.isEmpty()) {
|
if(!errors.isEmpty()) {
|
||||||
return response
|
return response
|
||||||
|
@ -238,6 +250,52 @@ app.post('/publishers', upload.none(),
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
app.put('/games/:id', upload.single('coverArt'),
|
||||||
|
check('title', 'You must enter a title.').isLength({min: 3}),
|
||||||
|
check('releaseDate', 'You must select a release date.').isDate(["YYYY-MM-DD"]),
|
||||||
|
check('win', 'Invalid Windows option.').isIn([0, 1]),
|
||||||
|
check('mac', 'Invalid MacOS option.').isIn([0, 1]),
|
||||||
|
check('linux', 'Invalid Linux option.').isIn([0, 1]),
|
||||||
|
check('shortDescription', 'You must enter a description'),
|
||||||
|
checkSchema({
|
||||||
|
'coverArt': {
|
||||||
|
optional: true,
|
||||||
|
custom: {
|
||||||
|
options: (value, {req, path}) => !!req.file[path],
|
||||||
|
errorMessage: 'Please upload an image file.',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
|
||||||
|
async (request, response) => {
|
||||||
|
|
||||||
|
const errors = validationResult(request);
|
||||||
|
if(!errors.isEmpty()) {
|
||||||
|
return response
|
||||||
|
.status(400)
|
||||||
|
.setHeader('Access-Control-Allow-Origin', '*') //Prevent CORS error
|
||||||
|
.json({
|
||||||
|
message: 'Request fields or files are invalid.',
|
||||||
|
errors: errors.array(),
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
console.log(request.query);
|
||||||
|
let result = {};
|
||||||
|
try {
|
||||||
|
result = await games.editGame(request.query.id, request.query, request.file.filename);
|
||||||
|
} catch (error) {
|
||||||
|
console.log(error);
|
||||||
|
return response
|
||||||
|
.status(500) //Error code when something goes wrong with the server
|
||||||
|
.setHeader('Access-Control-Allow-Origin', '*') //Prevent CORS error
|
||||||
|
.json({message: 'Something went wrong with the server.'});
|
||||||
|
}
|
||||||
|
response
|
||||||
|
.setHeader('Access-Control-Allow-Origin', '*') //Prevent CORS error
|
||||||
|
.json({message: 'Game added successfully!'});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
app.listen(port, () => {
|
app.listen(port, () => {
|
||||||
console.log(`Application listening at http://localhost:${port}`);
|
console.log(`Application listening at http://localhost:${port}`);
|
||||||
})
|
})
|
||||||
|
|
|
@ -4,7 +4,8 @@ const credentials = require('./creds.json');
|
||||||
let connection = null;
|
let connection = null;
|
||||||
|
|
||||||
async function query(sql, params) {
|
async function query(sql, params) {
|
||||||
console.log(params);
|
//console.log(sql);
|
||||||
|
//console.log(params);
|
||||||
if (null === connection) {
|
if (null === connection) {
|
||||||
console.log("Establishing connection to database!");
|
console.log("Establishing connection to database!");
|
||||||
connection = await mysql.createConnection(credentials);
|
connection = await mysql.createConnection(credentials);
|
||||||
|
|
|
@ -101,7 +101,9 @@ async function getGame(id) {
|
||||||
m.win_supported AS win,
|
m.win_supported AS win,
|
||||||
m.mac_supported AS mac,
|
m.mac_supported AS mac,
|
||||||
m.linux_supported AS linux,
|
m.linux_supported AS linux,
|
||||||
m.cover_art_filename AS coverArt
|
m.cover_art_filename AS coverArt,
|
||||||
|
m.short_description AS shortDescription,
|
||||||
|
m.long_description_markdown AS longDescription
|
||||||
FROM games_master_table m
|
FROM games_master_table m
|
||||||
INNER JOIN developers d ON m.developer_id = d.id
|
INNER JOIN developers d ON m.developer_id = d.id
|
||||||
INNER JOIN publishers p ON m.publisher_id = p.id`,
|
INNER JOIN publishers p ON m.publisher_id = p.id`,
|
||||||
|
@ -129,8 +131,8 @@ async function addNewGame(formInput, imagePath) {
|
||||||
|
|
||||||
let insertSql = `INSERT INTO games_master_table (game_title, developer_id, publisher_id, release_date,
|
let insertSql = `INSERT INTO games_master_table (game_title, developer_id, publisher_id, release_date,
|
||||||
win_supported, mac_supported, linux_supported,
|
win_supported, mac_supported, linux_supported,
|
||||||
short_description, long_description, cover_art_filename) VALUES
|
short_description, long_description, long_description_markdown, cover_art_filename) VALUES
|
||||||
(?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`;
|
(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`;
|
||||||
let queryParameters = [formInput.title,
|
let queryParameters = [formInput.title,
|
||||||
formInput.developerID,
|
formInput.developerID,
|
||||||
formInput.publisherID,
|
formInput.publisherID,
|
||||||
|
@ -140,13 +142,53 @@ async function addNewGame(formInput, imagePath) {
|
||||||
formInput.linux,
|
formInput.linux,
|
||||||
formInput.shortDescription,
|
formInput.shortDescription,
|
||||||
parsedDescription,
|
parsedDescription,
|
||||||
|
formInput.longDescription,
|
||||||
imagePath];
|
imagePath];
|
||||||
|
|
||||||
return await connection.query(insertSql, queryParameters);
|
return await connection.query(insertSql, queryParameters);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function editGame(id, formInput, imagePath) {
|
||||||
|
|
||||||
|
console.log("Image: " + imagePath);
|
||||||
|
|
||||||
|
let updateSql = `UPDATE games_master_table
|
||||||
|
SET game_title = ?,
|
||||||
|
developer_id = ?,
|
||||||
|
publisher_id = ?,
|
||||||
|
release_date = ?,
|
||||||
|
win_supported = ?,
|
||||||
|
mac_supported = ?,
|
||||||
|
linux_supported = ?,
|
||||||
|
short_description = ?,
|
||||||
|
long_description = ?,
|
||||||
|
long_description_markdown = ?,
|
||||||
|
cover_art_filename = ?
|
||||||
|
WHERE id =` + id;
|
||||||
|
|
||||||
|
console.log(updateSql);
|
||||||
|
|
||||||
|
let parsedDescription = await parseText.parseMarkdown(formInput.longDescription);
|
||||||
|
|
||||||
|
|
||||||
|
let queryParameters = [formInput.title,
|
||||||
|
formInput.developerID,
|
||||||
|
formInput.publisherID,
|
||||||
|
formInput.releaseDate,
|
||||||
|
formInput.win,
|
||||||
|
formInput.mac,
|
||||||
|
formInput.linux,
|
||||||
|
formInput.shortDescription,
|
||||||
|
parsedDescription,
|
||||||
|
formInput.longDescription,
|
||||||
|
imagePath];
|
||||||
|
|
||||||
|
return await connection.query(updateSql, queryParameters);
|
||||||
|
}
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
getAllGames,
|
getAllGames,
|
||||||
getGame,
|
getGame,
|
||||||
addNewGame
|
addNewGame,
|
||||||
|
editGame
|
||||||
}
|
}
|
||||||
|
|
33
server/package-lock.json
generated
33
server/package-lock.json
generated
|
@ -12,7 +12,8 @@
|
||||||
"jsdom": "^21.1.1",
|
"jsdom": "^21.1.1",
|
||||||
"marked": "^4.3.0",
|
"marked": "^4.3.0",
|
||||||
"multer": "^1.4.5-lts.1",
|
"multer": "^1.4.5-lts.1",
|
||||||
"mysql2": "^3.2.3"
|
"mysql2": "^3.2.3",
|
||||||
|
"path": "^0.12.7"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@tootallnate/once": {
|
"node_modules/@tootallnate/once": {
|
||||||
|
@ -1009,6 +1010,15 @@
|
||||||
"node": ">= 0.8"
|
"node": ">= 0.8"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/path": {
|
||||||
|
"version": "0.12.7",
|
||||||
|
"resolved": "https://registry.npmjs.org/path/-/path-0.12.7.tgz",
|
||||||
|
"integrity": "sha512-aXXC6s+1w7otVF9UletFkFcDsJeO7lSZBPUQhtb5O0xJe8LtYhj/GxldoL09bBj9+ZmE2hNoHqQSFMN5fikh4Q==",
|
||||||
|
"dependencies": {
|
||||||
|
"process": "^0.11.1",
|
||||||
|
"util": "^0.10.3"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/path-to-regexp": {
|
"node_modules/path-to-regexp": {
|
||||||
"version": "0.1.7",
|
"version": "0.1.7",
|
||||||
"resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz",
|
"resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz",
|
||||||
|
@ -1022,6 +1032,14 @@
|
||||||
"node": ">= 0.8.0"
|
"node": ">= 0.8.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/process": {
|
||||||
|
"version": "0.11.10",
|
||||||
|
"resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz",
|
||||||
|
"integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.6.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/process-nextick-args": {
|
"node_modules/process-nextick-args": {
|
||||||
"version": "2.0.1",
|
"version": "2.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz",
|
||||||
|
@ -1359,11 +1377,24 @@
|
||||||
"requires-port": "^1.0.0"
|
"requires-port": "^1.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/util": {
|
||||||
|
"version": "0.10.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/util/-/util-0.10.4.tgz",
|
||||||
|
"integrity": "sha512-0Pm9hTQ3se5ll1XihRic3FDIku70C+iHUdT/W926rSgHV5QgXsYbKZN8MSC3tJtSkhuROzvsQjAaFENRXr+19A==",
|
||||||
|
"dependencies": {
|
||||||
|
"inherits": "2.0.3"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/util-deprecate": {
|
"node_modules/util-deprecate": {
|
||||||
"version": "1.0.2",
|
"version": "1.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
|
||||||
"integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw=="
|
"integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw=="
|
||||||
},
|
},
|
||||||
|
"node_modules/util/node_modules/inherits": {
|
||||||
|
"version": "2.0.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
|
||||||
|
"integrity": "sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw=="
|
||||||
|
},
|
||||||
"node_modules/utils-merge": {
|
"node_modules/utils-merge": {
|
||||||
"version": "1.0.1",
|
"version": "1.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz",
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
"jsdom": "^21.1.1",
|
"jsdom": "^21.1.1",
|
||||||
"marked": "^4.3.0",
|
"marked": "^4.3.0",
|
||||||
"multer": "^1.4.5-lts.1",
|
"multer": "^1.4.5-lts.1",
|
||||||
"mysql2": "^3.2.3"
|
"mysql2": "^3.2.3",
|
||||||
|
"path": "^0.12.7"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue