Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
129 changes: 129 additions & 0 deletions CONFIGURATION.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
# Configuration Guide

This guide explains how to configure RideMatch dynamically using environment variables.

## Quick Setup

1. Run the setup script:
```bash
npm run setup
```

2. Edit `.env.local` with your configuration values

3. Start the development server:
```bash
npm run dev
```

## Environment Variables

### Required Variables

#### Firebase Configuration
- `NEXT_PUBLIC_FIREBASE_API_KEY` - Your Firebase API key
- `NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN` - Your Firebase auth domain
- `NEXT_PUBLIC_FIREBASE_PROJECT_ID` - Your Firebase project ID
- `NEXT_PUBLIC_FIREBASE_STORAGE_BUCKET` - Your Firebase storage bucket
- `NEXT_PUBLIC_FIREBASE_MESSAGING_SENDER_ID` - Your Firebase messaging sender ID
- `NEXT_PUBLIC_FIREBASE_APP_ID` - Your Firebase app ID

#### Google Maps
- `NEXT_PUBLIC_GOOGLE_MAPS_API_KEY` - Your Google Maps API key

### Optional Variables

#### App Configuration
- `NEXT_PUBLIC_APP_NAME` - App name (default: "RideMatch")
- `NEXT_PUBLIC_APP_DESCRIPTION` - App description
- `NEXT_PUBLIC_APP_URL` - App URL (default: "http://localhost:3000")
- `NEXT_PUBLIC_APP_VERSION` - App version (default: "0.1.0")

#### Feature Flags
- `NEXT_PUBLIC_ENABLE_REAL_TIME_TRACKING` - Enable real-time tracking (default: true)
- `NEXT_PUBLIC_ENABLE_NOTIFICATIONS` - Enable notifications (default: true)
- `NEXT_PUBLIC_ENABLE_ANALYTICS` - Enable analytics (default: true)

#### API Configuration
- `NEXT_PUBLIC_API_BASE_URL` - API base URL (default: "/api")
- `NEXT_PUBLIC_API_TIMEOUT` - API timeout in milliseconds (default: 5000)

## Getting Your API Keys

### Firebase Setup
1. Go to [Firebase Console](https://console.firebase.google.com/)
2. Create a new project or select existing one
3. Go to Project Settings > General
4. Scroll down to "Your apps" section
5. Click on the web app or create a new one
6. Copy the configuration values

### Google Maps Setup
1. Go to [Google Cloud Console](https://console.cloud.google.com/)
2. Create a new project or select existing one
3. Enable the Maps JavaScript API
4. Go to Credentials
5. Create an API key
6. Restrict the API key to your domain for security

## Customization Examples

### Change App Name
```bash
NEXT_PUBLIC_APP_NAME=MyRideApp
```

### Disable Features
```bash
NEXT_PUBLIC_ENABLE_ANALYTICS=false
NEXT_PUBLIC_ENABLE_NOTIFICATIONS=false
```

### Custom API Endpoint
```bash
NEXT_PUBLIC_API_BASE_URL=https://api.myapp.com
```

## Validation

The app automatically validates your configuration on startup. If any required variables are missing, you'll see helpful error messages.

You can also manually validate your configuration by importing the validation function:

```typescript
import { validateEnvironment } from '@/lib/validate-env';

// This will log validation results
validateEnvironment();
```

## Troubleshooting

### Common Issues

1. **"Missing required environment variables"**
- Ensure all required variables are set in `.env.local`
- Check that the file is in the project root
- Restart your development server after changes

2. **Firebase connection errors**
- Verify your Firebase project is active
- Check that Firestore is enabled in your Firebase project
- Ensure your API key has the necessary permissions

3. **Google Maps not loading**
- Verify your API key is correct
- Check that the Maps JavaScript API is enabled
- Ensure billing is set up for your Google Cloud project

### Debug Configuration

You can debug your current configuration by importing:

```typescript
import { getCurrentConfig } from '@/lib/validate-env';

console.log(getCurrentConfig());
```

This will show your current configuration with sensitive values masked.
11 changes: 10 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -132,9 +132,18 @@ directionsService.route({

3. **Set up environment variables**
```bash
# Run the setup script (recommended)
npm run setup

# Or manually copy the example file
cp .env.local.example .env.local
```
Add your Google Maps API key to `.env.local`

Configure your environment variables in `.env.local`:
- Firebase configuration (API key, project ID, etc.)
- Google Maps API key
- App name and description
- Feature flags

4. **Run the development server**
```bash
Expand Down
7 changes: 4 additions & 3 deletions app/auth/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { Input } from "@/components/ui/input"
import { Label } from "@/components/ui/label"
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs"
import { MapPin, Mail, Lock, User, Phone } from "lucide-react"
import { config } from "@/lib/config"

export default function AuthPage() {
const [isLoading, setIsLoading] = useState(false)
Expand All @@ -33,7 +34,7 @@ export default function AuthPage() {
<div className="w-10 h-10 bg-gradient-to-r from-blue-600 to-green-600 rounded-lg flex items-center justify-center">
<MapPin className="w-6 h-6 text-white" />
</div>
<span className="text-2xl font-bold text-gray-900">RideMatch</span>
<span className="text-2xl font-bold text-gray-900">{config.app.name}</span>
</Link>
<p className="text-gray-600">Join the community of smart travelers</p>
</div>
Expand All @@ -48,7 +49,7 @@ export default function AuthPage() {
<Card>
<CardHeader>
<CardTitle>Welcome Back</CardTitle>
<CardDescription>Sign in to your RideMatch account to start finding rides.</CardDescription>
<CardDescription>Sign in to your {config.app.name} account to start finding rides.</CardDescription>
</CardHeader>
<CardContent>
<form onSubmit={handleSubmit} className="space-y-4">
Expand Down Expand Up @@ -87,7 +88,7 @@ export default function AuthPage() {
<Card>
<CardHeader>
<CardTitle>Create Account</CardTitle>
<CardDescription>Join RideMatch and start sharing rides with your community.</CardDescription>
<CardDescription>Join {config.app.name} and start sharing rides with your community.</CardDescription>
</CardHeader>
<CardContent>
<form onSubmit={handleSubmit} className="space-y-4">
Expand Down
3 changes: 2 additions & 1 deletion app/dashboard/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import {
Bell,
Settings,
} from "lucide-react"
import { config } from "@/lib/config"

export default function DashboardPage() {
const [searchFrom, setSearchFrom] = useState("")
Expand Down Expand Up @@ -79,7 +80,7 @@ export default function DashboardPage() {
<div className="w-8 h-8 bg-gradient-to-r from-blue-600 to-green-600 rounded-lg flex items-center justify-center">
<MapPin className="w-5 h-5 text-white" />
</div>
<span className="text-xl font-bold text-gray-900">RideMatch</span>
<span className="text-xl font-bold text-gray-900">{config.app.name}</span>
</Link>

<div className="flex items-center space-x-4">
Expand Down
5 changes: 3 additions & 2 deletions app/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,11 @@ import type { Metadata } from 'next'
import { GeistSans } from 'geist/font/sans'
import { GeistMono } from 'geist/font/mono'
import './globals.css'
import { config } from '@/lib/config'

export const metadata: Metadata = {
title: 'RideMatch App',
description: 'A community-driven ride matching app',
title: config.app.name,
description: config.app.description,
generator: 'Next.js',
}

Expand Down
13 changes: 7 additions & 6 deletions app/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { Button } from "@/components/ui/button"
import { Card, CardDescription, CardHeader, CardTitle } from "@/components/ui/card"
import { Badge } from "@/components/ui/badge"
import { MapPin, Users, DollarSign, Leaf, Shield, Clock } from "lucide-react"
import { config } from "@/lib/config"

export default function HomePage() {
return (
Expand All @@ -14,7 +15,7 @@ export default function HomePage() {
<div className="w-8 h-8 bg-gradient-to-r from-blue-600 to-green-600 rounded-lg flex items-center justify-center">
<MapPin className="w-5 h-5 text-white" />
</div>
<span className="text-xl font-bold text-gray-900">RideMatch</span>
<span className="text-xl font-bold text-gray-900">{config.app.name}</span>
</div>
<nav className="hidden md:flex items-center space-x-6">
<Link href="#features" className="text-gray-600 hover:text-gray-900">
Expand Down Expand Up @@ -74,7 +75,7 @@ export default function HomePage() {
<section id="features" className="py-20 px-4 bg-white">
<div className="container mx-auto">
<div className="text-center mb-16">
<h2 className="text-3xl md:text-4xl font-bold text-gray-900 mb-4">Why Choose RideMatch?</h2>
<h2 className="text-3xl md:text-4xl font-bold text-gray-900 mb-4">Why Choose {config.app.name}?</h2>
<p className="text-xl text-gray-600 max-w-2xl mx-auto">
Our intelligent platform makes ride sharing safe, affordable, and environmentally friendly.
</p>
Expand Down Expand Up @@ -160,7 +161,7 @@ export default function HomePage() {
<section id="how-it-works" className="py-20 px-4 bg-gray-50">
<div className="container mx-auto">
<div className="text-center mb-16">
<h2 className="text-3xl md:text-4xl font-bold text-gray-900 mb-4">How RideMatch Works</h2>
<h2 className="text-3xl md:text-4xl font-bold text-gray-900 mb-4">How {config.app.name} Works</h2>
<p className="text-xl text-gray-600 max-w-2xl mx-auto">
Getting started is simple. Just three easy steps to find your perfect ride match.
</p>
Expand Down Expand Up @@ -253,7 +254,7 @@ export default function HomePage() {
</div>
<h3 className="text-2xl font-bold text-gray-900 mb-4">Ready to Start?</h3>
<p className="text-gray-600 mb-6">
Join thousands of users already saving money and making connections through RideMatch.
Join thousands of users already saving money and making connections through {config.app.name}.
</p>
<Link href="/dashboard">
<Button
Expand All @@ -278,7 +279,7 @@ export default function HomePage() {
<div className="w-8 h-8 bg-gradient-to-r from-blue-600 to-green-600 rounded-lg flex items-center justify-center">
<MapPin className="w-5 h-5 text-white" />
</div>
<span className="text-xl font-bold">RideMatch</span>
<span className="text-xl font-bold">{config.app.name}</span>
</div>
<p className="text-gray-400">
Connecting travelers, building community, and making transportation more sustainable.
Expand Down Expand Up @@ -365,7 +366,7 @@ export default function HomePage() {
</div>

<div className="border-t border-gray-800 mt-8 pt-8 text-center text-gray-400">
<p>&copy; 2024 RideMatch. All rights reserved. Built with Google Maps Platform and Firebase.</p>
<p>&copy; 2024 {config.app.name}. All rights reserved. Built with Google Maps Platform and Firebase.</p>
</div>
</div>
</footer>
Expand Down
3 changes: 2 additions & 1 deletion components/Header.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
"use client"

import { Bell, Menu, Search } from "lucide-react"
import { config } from "@/lib/config"

export function Header() {
return (
Expand All @@ -12,7 +13,7 @@ export function Header() {
<span className="text-white font-bold text-sm">R</span>
</div>
<div>
<h1 className="text-xl font-bold text-gray-900">RideMatch</h1>
<h1 className="text-xl font-bold text-gray-900">{config.app.name}</h1>
<p className="text-xs text-gray-600">Smart Ride Sharing</p>
</div>
</div>
Expand Down
3 changes: 2 additions & 1 deletion components/RidePanel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import { useState } from "react"
import { Car, MapPin, Star, Clock, Users, Settings, Bell } from "lucide-react"
import { config } from "@/lib/config"

interface Ride {
id: string
Expand Down Expand Up @@ -73,7 +74,7 @@ export function RidePanel() {
<div className="w-96 bg-white border-l border-gray-200 flex flex-col">
{/* Header */}
<div className="p-6 border-b border-gray-200">
<h1 className="text-2xl font-bold text-gray-900">RideMatch</h1>
<h1 className="text-2xl font-bold text-gray-900">{config.app.name}</h1>
<p className="text-sm text-gray-600 mt-1">Smart ride sharing with Google Maps</p>
</div>

Expand Down
70 changes: 70 additions & 0 deletions lib/config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
// App Configuration
export const config = {
// App metadata
app: {
name: process.env.NEXT_PUBLIC_APP_NAME || 'RideMatch',
description: process.env.NEXT_PUBLIC_APP_DESCRIPTION || 'A community-driven ride matching app',
url: process.env.NEXT_PUBLIC_APP_URL || 'http://localhost:3000',
version: process.env.NEXT_PUBLIC_APP_VERSION || '0.1.0',
},

// Firebase configuration
firebase: {
apiKey: process.env.NEXT_PUBLIC_FIREBASE_API_KEY,
authDomain: process.env.NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN,
projectId: process.env.NEXT_PUBLIC_FIREBASE_PROJECT_ID,
storageBucket: process.env.NEXT_PUBLIC_FIREBASE_STORAGE_BUCKET,
messagingSenderId: process.env.NEXT_PUBLIC_FIREBASE_MESSAGING_SENDER_ID,
appId: process.env.NEXT_PUBLIC_FIREBASE_APP_ID,
},

// Google Maps configuration
maps: {
apiKey: process.env.NEXT_PUBLIC_GOOGLE_MAPS_API_KEY,
},

// Feature flags
features: {
enableRealTimeTracking: process.env.NEXT_PUBLIC_ENABLE_REAL_TIME_TRACKING === 'true',
enableNotifications: process.env.NEXT_PUBLIC_ENABLE_NOTIFICATIONS === 'true',
enableAnalytics: process.env.NEXT_PUBLIC_ENABLE_ANALYTICS === 'true',
},

// API endpoints
api: {
baseUrl: process.env.NEXT_PUBLIC_API_BASE_URL || '/api',
timeout: parseInt(process.env.NEXT_PUBLIC_API_TIMEOUT || '5000'),
},

// Environment
env: {
isDevelopment: process.env.NODE_ENV === 'development',
isProduction: process.env.NODE_ENV === 'production',
isTest: process.env.NODE_ENV === 'test',
},
} as const;

// Validation function to check required environment variables
export function validateConfig() {
const requiredEnvVars = [
'NEXT_PUBLIC_FIREBASE_API_KEY',
'NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN',
'NEXT_PUBLIC_FIREBASE_PROJECT_ID',
'NEXT_PUBLIC_FIREBASE_STORAGE_BUCKET',
'NEXT_PUBLIC_FIREBASE_MESSAGING_SENDER_ID',
'NEXT_PUBLIC_FIREBASE_APP_ID',
'NEXT_PUBLIC_GOOGLE_MAPS_API_KEY'
];

const missingEnvVars = requiredEnvVars.filter(envVar => !process.env[envVar]);

if (missingEnvVars.length > 0) {
throw new Error(
`Missing required environment variables: ${missingEnvVars.join(', ')}. ` +
'Please check your .env.local file and ensure all required variables are set.'
);
}
}

// Type-safe config access
export type AppConfig = typeof config;
Loading