);
}
export default Dashboard;
```
---
## Step 4: Set Up Routes (5 minutes)
Update your `src/App.jsx`:
```javascript
import React from 'react';
import { BrowserRouter, Routes, Route, Navigate } from 'react-router-dom';
import LoginPage from './pages/LoginPage';
import Dashboard from './pages/Dashboard';
import AuthService from './services/auth';
// Protected Route component
function ProtectedRoute({ children }) {
if (!AuthService.isAuthenticated()) {
return ;
}
return children;
}
function App() {
return (
} />
}
/>
} />
);
}
export default App;
```
---
## 🎉 You're Done! Test It Out
### Test Login
1. Start your dev server: `npm start`
2. Go to `http://localhost:3000/login`
3. Enter credentials:
- Email: `user@example.com`
- Password: `SecurePass123!`
4. Click "Login"
5. Should redirect to dashboard
### Test Protected Route
1. Go to `http://localhost:3000/dashboard` without logging in
2. Should redirect to `/login`
### Test Logout
1. On dashboard, click "Logout"
2. Should redirect to `/login`
3. Try accessing `/dashboard` again
4. Should redirect to `/login`
---
## 🐛 Common Issues & Solutions
### Issue: "Login failed"
**Solution:** Check if API URL is correct. Verify email/password.
### Issue: "Failed to fetch user profile"
**Solution:** Token might be expired. Clear localStorage and login again.
### Issue: Infinite redirect loop
**Solution:** Check if token is being stored correctly in localStorage.
### Issue: CORS error
**Solution:** Backend needs to allow your frontend domain in CORS settings.
---
## 📝 What You Just Built
✅ **Login System** - Users can login with email/password
✅ **Token Management** - JWT token stored in localStorage
✅ **Protected Routes** - Dashboard only accessible when logged in
✅ **Auto-Logout** - Expired tokens handled automatically
✅ **User Profile** - Display current user information
✅ **Logout** - Users can logout
---
## 🚀 Next Steps
### Phase 2: Profile Management
Add ability to update user profile:
```javascript
// In Dashboard.jsx
const updateProfile = async () => {
const response = await fetch(`${API_BASE}/auth/me`, {
method: 'PUT',
headers: AuthService.getHeaders(),
body: JSON.stringify({
first_name: 'Jane',
phone: '+254712345678'
})
});
const updatedUser = await response.json();
setUser(updatedUser);
};
```
### Phase 3: Invitation System
Handle invitation links when users are invited:
```javascript
// InvitationAcceptPage.jsx
const acceptInvitation = async (token, password, name) => {
const response = await fetch(`${API_BASE}/invitations/accept`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
token,
password,
name,
accept_terms: true
})
});
const data = await response.json();
AuthService.setToken(data.access_token);
navigate('/dashboard');
};
```
### Phase 4: Password Reset
Add forgot password and reset password flows.
---
## 📚 Where to Go Next
1. **Quick Reference** - For quick endpoint lookups
2. **Complete API Guide** - For advanced features:
- Password management
- Invitation system
- Error handling patterns
- Security best practices
---
## 💬 Need Help?
### Common Questions
**Q: How long does the token last?**
A: 24 hours. After that, user must login again.
**Q: Can I use axios instead of fetch?**
A: Yes! Just replace fetch calls with axios. Example:
```javascript
const response = await axios.post(`${API_BASE}/auth/login`, {
email, password
});
const { access_token, user } = response.data;
```
**Q: How do I show loading spinners?**
A: Use the `loading` state variable like in the examples.
**Q: What if I need to call other APIs?**
A: Use `AuthService.getHeaders()` to include the auth token:
```javascript
fetch(`${API_BASE}/users`, {
headers: AuthService.getHeaders()
});
```
**Q: Mobile app development?**
A: Use SecureStore instead of localStorage:
```javascript
import * as SecureStore from 'expo-secure-store';
await SecureStore.setItemAsync('token', token);
```
---
## ✅ Checklist
Before moving to production:
- [ ] Login page works
- [ ] Dashboard shows user info
- [ ] Logout works
- [ ] Protected routes redirect to login
- [ ] Error messages display properly
- [ ] Token stored in localStorage
- [ ] 401 errors handled (auto-logout)
- [ ] Loading states shown
- [ ] Password validation on client side
---
## 🎯 Summary
**What you learned:**
- How to integrate SwiftOps authentication
- Token-based authentication flow
- Protected routes implementation
- Error handling patterns
**Time invested:** 30-60 minutes
**Result:** Working auth system
**Next steps:** Read the Quick Reference for other features like password reset, invitation system, and profile management.
---
**Good luck with your implementation! 🚀**
Need detailed information? See `AUTH_API_COMPLETE.md`
Need quick lookup? See `AUTH_API_QUICK_REFERENCE.md`