Complete Next.js migration with SSR and Docker deployment
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

- 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>
This commit is contained in:
Tudor
2026-02-02 20:34:35 +00:00
parent f4919db3b9
commit ff7f5487e6
72 changed files with 18636 additions and 20 deletions

View File

@@ -0,0 +1,32 @@
/**
* ComparisonContext
* Global state for school comparison basket
*/
'use client';
import { createContext, useContext } from 'react';
import type { School } from '@/lib/types';
interface ComparisonContextType {
selectedSchools: School[];
comparisonData: any;
isLoading: boolean;
error: any;
addSchool: (school: School) => void;
removeSchool: (urn: number) => void;
clearAll: () => void;
isSelected: (urn: number) => boolean;
canAddMore: boolean;
mutate: () => void;
}
export const ComparisonContext = createContext<ComparisonContextType | undefined>(undefined);
export function useComparisonContext() {
const context = useContext(ComparisonContext);
if (!context) {
throw new Error('useComparisonContext must be used within ComparisonProvider');
}
return context;
}

View File

@@ -0,0 +1,19 @@
/**
* ComparisonProvider
* Provides comparison state to all components
*/
'use client';
import { useComparison } from '@/hooks/useComparison';
import { ComparisonContext } from './ComparisonContext';
export function ComparisonProvider({ children }: { children: React.ReactNode }) {
const comparisonState = useComparison();
return (
<ComparisonContext.Provider value={comparisonState}>
{children}
</ComparisonContext.Provider>
);
}