Web frontend for Atmos — a personal carbon footprint tracker that automatically detects and logs commute trips via the companion mobile app.
The web app is built for deep data exploration and management. Trip logging happens on mobile (auto-detected via location); the web provides the dashboard, history, analytics, and settings that benefit from a larger screen.
| Screen | Description |
|---|---|
| Dashboard | Summary stats, weekly CO₂ trend chart, transport breakdown, recent trips, and insights feed |
| Trips | Full sortable/filterable trip history with date range picker, mode filter, and CSV export |
| Analytics | Monthly and yearly CO₂ trends, mode-by-mode breakdown over time, goal trajectory |
| Insights | Streaks, tips, milestones, comparisons, and anomaly alerts |
| Settings | Profile, daily goal, commute defaults, appearance, notification preferences, data export, account management |
| Layer | Choice | Why |
|---|---|---|
| Framework | Next.js 15 (App Router) | Production-grade React framework with built-in routing, SSR, and optimization. Learning React within an opinionated structure. |
| Language | TypeScript | Type safety, better IDE support, catches errors at compile time. |
| Styling | Tailwind CSS | Utility-first CSS. Rapid prototyping, consistent design system tokens, mobile-first by default. |
| Component Library | shadcn/ui | Pre-built, copy-paste React components built on Radix UI primitives. Accessible, customizable, production-ready. |
| State & Data | TanStack Query (React Query) | Server state management, caching, background refetching, DevTools. Handles API fetching elegantly. |
| Charts | Recharts | Declarative React chart library, composable, responsive, optimized for dashboards. |
| Testing | Vitest + React Testing Library | Fast unit/component testing with familiar Jest API. |
| E2E Testing | Playwright | Cross-browser E2E testing, visual regression, CI-friendly. |
| Package Manager | pnpm | Faster, more disk-efficient than npm. Strict dependency resolution. |
| Auth | JWT (issued by atmos-core) |
Stateless auth, secure token refresh, mobile/web compatible. |
| API | REST — atmos-core backend |
Type-safe fetchers with TanStack Query. |
- React Fundamentals (Next.js App Router, JSX, hooks, state)
- Styling (Tailwind CSS utility classes, responsive design)
- Data Fetching (TanStack Query, API integration, loading states)
- UI Components (shadcn/ui, Radix, accessibility)
- TypeScript (gradual adoption, type inference, generics)
- Charts & Visualization (Recharts, responsive dashboards)
- Testing (Vitest + RTL, component tests; Playwright for E2E)
- Node.js 20+
- npm or pnpm
atmos-corerunning locally (see../atmos-core/README.md)
cd atmos-web
npm install
npm run devOpen http://localhost:3000.
Copy .env.example to .env.local and fill in the values:
NEXT_PUBLIC_API_URL=http://localhost:8080
NEXT_PUBLIC_APP_NAME=Atmos
atmos-web/
├── app/ # Next.js App Router pages
│ ├── (auth)/ # Login, sign up, forgot password
│ ├── dashboard/ # Main dashboard
│ ├── trips/ # Trip history
│ ├── analytics/ # Charts and trends
│ ├── insights/ # Insight cards
│ └── settings/ # Profile and preferences
├── components/
│ ├── ui/ # Primitive components (Button, Card, Badge …)
│ ├── charts/ # Recharts wrappers (TrendLine, DonutChart …)
│ ├── trips/ # Trip table, filters, row components
│ └── insights/ # Insight card variants by type
├── lib/
│ ├── api/ # API client and typed fetchers
│ ├── hooks/ # Shared React hooks
│ └── utils/ # Formatters, CO₂ calculations, date helpers
├── types/ # Shared TypeScript types (mirrors atmos-core models)
└── public/ # Static assets
Atmos web shares the same visual language as the mobile app.
| Token | Hex | Usage |
|---|---|---|
horizon-blue |
#4A90C4 |
Primary actions, links, active states |
sage |
#3DAB82 |
Eco-positive, low-emission, streaks |
peach |
#F0956A |
Warnings, medium-emission modes |
alert-red |
#E05252 |
Errors, high-emission, destructive actions |
bg-page |
#F5F7FA |
Page background |
bg-card |
#FFFFFF |
Card surfaces |
text-primary |
#1A2332 |
Headings and body copy |
text-secondary |
#6B7A8D |
Labels, secondary copy |
divider |
#F0F2F5 |
Borders and separators |
- Font: Inter
- Heading: 24px / SemiBold
- Subheading: 17px / SemiBold
- Body: 15px / Regular
- Label: 13px / Medium
- Border radius: 16px
- Box shadow:
0 1px 3px rgba(0, 0, 0, 0.08) - Padding: 20px
| Project | Description |
|---|---|
atmos-mobile |
KMP mobile app (Android + iOS) |
atmos-core |
Backend API |
Private — Atmos