Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Mappa #21

Merged
merged 7 commits into from
Jun 1, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
102 changes: 62 additions & 40 deletions backend/parkings.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,13 @@ const storage = multer.diskStorage({
cb(null, "static/uploads")
},
filename: (rew, file, cb) => {
cb(null, ""+ Date.now() + ".png")
cb(null, "" + Date.now() + ".png")
}
})

// Needed to receive uploaded images from the users
const upload = multer({storage: storage,
const upload = multer({
storage: storage,
fileFilter: (req, file, cb) => {
if (file.mimetype === "image/png" || file.mimetype === "image/jpg" || file.mimetype === "image/jpeg") {
cb(null, true);
Expand All @@ -31,14 +32,14 @@ const router = express.Router()

// Create a new parking, pass through token and upload middlewares
router.post('', [tokenChecker, upload.single("image")], async (req, res) => {
if(!req.file) {
if (!req.file) {
return res.status(415).send({ message: 'Wrong file type for images' })
}
let bodyJSON = await JSON.parse(req.body["json"])
bodyJSON.image = "uploads/"+ req.file["filename"]
bodyJSON.image = "uploads/" + req.file["filename"]

let parking = new Parking(bodyJSON)

try {
let user = await User.findById(req.loggedInUser.userId)

Expand Down Expand Up @@ -69,9 +70,9 @@ router.get('/myParkings', tokenValid, async (req, res) => {
} else {
try {
const idUser = req.loggedInUser.userId

const parkings = await Parking.find({ owner: idUser })

return res.status(200).json(parkings)
} catch (err) {
console.log(err)
Expand All @@ -93,83 +94,105 @@ router.get('/:parkingId', async (req, res) => {

// Get all parkings
router.get('', async (req, res) => {
try {
try {
const query = { $and: [{ visible: true }, { insertions: { $exists: true, $ne: [] } }] }
const insertionMatch = {}
const testQuery = { $and: [{ visible: true }, { insertions: { $exists: true, $ne: [] } }] }
let fuzzySearchQuery = ""
if(Object.keys(req.query).length >= 0) {
if (Object.keys(req.query).length >= 0) {
const validParams = ["search", "priceMin", "priceMax", "dateMin", "dateMax"]
const queryDict = {}
for (let field in req.query) {
if(validParams.includes(field)) {
if (validParams.includes(field)) {
queryDict[field] = req.query[field]
} else {
return res.status(400).send({ message: 'Invalid query parameter' })
}
}
if("search" in queryDict) {
if ("search" in queryDict) {
fuzzySearchQuery = queryDict["search"]
}
if("priceMin" in queryDict) {
if ("priceMin" in queryDict) {
insertionMatch.priceHourly = {}
insertionMatch.priceHourly.$gte = queryDict["priceMin"]
}
if("priceMax" in queryDict) {
if(insertionMatch.priceHourly == null) {
}
if ("priceMax" in queryDict) {
if (insertionMatch.priceHourly == null) {
insertionMatch.priceHourly = {}
}
insertionMatch.priceHourly.$lte = queryDict["priceMax"]
}
if("dateMin" in queryDict) {
insertionMatch.priceHourly.$lte = queryDict["priceMax"]
}
if ("dateMin" in queryDict) {
console.log(queryDict["dateMin"])
insertionMatch.datetimeStart = {}
insertionMatch.datetimeEnd = {}
insertionMatch.datetimeStart.$lte = new Date(queryDict["dateMin"])
insertionMatch.datetimeEnd.$gte = new Date(queryDict["dateMin"])
}
if("dateMax" in queryDict) {
if ("dateMax" in queryDict) {
console.log(queryDict["dateMax"])
if (insertionMatch.datetimeStart == null) {
insertionMatch.datetimeStart = {}
}
if (insertionMatch.datetimeEnd == null) {
insertionMatch.datetimeEnd = {}
}
if(insertionMatch.datetimeStart.$lte != null && insertionMatch.datetimeStart.$lte > new Date(queryDict["dateMax"])) {
if (insertionMatch.datetimeStart.$lte != null && insertionMatch.datetimeStart.$lte > new Date(queryDict["dateMax"])) {
insertionMatch.datetimeStart.$lte = new Date(queryDict["dateMax"])
}
if(insertionMatch.datetimeEnd.$gte != null && insertionMatch.datetimeEnd.$gte < new Date(queryDict["dateMax"])) {
if (insertionMatch.datetimeEnd.$gte != null && insertionMatch.datetimeEnd.$gte < new Date(queryDict["dateMax"])) {
insertionMatch.datetimeEnd.$gte = new Date(queryDict["dateMax"])
}
insertionMatch.datetimeEnd.$gte = new Date(queryDict["dateMax"])
}
}

let parkings = []
if(fuzzySearchQuery !== "") {
parkings = await Parking.fuzzySearch(fuzzySearchQuery).select({__v: 0, confidenceScore: 0 }).populate(
{
if (fuzzySearchQuery !== "") {
parkings = await Parking.fuzzySearch(fuzzySearchQuery).select({ __v: 0, confidenceScore: 0 }).populate(
[{
path: "insertions",
model: "Insertion",
select: {_id: 0, __v:0,},
select: { _id: 0, __v: 0, },
match: insertionMatch
})
} else {
parkings = await Parking.find(query, { __v: 0 }).populate(
},
{
path: "reviews",
model: "Review",
select: { stars: 1 }
}
])
} else {
parkings = await Parking.find(query, { __v: 0 }).populate(
[{
path: "insertions",
model: "Insertion",
select: {_id: 0, __v:0,},
select: { _id: 0, __v: 0, },
match: insertionMatch
})
},
{
path: "reviews",
model: "Review",
select: { stars: 1 }
}])
}
parkings = parkings.filter(parking => parking.visible === true && parking.insertions.length > 0)
// remove property visible from the parkings
for (let parking of parkings) {
parking.visible = undefined
}
return res.status(200).json(parkings)
//calculate average stars for each parking
let parkingObjects = []
for (let parking of parkings) {
let sum = 0
for (let review of parking.reviews) {
sum += review.stars
}
let avg = sum / parking.reviews.length
avg = Math.round(avg * 10) / 10
parkingObjects.push(Object.assign(parking.toObject(), { averageStars: avg }))
}
return res.status(200).json(parkingObjects)
} catch (err) {
console.log(err)
return res.status(500).send({ message: 'Unexpected error' })
Expand All @@ -179,15 +202,15 @@ router.get('', async (req, res) => {
// Modify a parking
router.put('/:parkingId', [tokenChecker, upload.single("image")], async (req, res) => {
let bodyJSON
if(req.body["json"] !== undefined) {
if (req.body["json"] !== undefined) {
bodyJSON = await JSON.parse(req.body["json"])
if(!req.file) {
if (!req.file) {
// if no image is uploaded, the old one is kept
const oldParking = await Parking.findById(req.params.parkingId)
bodyJSON.image = oldParking.image
//return res.status(415).send({ message: 'Wrong file type for images' })
} else {
bodyJSON.image = "uploads/"+ req.file["filename"]
bodyJSON.image = "uploads/" + req.file["filename"]
}

const validFields = ["name", "address", "city", "country", "description", "image", "latitude", "longitude", "visible"]
Expand All @@ -197,7 +220,7 @@ router.put('/:parkingId', [tokenChecker, upload.single("image")], async (req, re
}
}

if(!bodyJSON.name || !bodyJSON.address || !bodyJSON.city || !bodyJSON.country || !bodyJSON.description) {
if (!bodyJSON.name || !bodyJSON.address || !bodyJSON.city || !bodyJSON.country || !bodyJSON.description) {
return res.status(400).send({ message: "Some fields are empty or undefined" })
}
} else {
Expand All @@ -213,8 +236,8 @@ router.put('/:parkingId', [tokenChecker, upload.single("image")], async (req, re
return res.status(403).send({ message: 'User is not authorized to do this action' })
}

const updatedParking = await Parking.findByIdAndUpdate(req.params.parkingId, bodyJSON, { runValidators: true , new: true })
const updatedParking = await Parking.findByIdAndUpdate(req.params.parkingId, bodyJSON, { runValidators: true, new: true })

return res.status(200).json(updatedParking)
} catch (err) {
console.log(err)
Expand All @@ -230,8 +253,7 @@ router.delete('/:parkingId', tokenChecker, async (req, res) => {
// if user is not the owner of the parking, return error
if (parkingOwner !== req.loggedInUser.userId) {
return res.status(403).send({ message: 'User is not authorized to do this action' })
}if(parking.insertions.length != 0)
{
} if (parking.insertions.length != 0) {
return res.status(405).send({ message: 'Cannot delete parking with active insertions' })
}

Expand Down
9 changes: 8 additions & 1 deletion backend/statics.js
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,6 @@ router.get('/detailParking', tokenValid, async function (req, res) {
try {
let parking = await Parking.findById(req.query.id).populate("owner")
const reservations = await Reservation.find({ client: req.loggedInUser.userId, reviewed: false })
console.log(reservations)
let reviewable = false
if (reservations.length !== 0) {
reviewable = true
Expand Down Expand Up @@ -163,6 +162,14 @@ router.get('/parkings', tokenValid, function (req, res) {

})

// Map page
router.get('/map', tokenValid, function (req, res) {
let loggedBool = false
if (isAuthToken(req))
loggedBool = true
res.render('./map.ejs', { logged: loggedBool})
})

// Index page
router.get('/', tokenValid, function (req, res) {
let loggedBool = false
Expand Down
1 change: 0 additions & 1 deletion backend/users.js
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,6 @@ router.get('/:userId/reservations', tokenChecker, async (req, res) => {
if (!checkUserAuthorization(req, res)) return
try {
const reservations = await Reservation.find({ client: { $eq: req.params.userId } }, { _id: 0, __v: 0, client: 0 })
console.log("Printing user's reservations", reservations)
return res.status(200).json(reservations)
} catch (err) {
console.log(err)
Expand Down
Binary file added static/img/parking-pin.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added static/img/powered_by_google_on_white.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
26 changes: 16 additions & 10 deletions static/scriptDetailParking.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,11 @@ async function createInsertion() {
}

// check if the form is valid
if (!$('form')[0].checkValidity()) {
if (!$('#insertionForm')[0].checkValidity()) {
$("#message").removeAttr('hidden')
$("#message").text("Per favore inserire tutti i dati")
$('#btnSubmit').prop("disabled", false)
$('#btnSubmit').text("Crea inserzione")
$('#btnSubmit').text("Invia")
return
}

Expand All @@ -27,7 +27,7 @@ async function createInsertion() {
$("#message").text("L'intervallo minimo deve essere maggiore di 0")
$("#message").text("L'intervallo minimo deve essere maggiore di 0")
$('#btnSubmit').prop("disabled", false)
$('#btnSubmit').text("Crea inserzione")
$('#btnSubmit').text("Invia")
return
}

Expand All @@ -37,7 +37,7 @@ async function createInsertion() {
$("#message").text("L'intervallo minimo deve essere maggiore di 0")
$("#message").text("Prezzo non valido")
$('#btnSubmit').prop("disabled", false)
$('#btnSubmit').text("Crea inserzione")
$('#btnSubmit').text("Invia")
return
}

Expand All @@ -47,7 +47,7 @@ async function createInsertion() {
$("#message").text("L'intervallo minimo deve essere maggiore di 0")
$("#message").text("Prezzo non valido")
$('#btnSubmit').prop("disabled", false)
$('#btnSubmit').text("Crea inserzione")
$('#btnSubmit').text("Invia")
return
}

Expand All @@ -72,7 +72,7 @@ async function createInsertion() {
$("#message").removeAttr('hidden')
$("#message").text("Per favore selezionare almeno un giorno")
$('#btnSubmit').prop("disabled", false)
$('#btnSubmit').text("Crea inserzione")
$('#btnSubmit').text("Invia")
return
}

Expand Down Expand Up @@ -104,7 +104,7 @@ async function createInsertion() {
// if the insertion is created, close the modal
$('#close-modal').click()
$('#btnSubmit').prop("disabled", false)
$('#btnSubmit').text("Crea inserzione")
$('#btnSubmit').text("Invia")
$(':input', 'form')
.not(':button, :submit, :reset, :hidden')
.val('')
Expand All @@ -118,11 +118,15 @@ async function createInsertion() {
$("#message").text(err.message)
$("#message").removeAttr('hidden')
$('#btnSubmit').prop("disabled", false)
$('#btnSubmit').text("Crea inserzione")
$('#btnSubmit').text("Invia")
}

}

function openMap(lat, long) {
window.location.href = `map?lat=${lat}&long=${long}`
}

// load the details of the parking
async function loadDetails() {
try {
Expand Down Expand Up @@ -153,6 +157,8 @@ async function loadDetails() {
$("#btnElimina").attr("onclick", `deleteParking('${data._id}')`);
$("#btnModifica").attr("onclick", `modifyParking('${data._id}')`);

$("#btnOpenMap").attr("onclick", `openMap('${data.latitude}', '${data.longitude}')`);

if (data.image != "")
$('#parkingImage').attr("src", data.image)
$("#newInsertion").attr("data-bs-name", `${data.name}`);
Expand Down Expand Up @@ -930,7 +936,7 @@ async function modifyInsertionSubmit(insertionid) {

async function deleteInsertion(insertionid) {
//chiamata per eliminare la reservation
if (confirm('Are you sure you want to delete this insertion?')) {
if (confirm('Vuoi veramente eliminare questa inserzione?\nL\'operazione non può essere annullata.')) {
try {
const res = await fetch(`/api/v1/insertions/${insertionid}`, {
method: "DELETE",
Expand All @@ -954,7 +960,7 @@ async function modifyParking(parkId) {

async function deleteParking(parkingid) {
console.log(parkingid)
if (confirm('Are you sure you want to delete this parking?')) {
if (confirm('Vuoi veramente eliminare questo parcheggio?\nL\'operazione non può essere annullata.')) {
try {
const res = await fetch(`/api/v1/parkings/${parkingid}`, {
method: "DELETE",
Expand Down