A React-based web application built with Vite and TypeScript.
- Node.js (v18 or higher recommended)
- npm or yarn
- Install dependencies:
npm installStart the development server:
npm run devThe app will open automatically at http://localhost:3000
Create a production build:
npm run buildPreview the production build:
npm run previewRun ESLint:
npm run lint- React 18 - UI library with hooks
- TypeScript - Type safety
- Vite - Build tool and dev server
- React Router - Client-side routing
- Zustand - Lightweight state management
- React Query - Server state management and data fetching
- Axios - HTTP client
- ESLint - Code linting
- Fast development with Vite HMR
- Type-safe development with TypeScript
- Client-side routing with React Router
- Global state management with Zustand
- Data fetching with React Query and Axios
- Loading and error states
- RESTful API integration (JSONPlaceholder demo)
- Pagination with reusable Pagination component
- Infinite scroll with React Query's useInfiniteQuery
- IntersectionObserver-based auto-loading
fallout/ ├── public/ # Static assets ├── src/ │ ├── api/ │ │ ├── axios.ts # Axios configuration │ │ └── services.ts # API service functions │ ├── components/ │ │ ├── Navigation.tsx │ │ ├── Navigation.css │ │ ├── Pagination.tsx │ │ └── Pagination.css │ ├── hooks/ │ │ └── useInfiniteScroll.ts # Custom hook for infinite scroll │ ├── pages/ │ │ ├── Home.tsx │ │ ├── Dashboard.tsx │ │ ├── Posts.tsx # Paginated posts list │ │ ├── InfinitePosts.tsx # Infinite scroll posts list │ │ ├── Profile.tsx │ │ ├── Settings.tsx │ │ ├── About.tsx │ │ └── NotFound.tsx │ ├── store/ │ │ └── counterStore.ts # Zustand store │ ├── App.tsx # Main app component │ ├── App.css # App styles │ ├── main.tsx # Entry point with React Query provider │ └── index.css # Global styles ├── .env.example # Environment variables template ├── index.html # HTML template ├── package.json # Dependencies ├── tsconfig.json # TypeScript config └── vite.config.ts # Vite config The app uses JSONPlaceholder as a demo REST API.
To configure a different API:
- Copy
.env.exampleto.env - Update
VITE_API_URLwith your API endpoint - Modify services in
src/api/services.tsas needed
- Automatic request/response interceptors
- Token-based authentication support
- Centralized error handling
- TypeScript types for all API responses
- React Query for caching and state management
The application includes the following pages:
- Home (
/) - Landing page with a counter using Zustand - Dashboard (
/dashboard) - Metrics and activity overview with real API data - Posts (
/posts) - Paginated list of posts with 10 items per page - Infinite Posts (
/posts/infinite) - Infinite scroll version of posts list - Profile (
/profile) - User profile with stats from API - Settings (
/settings) - App preferences and configuration - About (
/about) - Information about the tech stack
A reusable pagination component used in the Posts page:
<Pagination currentPage={currentPage} totalPages={totalPages} onPageChange={handlePageChange} maxVisible={5} // Optional: max page numbers to show />Features:
- Smart ellipsis display for large page counts
- Previous/Next buttons
- Active page highlighting
- Responsive design
A custom hook (useInfiniteScroll) combined with React Query's useInfiniteQuery for infinite scrolling:
import { useInfiniteScroll } from '../hooks/useInfiniteScroll' import { useInfiniteQuery } from '@tanstack/react-query' const { data, fetchNextPage, hasNextPage, isFetchingNextPage } = useInfiniteQuery({ queryKey: ['infinitePosts'], queryFn: ({ pageParam = 1 }) => postService.getPostsPage(pageParam, 10), getNextPageParam: (lastPage) => lastPage.nextPage, initialPageParam: 1, }) const loadMoreRef = useInfiniteScroll({ loading: isFetchingNextPage, hasMore: hasNextPage ?? false, onLoadMore: fetchNextPage, }) // In JSX: <div ref={loadMoreRef} />Features:
- IntersectionObserver-based detection
- Automatic loading when scrolling near bottom
- Loading spinner while fetching
- End of content indicator
- Configurable trigger distance and threshold
- Switch between pagination and infinite scroll views
Both pagination and infinite scroll patterns are demonstrated in the Posts pages, with a toggle button to switch between them.