fix(admissions): switch to EES content API + correct publication slug and columns
All checks were successful
Build and Push Docker Images / Build Backend (FastAPI) (push) Successful in 50s
Build and Push Docker Images / Build Frontend (Next.js) (push) Successful in 1m12s
Build and Push Docker Images / Build Integrator (push) Successful in 57s
Build and Push Docker Images / Build Kestra Init (push) Successful in 33s
Build and Push Docker Images / Trigger Portainer Update (push) Successful in 1s
All checks were successful
Build and Push Docker Images / Build Backend (FastAPI) (push) Successful in 50s
Build and Push Docker Images / Build Frontend (Next.js) (push) Successful in 1m12s
Build and Push Docker Images / Build Integrator (push) Successful in 57s
Build and Push Docker Images / Build Kestra Init (push) Successful in 33s
Build and Push Docker Images / Trigger Portainer Update (push) Successful in 1s
The EES statistics API only exposes ~13 publications; admissions data is not among them. Switch to the EES content API (content.explore-education-statistics. service.gov.uk) which covers all publications. - ees.py: add get_content_release_id() and download_release_zip_csv() that fetch the release ZIP and extract a named CSV member from it - admissions.py: use corrected slug (primary-and-secondary-school-applications- and-offers), correct column names from actual CSV (school_urn, total_number_places_offered, times_put_as_1st_preference, etc.), derive first_preference_offers_pct from offer/application ratio, filter to primary schools only, keep most recent year per URN Also includes SchoolDetailView UX redesign: parent-first section ordering, plain-English labels, national average benchmarks, progress score colour coding, expanded header, quick summary strip, and CSS consolidation. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -50,7 +50,34 @@
|
||||
.address {
|
||||
font-size: 0.875rem;
|
||||
color: var(--text-muted, #8a847a);
|
||||
margin: 0;
|
||||
margin: 0 0 0.75rem;
|
||||
}
|
||||
|
||||
/* Expanded header details (headteacher, website, trust, pupils) */
|
||||
.headerDetails {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 0.5rem 1.25rem;
|
||||
margin-top: 0.5rem;
|
||||
}
|
||||
|
||||
.headerDetail {
|
||||
font-size: 0.8125rem;
|
||||
color: var(--text-secondary, #5c564d);
|
||||
}
|
||||
|
||||
.headerDetail strong {
|
||||
color: var(--text-primary, #1a1612);
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.headerDetail a {
|
||||
color: var(--accent-teal, #2d7d7d);
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.headerDetail a:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.actions {
|
||||
@@ -90,6 +117,50 @@
|
||||
opacity: 0.9;
|
||||
}
|
||||
|
||||
/* Quick Summary Strip */
|
||||
.summaryStrip {
|
||||
display: flex;
|
||||
gap: 0.625rem;
|
||||
flex-wrap: wrap;
|
||||
margin: 0 0 1.25rem;
|
||||
}
|
||||
|
||||
.summaryPill {
|
||||
padding: 0.35rem 0.875rem;
|
||||
border-radius: 999px;
|
||||
font-size: 0.8125rem;
|
||||
font-weight: 600;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 0.3rem;
|
||||
}
|
||||
|
||||
.summaryPillGood {
|
||||
background: #d1fae5;
|
||||
color: #065f46;
|
||||
}
|
||||
|
||||
.summaryPillWarn {
|
||||
background: #fef3c7;
|
||||
color: #92400e;
|
||||
}
|
||||
|
||||
.summaryPillBad {
|
||||
background: #fee2e2;
|
||||
color: #991b1b;
|
||||
}
|
||||
|
||||
/* Unified card — replaces summary / chartsSection / detailedMetrics /
|
||||
absenceSection / historySection / supplementarySection / mapSection */
|
||||
.card {
|
||||
background: var(--bg-card, white);
|
||||
border: 1px solid var(--border-color, #e5dfd5);
|
||||
border-radius: 10px;
|
||||
padding: 1.25rem 1.5rem;
|
||||
margin-bottom: 1rem;
|
||||
box-shadow: var(--shadow-soft);
|
||||
}
|
||||
|
||||
/* Section Title */
|
||||
.sectionTitle {
|
||||
font-size: 1.125rem;
|
||||
@@ -102,6 +173,7 @@
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.375rem;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.sectionTitle::before {
|
||||
@@ -111,18 +183,35 @@
|
||||
height: 1em;
|
||||
background: var(--accent-coral, #e07256);
|
||||
border-radius: 2px;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
/* Summary Section */
|
||||
.summary {
|
||||
background: var(--bg-card, white);
|
||||
border: 1px solid var(--border-color, #e5dfd5);
|
||||
border-radius: 10px;
|
||||
padding: 1rem 1.25rem;
|
||||
margin-bottom: 1rem;
|
||||
box-shadow: var(--shadow-soft);
|
||||
.sectionSubtitle {
|
||||
font-size: 0.85rem;
|
||||
color: var(--text-muted, #8a847a);
|
||||
margin: -0.5rem 0 1rem;
|
||||
}
|
||||
|
||||
/* Response count badge (used in "What Parents Say") */
|
||||
.responseBadge {
|
||||
font-size: 0.75rem;
|
||||
font-weight: 500;
|
||||
font-family: var(--font-dm-sans), sans-serif;
|
||||
color: var(--text-muted, #8a847a);
|
||||
background: var(--bg-secondary, #f3ede4);
|
||||
padding: 0.1rem 0.5rem;
|
||||
border-radius: 999px;
|
||||
margin-left: auto;
|
||||
}
|
||||
|
||||
.subSectionTitle {
|
||||
font-size: 0.875rem;
|
||||
font-weight: 600;
|
||||
color: var(--text-secondary, #5c564d);
|
||||
margin: 1.25rem 0 0.75rem;
|
||||
}
|
||||
|
||||
/* Metrics Grid & Cards */
|
||||
.metricsGrid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
|
||||
@@ -156,21 +245,30 @@
|
||||
gap: 0.25rem;
|
||||
}
|
||||
|
||||
.metricHint {
|
||||
font-size: 0.7rem;
|
||||
color: var(--text-muted, #8a847a);
|
||||
margin-top: 0.3rem;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.metricTrend {
|
||||
font-size: 1rem;
|
||||
color: var(--accent-teal, #2d7d7d);
|
||||
}
|
||||
|
||||
/* Charts Section */
|
||||
.chartsSection {
|
||||
background: var(--bg-card, white);
|
||||
border: 1px solid var(--border-color, #e5dfd5);
|
||||
border-radius: 10px;
|
||||
padding: 1rem 1.25rem;
|
||||
margin-bottom: 1rem;
|
||||
box-shadow: var(--shadow-soft);
|
||||
/* Progress score colour coding */
|
||||
.progressPositive {
|
||||
color: var(--accent-teal, #2d7d7d);
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.progressNegative {
|
||||
color: var(--accent-coral, #e07256);
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
/* Charts Section */
|
||||
.chartContainer {
|
||||
width: 100%;
|
||||
height: 280px;
|
||||
@@ -178,15 +276,6 @@
|
||||
}
|
||||
|
||||
/* Detailed Metrics - Compact Grid Layout */
|
||||
.detailedMetrics {
|
||||
background: var(--bg-card, white);
|
||||
border: 1px solid var(--border-color, #e5dfd5);
|
||||
border-radius: 10px;
|
||||
padding: 1rem 1.25rem;
|
||||
margin-bottom: 1rem;
|
||||
box-shadow: var(--shadow-soft);
|
||||
}
|
||||
|
||||
.metricGroupsGrid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(3, 1fr);
|
||||
@@ -235,53 +324,7 @@
|
||||
color: var(--accent-teal, #2d7d7d);
|
||||
}
|
||||
|
||||
/* Absence Section */
|
||||
.absenceSection {
|
||||
background: var(--bg-card, white);
|
||||
border: 1px solid var(--border-color, #e5dfd5);
|
||||
border-radius: 10px;
|
||||
padding: 1rem 1.25rem;
|
||||
margin-bottom: 1rem;
|
||||
box-shadow: var(--shadow-soft);
|
||||
}
|
||||
|
||||
.absenceGrid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
|
||||
gap: 0.75rem;
|
||||
}
|
||||
|
||||
.absenceCard {
|
||||
background: var(--bg-secondary, #f3ede4);
|
||||
border: 1px solid var(--border-color, #e5dfd5);
|
||||
border-radius: 6px;
|
||||
padding: 0.75rem 1rem;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.absenceLabel {
|
||||
font-size: 0.75rem;
|
||||
color: var(--text-muted, #8a847a);
|
||||
margin-bottom: 0.25rem;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.absenceValue {
|
||||
font-size: 1.125rem;
|
||||
font-weight: 700;
|
||||
color: var(--text-primary, #1a1612);
|
||||
}
|
||||
|
||||
/* Map Section */
|
||||
.mapSection {
|
||||
background: var(--bg-card, white);
|
||||
border: 1px solid var(--border-color, #e5dfd5);
|
||||
border-radius: 10px;
|
||||
padding: 1rem 1.25rem;
|
||||
margin-bottom: 1rem;
|
||||
box-shadow: var(--shadow-soft);
|
||||
}
|
||||
|
||||
/* Map */
|
||||
.mapContainer {
|
||||
width: 100%;
|
||||
height: 250px;
|
||||
@@ -290,16 +333,7 @@
|
||||
border: 1px solid var(--border-color, #e5dfd5);
|
||||
}
|
||||
|
||||
/* History Section */
|
||||
.historySection {
|
||||
background: var(--bg-card, white);
|
||||
border: 1px solid var(--border-color, #e5dfd5);
|
||||
border-radius: 10px;
|
||||
padding: 1rem 1.25rem;
|
||||
margin-bottom: 1rem;
|
||||
box-shadow: var(--shadow-soft);
|
||||
}
|
||||
|
||||
/* History Table */
|
||||
.tableWrapper {
|
||||
overflow-x: auto;
|
||||
margin-top: 0.5rem;
|
||||
@@ -345,7 +379,186 @@
|
||||
color: var(--accent-gold, #c9a227);
|
||||
}
|
||||
|
||||
/* Responsive Design */
|
||||
/* Ofsted */
|
||||
.ofstedHeader {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex-wrap: wrap;
|
||||
gap: 0.75rem;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
.ofstedGrade {
|
||||
display: inline-block;
|
||||
padding: 0.3rem 0.75rem;
|
||||
font-size: 1rem;
|
||||
font-weight: 700;
|
||||
border-radius: 6px;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.ofstedGrade1 { background: rgba(45, 125, 125, 0.12); color: var(--accent-teal, #2d7d7d); }
|
||||
.ofstedGrade2 { background: rgba(60, 140, 60, 0.12); color: #3c8c3c; }
|
||||
.ofstedGrade3 { background: rgba(201, 162, 39, 0.15); color: #b8920e; }
|
||||
.ofstedGrade4 { background: rgba(224, 114, 86, 0.15); color: var(--accent-coral, #e07256); }
|
||||
|
||||
.ofstedDate {
|
||||
font-size: 0.85rem;
|
||||
color: var(--text-muted, #8a847a);
|
||||
}
|
||||
|
||||
.ofstedPrevious {
|
||||
font-size: 0.8125rem;
|
||||
color: var(--text-muted, #8a847a);
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.ofstedReportLink {
|
||||
font-size: 0.8125rem;
|
||||
color: var(--accent-teal, #2d7d7d);
|
||||
text-decoration: none;
|
||||
margin-left: auto;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.ofstedReportLink:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
/* Parent View */
|
||||
.parentViewGrid {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 0.5rem;
|
||||
}
|
||||
|
||||
.parentViewRow {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.75rem;
|
||||
font-size: 0.875rem;
|
||||
}
|
||||
|
||||
.parentViewLabel {
|
||||
flex: 0 0 18rem;
|
||||
color: var(--text-secondary, #5c564d);
|
||||
font-size: 0.8125rem;
|
||||
}
|
||||
|
||||
.parentViewBar {
|
||||
flex: 1;
|
||||
height: 0.5rem;
|
||||
background: var(--bg-secondary, #f3ede4);
|
||||
border-radius: 4px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.parentViewFill {
|
||||
height: 100%;
|
||||
background: var(--accent-teal, #2d7d7d);
|
||||
border-radius: 4px;
|
||||
transition: width 0.4s ease;
|
||||
}
|
||||
|
||||
.parentViewPct {
|
||||
flex: 0 0 2.75rem;
|
||||
text-align: right;
|
||||
font-size: 0.8125rem;
|
||||
font-weight: 600;
|
||||
color: var(--text-primary, #1a1612);
|
||||
}
|
||||
|
||||
/* Admissions badges */
|
||||
.admissionsBadge {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 0.35rem;
|
||||
padding: 0.3rem 0.75rem;
|
||||
border-radius: 6px;
|
||||
font-size: 0.8125rem;
|
||||
font-weight: 600;
|
||||
margin-top: 0.75rem;
|
||||
}
|
||||
|
||||
.admissionsBadgeWarn {
|
||||
background: rgba(201, 162, 39, 0.15);
|
||||
color: #b8920e;
|
||||
}
|
||||
|
||||
.admissionsBadgeGood {
|
||||
background: rgba(60, 140, 60, 0.12);
|
||||
color: #3c8c3c;
|
||||
}
|
||||
|
||||
/* Deprivation dot scale */
|
||||
.deprivationDots {
|
||||
display: flex;
|
||||
gap: 0.375rem;
|
||||
margin: 0.75rem 0 0.5rem;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.deprivationDot {
|
||||
width: 1.25rem;
|
||||
height: 1.25rem;
|
||||
border-radius: 50%;
|
||||
background: var(--bg-secondary, #f3ede4);
|
||||
border: 2px solid var(--border-color, #e5dfd5);
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.deprivationDotFilled {
|
||||
background: var(--accent-teal, #2d7d7d);
|
||||
border-color: var(--accent-teal, #2d7d7d);
|
||||
}
|
||||
|
||||
.deprivationDesc {
|
||||
font-size: 0.875rem;
|
||||
color: var(--text-secondary, #5c564d);
|
||||
line-height: 1.5;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.deprivationScaleLabel {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
font-size: 0.7rem;
|
||||
color: var(--text-muted, #8a847a);
|
||||
margin-top: 0.25rem;
|
||||
}
|
||||
|
||||
/* Progress note */
|
||||
.progressNote {
|
||||
margin-top: 0.75rem;
|
||||
font-size: 0.8rem;
|
||||
color: var(--text-muted);
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
/* Back navigation */
|
||||
.backNav {
|
||||
padding: 1rem var(--page-padding, 2rem);
|
||||
padding-bottom: 0;
|
||||
}
|
||||
|
||||
.backButton {
|
||||
background: none;
|
||||
border: none;
|
||||
color: var(--text-secondary);
|
||||
font-size: 0.875rem;
|
||||
cursor: pointer;
|
||||
padding: 0.375rem 0;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 0.25rem;
|
||||
transition: color var(--transition);
|
||||
}
|
||||
|
||||
.backButton:hover {
|
||||
color: var(--text-primary);
|
||||
}
|
||||
|
||||
/* ── Responsive ──────────────────────────────────────── */
|
||||
@media (max-width: 768px) {
|
||||
.headerContent {
|
||||
flex-direction: column;
|
||||
@@ -396,148 +609,27 @@
|
||||
}
|
||||
}
|
||||
|
||||
.backNav {
|
||||
padding: 1rem var(--page-padding, 2rem);
|
||||
padding-bottom: 0;
|
||||
}
|
||||
|
||||
.backButton {
|
||||
background: none;
|
||||
border: none;
|
||||
color: var(--text-secondary);
|
||||
font-size: 0.875rem;
|
||||
cursor: pointer;
|
||||
padding: 0.375rem 0;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 0.25rem;
|
||||
transition: color var(--transition);
|
||||
}
|
||||
|
||||
.backButton:hover {
|
||||
color: var(--text-primary);
|
||||
}
|
||||
|
||||
.progressNote {
|
||||
margin-top: 0.75rem;
|
||||
font-size: 0.8rem;
|
||||
color: var(--text-muted);
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
/* ── Supplementary Data Sections ──────────────────────── */
|
||||
.supplementarySection {
|
||||
background: var(--bg-card, white);
|
||||
border: 1px solid var(--border-color, #e5dfd5);
|
||||
border-radius: 10px;
|
||||
padding: 1.25rem 1.5rem;
|
||||
}
|
||||
|
||||
.supplementarySubtitle {
|
||||
font-size: 0.85rem;
|
||||
color: var(--text-muted, #8a847a);
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
.subSectionTitle {
|
||||
font-size: 0.875rem;
|
||||
font-weight: 600;
|
||||
color: var(--text-secondary, #5c564d);
|
||||
margin: 1.25rem 0 0.75rem;
|
||||
}
|
||||
|
||||
/* Ofsted */
|
||||
.ofstedHeader {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.75rem;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
.ofstedGrade {
|
||||
display: inline-block;
|
||||
padding: 0.3rem 0.75rem;
|
||||
font-size: 1rem;
|
||||
font-weight: 700;
|
||||
border-radius: 6px;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.ofstedGrade1 { background: rgba(45, 125, 125, 0.12); color: var(--accent-teal, #2d7d7d); }
|
||||
.ofstedGrade2 { background: rgba(60, 140, 60, 0.12); color: #3c8c3c; }
|
||||
.ofstedGrade3 { background: rgba(201, 162, 39, 0.15); color: #b8920e; }
|
||||
.ofstedGrade4 { background: rgba(224, 114, 86, 0.15); color: var(--accent-coral, #e07256); }
|
||||
|
||||
.ofstedDate {
|
||||
font-size: 0.85rem;
|
||||
color: var(--text-muted, #8a847a);
|
||||
}
|
||||
|
||||
.ofstedType {
|
||||
font-size: 0.8rem;
|
||||
color: var(--text-muted, #8a847a);
|
||||
margin-top: 0.5rem;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
/* Parent View */
|
||||
.parentViewGrid {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 0.5rem;
|
||||
}
|
||||
|
||||
.parentViewRow {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.75rem;
|
||||
font-size: 0.875rem;
|
||||
}
|
||||
|
||||
.parentViewLabel {
|
||||
flex: 0 0 18rem;
|
||||
color: var(--text-secondary, #5c564d);
|
||||
font-size: 0.8125rem;
|
||||
}
|
||||
|
||||
.parentViewBar {
|
||||
flex: 1;
|
||||
height: 0.5rem;
|
||||
background: var(--bg-secondary, #f3ede4);
|
||||
border-radius: 4px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.parentViewFill {
|
||||
height: 100%;
|
||||
background: var(--accent-teal, #2d7d7d);
|
||||
border-radius: 4px;
|
||||
transition: width 0.4s ease;
|
||||
}
|
||||
|
||||
.parentViewPct {
|
||||
flex: 0 0 2.75rem;
|
||||
text-align: right;
|
||||
font-size: 0.8125rem;
|
||||
font-weight: 600;
|
||||
color: var(--text-primary, #1a1612);
|
||||
}
|
||||
|
||||
/* Metric hint (small label below metricValue) */
|
||||
.metricHint {
|
||||
font-size: 0.75rem;
|
||||
color: var(--text-muted, #8a847a);
|
||||
margin-top: 0.25rem;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
/* ── Mobile ──────────────────────────────────────────── */
|
||||
@media (max-width: 640px) {
|
||||
.supplementarySection {
|
||||
padding: 1rem;
|
||||
@media (max-width: 480px) {
|
||||
.parentViewRow {
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
gap: 0.25rem;
|
||||
}
|
||||
|
||||
.parentViewLabel {
|
||||
flex: 0 0 10rem;
|
||||
flex: none;
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
.parentViewBar {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.parentViewPct {
|
||||
flex: none;
|
||||
}
|
||||
|
||||
.card {
|
||||
padding: 1rem;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user