chuksjoe/AutoMart_UI

View on GitHub
UI/js/admin.js

Summary

Maintainability
A
1 hr
Test Coverage
const carPreview = document.getElementById('car-preview-overlay');
const flagList = document.getElementById('flag-listing-overlay');
const notificationModal = document.getElementById('notification-overlay');
const confirmationModal = document.getElementById('confirmation-overlay');
const closeCarPreview = document.getElementById('close-car-preview');
const closeFlagList = document.getElementById('close-flag-listing');
const closeNotifation = document.querySelector('.close-notification');
const message = document.querySelector('#notification-overlay .message');
const confMsg = document.querySelector('#confirmation-overlay .message');
 
const user_id = sessionStorage.getItem('user_id');
const is_loggedin = sessionStorage.getItem('is_loggedin');
const is_admin = sessionStorage.getItem('is_admin');
const token = sessionStorage.getItem('token');
 
const urlPrefix = 'https://auto-mart-adc.herokuapp.com';
 
// used for selecting the right url for filtering
const currentPage = 'admin';
 
let hasUpdatedInfo = false;
 
/* ================ Helper funtions ================= */
const deleteFlag = (params) => {
const {
id, car_name, owner, owner_id,
} = params;
const confirm = document.querySelector('#confirmation-overlay .yes');
const decline = document.querySelector('#confirmation-overlay .no');
 
confMsg.innerHTML = `Are you sure you want to delete<br/>flag with ID ${id} placed on<br/><b>${car_name}</b>
<br/>owned by ${(owner_id === parseInt(user_id, 10) ? 'you' : owner)}?`;
confirmationModal.style.display = 'block';
toggleScroll();
 
confirm.onclick = (e) => {
e.preventDefault();
const options = {
method: 'DELETE',
headers: { authorization: `Bearer ${token}` },
};
fetch(`${urlPrefix}/api/v1/flag/${id}`, options)
.then(res => res.json())
.then((response) => {
if (response.status === 200) {
message.innerHTML = response.message;
hasUpdatedInfo = true;
} else {
message.innerHTML = response.error;
}
confirmationModal.style.display = 'none';
notificationModal.style.display = 'block';
})
.catch((err) => {
message.innerHTML = errorMessage(err);
notificationModal.style.display = 'block';
});
};
decline.onclick = (e) => {
e.preventDefault();
confirmationModal.style.display = 'none';
toggleScroll();
};
};
 
const markAddressed = (params) => {
const {
id, car_name, owner, owner_id,
} = params;
const confirm = document.querySelector('#confirmation-overlay .yes');
const decline = document.querySelector('#confirmation-overlay .no');
 
confMsg.innerHTML = `Are you sure you want to mark<br/>flag with ID ${id} placed on<br/><b>${car_name}</b>
<br/>owned by ${(owner_id === parseInt(user_id, 10) ? 'you' : owner)} as Addressed?`;
confirmationModal.style.display = 'block';
toggleScroll();
 
confirm.onclick = (e) => {
e.preventDefault();
const options = {
method: 'PATCH',
headers: { authorization: `Bearer ${token}` },
};
fetch(`${urlPrefix}/api/v1/flag/${id}/status`, options)
.then(res => res.json())
.then((response) => {
if (response.status === 200) {
message.innerHTML = response.message;
hasUpdatedInfo = true;
} else {
message.innerHTML = response.error;
}
confirmationModal.style.display = 'none';
notificationModal.style.display = 'block';
})
.catch((err) => {
message.innerHTML = errorMessage(err);
notificationModal.style.display = 'block';
});
};
decline.onclick = (e) => {
e.preventDefault();
confirmationModal.style.display = 'none';
toggleScroll();
};
};
 
const viewFlagList = (carId, carName) => {
const flagListModal = document.querySelector('#flag-listing-overlay .flag-list');
flagListModal.innerHTML = '<div id="loading"><img src="../images/loader.gif" /></div>';
flagListModal.style.textAlign = 'left';
document.querySelector('#flag-listing-overlay .modal-header').innerHTML = carName;
flagList.style.display = 'block';
toggleScroll();
 
const options = {
method: 'GET',
headers: { authorization: `Bearer ${token}` },
};
fetch(`${urlPrefix}/api/v1/flag/${carId}`, options)
.then(res => res.json())
.then((response) => {
const res = response;
if (res.data.length > 0) {
flagListModal.innerHTML = null;
res.data.map((flag) => {
const {
id, reporter_id, owner, owner_id, reason, description, status, created_on, car_name,
} = flag;
const flagCard = document.createElement('li');
const btnGrp = document.createElement('div');
const markAddressedBtn = document.createElement('button');
const deleteFlagBtn = document.createElement('button');
 
flagCard.setAttribute('class', 'flag-details flex-container');
flagCard.innerHTML = `
<div class="date-time p-15">
<p>${configDate(created_on)}</p>
<label class="f-status"
style="background:${status === 'Pending' ? '#FEBD2D' : '#48F038'}">${status}</label>
</div>
<div class="flag-main-desc">
<h3>Reason: ${reason}</h3>
<p>Description: ${description}</p>
<p>Car Owner: ${owner}, Reporter ID: ${reporter_id}, Flag ID: ${id}</p>
</div>`;
 
markAddressedBtn.setAttribute('class', 'mark-addressed full-btn btn');
markAddressedBtn.innerHTML = 'Mark Addressed';
markAddressedBtn.onclick = () => {
markAddressed({
id, car_name, owner, owner_id,
});
};
deleteFlagBtn.setAttribute('class', 'del-flag delete full-btn btn');
deleteFlagBtn.innerHTML = 'Delete Flag';
deleteFlagBtn.onclick = () => {
deleteFlag({
id, car_name, owner, owner_id,
});
};
 
btnGrp.setAttribute('class', 'flag-actions p-15');
btnGrp.appendChild(markAddressedBtn);
btnGrp.appendChild(deleteFlagBtn);
 
flagCard.appendChild(btnGrp);
flagListModal.appendChild(flagCard);
return 0;
});
} else {
// the car list is empty
flagListModal.style.textAlign = 'center';
flagListModal.innerHTML = 'This car Ad has not been flagged.';
}
})
.catch((error) => {
message.innerHTML = errorMessage(error);
flagListModal.innerHTML = errorMessage(error);
notificationModal.style.display = 'block';
toggleScroll();
});
};
 
const deleteAd = (params) => {
const {
id, name, owner_id, owner,
} = params;
const confirm = document.querySelector('#confirmation-overlay .yes');
const decline = document.querySelector('#confirmation-overlay .no');
 
confMsg.innerHTML = `Are you sure you want to delete<br/><b>${name}</b>
<br/>owned by ${(owner_id === parseInt(user_id, 10) ? 'you' : owner)}?`;
confirmationModal.style.display = 'block';
toggleScroll();
 
confirm.onclick = (e) => {
e.preventDefault();
const options = {
method: 'DELETE',
headers: { authorization: `Bearer ${token}` },
};
fetch(`${urlPrefix}/api/v1/car/${id}`, options)
.then(res => res.json())
.then((response) => {
if (response.status === 200) {
message.innerHTML = response.message;
hasUpdatedInfo = true;
} else {
message.innerHTML = response.error;
}
confirmationModal.style.display = 'none';
notificationModal.style.display = 'block';
})
.catch((err) => {
message.innerHTML = errorMessage(err);
notificationModal.style.display = 'block';
});
};
decline.onclick = (e) => {
e.preventDefault();
confirmationModal.style.display = 'none';
toggleScroll();
};
};
 
const fetchCarAds = (url, msgIfEmpty) => {
const options = {
method: 'GET',
headers: { authorization: `Bearer ${token}` },
};
const carList = document.querySelector('.car-list');
carList.innerHTML = '<div id="loading"><img src="../images/loader.gif" /></div>';
fetch(url, options)
.then(res => res.json())
.then((response) => {
const res = response;
if (res.data.length > 0) {
carList.innerHTML = null;
res.data.map((car) => {
const {
id, name, owner_id, owner, body_type, state, status, price, image_url, created_on,
} = car;
const carCard = document.createElement('li');
const carImg = document.createElement('div');
const carInfo = document.createElement('div');
const btnGrp = document.createElement('div');
const viewFlagsBtn = document.createElement('button');
const deleteAdBtn = document.createElement('button');
 
carCard.setAttribute('class', 'car-card flex-container');
carImg.classList.add('car-image');
carImg.innerHTML = `<img src="${image_url}" title="Preview AD">
<label class="car-state-tag">${state}</label>`;
carImg.onclick = () => {
const btnGrpPrev = document.createElement('div');
const viewFlagsBtnPrev = document.createElement('button');
const deleteAdBtnPrev = document.createElement('button');
 
viewFlagsBtnPrev.setAttribute('class', 'view-reports half-btn btn');
viewFlagsBtnPrev.innerHTML = 'View Flags';
viewFlagsBtnPrev.onclick = () => {
viewFlagList(id, name);
};
deleteAdBtnPrev.setAttribute('class', 'delete half-btn btn');
deleteAdBtnPrev.innerHTML = 'Delete Ad';
deleteAdBtnPrev.onclick = () => {
deleteAd({
id, name, owner_id, owner,
});
};
btnGrpPrev.setAttribute('class', 'btn-group flex-container');
btnGrpPrev.appendChild(viewFlagsBtnPrev);
btnGrpPrev.appendChild(deleteAdBtnPrev);
 
// call the previewCar function defined in preview-car.js
previewCar(id, btnGrpPrev);
 
carPreview.style.display = 'block';
toggleScroll();
};
 
carInfo.classList.add('car-info');
carInfo.innerHTML = `<h3 class="c-details-list">${name}</h3>
<label class="car-status-tag">${status}</label>
<p class="car-price">&#8358 ${parseInt(price, 10).toLocaleString('en-US')}</p>
<p><b>Body type:</b> ${body_type}</p>
<p>Posted by ${owner}, on: ${configDate(created_on)}</p>`;
 
viewFlagsBtn.setAttribute('class', 'view-reports full-btn btn b49');
viewFlagsBtn.innerHTML = 'View Flags';
viewFlagsBtn.onclick = () => {
viewFlagList(id, name);
};
deleteAdBtn.setAttribute('class', 'delete full-btn btn b49');
deleteAdBtn.innerHTML = 'Delete Ad';
deleteAdBtn.onclick = () => {
deleteAd({
id, name, owner_id, owner,
});
};
btnGrp.setAttribute('class', 'admin-actions');
btnGrp.appendChild(viewFlagsBtn);
btnGrp.appendChild(deleteAdBtn);
 
carCard.appendChild(carImg);
carCard.appendChild(carInfo);
carCard.appendChild(btnGrp);
carList.appendChild(carCard);
return 0;
});
} else {
// the car list is empty
carList.style.textAlign = 'center';
carList.innerHTML = msgIfEmpty;
}
})
.catch((error) => {
message.innerHTML = errorMessage(error);
carList.innerHTML = errorMessage(error);
notificationModal.style.display = 'block';
toggleScroll();
});
};
 
/* ==================== MAIN LOGICS ====================== */
window.onload = () => {
// redirect to sign in page if the user is not logged in
if (!(is_loggedin || is_admin)) {
window.location.href = './signin.html';
}
const userName = document.querySelector('.user-name');
 
userName.innerHTML = `${sessionStorage.getItem('first_name')}
${sessionStorage.getItem('last_name').charAt(0)}.`;
 
// fetch the cars from database and populate the marketplace
fetchCarAds(`${urlPrefix}/api/v1/car`, 'No car sale ad has been posted.');
};
 
closeCarPreview.onclick = () => {
carPreview.style.display = 'none';
toggleScroll();
};
 
closeFlagList.onclick = () => {
flagList.style.display = 'none';
toggleScroll();
};
 
Identical blocks of code found in 5 locations. Consider refactoring.
closeNotifation.onclick = (e) => {
e.preventDefault();
notificationModal.style.display = 'none';
if (hasUpdatedInfo) autoRefresh(0);
toggleScroll();
};