@@ -17,40 +17,49 @@ function initialiseFacilityData(data, force = false) {
|
||||
}
|
||||
// Store the data in sessionStorage for persistence
|
||||
sessionStorage.setItem('facilityData', JSON.stringify(data));
|
||||
// Ensure table exists
|
||||
const table = document.querySelector('#facilityTable');
|
||||
if (!table) {
|
||||
console.error('Table not found in DOM. Available elements:',
|
||||
Array.from(document.querySelectorAll('table')).map(t => t.id || 'no-id'));
|
||||
throw new Error('Facility table not found in DOM');
|
||||
}
|
||||
// Clear existing table content
|
||||
const tbody = table.querySelector('tbody');
|
||||
if (tbody) {
|
||||
tbody.innerHTML = '';
|
||||
} else {
|
||||
console.warn('No tbody found in table, creating one');
|
||||
const newTbody = document.createElement('tbody');
|
||||
table.appendChild(newTbody);
|
||||
}
|
||||
|
||||
// Initialize filteredData with all data
|
||||
filteredData = data;
|
||||
// Calculate total pages
|
||||
totalPages = Math.ceil(filteredData.length / itemsPerPage);
|
||||
// Set current page to 1
|
||||
currentPage = 1;
|
||||
|
||||
// Update table with paginated data
|
||||
updateTableWithPagination();
|
||||
// Check if we're on the map page
|
||||
const isMapPage = window.location.pathname.includes('map.php');
|
||||
if (!isMapPage) {
|
||||
// Only try to initialize table if we're not on the map page
|
||||
const table = document.querySelector('#facilityTable');
|
||||
if (!table) {
|
||||
console.error('Table not found in DOM. Available elements:',
|
||||
Array.from(document.querySelectorAll('table')).map(t => t.id || 'no-id'));
|
||||
throw new Error('Facility table not found in DOM');
|
||||
}
|
||||
// Clear existing table content
|
||||
const tbody = table.querySelector('tbody');
|
||||
if (tbody) {
|
||||
tbody.innerHTML = '';
|
||||
} else {
|
||||
console.warn('No tbody found in table, creating one');
|
||||
const newTbody = document.createElement('tbody');
|
||||
table.appendChild(newTbody);
|
||||
}
|
||||
|
||||
// Set up table controls (sorting and filtering)
|
||||
setupTableControls();
|
||||
// Initialize filteredData with all data
|
||||
filteredData = data;
|
||||
// Calculate total pages
|
||||
totalPages = Math.ceil(filteredData.length / itemsPerPage);
|
||||
// Set current page to 1
|
||||
currentPage = 1;
|
||||
|
||||
// Update table with paginated data
|
||||
updateTable();
|
||||
|
||||
// Set up table controls (sorting and filtering)
|
||||
setupTableControls();
|
||||
}
|
||||
|
||||
// Mark as initialized
|
||||
isInitialized = true;
|
||||
} catch (error) {
|
||||
error_log('Error initialising facility data:', error);
|
||||
console.error('Error initialising facility data:', error);
|
||||
// Don't throw error if we're on map page, as table errors are expected
|
||||
if (!window.location.pathname.includes('map.php')) {
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -68,6 +77,10 @@ function renderFacilityTable(data) {
|
||||
// Clear existing table content
|
||||
tbody.innerHTML = '';
|
||||
|
||||
// Check if user is admin
|
||||
const userIsAdmin = isAdmin();
|
||||
console.log('renderFacilityTable - userIsAdmin:', userIsAdmin);
|
||||
|
||||
// Render each row
|
||||
data.forEach((facility, index) => {
|
||||
if (!facility) return;
|
||||
@@ -82,9 +95,22 @@ function renderFacilityTable(data) {
|
||||
// Create category badge with color based on category
|
||||
const categoryClass = getCategoryColorClass(facility.category);
|
||||
|
||||
row.innerHTML = `
|
||||
<td class="d-none">${escapeHtml(facility.id)}</td>
|
||||
<td class="fw-medium align-middle" style="width: 15%;">
|
||||
// Start building the row HTML
|
||||
let rowHtml = '';
|
||||
|
||||
// Only show ID column for admins
|
||||
if (userIsAdmin) {
|
||||
console.log('Adding ID column for facility:', facility.id);
|
||||
rowHtml += `
|
||||
<td class="fw-medium align-middle text-center" style="width: 40px;">
|
||||
${escapeHtml(facility.id)}
|
||||
</td>
|
||||
`;
|
||||
}
|
||||
|
||||
// Add the rest of the columns
|
||||
rowHtml += `
|
||||
<td class="fw-medium align-middle" style="${userIsAdmin ? 'width: 15%;' : 'width: 17%;'}">
|
||||
<div class="d-flex align-items-center h-100">
|
||||
<div class="facility-icon me-2 rounded-circle bg-light d-flex align-items-center justify-content-center" style="width: 28px; height: 28px; min-width: 28px;">
|
||||
<i class="${getFacilityIcon(facility.category)} text-${categoryClass}"></i>
|
||||
@@ -92,14 +118,14 @@ function renderFacilityTable(data) {
|
||||
<span class="text-truncate" style="max-width: calc(100% - 35px);">${escapeHtml(facility.title)}</span>
|
||||
</div>
|
||||
</td>
|
||||
<td class="text-center align-middle" style="width: 10%;">
|
||||
<td class="text-center align-middle" style="${userIsAdmin ? 'width: 10%;' : 'width: 11%;'}">
|
||||
<div class="d-flex align-items-center justify-content-center h-100">
|
||||
<span class="badge bg-${categoryClass} bg-opacity-10 text-${categoryClass} px-2 py-1 rounded-pill">
|
||||
${escapeHtml(facility.category)}
|
||||
</span>
|
||||
</div>
|
||||
</td>
|
||||
<td class="align-middle" style="width: 25%;">
|
||||
<td class="align-middle" style="${userIsAdmin ? 'width: 25%;' : 'width: 27%;'}">
|
||||
<div class="description-container d-flex flex-column justify-content-center">
|
||||
<div class="cell-content" data-full-text="${escapeHtml(facility.description)}">
|
||||
${escapeHtml(facility.description)}
|
||||
@@ -118,16 +144,15 @@ function renderFacilityTable(data) {
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
<td class="small fw-medium text-center align-middle" style="width: 8%;" hidden>${escapeHtml(facility.postcode)}</td>
|
||||
<td class="small text-nowrap text-center align-middle" style="width: 12%;">
|
||||
<td class="small text-nowrap text-center align-middle" style="${userIsAdmin ? 'width: 12%;' : 'width: 12%;'}">
|
||||
<span class="badge bg-light text-dark border">
|
||||
${escapeHtml(coordinates)}
|
||||
</span>
|
||||
</td>
|
||||
<td class="small text-center align-middle" style="width: 8%;">${escapeHtml(facility.contributor)}</td>
|
||||
<td class="text-center align-middle" style="width: 10%;">
|
||||
<td class="text-center align-middle" style="${userIsAdmin ? 'width: 10%;' : 'width: 5%;'}">
|
||||
<div class="d-flex justify-content-center gap-1">
|
||||
${isAdmin() ? `
|
||||
${userIsAdmin ? `
|
||||
<button type="button" class="btn btn-sm btn-outline-primary update-btn rounded-circle d-flex align-items-center justify-content-center" style="width: 30px; height: 30px;" data-bs-toggle="modal" data-bs-target="#updateModal" data-facility-id="${facility.id}" title="Edit">
|
||||
<span class="bi bi-pen-fill"></span>
|
||||
</button>
|
||||
@@ -141,15 +166,17 @@ function renderFacilityTable(data) {
|
||||
</div>
|
||||
</td>
|
||||
`;
|
||||
|
||||
|
||||
row.innerHTML = rowHtml;
|
||||
tbody.appendChild(row);
|
||||
});
|
||||
|
||||
// If no data, show a message
|
||||
if (data.length === 0) {
|
||||
const emptyRow = document.createElement('tr');
|
||||
const colSpan = userIsAdmin ? 8 : 7; // Adjust colspan based on number of columns
|
||||
emptyRow.innerHTML = `
|
||||
<td colspan="9" class="text-center py-4 text-muted">
|
||||
<td colspan="${colSpan}" class="text-center py-4 text-muted">
|
||||
<div class="d-flex flex-column align-items-center">
|
||||
<span class="bi bi-inbox fs-2 mb-2"></span>
|
||||
<p class="mb-0">No facilities found</p>
|
||||
@@ -204,10 +231,15 @@ function formatAddress(facility) {
|
||||
* @returns {boolean} True if user is admin, false otherwise
|
||||
*/
|
||||
function isAdmin() {
|
||||
console.log('Checking admin status...');
|
||||
|
||||
// Check if auth service is available and has user data
|
||||
if (window.auth && window.auth.getUser()) {
|
||||
const authUser = window.auth.getUser();
|
||||
if (simpleAuth && simpleAuth.getUser()) {
|
||||
const authUser = simpleAuth.getUser();
|
||||
console.log('Auth service user data:', authUser);
|
||||
console.log('Auth service accessLevel:', authUser.accessLevel);
|
||||
console.log('Auth service isAdmin check:', authUser.accessLevel === 1 || authUser.accessLevel === 0);
|
||||
|
||||
if (authUser && (authUser.accessLevel === 1 || authUser.accessLevel === 0)) {
|
||||
console.log('User is admin according to auth service');
|
||||
return true;
|
||||
@@ -217,17 +249,26 @@ function isAdmin() {
|
||||
// Fallback to localStorage
|
||||
const user = JSON.parse(localStorage.getItem('user') || '{}');
|
||||
console.log('Checking admin status from localStorage:', user);
|
||||
const isAdminUser = user && (user.accessLevel === 1 || user.accessLevel === 0);
|
||||
console.log('Is admin according to localStorage:', isAdminUser);
|
||||
console.log('localStorage accessLevel:', user.accessLevel);
|
||||
console.log('localStorage isAdmin check:', user.accessLevel === 1 || user.accessLevel === 0);
|
||||
|
||||
const isAdminUser = user && (user.accessLevel === 1 || user.accessLevel === 0);
|
||||
|
||||
console.log('Final isAdmin result:', isAdminUser);
|
||||
return isAdminUser;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the current user is authenticated
|
||||
* (helper function) Checks if the current user is authenticated
|
||||
* @returns {boolean} True if authenticated, false otherwise
|
||||
*/
|
||||
function isAuthenticated() {
|
||||
// Check if auth service is available
|
||||
if (simpleAuth) {
|
||||
return simpleAuth.isAuthenticated();
|
||||
}
|
||||
|
||||
// Fallback to localStorage
|
||||
const token = localStorage.getItem('token');
|
||||
return !!token;
|
||||
}
|
||||
@@ -395,8 +436,8 @@ function setupFormHandlers() {
|
||||
// Set the contributor to the current user's username
|
||||
formData.set('contCreate', JSON.parse(localStorage.getItem('user'))?.username);
|
||||
try {
|
||||
// Use authFetch instead of regular fetch
|
||||
const response = await window.authFetch('/facilitycontroller.php', {
|
||||
// Use simpleAuth.fetchAuth for authenticated requests
|
||||
const response = await simpleAuth.fetchAuth('/facilitycontroller.php', {
|
||||
method: 'POST',
|
||||
body: formData
|
||||
});
|
||||
@@ -493,8 +534,8 @@ function setupFormHandlers() {
|
||||
}
|
||||
|
||||
try {
|
||||
// Use authFetch instead of regular fetch
|
||||
const response = await window.authFetch('/facilitycontroller.php', {
|
||||
// Use simpleAuth.fetchAuth for authenticated requests
|
||||
const response = await simpleAuth.fetchAuth('/facilitycontroller.php', {
|
||||
method: 'POST',
|
||||
body: serverFormData
|
||||
});
|
||||
@@ -582,19 +623,19 @@ function setupFormHandlers() {
|
||||
|
||||
try {
|
||||
// Check if token is valid
|
||||
if (!window.auth) {
|
||||
if (!simpleAuth) {
|
||||
throw new Error('Auth service not available');
|
||||
}
|
||||
|
||||
// Validate token with server before proceeding
|
||||
console.log('Validating token with server...');
|
||||
const isValid = await window.auth.validateToken();
|
||||
const isValid = await simpleAuth.validateToken();
|
||||
if (!isValid) {
|
||||
throw new Error('Authentication token is invalid or expired');
|
||||
}
|
||||
|
||||
// Get token after validation to ensure it's fresh
|
||||
const token = window.auth.getToken();
|
||||
const token = simpleAuth.getToken();
|
||||
console.log('Using token for delete request:', token);
|
||||
|
||||
if (!token) {
|
||||
@@ -602,16 +643,16 @@ function setupFormHandlers() {
|
||||
}
|
||||
|
||||
// Decode token to check payload
|
||||
if (window.auth.parseJwt) {
|
||||
const payload = window.auth.parseJwt(token);
|
||||
if (simpleAuth.parseJwt) {
|
||||
const payload = simpleAuth.parseJwt(token);
|
||||
console.log('Token payload:', payload);
|
||||
console.log('Access level:', payload.accessLevel);
|
||||
console.log('Is admin check:', payload.accessLevel === 0 || payload.accessLevel === 1);
|
||||
}
|
||||
|
||||
// Use direct fetch with manual token inclusion
|
||||
// Use simpleAuth.fetchAuth for authenticated requests
|
||||
console.log('Sending delete request to server...');
|
||||
const response = await fetch('/facilitycontroller.php', {
|
||||
const response = await simpleAuth.fetchAuth('/facilitycontroller.php', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Authorization': `Bearer ${token}`,
|
||||
@@ -1112,86 +1153,5 @@ function getCategoryColorClass(category) {
|
||||
return 'secondary';
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets up expandable content for a table row
|
||||
* @param {HTMLElement} row - The table row element
|
||||
*/
|
||||
function setupExpandableContent(row) {
|
||||
// Setup description expansion
|
||||
const descriptionContent = row.querySelector('.cell-content');
|
||||
const toggleBtn = row.querySelector('.toggle-content-btn');
|
||||
|
||||
if (descriptionContent) {
|
||||
// Make description expandable on click
|
||||
descriptionContent.addEventListener('click', function() {
|
||||
this.classList.toggle('expanded');
|
||||
|
||||
// Update button text if it exists
|
||||
if (toggleBtn) {
|
||||
toggleBtn.querySelector('small').textContent =
|
||||
this.classList.contains('expanded') ? 'Show less' : 'Show more';
|
||||
}
|
||||
|
||||
// Ensure proper alignment when expanded
|
||||
const container = this.closest('.description-container');
|
||||
if (container) {
|
||||
if (this.classList.contains('expanded')) {
|
||||
container.classList.remove('justify-content-center');
|
||||
container.classList.add('justify-content-start');
|
||||
} else {
|
||||
container.classList.remove('justify-content-start');
|
||||
container.classList.add('justify-content-center');
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Setup toggle button if it exists
|
||||
if (toggleBtn) {
|
||||
toggleBtn.addEventListener('click', function(e) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
|
||||
const content = this.closest('.description-container').querySelector('.cell-content');
|
||||
content.classList.toggle('expanded');
|
||||
|
||||
this.querySelector('small').textContent =
|
||||
content.classList.contains('expanded') ? 'Show less' : 'Show more';
|
||||
|
||||
// Ensure proper alignment when expanded
|
||||
const container = content.closest('.description-container');
|
||||
if (container) {
|
||||
if (content.classList.contains('expanded')) {
|
||||
container.classList.remove('justify-content-center');
|
||||
container.classList.add('justify-content-start');
|
||||
} else {
|
||||
container.classList.remove('justify-content-start');
|
||||
container.classList.add('justify-content-center');
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// Setup address expansion
|
||||
const addressContent = row.querySelector('.address-content');
|
||||
if (addressContent) {
|
||||
addressContent.addEventListener('click', function() {
|
||||
this.classList.toggle('expanded');
|
||||
|
||||
// Ensure proper alignment when expanded
|
||||
const container = this.closest('.d-flex');
|
||||
if (container) {
|
||||
if (this.classList.contains('expanded')) {
|
||||
container.classList.remove('align-items-center');
|
||||
container.classList.add('align-items-start');
|
||||
} else {
|
||||
container.classList.remove('align-items-start');
|
||||
container.classList.add('align-items-center');
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// Export the initialization function
|
||||
window.initializeFacilityData = initialiseFacilityData;
|
Reference in New Issue
Block a user