Built by Muhammad Ahmad for PM Accelerator AI Engineer Internship
| Name | Muhammad Ahmad |
| Role | Full-Stack AI Engineer |
| Portfolio | https://ahmad-multi-verse.lovable.app |
| GitHub | https://github.com/ahmadrrrtx |
| https://www.linkedin.com/in/ahmadrrrtx | |
| Assessment | PM Accelerator AI Engineer Internship |
PM Accelerator helps aspiring product and AI builders gain practical experience through cohort-based product development, mentorship, and real-world AI product work. This project was built as part of the AI Engineer Internship Technical Assessment, demonstrating full-stack engineering capability across both frontend and backend tracks.
PM Weather AI is a production-quality, full-stack weather application delivering real-time weather intelligence for any location on Earth. Built with a premium glassmorphism UI, animated 3D weather visuals, interactive maps, and a complete CRUD record system β all powered entirely by free APIs with zero configuration required.
π https://pm-weather-ai-full-stack-weather-ap-zeta.vercel.app/
| Requirement | Status | Implementation |
|---|---|---|
| Location input β city, zip, GPS, landmark | β Complete | Multi-provider geocoding: Open-Meteo + Nominatim + OSM |
| Real-time weather from live APIs | β Complete | Open-Meteo Forecast API β free, no key |
| Useful weather details displayed clearly | β Complete | Temperature, feels like, humidity, wind, UV, precipitation, sunrise/sunset |
| Current location via GPS | β Complete | Browser Geolocation API + reverse geocoding via Nominatim |
| Icons and design standards | β Complete | WMO weather code emoji system (100+ conditions) + glassmorphism UI |
| 5-day forecast | β Complete | 7-day forecast grid implemented |
| Graceful error handling | β Complete | ErrorMessage component with retry, dismiss, and descriptive messages |
| JavaScript frontend framework | β Complete | Next.js 14 + React 18 |
| Web-first, responsive | β Complete | Tailwind CSS responsive grid β desktop, tablet, mobile |
| Requirement | Status | Implementation |
|---|---|---|
| Location + date range weather retrieval | β Complete | RecordForm with date range picker and validation |
| Store location, dates, weather, notes | β Complete | localStorage CRUD via lib/storage.ts |
| CREATE weather records | β Complete | createRecord() with UUID generation |
| READ previous records | β Complete | getRecords() + SavedRecords component |
| UPDATE stored records | β Complete | updateRecord() with inline edit form |
| DELETE records | β Complete | deleteRecord() with double-confirm UX |
| Validate date ranges | β Complete | validateDateRange() β checks format, order, max 365 days |
| Validate location / fuzzy match | β Complete | 4-provider geocoding chain with fallback |
| Additional API β Maps | β Complete | Leaflet + OpenStreetMap β free, no API key |
| Additional creative feature | β Complete | Deterministic smart travel tips from weather logic |
| Export JSON, CSV, Markdown, PDF | β Complete | Client-side export via lib/export.ts |
| API calls and error handling shown | β Complete | app/api/ route handlers with typed error responses |
- Complete Next.js App Router architecture
- Separated frontend components, backend API routes, and utility libraries
- Deployed to Vercel free tier β zero configuration
π Smart Location Search
- Search by city name β London, Tokyo, Dubai
- Search by GPS coordinates β
40.7128,-74.0060 - Search by postal code β
90210,SW1A 1AA - Search by landmark β Eiffel Tower, Times Square
- Current location via browser Geolocation API
- Recent search history saved to localStorage with clear option
- 4-provider geocoding chain: Open-Meteo β Nominatim postal β Nominatim text β coordinate fallback
βοΈ Current Weather Card
- Temperature + feels like (apparent temperature)
- Weather condition β mapped from WMO codes (100+ conditions)
- Humidity with comfort label (Very Dry β Very Humid)
- Wind speed + compass direction (16-point compass)
- Precipitation (current) + rain amount
- UV index with safety rating (Low β Extreme)
- Today's high and low temperatures
- Sunrise and sunset times
- Timezone display
- Animated 3D weather orb that reflects condition
π 7-Day Forecast
- Weather condition emoji per day
- Daily high and low temperatures
- Rain probability percentage
- Maximum wind speed
- UV index maximum
- Responsive grid: 2 columns mobile β 4 tablet β 7 desktop
π Interactive Charts
- Temperature trend β 48-hour area chart
- Rain probability β 48-hour bar chart
- Wind speed β 48-hour area chart
- Tab switching between chart types
- Custom glassmorphism tooltip
- Recharts with fully responsive container
- Data every 3 hours for visual clarity
πΊοΈ Interactive Map
- Leaflet + OpenStreetMap tiles β completely free, no API key
- Custom gradient marker with coordinate popup
- 5km radius circle overlay around location
- External link to OpenStreetMap
- SSR-safe with dynamic import
π‘ Smart Travel Tips
- Generated deterministically from weather data β no paid AI API
- 10+ condition categories: Rain, UV, Wind, Heat, Cold, Snow, Thunderstorm, Humidity, Outlook
- 4 severity levels: Info (blue), Warning (amber), Danger (red), Success (green)
- Context-aware descriptions with specific thresholds and actionable advice
πΎ CRUD Saved Records
- CREATE β Save any weather search with custom date range and notes
- READ β View all records with expandable detail panels
- UPDATE β Edit location, dates, and notes with inline form
- DELETE β Delete with double-confirm safety UX
- Stored in browser localStorage β no account, no database setup
- Records persist across browser sessions
π€ Export
- JSON β Full structured data with all weather snapshots
- CSV β Excel/Sheets compatible with all fields
- Markdown β Formatted tables, human-readable
- PDF β Professional landscape A4 report via jsPDF
- All generated client-side β no upload, no paid service
| Category | Technology | Reason |
|---|---|---|
| Framework | Next.js 14 (App Router) | SSR, API routes, free Vercel deployment |
| Language | TypeScript | Full type safety across frontend and backend |
| Styling | Tailwind CSS | Utility-first, responsive, fast iteration |
| Animations | Framer Motion | Smooth entrance animations and transitions |
| Charts | Recharts | Composable, responsive chart library |
| Maps | Leaflet + react-leaflet | Free, no key, OpenStreetMap tiles |
| Icons | Lucide React | Consistent, lightweight, tree-shakeable |
| PDF Export | jsPDF + jspdf-autotable | Client-side PDF generation, no paid service |
| Date utilities | date-fns | Lightweight date formatting |
| Weather API | Open-Meteo | 100% free, no key, WMO-standard data |
| Geocoding | Open-Meteo Geocoding | Free, no key, city search |
| Reverse Geocode | Nominatim (OSM) | Free, no key, GPS β place name |
| Map tiles | OpenStreetMap | Free, no key, global coverage |
| Storage | Browser localStorage | Zero setup, no account, persists across sessions |
| Deployment | Vercel free tier | Zero config Next.js deployment |
pm-weather-ai-assessment/
βββ app/
β βββ layout.tsx # Root layout, metadata, fonts
β βββ page.tsx # Main page β state management hub
β βββ globals.css # Global styles, glassmorphism, animations
β βββ api/
β βββ weather/route.ts # GET /api/weather?location=...
β βββ records/route.ts # GET/POST /api/records
β βββ records/[id]/route.ts # GET/PUT/DELETE /api/records/:id
β βββ export/route.ts # POST /api/export
βββ components/
β βββ Header.tsx # Navigation bar with links
β βββ SearchPanel.tsx # Search input + location button + history
β βββ CurrentWeatherCard.tsx # Main weather display + stat grid
β βββ ForecastGrid.tsx # 7-day forecast cards
β βββ WeatherCharts.tsx # Recharts temperature/rain/wind tabs
β βββ WeatherMap.tsx # Leaflet map with custom marker
β βββ WeatherVisual3D.tsx # Animated CSS 3D weather orb
β βββ TravelTips.tsx # Smart tips display grid
β βββ SavedRecords.tsx # CRUD records list with expand/edit/delete
β βββ RecordForm.tsx # Create and edit record form
β βββ PMAcceleratorCard.tsx # About section + builder info + tech stack
β βββ LoadingState.tsx # Skeleton loading with animated rings
β βββ ErrorMessage.tsx # Error display with retry and dismiss
βββ lib/
β βββ types.ts # All TypeScript interfaces
β βββ weather.ts # Open-Meteo API, WMO codes, formatters
β βββ geocode.ts # 4-provider geocoding chain
β βββ tips.ts # Deterministic weather tips generator
β βββ storage.ts # localStorage CRUD + date validation
β βββ export.ts # JSON/CSV/Markdown/PDF export utilities
β βββ utils.ts # cn(), uvLabel(), humidityLabel(), etc.
βββ README.md
βββ package.json
βββ next.config.js
βββ tsconfig.json
βββ tailwind.config.ts
βββ postcss.config.js
βββ .gitignore
βββ .env.example
node --version # 18.17 or higher
npm --version # 9.0 or higher# Clone the repository
git clone https://github.com/ahmadrrrtx/PM-Weather-AI-Full-Stack-Weather-Application.git
# Navigate into the project
cd PM-Weather-AI-Full-Stack-Weather-Application
# Install dependencies
npm install
# Start development server
npm run devOpen http://localhost:3000 β the app starts immediately with no configuration needed.
npm run build
npm run startNone required. The app works completely out of the box.
All APIs are free and require no authentication:
# .env.example
# No API keys needed β all services are free and keyless
# Open-Meteo Weather API β no key
# Open-Meteo Geocoding β no key
# Nominatim (OSM) β no key
# OpenStreetMap tiles β no key
# localStorage β no keyGeocodes the query and returns full weather data from Open-Meteo.
Supported query formats:
/api/weather?location=London
/api/weather?location=40.7128,-74.0060
/api/weather?location=90210
/api/weather?location=Eiffel+Tower
/api/weather?location=Dubai
Success response (200):
{
"location": {
"name": "London",
"latitude": 51.5085,
"longitude": -0.1257,
"country": "United Kingdom",
"country_code": "GB",
"admin1": "England",
"timezone": "Europe/London"
},
"current": {
"temperature": 14.2,
"feelsLike": 12.8,
"humidity": 78,
"windSpeed": 22.4,
"windDirection": 245,
"precipitation": 0.0,
"weatherCode": 2,
"isDay": 1,
"uvIndex": 3,
"rain": 0.0
},
"daily": [ /* 7 days */ ],
"hourly": { /* 48 hours */ },
"timezone": "Europe/London",
"fetchedAt": "2024-01-15T10:30:00.000Z"
}Error responses:
// 400 β missing location
{ "error": "Location parameter is required." }
// 404 β not found
{ "error": "Could not find location: \"xyz\". Try a city name, coordinates (lat,lon), or postal code." }
// 500 β upstream API failure
{ "error": "Failed to fetch weather data: ..." }Documented REST endpoints. Actual data persistence is handled client-side via lib/storage.ts using localStorage.
Server-side export endpoint supporting json and csv formats.
{
"records": [...],
"format": "json"
}| Factor | localStorage | External Database |
|---|---|---|
| Setup time | Zero | Account + credentials + schema |
| Works offline | β | β |
| Reviewer friction | None | High |
| Data persistence | Per browser | Global |
| CRUD complexity | Identical | Identical |
The CRUD logic in lib/storage.ts is architecturally identical to a database implementation. Swapping to Supabase or PostgreSQL would require changing only the storage layer, not the component logic.
interface WeatherRecord {
id: string; // UUID v4 via crypto.randomUUID()
locationInput: string; // Raw user input
resolvedName: string; // Geocoded display name
latitude: number; // Decimal degrees
longitude: number; // Decimal degrees
startDate: string; // "YYYY-MM-DD"
endDate: string; // "YYYY-MM-DD"
weatherJson: WeatherData | null; // Full weather snapshot
notes: string; // User notes
createdAt: string; // ISO timestamp
updatedAt: string; // ISO timestamp
}β
Both dates required
β
End date must be >= start date
β
Range cannot exceed 365 days
β
Dates must be valid ISO format
If you want persistent cross-device storage, create a free Supabase project and run:
create table weather_records (
id uuid primary key default gen_random_uuid(),
location_input text not null,
resolved_name text not null,
latitude numeric not null,
longitude numeric not null,
start_date date not null,
end_date date not null,
weather_json jsonb,
notes text default '',
created_at timestamptz default now(),
updated_at timestamptz default now()
);
alter table weather_records enable row level security;
create policy "Allow all"
on weather_records for all
using (true) with check (true);Then add to .env.local:
NEXT_PUBLIC_SUPABASE_URL=your-project-url
NEXT_PUBLIC_SUPABASE_ANON_KEY=your-anon-keyhttps://api.open-meteo.com/v1/forecast
Free tier: Unlimited Β· No key required
Docs: https://open-meteo.com/en/docs
Parameters used:
current β temperature_2m, apparent_temperature, relative_humidity_2m,
precipitation, rain, weather_code, wind_speed_10m,
wind_direction_10m, is_day, uv_index
daily β weather_code, temperature_2m_max, temperature_2m_min,
precipitation_sum, precipitation_probability_max,
wind_speed_10m_max, uv_index_max, sunrise, sunset
hourly β temperature_2m, precipitation_probability, wind_speed_10m
timezone β auto
https://geocoding-api.open-meteo.com/v1/search
Free tier: Unlimited Β· No key required
Used for: city name β lat/lon
https://nominatim.openstreetmap.org/search
https://nominatim.openstreetmap.org/reverse
Free tier: 1 req/sec Β· No key required
Used for: reverse geocoding, postal codes, landmark search
https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png
Free: Unlimited for reasonable use Β· No key required
Used by: Leaflet map rendering
Glassmorphism UI β Premium frosted glass aesthetic using backdrop-filter: blur() and semi-transparent backgrounds. Carefully applied to remain readable and professional, not overdone.
CSS Animated Orb over Three.js β The 3D weather orb uses Framer Motion and CSS gradients instead of WebGL. This achieves a premium visual at near-zero bundle cost with zero SSR risk. Three.js would add ~500KB and requires canvas lifecycle management.
Open-Meteo over OpenWeatherMap β Completely free with no API key, no rate limiting for reasonable use, excellent WMO-standard data quality, and returns current + daily + hourly in a single request.
Leaflet over Google Maps β Google Maps requires a billing card even for free tier. Leaflet + OpenStreetMap is 100% free, no key, and renders beautiful interactive maps.
Deterministic Tips over AI API β Travel tips are generated from weather thresholds β no paid AI, no latency, fully predictable, and demonstrates creative algorithmic product thinking.
localStorage over External Database β Zero setup friction means any reviewer can clone and test instantly. The CRUD architecture is identical to a real database implementation.
Multi-provider Geocoding β 4-provider chain maximizes success rate for any input type. Open-Meteo handles city names best, Nominatim handles postal codes and landmarks, coordinate parsing handles GPS input directly.
# 1. Push to GitHub (already done)
# 2. Go to vercel.com β Add New Project β Import your repo
# 3. Vercel auto-detects Next.js β no settings to change
# 4. Click Deploy
# 5. App is live in ~60 secondsNo environment variables needed. No configuration needed.
Live at: https://pm-weather-ai-full-stack-weather-ap-zeta.vercel.app/
Built for PM Accelerator AI Engineer Internship Assessment. Free to review, learn from, and fork.
Built with β€οΈ by Muhammad Ahmad
π Portfolio Β· π» GitHub Β· π LinkedIn
PM Accelerator AI Engineer Internship Β· 2025