Skip to content

06. Frontend

Repository: aclimate_v3_frontend Stack: TypeScript (97.4%), CSS (1.6%), React 19, Next.js 15

Overview

The frontend is the primary web application that end users interact with. It consumes the AClimate v3 WebAPI to provide climate analysis, forecast visualization, and agronomic decision support.

Technology Stack

Component Technology Purpose
Framework Next.js 15 (App Router) Server-side rendering, routing, API proxy
UI Library React 19 Component-based UI
Language TypeScript 5 Type safety
Styling Tailwind CSS 4 + Flowbite 3 Responsive design system
Charts ApexCharts 5 + react-apexcharts Climate data visualization
Maps Leaflet + react-leaflet + leaflet-timedimension Spatial data layers
Auth keycloak-js 26 Keycloak SSO integration
HTTP axios 1 API client
Icons FontAwesome 7 + Lucide React Icon system
PDF jsPDF + html-to-image Report generation

Architecture

The application uses Next.js App Router architecture with both server and client components:

src/
  app/
    layout.tsx          # Root layout with all providers
    page.tsx            # Home page
    HomeClient.tsx      # Home client component
    config.ts           # Environment configuration
    locations/          # Weather stations module
    spatial/            # Spatial maps module
    scenario/           # Climate scenarios module
    favorites/          # Favorite stations
    user-profile/       # User profile and subscriptions
    about/              # About AClimate
    api/                # API proxy routes
    components/         # Shared UI components
    components_special/ # Specialized components
    contexts/           # React contexts (Auth, Country, I18n, etc.)
    hooks/              # Custom React hooks
    i18n/               # Internationalization
    lib/                # Library utilities
    services/           # API service layer
    types/              # TypeScript type definitions
    utils/              # Utility functions
    configs/            # Branch-specific configs
    m/                  # Mobile-specific views

Providers (layout.tsx)

The root layout wraps the application in multiple context providers:

ColorProvider -> I18nProvider -> CookieConsentProvider -> AuthProvider -> CountryProvider -> StationsProvider
Provider Purpose
AuthProvider Keycloak authentication state management
CountryProvider Selected country context for data queries
StationsProvider Active weather station context
I18nProvider Internationalization and translations
CookieConsentProvider GDPR cookie consent management
ColorProvider Theme color customization

Configuration

Environment variables configured at build-time (NEXT_PUBLIC_* prefix):

Variable Default Description
NEXT_PUBLIC_ACLIMATE_API_URL http://127.0.0.1:8000 WebAPI base URL
NEXT_PUBLIC_ACLIMATE_API_FRONTEND_URL http://127.0.0.1:9000 Users/Auth API
NEXT_PUBLIC_KEYCLOAK_URL http://localhost:8080 Keycloak server
NEXT_PUBLIC_KEYCLOAK_REALM aclimate Keycloak realm
NEXT_PUBLIC_KEYCLOAK_CLIENT_ID aclimate_admin Keycloak client
NEXT_PUBLIC_GEOSERVER_URL https://geo.aclimate.org/geoserver/climate_historical GeoServer WMS
NEXT_PUBLIC_COUNTRY_NAME Colombia Default country
NEXT_PUBLIC_ACLIMATE_APP_ID 1 Application identifier

Feature flags:

  • NEXT_PUBLIC_SHOW_STATIONS_MODULE
  • NEXT_PUBLIC_SHOW_USERS_MODULE

Deployment

Docker

Multi-stage Dockerfile with 3 stages:

  1. deps: Install dependencies (npm ci)
  2. builder: Build Next.js with build-time ARGs (NEXTPUBLIC*)
  3. runner: Production image with dumb-init, non-root user (nextjs), HEALTHCHECK
docker build \
  --build-arg NEXT_PUBLIC_ACLIMATE_API_URL=https://api.aclimate.org \
  --build-arg NEXT_PUBLIC_KEYCLOAK_URL=https://keycloak.aclimate.org \
  -t aclimate-v3-frontend:latest .

PM2

The ecosystem.config.js manages the application with PM2 process manager:

{
  name: 'aclimate_v3_hn',
  script: 'npm start',
  cwd: './src',
  instances: 1,
  port: 8005
}

CI/CD

Jenkins pipeline that:

  1. SSH to deployment server
  2. Git pull latest code
  3. npm install + npm run build
  4. PM2 restart application

Health Check

GET /api/health -> 200 OK