fix: UserManagementPage delete error feedback, input disable, date guard
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -47,7 +47,8 @@ const tdStyle = {
|
|||||||
|
|
||||||
const formatDate = (dateStr) => {
|
const formatDate = (dateStr) => {
|
||||||
if (!dateStr) return '—';
|
if (!dateStr) return '—';
|
||||||
return new Date(dateStr).toLocaleDateString('ru-RU');
|
const d = new Date(dateStr);
|
||||||
|
return isNaN(d) ? '—' : d.toLocaleDateString('ru-RU');
|
||||||
};
|
};
|
||||||
|
|
||||||
const UserManagementPage = () => {
|
const UserManagementPage = () => {
|
||||||
@@ -59,6 +60,7 @@ const UserManagementPage = () => {
|
|||||||
|
|
||||||
const [confirmDeleteId, setConfirmDeleteId] = useState(null);
|
const [confirmDeleteId, setConfirmDeleteId] = useState(null);
|
||||||
const [deleting, setDeleting] = useState(false);
|
const [deleting, setDeleting] = useState(false);
|
||||||
|
const [deleteError, setDeleteError] = useState('');
|
||||||
|
|
||||||
const handleInvite = async (e) => {
|
const handleInvite = async (e) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
@@ -76,13 +78,14 @@ const UserManagementPage = () => {
|
|||||||
|
|
||||||
const handleDeleteConfirm = async (userId) => {
|
const handleDeleteConfirm = async (userId) => {
|
||||||
setDeleting(true);
|
setDeleting(true);
|
||||||
|
setDeleteError('');
|
||||||
try {
|
try {
|
||||||
await deleteUser(userId);
|
await deleteUser(userId);
|
||||||
} catch {
|
|
||||||
// deletion errors surface in the hook's error state
|
|
||||||
} finally {
|
|
||||||
setDeleting(false);
|
setDeleting(false);
|
||||||
setConfirmDeleteId(null);
|
setConfirmDeleteId(null);
|
||||||
|
} catch (err) {
|
||||||
|
setDeleting(false);
|
||||||
|
setDeleteError(err?.message ?? 'Ошибка удаления');
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -128,6 +131,7 @@ const UserManagementPage = () => {
|
|||||||
value={inviteEmail}
|
value={inviteEmail}
|
||||||
onChange={(e) => setInviteEmail(e.target.value)}
|
onChange={(e) => setInviteEmail(e.target.value)}
|
||||||
required
|
required
|
||||||
|
disabled={inviting}
|
||||||
style={inputStyle}
|
style={inputStyle}
|
||||||
/>
|
/>
|
||||||
<button
|
<button
|
||||||
@@ -191,6 +195,7 @@ const UserManagementPage = () => {
|
|||||||
<td style={tdStyle}>{formatDate(user.last_sign_in_at)}</td>
|
<td style={tdStyle}>{formatDate(user.last_sign_in_at)}</td>
|
||||||
<td style={{ ...tdStyle, textAlign: 'right', whiteSpace: 'nowrap' }}>
|
<td style={{ ...tdStyle, textAlign: 'right', whiteSpace: 'nowrap' }}>
|
||||||
{confirmDeleteId === user.id ? (
|
{confirmDeleteId === user.id ? (
|
||||||
|
<span style={{ display: 'inline-flex', flexDirection: 'column', alignItems: 'flex-end', gap: '4px' }}>
|
||||||
<span style={{ display: 'inline-flex', alignItems: 'center', gap: '8px' }}>
|
<span style={{ display: 'inline-flex', alignItems: 'center', gap: '8px' }}>
|
||||||
<span style={{ fontSize: '0.82rem', color: 'var(--text-muted)' }}>
|
<span style={{ fontSize: '0.82rem', color: 'var(--text-muted)' }}>
|
||||||
Вы уверены?
|
Вы уверены?
|
||||||
@@ -214,7 +219,7 @@ const UserManagementPage = () => {
|
|||||||
Удалить
|
Удалить
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
onClick={() => setConfirmDeleteId(null)}
|
onClick={() => { setConfirmDeleteId(null); setDeleteError(''); }}
|
||||||
disabled={deleting}
|
disabled={deleting}
|
||||||
style={{
|
style={{
|
||||||
padding: '4px 10px',
|
padding: '4px 10px',
|
||||||
@@ -231,6 +236,12 @@ const UserManagementPage = () => {
|
|||||||
Отмена
|
Отмена
|
||||||
</button>
|
</button>
|
||||||
</span>
|
</span>
|
||||||
|
{deleteError && (
|
||||||
|
<span style={{ fontSize: '0.78rem', color: '#ef4444' }}>
|
||||||
|
{deleteError}
|
||||||
|
</span>
|
||||||
|
)}
|
||||||
|
</span>
|
||||||
) : (
|
) : (
|
||||||
<button
|
<button
|
||||||
onClick={() => setConfirmDeleteId(user.id)}
|
onClick={() => setConfirmDeleteId(user.id)}
|
||||||
|
|||||||
Reference in New Issue
Block a user