Skip to content

Latest commit

 

History

1 Commit

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Aura — Weather, Beautifully Simple

React Vite License

A dark, sleek weather forecast app built with React and Vite, powered by the OpenWeatherMap API. Built as a portfolio project to demonstrate component architecture, custom hooks, and clean API layering in a real-world frontend app.

Features

  • 🔍 City search with autocomplete — debounced (350ms) lookups against the OpenWeatherMap geocoding API
  • 🌡️ Current conditions — temperature, "feels like," description, wind, humidity, pressure, visibility, sunrise & sunset
  • 📅 5-day forecast — grouped from 3-hour interval data, showing daily highs/lows and a midday icon
  • 📍 Geolocation — auto-detects your location on first visit, with a manual "use my location" button and graceful fallback if permission is denied
  • ⭐ Favorites — save cities with one tap; persisted in localStorage
  • 🌗 Unit toggle — instant °C / °F switching, persisted in localStorage
  • ⏳ Full async coverage — loading, error, and empty states handled on every screen
  • 🎨 Hand-crafted SVG icons — no icon library, ten custom weather icons mapped to OpenWeatherMap's icon codes

Tech Stack

Layer Choice
UI React 18 (functional components + hooks)
Build tool Vite
Styling Plain CSS with custom properties
Data OpenWeatherMap (Geocoding, Current, Forecast)
Language JavaScript

Architecture

src/
├── components/   UI only — no fetch calls, no business logic
├── hooks/        Reusable stateful logic (data fetching, debouncing, persistence)
├── services/     The only layer allowed to talk to the network
└── utils/        Pure functions — formatting, grouping, no side effects

Why a service layer? Every OpenWeatherMap call lives in services/weatherApi.js. Components never call fetch directly — this keeps API shape changes, error handling, and auth (the API key) in one place, and makes the rest of the app trivially testable.

Why custom hooks? useWeather encapsulates fetching + loading/error state so App.jsx stays declarative. It accepts either a city name string or { lat, lon } coordinates, so the same hook powers search, geolocation, and favorites. useLocalStorage and useDebounce are generic and reusable outside this project.

Why the folder split? Separating components (view), hooks (state), services (I/O), and utils (pure logic) keeps each file testable in isolation and makes it obvious where new code belongs as the app grows.

Getting Started

Prerequisites

Setup

# Install dependencies
npm install

# Create your local environment file
cp .env.example .env

Open .env and paste your API key:

VITE_OPENWEATHER_API_KEY=your_api_key_here

Run

npm run dev

Build

npm run build

API Reference

All requests are made from src/services/weatherApi.js.

Function Endpoint Purpose
searchCities(query) geo/1.0/direct City autocomplete suggestions
getCurrentWeatherByCity(city) data/2.5/weather?q= Current weather by city name
getCurrentWeatherByCoords(lat,lon) data/2.5/weather?lat=&lon= Current weather by coordinates
getForecastByCity(city) data/2.5/forecast?q= 5-day / 3-hour forecast by city
getForecastByCoords(lat,lon) data/2.5/forecast?lat=&lon= 5-day / 3-hour forecast by coords

Failed requests throw a WeatherApiError with a status code and a human-readable message (invalid API key, city not found, or a generic network failure).

License

MIT © Erijon Bytyqi


Built with ☕ in Pristina, Kosovo

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages