Files
school_compare/nextjs-app/hooks/useSchools.ts
Tudor ff7f5487e6
Some checks failed
Build and Push Docker Images / Build Backend (FastAPI) (push) Successful in 1m26s
Build and Push Docker Images / Build Frontend (Next.js) (push) Failing after 1m48s
Build and Push Docker Images / Trigger Portainer Update (push) Has been skipped
Complete Next.js migration with SSR and Docker deployment
- Migrate from vanilla JavaScript SPA to Next.js 16 with App Router
- Add server-side rendering for all pages (Home, Compare, Rankings)
- Create individual school pages with dynamic routing (/school/[urn])
- Implement Chart.js and Leaflet map integrations
- Add comprehensive SEO with sitemap, robots.txt, and JSON-LD
- Set up Docker multi-service architecture (PostgreSQL, FastAPI, Next.js)
- Update CI/CD pipeline to build both backend and frontend images
- Fix Dockerfile to include devDependencies for TypeScript compilation
- Add Jest testing configuration
- Implement performance optimizations (code splitting, caching)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-02 20:34:35 +00:00

47 lines
1.1 KiB
TypeScript

/**
* Custom hook for fetching schools with SWR
*/
'use client';
import useSWR from 'swr';
import { fetcher } from '@/lib/api';
import type { SchoolsResponse, SchoolSearchParams } from '@/lib/types';
export function useSchools(params: SchoolSearchParams = {}, shouldFetch: boolean = true) {
const queryParams = new URLSearchParams();
Object.entries(params).forEach(([key, value]) => {
if (value !== undefined && value !== null && value !== '') {
queryParams.set(key, String(value));
}
});
const queryString = queryParams.toString();
const url = `/schools${queryString ? `?${queryString}` : ''}`;
const { data, error, isLoading, mutate } = useSWR<SchoolsResponse>(
shouldFetch ? url : null,
fetcher,
{
revalidateOnFocus: false,
dedupingInterval: 5000, // 5 seconds
}
);
return {
schools: data?.schools || [],
pagination: data ? {
page: data.page,
page_size: data.page_size,
total: data.total,
total_pages: data.total_pages,
} : null,
searchMode: data?.search_mode,
locationInfo: data?.location_info,
isLoading,
error,
mutate,
};
}