A modern, full-stack car rental application with Spring Boot backend and React frontend
Modern car rental platform with flexible subscription options, real-time pricing, and seamless booking experience
Features • Tech Stack • Screenshots • Installation • Documentation
- Overview
- Features
- Tech Stack
- Screenshots
- Installation
- Usage
- Project Structure
- API Documentation
- Database Schema
- Security
- Contributing
- License
The Car Rental Subscription Platform is a comprehensive full-stack application that allows users to browse, configure, and book car rentals with flexible subscription options. The platform features a modern dark-themed UI, real-time price calculations, secure authentication, and a complete booking management system.
- Modern UI/UX - Beautiful dark theme with smooth animations
- Secure Authentication - JWT-based authentication with Spring Security
- Dynamic Pricing - Real-time price calculation based on rental configuration
- Responsive Design - Works seamlessly on desktop, tablet, and mobile
- Fast Performance - Optimized React frontend with Vite build tool
- Robust Backend - Spring Boot with PostgreSQL for reliable data persistence
- User registration and login
- JWT token-based authentication
- Protected routes and API endpoints
- Secure password hashing with BCrypt
- Session management
- Browse available cars with beautiful card layouts
- Filter cars by category (Sedan, SUV, Luxury)
- Filter cars by brand
- View detailed car information
- Real-time availability status
- Duration Options: 1, 3, or 6 months
- KM Packages: 500, 1000, or 2000 km/month
- Real-time price calculation
- Visual configuration interface
- Dynamic pricing based on category, duration, and KM package
- Price snapshot at booking time
- Transparent pricing breakdown
- Multiple pricing plans per category
- Create bookings with date selection
- View all bookings in user dashboard
- Booking status tracking (Pending, Confirmed, Cancelled, Completed)
- Booking history and details
- Mock payment integration
- Payment success/failure handling
- Transaction ID generation
- Payment confirmation
- View all user bookings
- Booking status overview
- Quick access to booking details
- User profile management
- Modern dark theme
- Smooth animations and transitions
- Glass morphism design elements
- Gradient buttons and cards
- Loading states and error handling
- Responsive grid layouts
- Interactive hover effects
| Technology | Version | Purpose |
|---|---|---|
| Spring Boot | 4.0.1 | Java framework for building REST APIs |
| Spring Security | - | Authentication and authorization |
| Spring Data JPA | - | Database abstraction layer |
| PostgreSQL | 15+ | Relational database |
| JWT (JJWT) | 0.12.3 | Token-based authentication |
| Hibernate | - | ORM framework |
| Gradle | 9.2.1 | Build automation tool |
| Lombok | - | Reduces boilerplate code |
| Technology | Version | Purpose |
|---|---|---|
| React | 18 | UI library |
| TypeScript | 5.0 | Type-safe JavaScript |
| Vite | 5.4 | Build tool and dev server |
| React Router | 6 | Client-side routing |
| Axios | 1.6 | HTTP client |
| Tailwind CSS | 3.4 | Utility-first CSS framework |
| Context API | - | State management |
- PostgreSQL - Database
- Gradle Wrapper - Build tool
- npm/yarn - Package manager
- Git - Version control
Beautiful landing page with hero section and call-to-action buttons
Browse available cars with filtering options by category and brand
Configure rental duration and KM package with real-time price calculation
Review booking details and process payment
View and manage all your bookings in one place
Secure login and signup with JWT authentication
Booking confirmation with payment details
Before you begin, ensure you have the following installed:
- Java 17+ (or Java 25)
- Node.js 18+ and npm
- PostgreSQL 15+ (running on port 5432)
- Gradle (or use Gradle wrapper included)
git clone <repository-url>
cd rental# Create PostgreSQL database
psql -U your_username -c "CREATE DATABASE carrental_db;"
# Or use the verification script
./verify-db.shUpdate database credentials in src/main/resources/application.properties:
spring.datasource.url=jdbc:postgresql://localhost:5432/carrental_db
spring.datasource.username=your_username
spring.datasource.password=your_password# Build the project
./gradlew clean build
# Run the backend
./gradlew bootRun
# Backend will start on http://localhost:8080
# Sample data will be automatically seeded on first runExpected Output:
Started CarrentalApplication in X.XXX seconds
Sample data seeded successfully
# Navigate to frontend directory
cd frontend
# Install dependencies (first time only)
npm install
# Start development server
npm run dev
# Frontend will start on http://localhost:3000- Frontend: http://localhost:3000
- Backend API: http://localhost:8080/api
- API Documentation: See API Documentation section
Alternatively, use the provided start script:
./start.shThis script will:
- Check prerequisites
- Start PostgreSQL (if needed)
- Build and run the backend
- Start the frontend
-
Sign Up / Login
- Create a new account or login with existing credentials
- JWT token is automatically stored and used for authenticated requests
-
Browse Cars
- View all available cars
- Filter by category (Sedan, SUV, Luxury)
- Filter by brand
- Click on a car to configure rental
-
Configure Rental
- Select rental duration (1, 3, or 6 months)
- Choose KM package (500, 1000, or 2000 km/month)
- View real-time price calculation
- Click "Continue to Review"
-
Review & Book
- Review all booking details
- Select rental start date
- Click "Confirm & Pay"
- Process mock payment
-
Confirmation
- View booking confirmation
- See payment details
- Access booking ID for reference
-
Dashboard
- View all your bookings
- Check booking status
- Access booking details
# Get all categories
curl http://localhost:8080/api/categories
# Get all cars
curl http://localhost:8080/api/cars
# Get cars by category
curl http://localhost:8080/api/cars/category/1
# Calculate price
curl "http://localhost:8080/api/pricing/calculate?categoryId=1&durationMonths=3&kmPackage=1000"# Sign up
curl -X POST http://localhost:8080/api/auth/signup \
-H "Content-Type: application/json" \
-d '{
"email": "user@example.com",
"password": "password123",
"firstName": "John",
"lastName": "Doe",
"phoneNumber": "+1234567890"
}'
# Login
curl -X POST http://localhost:8080/api/auth/login \
-H "Content-Type: application/json" \
-d '{
"email": "user@example.com",
"password": "password123"
}'# Create booking
curl -X POST http://localhost:8080/api/bookings \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_JWT_TOKEN" \
-d '{
"userId": 1,
"carId": 1,
"categoryId": 1,
"durationMonths": 3,
"kmPackage": 1000,
"startDate": "2024-01-15"
}'
# Get user bookings
curl -H "Authorization: Bearer YOUR_JWT_TOKEN" \
http://localhost:8080/api/bookings/user/1rental/
├── src/main/java/com/sixt/carrental/
│ ├── CarrentalApplication.java # Main application class
│ ├── config/ # Configuration classes
│ │ ├── DataSeeder.java # Sample data seeder
│ │ ├── JwtAuthenticationFilter.java
│ │ ├── JwtTokenProvider.java
│ │ └── SecurityConfig.java
│ ├── controller/ # REST API controllers
│ │ ├── AuthController.java
│ │ ├── BookingController.java
│ │ ├── CarController.java
│ │ ├── CategoryController.java
│ │ ├── PaymentController.java
│ │ └── PricingController.java
│ ├── service/ # Business logic layer
│ │ ├── BookingService.java
│ │ ├── CarService.java
│ │ ├── CategoryService.java
│ │ ├── PaymentService.java
│ │ ├── PricingService.java
│ │ └── UserService.java
│ ├── repository/ # Data access layer
│ │ ├── BookingRepository.java
│ │ ├── CarRepository.java
│ │ ├── CategoryRepository.java
│ │ ├── PaymentRepository.java
│ │ ├── PricingPlanRepository.java
│ │ └── UserRepository.java
│ ├── entity/ # JPA entities
│ │ ├── Booking.java
│ │ ├── Car.java
│ │ ├── Category.java
│ │ ├── Payment.java
│ │ ├── PricingPlan.java
│ │ └── User.java
│ └── dto/ # Data transfer objects
│ ├── request/
│ │ ├── BookingRequest.java
│ │ ├── LoginRequest.java
│ │ ├── PaymentRequest.java
│ │ └── SignupRequest.java
│ └── response/
│ ├── ApiResponse.java
│ ├── LoginResponse.java
│ └── PriceCalculationResponse.java
├── frontend/
│ ├── src/
│ │ ├── components/ # React components
│ │ │ ├── Home.tsx
│ │ │ ├── CarList.tsx
│ │ │ ├── Configuration.tsx
│ │ │ ├── Review.tsx
│ │ │ ├── Confirmation.tsx
│ │ │ ├── Dashboard.tsx
│ │ │ ├── Login.tsx
│ │ │ ├── Signup.tsx
│ │ │ ├── Navbar.tsx
│ │ │ └── ProtectedRoute.tsx
│ │ ├── context/ # React Context
│ │ │ └── AuthContext.tsx
│ │ ├── services/ # API service layer
│ │ │ └── api.ts
│ │ ├── types/ # TypeScript types
│ │ │ └── index.ts
│ │ ├── App.tsx # Main app component
│ │ ├── main.tsx # Entry point
│ │ └── index.css # Global styles
│ ├── package.json
│ ├── vite.config.ts
│ └── tailwind.config.js
├── build.gradle # Gradle build configuration
├── start.sh # Quick start script
├── verify-db.sh # Database verification script
└── README.md # This file
http://localhost:8080/api
All API responses follow this standard format:
{
"success": true,
"message": "Operation successful",
"data": { ... }
}Error Response:
{
"success": false,
"message": "Error message",
"data": null
}Create a new user account.
Request Body:
{
"email": "user@example.com",
"password": "password123",
"firstName": "John",
"lastName": "Doe",
"phoneNumber": "+1234567890"
}Response:
{
"success": true,
"message": "User registered successfully",
"data": {
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"user": {
"id": 1,
"email": "user@example.com",
"firstName": "John",
"lastName": "Doe"
}
}
}Authenticate user and get JWT token.
Request Body:
{
"email": "user@example.com",
"password": "password123"
}Get all available cars.
Get car by ID.
Get cars by category.
Get cars by brand.
Create a new booking.
Headers:
Authorization: Bearer <JWT_TOKEN>
Request Body:
{
"userId": 1,
"carId": 1,
"categoryId": 1,
"durationMonths": 3,
"kmPackage": 1000,
"startDate": "2024-01-15"
}Get all bookings for a user.
Get booking by ID.
Cancel a booking.
Process payment for a booking.
Request Body:
{
"bookingId": 1,
"mockSuccess": true
}Get payment by booking ID.
Get all pricing plans for a category.
Calculate price for a configuration.
Query Parameters:
categoryId- Category IDdurationMonths- Duration in monthskmPackage- KM package
Example:
GET /api/pricing/calculate?categoryId=1&durationMonths=3&kmPackage=1000
For complete API documentation, see INTEGRATION_GUIDE.md.
The application uses PostgreSQL with the following main tables:
users
├── id (PK)
├── email (unique)
├── password (encrypted)
├── first_name
├── last_name
├── phone_number
├── role
└── created_at, updated_atcategories
├── id (PK)
├── code (unique)
├── name
└── descriptioncars
├── id (PK)
├── category_id (FK → categories)
├── brand
├── model
├── image_url
├── status
└── created_at, updated_atpricing_plans
├── id (PK)
├── category_id (FK → categories)
├── duration_month
├── km_package
├── price_per_month
└── is_activebookings
├── id (PK)
├── user_id (FK → users)
├── car_id (FK → cars)
├── duration_months
├── km_package
├── price_per_month
├── total_amount
├── start_date
├── end_date
├── status
└── created_at, updated_atpayments
├── id (PK)
├── booking_id (FK → bookings, unique)
├── amount
├── status
├── transaction_id
└── created_atNote: Tables are automatically created by Hibernate on first run with spring.jpa.hibernate.ddl-auto=update.
- JWT Tokens - Stateless authentication
- Token Expiration - 24 hours (configurable)
- Password Hashing - BCrypt with salt rounds
- Protected Routes - Frontend route protection
- Protected Endpoints - Backend API security
- Role-based Access - User roles (USER, ADMIN)
- Endpoint Protection - Spring Security configuration
- Token Validation - JWT filter on every request
- SQL Injection Prevention - JPA parameterized queries
- CORS Configuration - Configured for allowed origins
- Input Validation - Request validation
- Error Handling - Secure error messages
- Passwords never stored in plain text
- Tokens stored securely in localStorage
- HTTPS recommended for production
- Regular security updates
./verify-db.sh-- Connect to database
psql -U your_username -d carrental_db
-- Check data counts
SELECT COUNT(*) FROM cars; -- Should be 12
SELECT COUNT(*) FROM categories; -- Should be 3
SELECT COUNT(*) FROM pricing_plans; -- Should be 27Use the examples in the Usage section or use tools like:
- Postman
- cURL
- Insomnia
- Browser DevTools
- Open browser DevTools (F12)
- Check Console for errors
- Check Network tab for API calls
- Verify localStorage for JWT token
Database Connection Error
Solution: Check PostgreSQL is running and credentials in application.properties are correct
Port 8080 Already in Use
Solution: Change server.port in application.properties or stop the service using port 8080
No Sample Data
Solution: Check DataSeeder ran successfully. Look for "Sample data seeded successfully" in logs
CORS Errors
Solution: Verify backend CORS configuration in SecurityConfig.java
API Connection Errors
Solution: Ensure backend is running on http://localhost:8080
No Data Displayed
Solution: Check backend is running and database has sample data
401 Unauthorized
Solution: Check JWT token is valid. Try logging out and logging back in
Booking Not Saving
Solution: Check backend logs for errors. Verify database connection and transaction logs
Network Errors
Solution: Verify both frontend (port 3000) and backend (port 8080) are running
For detailed troubleshooting, see INTEGRATION_GUIDE.md and frontend/DEBUGGING.md.
- SETUP.md - Detailed setup instructions
- INTEGRATION_GUIDE.md - Complete integration guide
- INTEGRATION_SUMMARY.md - Integration overview
- frontend/FLOW.md - Frontend flow documentation
- frontend/DEBUGGING.md - Debugging guide
- ARCHITECTURE_DIAGRAM.md - Architecture overview
Contributions are welcome! Please follow these steps:
- Fork the repository
- Create a feature branch
git checkout -b feature/amazing-feature
- Make your changes
- Follow code style guidelines
- Add comments where necessary
- Update documentation if needed
- Test your changes
- Test all affected functionality
- Verify no breaking changes
- Commit your changes
git commit -m "Add amazing feature" - Push to the branch
git push origin feature/amazing-feature
- Open a Pull Request
- Backend: Follow Java conventions and Spring Boot best practices
- Frontend: Follow React and TypeScript conventions
- Documentation: Update README and relevant docs
Your Name
- GitHub: @sarthakporwal
- Email: sarthakporwal12@gmail.com