A modern React frontend application for managing educational resources with JWT-based authentication and role-based access control.
- Modern React Stack: Built with React 18, TypeScript, and Vite
- Fast Development: Vite provides lightning-fast HMR and builds
- Routing: React Router v6 for navigation and protected routes
- Authentication: JWT-based authentication with context API
- Styling: Tailwind CSS for utility-first responsive design
- API Integration: Axios with interceptors for API calls
- Role-Based Access: Admin and User role-based routing
- Type Safety: Full TypeScript support throughout
src/
βββ components/ # Reusable UI components
β βββ ProtectedRoute.tsx
βββ pages/ # Page components
β βββ LoginPage.tsx
β βββ RegisterPage.tsx
β βββ HomePage.tsx
β βββ ResourcesPage.tsx
β βββ AdminDashboard.tsx
β βββ UnauthorizedPage.tsx
βββ layouts/ # Layout components
β βββ MainLayout.tsx
βββ services/ # API services
β βββ authService.ts
β βββ resourceService.ts
βββ contexts/ # React contexts
β βββ AuthContext.tsx
βββ hooks/ # Custom hooks
β βββ useAuth.ts
βββ types/ # TypeScript type definitions
β βββ index.ts
βββ utils/ # Utility functions
β βββ tokenManager.ts
β βββ axiosInstance.ts
βββ index.css # Global styles with Tailwind
βββ App.tsx # Main app component
βββ main.tsx # Entry point
-
Clone the repository
git clone <repository-url> cd edu-library
-
Install dependencies
npm install
-
Environment Setup
cp .env.example .env
-
Start development server
npm run dev
The application will be available at http://localhost:5173
react- UI libraryreact-dom- React DOM rendererreact-router-dom- Routing librarytypescript- Type system
tailwindcss- Utility-first CSS frameworkpostcss- CSS transformationsautoprefixer- CSS vendor prefixes
axios- HTTP client
vite- Build tool@vitejs/plugin-react- Vite React plugin@types/react- React type definitions@types/react-dom- React DOM type definitions
The application uses JWT-based authentication with the following features:
- Login: Credentials-based authentication
- Registration: New user registration
- Token Management: Automatic token storage and retrieval
- Protected Routes: Routes requiring authentication
- Role-Based Access: Differentiated access for Admin and User roles
- Auto-Logout: Automatic logout on token expiration (401 response)
- User logs in with email/password
- Server returns JWT token and user data
- Token stored in localStorage
- Token added to all API requests via axios interceptor
- Protected routes check authentication status
- Admin-only routes check user role
/login- User login/register- User registration
/- Home page/resources- Browse educational resources
/admin- Admin dashboard with resource management
/unauthorized- Access denied page
The axiosInstance in src/utils/axiosInstance.ts automatically:
- Adds authentication tokens to requests
- Handles 401 responses with auto-logout
- Uses the base URL from environment variables
Auth Service (src/services/authService.ts)
login(email, password)- User loginregister(email, password, name)- User registrationlogout()- User logoutverifyToken()- Verify JWT token
Resource Service (src/services/resourceService.ts)
getAll()- Fetch all resourcesgetById(id)- Fetch single resourcecreate(resource)- Create new resourceupdate(id, resource)- Update resourcedelete(id)- Delete resource
The project uses Tailwind CSS with custom theme colors:
- Primary:
#3B82F6(Blue) - Secondary:
#10B981(Green) - Danger:
#EF4444(Red) - Warning:
#F59E0B(Amber) - Dark:
#1F2937(Dark Gray) - Light:
#F3F4F6(Light Gray)
Create a .env file based on .env.example:
VITE_API_URL=http://localhost:3000/apinpm run buildBuilds the application for production. The optimized build will be in the dist directory.
npm run devStarts the development server with hot module replacement (HMR).
Routes are protected using the ProtectedRoute component which:
- Checks authentication status
- Redirects unauthenticated users to login
- Enforces role-based access control
- Shows loading state during auth verification
Tokens are managed using:
- localStorage for persistence
- axios interceptors for automatic attachment
- Custom
tokenManagerutility for clean API
Authentication state managed via:
AuthContextfor global auth stateuseAuthhook for easy accessAuthProviderwrapper component
- Handle routing and data fetching
- Pass data to presentational components
- Receive data via props
- Handle UI rendering and user interactions
- Wrap page content
- Provide consistent structure (header, footer, navigation)
Resources follow this structure:
interface Resource {
id: string;
title: string;
description: string;
category: string;
author: string;
url: string;
createdAt: string;
updatedAt: string;
}If you encounter CORS errors, ensure your backend is configured to accept requests from localhost:5173 in development.
Implement token refresh logic in axiosInstance.ts to handle token expiration gracefully.
Clear cache and restart dev server if Tailwind styles aren't applying:
npm run dev- React Documentation
- React Router Documentation
- Tailwind CSS Documentation
- Axios Documentation
- Vite Documentation
- TypeScript Documentation
Contributions are welcome! Please follow these guidelines:
- Create a new branch for your feature
- Make your changes with clear commit messages
- Ensure code follows the project style
- Test your changes thoroughly
- Submit a pull request
This project is licensed under the MIT License - see the LICENSE file for details.
- Connect Backend API: Update API endpoints in services
- Implement Real Authentication: Connect to real authentication backend
- Add More Features: Implement resource creation, editing, and deletion
- Testing: Add unit and integration tests
- Error Handling: Implement comprehensive error handling
- Analytics: Add application analytics
- Performance: Optimize bundle size and performance
Happy coding! π
export default defineConfig([
globalIgnores(['dist']),
{
files: ['**/*.{ts,tsx}'],
extends: [
// Other configs...
// Remove tseslint.configs.recommended and replace with this
tseslint.configs.recommendedTypeChecked,
// Alternatively, use this for stricter rules
tseslint.configs.strictTypeChecked,
// Optionally, add this for stylistic rules
tseslint.configs.stylisticTypeChecked,
// Other configs...
],
languageOptions: {
parserOptions: {
project: ['./tsconfig.node.json', './tsconfig.app.json'],
tsconfigRootDir: import.meta.dirname,
},
// other options...
},
},
])You can also install eslint-plugin-react-x and eslint-plugin-react-dom for React-specific lint rules:
// eslint.config.js
import reactX from 'eslint-plugin-react-x'
import reactDom from 'eslint-plugin-react-dom'
export default defineConfig([
globalIgnores(['dist']),
{
files: ['**/*.{ts,tsx}'],
extends: [
// Other configs...
// Enable lint rules for React
reactX.configs['recommended-typescript'],
// Enable lint rules for React DOM
reactDom.configs.recommended,
],
languageOptions: {
parserOptions: {
project: ['./tsconfig.node.json', './tsconfig.app.json'],
tsconfigRootDir: import.meta.dirname,
},
// other options...
},
},
])