All checks were successful
Build and Push Docker Images / Build Backend (FastAPI) (push) Successful in 32s
Build and Push Docker Images / Build Frontend (Next.js) (push) Successful in 1m6s
Build and Push Docker Images / Build Pipeline (Meltano + dbt + Airflow) (push) Successful in 32s
Build and Push Docker Images / Trigger Portainer Update (push) Successful in 1s
These params were present in the URL but never passed to fetchSchools on the server side, so the backend never applied the filters. Also include them in hasSearchParams so filter-only searches trigger a fetch. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
98 lines
2.8 KiB
TypeScript
98 lines
2.8 KiB
TypeScript
/**
|
|
* Home Page (SSR)
|
|
* Main landing page with school search and browsing
|
|
*/
|
|
|
|
import { fetchSchools, fetchFilters, fetchDataInfo } from '@/lib/api';
|
|
import { HomeView } from '@/components/HomeView';
|
|
|
|
interface HomePageProps {
|
|
searchParams: Promise<{
|
|
search?: string;
|
|
local_authority?: string;
|
|
school_type?: string;
|
|
phase?: string;
|
|
page?: string;
|
|
postcode?: string;
|
|
radius?: string;
|
|
sort?: string;
|
|
gender?: string;
|
|
admissions_policy?: string;
|
|
has_sixth_form?: string;
|
|
}>;
|
|
}
|
|
|
|
export const metadata = {
|
|
title: 'Home',
|
|
description: 'Search and compare school performance across England',
|
|
};
|
|
|
|
// Force dynamic rendering (no static generation at build time)
|
|
export const dynamic = 'force-dynamic';
|
|
|
|
export default async function HomePage({ searchParams }: HomePageProps) {
|
|
// Await search params (Next.js 15 requirement)
|
|
const params = await searchParams;
|
|
|
|
// Parse search params
|
|
const page = parseInt(params.page || '1');
|
|
const radius = params.radius ? parseFloat(params.radius) : undefined;
|
|
|
|
// Check if user has performed a search
|
|
const hasSearchParams = !!(
|
|
params.search ||
|
|
params.local_authority ||
|
|
params.school_type ||
|
|
params.phase ||
|
|
params.postcode ||
|
|
params.gender ||
|
|
params.admissions_policy ||
|
|
params.has_sixth_form
|
|
);
|
|
|
|
// Fetch data on server with error handling
|
|
try {
|
|
const [filtersData, dataInfo] = await Promise.all([fetchFilters(), fetchDataInfo().catch(() => null)]);
|
|
|
|
// Only fetch schools if there are search parameters
|
|
let schoolsData;
|
|
if (hasSearchParams) {
|
|
schoolsData = await fetchSchools({
|
|
search: params.search,
|
|
local_authority: params.local_authority,
|
|
school_type: params.school_type,
|
|
phase: params.phase,
|
|
postcode: params.postcode,
|
|
radius,
|
|
page,
|
|
page_size: 50,
|
|
gender: params.gender,
|
|
admissions_policy: params.admissions_policy,
|
|
has_sixth_form: params.has_sixth_form,
|
|
});
|
|
} else {
|
|
// Empty state by default
|
|
schoolsData = { schools: [], page: 1, page_size: 50, total: 0, total_pages: 0 };
|
|
}
|
|
|
|
return (
|
|
<HomeView
|
|
initialSchools={schoolsData}
|
|
filters={filtersData || { local_authorities: [], school_types: [], years: [], phases: [], genders: [], admissions_policies: [] }}
|
|
totalSchools={dataInfo?.total_schools ?? null}
|
|
/>
|
|
);
|
|
} catch (error) {
|
|
console.error('Error fetching data for home page:', error);
|
|
|
|
// Return error state with empty data
|
|
return (
|
|
<HomeView
|
|
initialSchools={{ schools: [], page: 1, page_size: 50, total: 0, total_pages: 0 }}
|
|
filters={{ local_authorities: [], school_types: [], years: [], phases: [], genders: [], admissions_policies: [] }}
|
|
totalSchools={null}
|
|
/>
|
|
);
|
|
}
|
|
}
|