Add password reset for users in admin panel
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
import { useState, useEffect } from 'react';
|
||||
import { Users, Mail, Plus, Trash2, Copy, Check } from 'lucide-react';
|
||||
import { Users, Mail, Plus, Trash2, Copy, Check, KeyRound } from 'lucide-react';
|
||||
import { api } from '@/lib/api';
|
||||
import { useAuthStore } from '@/stores/auth';
|
||||
import type { User, Invite } from '@/types';
|
||||
@@ -70,6 +70,22 @@ export function AdminPage() {
|
||||
}
|
||||
};
|
||||
|
||||
const [resetUserId, setResetUserId] = useState<string | null>(null);
|
||||
const [newPassword, setNewPassword] = useState('');
|
||||
const [resetSuccess, setResetSuccess] = useState('');
|
||||
|
||||
const handleResetPassword = async (userId: string) => {
|
||||
if (!newPassword || newPassword.length < 8) return;
|
||||
try {
|
||||
await api.resetUserPassword(userId, newPassword);
|
||||
setResetSuccess(userId);
|
||||
setNewPassword('');
|
||||
setTimeout(() => { setResetSuccess(''); setResetUserId(null); }, 2000);
|
||||
} catch (error) {
|
||||
console.error('Failed to reset password:', error);
|
||||
}
|
||||
};
|
||||
|
||||
const handleDeleteUser = async (userId: string) => {
|
||||
if (!confirm('Are you sure you want to delete this user?')) return;
|
||||
|
||||
@@ -188,14 +204,64 @@ export function AdminPage() {
|
||||
{new Date(user.createdAt).toLocaleDateString()}
|
||||
</td>
|
||||
<td className="px-4 py-3">
|
||||
{user.id !== currentUser?.id && user.role !== 'service' && (
|
||||
<button
|
||||
onClick={() => handleDeleteUser(user.id)}
|
||||
className="p-1 text-gray-400 hover:text-red-500"
|
||||
>
|
||||
<Trash2 className="w-4 h-4" />
|
||||
</button>
|
||||
)}
|
||||
<div className="flex items-center gap-1">
|
||||
{user.id !== currentUser?.id && (
|
||||
<>
|
||||
{resetUserId === user.id ? (
|
||||
<div className="flex items-center gap-1">
|
||||
{resetSuccess === user.id ? (
|
||||
<span className="text-xs text-green-600">✓ Reset!</span>
|
||||
) : (
|
||||
<>
|
||||
<input
|
||||
type="text"
|
||||
value={newPassword}
|
||||
onChange={(e) => setNewPassword(e.target.value)}
|
||||
placeholder="New password (8+ chars)"
|
||||
className="text-xs border border-gray-200 rounded px-2 py-1 w-40"
|
||||
autoFocus
|
||||
onKeyDown={(e) => {
|
||||
if (e.key === 'Enter') handleResetPassword(user.id);
|
||||
if (e.key === 'Escape') { setResetUserId(null); setNewPassword(''); }
|
||||
}}
|
||||
/>
|
||||
<button
|
||||
onClick={() => handleResetPassword(user.id)}
|
||||
disabled={newPassword.length < 8}
|
||||
className="text-xs px-2 py-1 bg-blue-600 text-white rounded disabled:opacity-50"
|
||||
>
|
||||
Set
|
||||
</button>
|
||||
<button
|
||||
onClick={() => { setResetUserId(null); setNewPassword(''); }}
|
||||
className="text-xs px-1 py-1 text-gray-400 hover:text-gray-600"
|
||||
>
|
||||
✕
|
||||
</button>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
) : (
|
||||
<button
|
||||
onClick={() => setResetUserId(user.id)}
|
||||
className="p-1 text-gray-400 hover:text-blue-500"
|
||||
title="Reset password"
|
||||
>
|
||||
<KeyRound className="w-4 h-4" />
|
||||
</button>
|
||||
)}
|
||||
{user.role !== 'service' && resetUserId !== user.id && (
|
||||
<button
|
||||
onClick={() => handleDeleteUser(user.id)}
|
||||
className="p-1 text-gray-400 hover:text-red-500"
|
||||
title="Delete user"
|
||||
>
|
||||
<Trash2 className="w-4 h-4" />
|
||||
</button>
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
))}
|
||||
|
||||
Reference in New Issue
Block a user