'use client'; import { useState, useEffect } from 'react'; import { Box, Typography, Card, CardContent, Button, Dialog, DialogTitle, DialogContent, DialogActions, Alert, CircularProgress, Chip, List, ListItem, ListItemText, ListItemSecondaryAction, IconButton, Divider, ToggleButton, ToggleButtonGroup, } from '@mui/material'; import { Devices, Computer, PhoneAndroid, Tablet, Delete, CheckCircle, Shield, ShieldOutlined, } from '@mui/icons-material'; import { devicesApi, type DeviceInfo } from '@/lib/api/devices'; import { motion } from 'framer-motion'; import { useLocalizedDate } from '@/hooks/useLocalizedDate'; export function DeviceTrustManagement() { const { formatDistanceToNow } = useLocalizedDate(); const [devices, setDevices] = useState([]); const [isLoading, setIsLoading] = useState(true); const [error, setError] = useState(null); const [successMessage, setSuccessMessage] = useState(null); const [filter, setFilter] = useState<'all' | 'trusted' | 'untrusted'>('all'); // Remove device dialog const [removeDialogOpen, setRemoveDialogOpen] = useState(false); const [deviceToRemove, setDeviceToRemove] = useState(null); const [isRemoving, setIsRemoving] = useState(false); // Remove all dialog const [removeAllDialogOpen, setRemoveAllDialogOpen] = useState(false); const [isRemovingAll, setIsRemovingAll] = useState(false); useEffect(() => { loadDevices(); }, []); const loadDevices = async () => { try { setIsLoading(true); const response = await devicesApi.getDevices(); setDevices(response.devices); setError(null); } catch (err: any) { console.error('Failed to load devices:', err); setError('Failed to load devices'); } finally { setIsLoading(false); } }; const handleTrustToggle = async (device: DeviceInfo) => { try { if (device.trusted) { await devicesApi.revokeDeviceTrust(device.id); setSuccessMessage('Device trust revoked'); } else { await devicesApi.trustDevice(device.id); setSuccessMessage('Device marked as trusted'); } await loadDevices(); } catch (err: any) { console.error('Failed to toggle device trust:', err); setError(err.response?.data?.message || 'Failed to update device trust'); } }; const handleRemoveDevice = async () => { if (!deviceToRemove) return; try { setIsRemoving(true); await devicesApi.removeDevice(deviceToRemove.id); setSuccessMessage('Device removed successfully'); setRemoveDialogOpen(false); setDeviceToRemove(null); await loadDevices(); } catch (err: any) { console.error('Failed to remove device:', err); setError(err.response?.data?.message || 'Failed to remove device'); } finally { setIsRemoving(false); } }; const handleRemoveAllDevices = async () => { try { setIsRemovingAll(true); const response = await devicesApi.removeAllDevices(); setSuccessMessage(`${response.removedCount} device(s) removed successfully`); setRemoveAllDialogOpen(false); await loadDevices(); } catch (err: any) { console.error('Failed to remove all devices:', err); setError(err.response?.data?.message || 'Failed to remove devices'); } finally { setIsRemovingAll(false); } }; const getPlatformIcon = (platform?: string) => { if (!platform) return ; const p = platform.toLowerCase(); if (p.includes('android') || p.includes('mobile')) return ; if (p.includes('ios') || p.includes('iphone') || p.includes('ipad')) return ; if (p.includes('tablet')) return ; return ; }; const filteredDevices = devices.filter((device) => { if (filter === 'trusted') return device.trusted; if (filter === 'untrusted') return !device.trusted; return true; }); if (isLoading) { return ( ); } return ( <> Device Trust Management Manage which devices are trusted to access your account. Untrusted devices will require additional verification. {error && ( setError(null)}> {error} )} {successMessage && ( setSuccessMessage(null)}> {successMessage} )} {/* Filter Toggle */} newFilter && setFilter(newFilter)} size="small" > All ({devices.length}) Trusted ({devices.filter((d) => d.trusted).length}) Untrusted ({devices.filter((d) => !d.trusted).length}) {filteredDevices.length === 0 ? ( No devices found for the selected filter. ) : ( <> {filteredDevices.map((device, index) => ( {index > 0 && } {getPlatformIcon(device.platform)} Device: {device.deviceFingerprint}
Last seen: {formatDistanceToNow(new Date(device.lastSeen))} ago } primaryTypographyProps={{ sx: { display: 'inline', mr: 1 } }} /> {device.isCurrent && ( } /> )} {device.trusted ? ( } /> ) : ( } /> )} {!device.isCurrent && ( { setDeviceToRemove(device); setRemoveDialogOpen(true); }} color="error" > )}
))}
{devices.length > 1 && ( )} )}
{/* Remove Device Dialog */} setRemoveDialogOpen(false)} maxWidth="sm" fullWidth> Remove Device? This will completely remove the device. All sessions from this device will be terminated. {deviceToRemove && ( Device: {deviceToRemove.deviceFingerprint} Platform: {deviceToRemove.platform || 'Unknown'} Last seen: {formatDistanceToNow(new Date(deviceToRemove.lastSeen))} ago )} {/* Remove All Devices Dialog */} setRemoveAllDialogOpen(false)} maxWidth="sm" fullWidth> Remove All Other Devices? This will remove all devices except your current one. All other sessions will be terminated. You are about to remove {devices.filter((d) => !d.isCurrent).length} device(s). ); }