Localbite is a modern, full-stack food delivery platform connecting customers with local restaurants. Built with Next.js 16 (Frontend) and FastAPI (Backend), it features role-based access for Customers, Restaurant Owners, and Delivery Agents.
- Framework: Next.js 16 (App Router)
- Language: TypeScript
- Styling: Tailwind CSS
- UI Components: shadcn/ui
- Icons: Lucide React
- State Management: React Context API
- Form Handling: React Hook Form + Zod validation
- Framework: FastAPI
- Language: Python 3.10+
- Database: PostgreSQL (via Supabase) with SQLAlchemy ORM
- Authentication: JWT (JSON Web Tokens) with HttpOnly cookies
- Password Hashing: Argon2 (via Passlib)
- Validation: Pydantic schemes
localbite/
βββ localbite-backend/ # Python FastAPI Application
β βββ app/
β β βββ api/ # API Route Handlers (endpoints)
β β βββ core/ # Config, Security, Hashing utilities
β β βββ crud/ # Database Operations (Create, Read, Update, Delete)
β β βββ models/ # SQLAlchemy Database Models
β β βββ schemas/ # Pydantic Request/Response Schemas
β β βββ database.py # Database Connection Setup
β βββ main.py # Application Entry Point
β βββ requirements.txt # Python Dependencies
β
βββ localbite-frontend/ # Next.js Application
β βββ app/ # App Router Pages & Layouts
β β βββ dashboard/ # Role-protected Dashboards (Customer/Restaurant)
β β βββ login/ # Authentication Pages
β β βββ page.tsx # Landing Page
β βββ components/ # Reusable UI Components
β βββ context/ # React Context (Auth, Theme)
β βββ hooks/ # Custom React Hooks
β βββ lib/ # Utilities & Mock Data
β βββ public/ # Static Assets
βββ README.md # Project Documentation- Secure Login/Signup: Supports separate flows for Customers, Restaurant Owners, and Delivery Agents.
- JWT Auth: HttpOnly cookies for secure session management.
- Role-Based Redirects: Automatically routes users to their specific dashboard upon login.
- Restaurant Discovery: Browse and search restaurants by name or cuisine.
- Menu Interaction: View detailed restaurant menus with categories.
- Smart Filtering: Filter by cuisine type (Thai, Mexican, Halal, etc.).
- Live Data: Connects to backend API for real-time restaurant and menu data.
- Menu Management: Add, update, and delete menu items dynamically.
- Business Insights: View order stats and manage restaurant profile (Name, Cuisine, etc.).
- Real-time Updates: Changes reflect immediately on the customer side.
- Task Management: (In progress) View available orders for pickup.
- Earnings Tracker: Monitor completed deliveries and earnings.
The backend provides a comprehensive REST API. Once running, visit http://localhost:8000/docs for the interactive Swagger UI.
| Method | Endpoint | Description |
|---|---|---|
| Auth | /api/v1/auth/signup |
Register a new user |
| Auth | /api/v1/auth/token |
Login & receive access token |
| Restaurant | /api/v1/restaurants/ |
List all restaurants |
| Restaurant | /api/v1/restaurants/{id} |
Get restaurant details |
| Menu | /api/v1/menu/restaurant/{id} |
Get menu items for a restaurant |
| Menu | /api/v1/menu/ |
Create new menu item (Auth required) |
- Node.js: v18+ & npm
- Python: v3.10+
- PostgreSQL Database: Local instance or cloud (e.g., Supabase, Neon)
-
Navigate to the backend directory:
cd localbite-backend -
Create a virtual environment:
python -m venv venv source venv/bin/activate # Windows: venv\Scripts\activate
-
Install dependencies:
pip install -r requirements.txt
-
Environment Configuration (
.env): Create a.envfile inlocalbite-backend/with the following variables:# Database Configuration DB_USER=your_db_user DB_PASSWORD=your_db_password DB_HOST=your_db_host.supabase.co DB_NAME=postgres # Security SECRET_KEY=your_super_secret_key_openssl_rand_hex_32 ALGORITHM=HS256 ACCESS_TOKEN_EXPIRE_MINUTES=30
-
Run the server:
uvicorn main:app --reload
Server will start at
http://localhost:8000.
- Navigate to the frontend directory:
cd localbite-frontend
Before starting, ensure your Neon connection is configured in:
localbite-backend/.env(DATABASE_URL=...) or set the individual DB env vars used by the backend.
Start backend + local Redis:
./deploy_backend.shThis starts:
- Redis:
localhost:6379(if installed locally and not already running) - Backend: http://localhost:8000
cd localbite-frontend
npm install
npm run devFrontend:
- Frontend: http://localhost:3000
Run the Postman/Newman integration workflow (local backend):
./run_api_tests.shReports are written to:
localbite-backend/postman/reports/
To start both the Backend and Frontend servers in separate terminals, run:
./start_servers.shThis will launch:
- Backend: http://localhost:8000 (with auto-reload)
- Frontend: http://localhost:3000
For dispatch timer and bidding workflows (which require Redis), use:
cd localbite-backend
./scripts/start_backend_with_redis.shOnce the backend is running, you can access the interactive API docs at:
- Swagger UI: http://localhost:8000/docs
- ReDoc: http://localhost:8000/redoc
New endpoint:
POST /api/v1/fares/recommendation
Purpose:
- Calculates
base_fare(minimum bidding fare for delivery agents) - Calculates
max_bid_limit(1.5xofbase_fare) - Returns
eta_estimate_minutes
Payload supports either:
distance_kmfrom your distance API, or- coordinates for both user and restaurant (
latitude/longitude) to compute distance with Haversine.
Example request body:
{
"user_location": {
"address": "500 1st St, Davis, CA",
"latitude": 38.5449,
"longitude": -121.7405
},
"restaurant_location": {
"address": "220 G St, Davis, CA",
"latitude": 38.5435,
"longitude": -121.7407
},
"incentive_metrics": {
"demand_index": 1.1,
"supply_index": 0.9,
"weather_severity": 0.1
}
}New endpoint:
POST /api/v1/delivery-bids/
Behavior:
- Validates bid against the order's bidding window:
- minimum =
orders.base_fare - maximum =
1.5 * orders.base_fare
- minimum =
- Supports phased dispatch bidding:
student_pool: only student delivery agents can bidall_agents: all active agents can bid
Example request body:
{
"order_id": 101,
"agent_id": "agent_123",
"bid_amount": 6.5,
"pool_phase": "student_pool"
}Accept a bid (assign order + stop dispatch flow):
POST /api/v1/delivery-bids/{bid_id}/accept
Notes:
- Marks selected bid as
accepted - Rejects competing
placedbids for the same order - Assigns
orders.assigned_partner_id - Updates dispatch state in Redis so phase timers stop
New endpoints:
POST /api/v1/dispatch/orders/{order_id}/startGET /api/v1/dispatch/orders/{order_id}/status
Behavior:
- Starts two-phase dispatch in background
- Phase 1 (
student_pool): student-only broadcast, waits configurable timer - Phase 2 (
all_agents): full-pool broadcast, waits configurable timer - If still unassigned after Phase 2: status becomes
needs_fee_increase
Example start request body:
{
"delivery_address": "500 1st St, Davis, CA",
"phase1_wait_seconds_min": 180,
"phase1_wait_seconds_max": 240,
"phase2_wait_seconds": 180,
"poll_interval_seconds": 5
}