PA 7 (DELETE).
This commit is contained in:
parent
9fae467b25
commit
b6135191b5
5 changed files with 375 additions and 11 deletions
27
css/main.css
27
css/main.css
|
@ -156,16 +156,39 @@ input, select, textarea {
|
|||
box-shadow: #000000 3px 3px 5px;
|
||||
}
|
||||
|
||||
#deleteButton {
|
||||
border-radius: 5px;
|
||||
border:0;
|
||||
min-width: 150px;
|
||||
min-height: 50px;
|
||||
background-image: linear-gradient(#c51210, #5c1210);
|
||||
color: #ffffff;
|
||||
}
|
||||
|
||||
#deleteButton:hover {
|
||||
background-image: linear-gradient(#e53333, #d51210);
|
||||
box-shadow: #000000 3px 3px 5px;
|
||||
}
|
||||
|
||||
#successMessage {
|
||||
background-color: #4c6b22;
|
||||
color: #b3d4fc;
|
||||
min-height: 50px;
|
||||
min-height: 30px;
|
||||
}
|
||||
|
||||
#errorMessage {
|
||||
background-color: darkred;
|
||||
color: #b3d4fc;
|
||||
min-height: 50px;
|
||||
min-height: 30px;
|
||||
}
|
||||
|
||||
.warning {
|
||||
background-color: darkred;
|
||||
color: #b3d4fc;
|
||||
min-height: 30px;
|
||||
font-weight: bolder;
|
||||
font-size: 24px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.tableCoverArt {
|
||||
|
|
310
delete.html
Normal file
310
delete.html
Normal file
|
@ -0,0 +1,310 @@
|
|||
<!doctype html>
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Delete 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>
|
||||
|
||||
<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 class="row mb-3">
|
||||
<div class="col"></div>
|
||||
<div class="col card warning">
|
||||
<p>Are you SURE you want to delete this game?</p>
|
||||
</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
|
||||
</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
|
||||
</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>
|
||||
</div>
|
||||
<div class="col"></div>
|
||||
</div>
|
||||
|
||||
<div class="row mb-3">
|
||||
<div class="col">
|
||||
<label>Short Description</label>
|
||||
</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>
|
||||
</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-2 align-content-center">
|
||||
<button id="deleteButton" type="submit">Delete</button>
|
||||
</div>
|
||||
<div class="col-2 align-content-center">
|
||||
<button id="backButton">Back</button>
|
||||
</div>
|
||||
<div class="col-8"></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('deleteButton').addEventListener('click', (event) => {
|
||||
const parameters = {};
|
||||
|
||||
if(urlParams.get("id") !== undefined) {
|
||||
parameters.id = urlParams.get("id");
|
||||
}
|
||||
|
||||
|
||||
//Settings for FETCH API request
|
||||
let fetchSettings = {
|
||||
method: 'DELETE'
|
||||
};
|
||||
|
||||
//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 deletion successful!"
|
||||
document.getElementById('successMessage').hidden = false;
|
||||
document.getElementById('successMessage').innerHTML = message;
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('Error:', error);
|
||||
});
|
||||
return;
|
||||
});
|
||||
</script>
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
|
@ -293,8 +293,8 @@
|
|||
.then(({status, json}) => {
|
||||
if (status === 200) {
|
||||
let message = "Game submission successful!"
|
||||
document.getElementById('outputMessage').hidden = false;
|
||||
document.getElementById('outputMessage').innerHTML = message;
|
||||
document.getElementById('successMessage').hidden = false;
|
||||
document.getElementById('successMessage').innerHTML = message;
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
|
|
|
@ -156,7 +156,7 @@ app.post('/games', upload.single('coverArt'),
|
|||
async (request, response) => {
|
||||
console.log(request.file);
|
||||
const errors = validationResult(request);
|
||||
if(!errors.isEmpty()) {
|
||||
if (!errors.isEmpty()) {
|
||||
return response
|
||||
.status(400)
|
||||
.setHeader('Access-Control-Allow-Origin', '*') //Prevent CORS error
|
||||
|
@ -184,13 +184,13 @@ app.post('/games', upload.single('coverArt'),
|
|||
|
||||
app.post('/developers', upload.none(),
|
||||
check('name', 'You must enter a name.').isLength({min: 3}),
|
||||
check('description', 'You must enter a description').isLength({min:5}),
|
||||
check('description', 'You must enter a description').isLength({min: 5}),
|
||||
check('homepage', 'You must enter a homepage URL.').isURL(),
|
||||
|
||||
async (request, response) => {
|
||||
|
||||
const errors = validationResult(request);
|
||||
if(!errors.isEmpty()) {
|
||||
if (!errors.isEmpty()) {
|
||||
return response
|
||||
.status(400)
|
||||
.setHeader('Access-Control-Allow-Origin', '*') //Prevent CORS error
|
||||
|
@ -218,13 +218,13 @@ app.post('/developers', upload.none(),
|
|||
|
||||
app.post('/publishers', upload.none(),
|
||||
check('name', 'You must enter a name.').isLength({min: 3}),
|
||||
check('description', 'You must enter a description').isLength({min:5}),
|
||||
check('description', 'You must enter a description').isLength({min: 5}),
|
||||
check('homepage', 'You must enter a homepage URL.').isURL(),
|
||||
|
||||
async (request, response) => {
|
||||
|
||||
const errors = validationResult(request);
|
||||
if(!errors.isEmpty()) {
|
||||
if (!errors.isEmpty()) {
|
||||
return response
|
||||
.status(400)
|
||||
.setHeader('Access-Control-Allow-Origin', '*') //Prevent CORS error
|
||||
|
@ -270,7 +270,7 @@ app.put('/games/:id', upload.single('coverArt'),
|
|||
async (request, response) => {
|
||||
|
||||
const errors = validationResult(request);
|
||||
if(!errors.isEmpty()) {
|
||||
if (!errors.isEmpty()) {
|
||||
return response
|
||||
.status(400)
|
||||
.setHeader('Access-Control-Allow-Origin', '*') //Prevent CORS error
|
||||
|
@ -296,6 +296,25 @@ app.put('/games/:id', upload.single('coverArt'),
|
|||
}
|
||||
});
|
||||
|
||||
app.delete('/games/:id', upload.none(),
|
||||
|
||||
async (request, response) => {
|
||||
let result = {};
|
||||
try {
|
||||
result = await games.deleteGame(request.query.id);
|
||||
} 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 deleted successfully!'});
|
||||
|
||||
});
|
||||
|
||||
app.listen(port, () => {
|
||||
console.log(`Application listening at http://localhost:${port}`);
|
||||
})
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
const connection = require('./connection');
|
||||
const parseText = require('./parseText');
|
||||
const {del} = require("express/lib/application");
|
||||
|
||||
async function getAllGames(parameters = {}) {
|
||||
let selectSql = `SELECT
|
||||
|
@ -186,9 +187,20 @@ async function editGame(id, formInput, imagePath) {
|
|||
return await connection.query(updateSql, queryParameters);
|
||||
}
|
||||
|
||||
async function deleteGame(id) {
|
||||
|
||||
let deleteSql = `DELETE FROM games_master_table
|
||||
WHERE id =` + id;
|
||||
|
||||
console.log(deleteSql);
|
||||
|
||||
return await connection.query(deleteSql);
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
getAllGames,
|
||||
getGame,
|
||||
addNewGame,
|
||||
editGame
|
||||
editGame,
|
||||
deleteGame
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue