A modern van rental web application built with React, featuring advanced routing, authentication, and cloud database integration.
This project focuses on real-world routing, Firebase integration, modern React patterns and data loading patterns using React Router loaders instead of traditional useEffect.
This project was created to practice Firebase Firestore integration, state management, and component architecture in React.
Test Credentials:
- Email:
[email protected] - Password:
123
Note: This is a demonstration project with simplified authentication. Do not use this authentication pattern in production.
Gm.s.video.mp4
-
Home Page: Welcoming landing page with call-to-action.
-
About Page: Information about the VanLife service.
-
Van Listings: Browse all available vans with filtering options.
-
Filter by type: Simple, Luxury, Rugged.
-
Detailed van information pages.
-
-
Responsive Design: Mobile-friendly interface.
-
Dashboard: Overview of income, reviews, and listed vans.
-
Income Tracking: View earnings and transaction history.
-
Van Management: List and manage your vans.
-
Reviews: View customer reviews and ratings.
-
Detailed Van Pages:
- Van information.
- Pricing details.
- Photo gallery.
-
User Authentication: Secure login system with protected routes.
-
Protected Routes: Route-level auth using React Router loaders.
-
Advanced Routing: Nested & layout routes with React Router v6.
-
Real-time Database: Firebase Firestore integration for data persistence.
-
Mock API: Development mode with MirageJS for rapid prototyping.
-
Clean UI: Modern, minimalist interface with intuitive navigation.
-
Data Loading: Efficient data fetching using React Router loaders instead of
useEffect. -
Performance: Optimized rendering with React best practices.
-
Built with Modern Tools: Built using React 19 and Vite for fast development and builds.
-
Route-level authentication using React Router loaders.
-
User login system with route protection.
-
Redirect to login for unauthorized access.
-
Preserves intended destination after login.
-
Built nested and dynamic routes with shared layouts using
Outlet. -
Gained hands-on experience with React Router v6 Data APIs, including
loaders,defer, andAwaitfor data fetching. -
Learned to replace traditional
useEffect-basedAPI calls with route-level data loading for cleaner and more predictable component logic. -
Implemented
route-basedauthentication usingloaders, protecting entire route trees instead of individual components. -
Integrated Firebase Firestore for real-time data storage and retrieval.
-
Understood how to handle redirects and error boundaries correctly in React Router.
-
Improved understanding of asynchronous JavaScript, promises, and loading states with
Suspense. -
Practiced separation of concerns by keeping data logic in loaders and UI logic in components.
-
Used Mirage JS to mock backend APIs and simulate real-world server behavior during development.
-
Practiced Fetching and handling data from Firebase Firestore.
-
Practiced Async Operations and Handling asynchronous data fetching and loading states.
-
Solved real-world issues related to static asset handling and base paths when deploying with Vite.
-
Strengthened overall React component architecture, file organization, and scalability practices.
-
Responsive Design: Creating mobile-first, adaptive layouts.
-
React 19 β UI library
-
React Router DOM 6 β Routing with data loaders
-
Vite 7.2 β Build tool and dev server
-
Firebase 12.7 β Backend and database (Firestore)
-
MirageJS 0.1 β Mock API server for development
-
React Icons 5 β Icon components
-
CSS3 β Styling
-
GitHub Pages β Deployment
vanlife/
βββ src/
β βββ assets/
β β βββ images/ # Image assets
β βββ components/
β β βββ Error.jsx # Error boundary component
β β βββ Footer.jsx # Footer component
β β βββ Header.jsx # Navigation header
β β βββ HostLayout.jsx # Host section layout
β β βββ Layout.jsx # Main layout wrapper
β βββ pages/
β β βββ Host/
β β β βββ Dashboard.jsx
β β β βββ HostVans.jsx
β β β βββ HostVanDetail.jsx
β β β βββ HostVanInfo.jsx
β β β βββ HostVanPhotos.jsx
β β β βββ HostVanPricing.jsx
β β β βββ Income.jsx
β β β βββ Reviews.jsx
β β βββ Vans/
β β β βββ Vans.jsx
β β β βββ VanDetail.jsx
β β βββ About.jsx
β β βββ Home.jsx
β β βββ Login.jsx
β β βββ NotFound.jsx
β βββ api.js # Firebase API functions
β βββ index.css # Global styles
β βββ index.jsx # App entry point
β βββ server.js # MirageJS mock server
β βββ utils.js # Utility functions
βββ package.json
βββ vite.config.js
- Node.js (v16 or higher)
- npm or yarn
- Firebase account (for production use)
-
Clone the repository:
git clone https://github.com/gmarav05/vanlife.git cd vanlife -
Install dependencies:
npm install-
Configure Firebase:
- Update the Firebase configuration in
api.jswith your own credentials. - Set up Firestore database with a
vanscollection.
- Update the Firebase configuration in
-
Start the development server:
npm run dev- Open your browser and navigate to
http://localhost:5173
vanlife/
βββ src/
β βββ assets/
β β βββ images/ # Image assets
β βββ components/
β β βββ Error.jsx # Error boundary component
β β βββ Footer.jsx # Footer component
β β βββ Header.jsx # Navigation header
β β βββ HostLayout.jsx # Host section layout
β β βββ Layout.jsx # Main layout wrapper
β βββ pages/
β β βββ Host/
β β β βββ Dashboard.jsx
β β β βββ HostVans.jsx
β β β βββ HostVanDetail.jsx
β β β βββ HostVanInfo.jsx
β β β βββ HostVanPhotos.jsx
β β β βββ HostVanPricing.jsx
β β β βββ Income.jsx
β β β βββ Reviews.jsx
β β βββ Vans/
β β β βββ Vans.jsx
β β β βββ VanDetail.jsx
β β βββ About.jsx
β β βββ Home.jsx
β β βββ Login.jsx
β β βββ NotFound.jsx
β βββ api.js # Firebase API functions
β βββ index.css # Global styles
β βββ index.jsx # App entry point
β βββ server.js # MirageJS mock server
β βββ utils.js # Utility functions
βββ package.json
βββ vite.config.js
npm run buildnpm run deployThis project uses React Router's data loading pattern instead of useEffect for data fetching:
// Example loader function
export async function loader({ params }) {
return getVan(params.id)
}
// Usage in component
const van = useLoaderData()Benefits:
- Data loads before component renders.
- Better error handling.
- Improved user experience with loading states.
- Cleaner component code.
Authentication is handled using route loaders:
export async function requireAuth(request) {
const isLoggedIn = localStorage.getItem("loggedin")
if (!isLoggedIn) {
throw redirect(`/login?message=You must log in first`)
}
}Firestore Lite is used for optimized data fetching:
export async function getVans() {
const querySnapshot = await getDocs(vansCollectionRef)
return querySnapshot.docs.map(doc => ({
...doc.data(),
id: doc.id
}))
}Uses React Router's defer for improved loading states:
export function loader() {
return defer({ vans: getVans() })
}
// In component
<React.Suspense fallback={<h2>Loading...</h2>}>
<Await resolve={dataPromise.vans}>
{renderVanElements}
</Await>
</React.Suspense>Test Credentials:
- Email:
[email protected] - Password:
123
Note: This is a demonstration project with simplified authentication. Do not use this authentication pattern in production.
npm run dev- Start development server.npm run build- Build for production.npm run preview- Preview production build.npm run lint- Run ESLint.npm run deploy- Deploy to GitHub Pages.
The project is configured for GitHub Pages deployment:
- Update the
homepagefield inpackage.json. - Run
npm run deploy.
{
id: string,
name: string,
price: number,
description: string,
imageUrl: string,
type: "simple" | "luxury" | "rugged",
hostId: string
}Note: This is a portfolio/learning project. While functional, it should not be used as-is for production applications without implementing proper security measures, particularly around authentication and payment processing.


