addings details and map to modal
All checks were successful
Build and Push Docker Image / build-and-push (push) Successful in 59s
All checks were successful
Build and Push Docker Image / build-and-push (push) Successful in 59s
This commit is contained in:
@@ -349,6 +349,10 @@ async def get_school_details(request: Request, urn: int):
|
|||||||
"local_authority": latest.get("local_authority", ""),
|
"local_authority": latest.get("local_authority", ""),
|
||||||
"school_type": latest.get("school_type", ""),
|
"school_type": latest.get("school_type", ""),
|
||||||
"address": latest.get("address", ""),
|
"address": latest.get("address", ""),
|
||||||
|
"religious_denomination": latest.get("religious_denomination", ""),
|
||||||
|
"age_range": latest.get("age_range", ""),
|
||||||
|
"latitude": latest.get("latitude"),
|
||||||
|
"longitude": latest.get("longitude"),
|
||||||
"phase": "Primary",
|
"phase": "Primary",
|
||||||
},
|
},
|
||||||
"yearly_data": clean_for_json(school_data),
|
"yearly_data": clean_for_json(school_data),
|
||||||
|
|||||||
@@ -35,6 +35,7 @@ const state = {
|
|||||||
// Charts
|
// Charts
|
||||||
let comparisonChart = null;
|
let comparisonChart = null;
|
||||||
let schoolDetailChart = null;
|
let schoolDetailChart = null;
|
||||||
|
let modalMap = null;
|
||||||
|
|
||||||
// Chart colors
|
// Chart colors
|
||||||
const CHART_COLORS = [
|
const CHART_COLORS = [
|
||||||
@@ -94,7 +95,10 @@ const elements = {
|
|||||||
modalClose: document.getElementById("modal-close"),
|
modalClose: document.getElementById("modal-close"),
|
||||||
modalSchoolName: document.getElementById("modal-school-name"),
|
modalSchoolName: document.getElementById("modal-school-name"),
|
||||||
modalMeta: document.getElementById("modal-meta"),
|
modalMeta: document.getElementById("modal-meta"),
|
||||||
|
modalDetails: document.getElementById("modal-details"),
|
||||||
modalStats: document.getElementById("modal-stats"),
|
modalStats: document.getElementById("modal-stats"),
|
||||||
|
modalMapContainer: document.getElementById("modal-map-container"),
|
||||||
|
modalMap: document.getElementById("modal-map"),
|
||||||
schoolDetailChart: document.getElementById("school-detail-chart"),
|
schoolDetailChart: document.getElementById("school-detail-chart"),
|
||||||
addToCompare: document.getElementById("add-to-compare"),
|
addToCompare: document.getElementById("add-to-compare"),
|
||||||
};
|
};
|
||||||
@@ -1174,12 +1178,35 @@ async function openSchoolModal(urn) {
|
|||||||
state.currentSchoolData = data;
|
state.currentSchoolData = data;
|
||||||
|
|
||||||
elements.modalSchoolName.textContent = data.school_info.school_name;
|
elements.modalSchoolName.textContent = data.school_info.school_name;
|
||||||
|
|
||||||
|
// Build meta tags including faith if applicable
|
||||||
|
const faithDenom = data.school_info.religious_denomination;
|
||||||
|
const showFaith = faithDenom &&
|
||||||
|
faithDenom !== "None" &&
|
||||||
|
faithDenom !== "Does not apply" &&
|
||||||
|
faithDenom !== "";
|
||||||
|
const faithTag = showFaith
|
||||||
|
? `<span class="school-tag faith">${escapeHtml(faithDenom)}</span>`
|
||||||
|
: "";
|
||||||
|
|
||||||
elements.modalMeta.innerHTML = `
|
elements.modalMeta.innerHTML = `
|
||||||
<span class="school-tag">${escapeHtml(data.school_info.local_authority || "")}</span>
|
<span class="school-tag">${escapeHtml(data.school_info.local_authority || "")}</span>
|
||||||
<span class="school-tag type">${escapeHtml(data.school_info.school_type || "")}</span>
|
<span class="school-tag type">${escapeHtml(data.school_info.school_type || "")}</span>
|
||||||
<span class="school-tag">Primary</span>
|
${faithTag}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
// Build details section (address and age range)
|
||||||
|
const ageRange = data.school_info.age_range;
|
||||||
|
const address = data.school_info.address;
|
||||||
|
let detailsHtml = "";
|
||||||
|
if (address) {
|
||||||
|
detailsHtml += `<div class="modal-address">${escapeHtml(address)}</div>`;
|
||||||
|
}
|
||||||
|
if (ageRange) {
|
||||||
|
detailsHtml += `<div class="modal-age-range">Ages ${escapeHtml(ageRange)}</div>`;
|
||||||
|
}
|
||||||
|
elements.modalDetails.innerHTML = detailsHtml;
|
||||||
|
|
||||||
// Get latest year data with actual results
|
// Get latest year data with actual results
|
||||||
const sortedData = data.yearly_data.sort((a, b) => b.year - a.year);
|
const sortedData = data.yearly_data.sort((a, b) => b.year - a.year);
|
||||||
const latest =
|
const latest =
|
||||||
@@ -1327,6 +1354,46 @@ async function openSchoolModal(urn) {
|
|||||||
? "Remove from Compare"
|
? "Remove from Compare"
|
||||||
: "Add to Compare";
|
: "Add to Compare";
|
||||||
elements.addToCompare.dataset.urn = data.school_info.urn;
|
elements.addToCompare.dataset.urn = data.school_info.urn;
|
||||||
|
|
||||||
|
// Initialize modal map if coordinates available
|
||||||
|
const lat = data.school_info.latitude;
|
||||||
|
const lng = data.school_info.longitude;
|
||||||
|
|
||||||
|
if (lat && lng && typeof L !== "undefined") {
|
||||||
|
elements.modalMapContainer.style.display = "block";
|
||||||
|
|
||||||
|
// Destroy existing map if any
|
||||||
|
if (modalMap) {
|
||||||
|
modalMap.remove();
|
||||||
|
modalMap = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create map after a brief delay to ensure container is visible
|
||||||
|
setTimeout(() => {
|
||||||
|
try {
|
||||||
|
modalMap = L.map(elements.modalMap, {
|
||||||
|
scrollWheelZoom: false,
|
||||||
|
}).setView([lat, lng], 15);
|
||||||
|
|
||||||
|
L.tileLayer("https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png", {
|
||||||
|
attribution: "© OpenStreetMap contributors",
|
||||||
|
maxZoom: 19,
|
||||||
|
}).addTo(modalMap);
|
||||||
|
|
||||||
|
L.marker([lat, lng]).addTo(modalMap);
|
||||||
|
|
||||||
|
// Handle click to open fullscreen map
|
||||||
|
elements.modalMap.addEventListener("click", () => {
|
||||||
|
openMapModal(lat, lng, data.school_info.school_name);
|
||||||
|
});
|
||||||
|
} catch (err) {
|
||||||
|
console.error("Error initializing modal map:", err);
|
||||||
|
elements.modalMapContainer.style.display = "none";
|
||||||
|
}
|
||||||
|
}, 100);
|
||||||
|
} else {
|
||||||
|
elements.modalMapContainer.style.display = "none";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function closeModal() {
|
function closeModal() {
|
||||||
@@ -1334,6 +1401,12 @@ function closeModal() {
|
|||||||
document.body.style.overflow = "";
|
document.body.style.overflow = "";
|
||||||
state.currentSchoolData = null;
|
state.currentSchoolData = null;
|
||||||
|
|
||||||
|
// Clean up modal map
|
||||||
|
if (modalMap) {
|
||||||
|
modalMap.remove();
|
||||||
|
modalMap = null;
|
||||||
|
}
|
||||||
|
|
||||||
// Restore visibility of school maps
|
// Restore visibility of school maps
|
||||||
document.querySelectorAll('.school-map').forEach(el => {
|
document.querySelectorAll('.school-map').forEach(el => {
|
||||||
el.style.visibility = 'visible';
|
el.style.visibility = 'visible';
|
||||||
|
|||||||
@@ -329,12 +329,17 @@
|
|||||||
<div class="modal-header">
|
<div class="modal-header">
|
||||||
<h2 id="modal-school-name"></h2>
|
<h2 id="modal-school-name"></h2>
|
||||||
<div class="modal-meta" id="modal-meta"></div>
|
<div class="modal-meta" id="modal-meta"></div>
|
||||||
|
<div class="modal-details" id="modal-details"></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="modal-body">
|
<div class="modal-body">
|
||||||
<div class="modal-chart-container">
|
<div class="modal-chart-container">
|
||||||
<canvas id="school-detail-chart"></canvas>
|
<canvas id="school-detail-chart"></canvas>
|
||||||
</div>
|
</div>
|
||||||
<div class="modal-stats" id="modal-stats"></div>
|
<div class="modal-stats" id="modal-stats"></div>
|
||||||
|
<div class="modal-map-container" id="modal-map-container">
|
||||||
|
<h4>Location</h4>
|
||||||
|
<div class="modal-map" id="modal-map"></div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="modal-footer">
|
<div class="modal-footer">
|
||||||
<button class="btn btn-primary" id="add-to-compare">Add to Compare</button>
|
<button class="btn btn-primary" id="add-to-compare">Add to Compare</button>
|
||||||
|
|||||||
@@ -1051,6 +1051,20 @@ body {
|
|||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.modal-details {
|
||||||
|
margin-top: 0.75rem;
|
||||||
|
font-size: 0.875rem;
|
||||||
|
color: var(--text-secondary);
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-details .modal-address {
|
||||||
|
margin-bottom: 0.25rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-details .modal-age-range {
|
||||||
|
color: var(--text-muted);
|
||||||
|
}
|
||||||
|
|
||||||
.modal-body {
|
.modal-body {
|
||||||
padding: 2rem;
|
padding: 2rem;
|
||||||
}
|
}
|
||||||
@@ -1106,6 +1120,24 @@ body {
|
|||||||
margin-top: 0.25rem;
|
margin-top: 0.25rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.modal-map-container {
|
||||||
|
margin-top: 2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-map-container h4 {
|
||||||
|
font-size: 1rem;
|
||||||
|
font-weight: 600;
|
||||||
|
color: var(--text-primary);
|
||||||
|
margin-bottom: 0.75rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-map {
|
||||||
|
height: 200px;
|
||||||
|
border-radius: var(--radius-md);
|
||||||
|
overflow: hidden;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
.modal-footer {
|
.modal-footer {
|
||||||
padding: 1.5rem 2rem;
|
padding: 1.5rem 2rem;
|
||||||
border-top: 1px solid var(--border-color);
|
border-top: 1px solid var(--border-color);
|
||||||
|
|||||||
Reference in New Issue
Block a user