Add Session Management UI

Implements user interface for viewing and managing active sessions:

Session Management Features:
- SessionsManagement component with full session management UI
- List all active sessions with device information
- Platform-specific icons (Computer, Phone, Tablet)
- Current session indicator with green chip
- Session details: device fingerprint, platform, last used, created date
- Revoke individual sessions with confirmation dialog
- Revoke all sessions except current with bulk action
- Real-time session count display

User Experience:
- Visual device type indicators
- Human-readable time formatting (e.g., "2 hours ago")
- Current session clearly marked and protected from removal
- Warning dialogs before revoking sessions
- Success/error feedback with alerts
- Loading states for all operations
- Empty state handling

API Integration:
- Sessions API client in lib/api/sessions.ts
- Get all sessions
- Get session count
- Revoke specific session
- Revoke all sessions except current
- Proper error handling and user feedback

Settings Page Integration:
- Added Sessions Management section
- Placed after Security/MFA settings
- Animated transitions with staggered delays
- Maintains consistent settings page layout

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2025-10-01 21:11:30 +00:00
parent 48f45f1b04
commit 50353d8fc1
3 changed files with 346 additions and 1 deletions

View File

@@ -0,0 +1,55 @@
import axios from 'axios';
const API_BASE_URL = process.env.NEXT_PUBLIC_API_URL || 'http://localhost:3020';
export interface SessionInfo {
id: string;
deviceFingerprint: string;
platform?: string;
lastUsed: Date;
createdAt: Date;
ipAddress?: string;
isCurrent: boolean;
}
export const sessionsApi = {
// Get all sessions
async getSessions(): Promise<{ success: boolean; sessions: SessionInfo[]; totalCount: number }> {
const response = await axios.get(`${API_BASE_URL}/api/v1/auth/sessions`, {
headers: {
Authorization: `Bearer ${localStorage.getItem('accessToken')}`,
},
});
return response.data;
},
// Get session count
async getSessionCount(): Promise<{ success: boolean; activeSessionCount: number }> {
const response = await axios.get(`${API_BASE_URL}/api/v1/auth/sessions/count`, {
headers: {
Authorization: `Bearer ${localStorage.getItem('accessToken')}`,
},
});
return response.data;
},
// Revoke specific session
async revokeSession(sessionId: string): Promise<{ success: boolean; message: string }> {
const response = await axios.delete(`${API_BASE_URL}/api/v1/auth/sessions/${sessionId}`, {
headers: {
Authorization: `Bearer ${localStorage.getItem('accessToken')}`,
},
});
return response.data;
},
// Revoke all sessions except current
async revokeAllSessions(): Promise<{ success: boolean; message: string; revokedCount: number }> {
const response = await axios.delete(`${API_BASE_URL}/api/v1/auth/sessions`, {
headers: {
Authorization: `Bearer ${localStorage.getItem('accessToken')}`,
},
});
return response.data;
},
};