Skip to content

splitllmbill/flutter-app

Repository files navigation

SplitLLM — Flutter Web

Production-grade Flutter Web rewrite of the SplitLLM React frontend. Features Supabase Authentication, Riverpod state management, and Dio-based API integration with the existing Flask backend.

Tech Stack

Layer Technology
Framework Flutter 3.x (Web + Android + iOS)
State Management Riverpod
Routing go_router
HTTP Client Dio
Auth Supabase Authentication
Config flutter_dotenv (.env)
Charts fl_chart
Hosting / CI Vercel

Getting Started

Prerequisites

  • Flutter SDK ≥ 3.2.0

1. Clone & Install

cd flutter-app
flutter pub get

2. Configure environment

Runtime configuration lives in a .env file (loaded at startup via flutter_dotenv). Copy the template and fill in your values:

cp .env.example .env
# .env
SUPABASE_URL=https://YOUR_PROJECT.supabase.co
SUPABASE_ANON_KEY=sb_publishable_xxx        # publishable/anon key — safe in client
API_BASE_URL=http://localhost:8081

.env is git-ignored. To change Supabase or the backend URL later, just edit .env (local) or the Vercel Environment Variables (production) — no Dart code changes needed.

Resolution order for each value: .env--dart-define=KEY=value → built-in default.

3. Run Locally

flutter run -d chrome

.env is picked up automatically. You can still override per-run with --dart-define=API_BASE_URL=https://your-api.domain.com if you prefer.

4. Build for Production

flutter build web --release --tree-shake-icons

Output is written to build/web.

Deployment (Vercel)

The app deploys to Vercel via vercel.json + vercel_build.sh. Because Vercel's build image has no Flutter SDK, the build script installs Flutter, writes a .env from the project's Environment Variables, then runs flutter build web.

Setup:

  1. Import the repository into Vercel (Root Directory = flutter-app).

  2. Vercel reads vercel.json automatically:

    • Build command: bash vercel_build.sh
    • Output directory: build/web
  3. In Project Settings → Environment Variables, add:

    Variable Description
    SUPABASE_URL Supabase project URL
    SUPABASE_ANON_KEY Supabase publishable / anon key
    API_BASE_URL Production backend API base URL
  4. Push to your default branch — Vercel builds and deploys automatically.

vercel.json also configures SPA rewrites (all routes → index.html) and security headers (X-Frame-Options, Strict-Transport-Security, etc.).

Project Structure

lib/
├── main.dart                          # Entry point (loads .env, inits Supabase)
├── app.dart                           # MaterialApp.router
├── core/
│   ├── constants/constants.dart       # Config resolved from .env / dart-define
│   ├── models/                        # Data models
│   │   ├── user_model.dart
│   │   ├── event_model.dart
│   │   ├── expense_model.dart
│   │   ├── share_model.dart
│   │   └── filter_input_model.dart
│   ├── services/
│   │   ├── api_client.dart            # Dio + Supabase token interceptor
│   │   └── auth_service.dart          # Supabase Auth abstraction
│   ├── router/router.dart             # go_router with auth guard
│   ├── providers.dart                 # Top-level Riverpod providers
│   ├── utils/
│   │   ├── app_theme.dart             # Material 3 dark theme
│   │   ├── date_utils.dart            # Date formatting
│   │   └── helpers.dart               # Utilities
│   └── widgets/shell_screen.dart      # Responsive nav shell
└── features/
    ├── auth/presentation/login_screen.dart
    ├── dashboard/presentation/dashboard_screen.dart
    ├── events/presentation/
    │   ├── events_screen.dart
    │   ├── event_detail_screen.dart
    │   └── create_event_screen.dart
    ├── expenses/presentation/
    │   ├── create_expense_screen.dart
    │   ├── expense_detail_screen.dart
    │   └── share_bill_screen.dart
    ├── friends/presentation/
    │   ├── friends_screen.dart
    │   ├── friend_detail_screen.dart
    │   └── add_friend_screen.dart
    ├── personal_expenses/presentation/
    │   └── personal_expenses_screen.dart
    ├── account/presentation/account_screen.dart
    └── settlements/presentation/payment_screen.dart

Environment Configuration

All runtime config (SUPABASE_URL, SUPABASE_ANON_KEY, API_BASE_URL) is resolved at startup, in order of precedence:

  1. the bundled .env file (flutter_dotenv),
  2. a compile-time --dart-define=KEY=value,
  3. a built-in default.
# Local dev: values come from .env
flutter run -d chrome

# Override a single value at build time
flutter build web --release --dart-define=API_BASE_URL=https://api.domain.com

# Production: Vercel injects env vars → vercel_build.sh writes them into .env

Backend Integration

The Flutter app sends Authorization: Bearer <supabase_access_token> in all API requests. The Flask backend validates the Supabase JWT (e.g. against the project's JWKS / JWT secret) and reads the user id from the sub claim.

Migration Checklist

  • Analyze React repository
  • Create Flutter project structure
  • Core infrastructure (Dio, Supabase Auth, Riverpod, go_router)
  • Data models (User, Event, Expense, Share, FilterInput)
  • Auth feature (Login, Sign-up, Google Sign-In, Forgot Password)
  • Dashboard (Summary cards, Pie chart, Quick actions)
  • Events (List, Detail, Create/Edit, Delete)
  • Expenses (Create/Edit, Detail, Share Bill)
  • Friends (List, Detail, Add, Delete, Settle)
  • Personal Expenses (List, LLM Chatbot)
  • Account (Profile, QR Code, UPI, Change Password, Sign Out)
  • Payment page (Public payment with QR)
  • Vercel config (vercel.json, vercel_build.sh)
  • Environment config via .env (flutter_dotenv)
  • Update Flask backend to validate Supabase JWTs
  • Set Vercel Environment Variables for deployment

Releases

No releases published

Packages

 
 
 

Contributors

Languages