diff --git a/dist/index.html b/dist/index.html index f80dc07..e458783 100644 --- a/dist/index.html +++ b/dist/index.html @@ -6,8 +6,8 @@ Todo App - - + +
diff --git a/src/lib/api.ts b/src/lib/api.ts index 95e218a..f11e1e6 100644 --- a/src/lib/api.ts +++ b/src/lib/api.ts @@ -246,6 +246,13 @@ class ApiClient { }); } + async resetUserPassword(id: string, newPassword: string): Promise { + await this.fetch(`/admin/users/${id}/reset-password`, { + method: 'POST', + body: JSON.stringify({ newPassword }), + }); + } + async deleteUser(id: string): Promise { await this.fetch(`/admin/users/${id}`, { method: 'DELETE' }); } diff --git a/src/pages/Admin.tsx b/src/pages/Admin.tsx index 96a0c98..c9329ac 100644 --- a/src/pages/Admin.tsx +++ b/src/pages/Admin.tsx @@ -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(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()} - {user.id !== currentUser?.id && user.role !== 'service' && ( - - )} +
+ {user.id !== currentUser?.id && ( + <> + {resetUserId === user.id ? ( +
+ {resetSuccess === user.id ? ( + ✓ Reset! + ) : ( + <> + 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(''); } + }} + /> + + + + )} +
+ ) : ( + + )} + {user.role !== 'service' && resetUserId !== user.id && ( + + )} + + )} +
))}