Add password reset functionality for admin users: implement ResetPassword endpoint, update AdminUserEndpoints to include password reset logic, and enhance user interface for password management. Update translations for new features and ensure proper error handling in the reset process.

This commit is contained in:
Leonid Pershin
2026-07-25 19:49:08 +03:00
parent d44aa44d95
commit 1f6fa6f1ae
30 changed files with 1755 additions and 58 deletions
@@ -6,6 +6,7 @@ import { HttpError } from '@/shared/api/client'
import type { MediaAssetDto, MediaAssetStatus } from '@/shared/api/types'
import { Badge, type BadgeProps } from '@/shared/ui/badge'
import { Button } from '@/shared/ui/button'
import { Pager } from '@/shared/ui/pager'
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/shared/ui/select'
import { toast } from '@/shared/ui/toast-store'
import { deleteMedia, listMedia } from './api'
@@ -46,12 +47,13 @@ export function MediaPanel() {
const fileInput = useRef<HTMLInputElement>(null)
const fileInputShow = useRef<HTMLInputElement>(null)
const [filter, setFilter] = useState<MediaFilter>('active')
const [page, setPage] = useState(1)
const [filesForShow, setFilesForShow] = useState<File[] | null>(null)
const enqueue = useUploadStore((s) => s.enqueue)
const { data, isLoading } = useQuery({
queryKey: ['admin', 'media', filter],
queryFn: () => listMedia({ page: 1, pageSize: PAGE_SIZE, statuses: filterStatuses[filter] }),
queryKey: ['admin', 'media', filter, page],
queryFn: () => listMedia({ page, pageSize: PAGE_SIZE, statuses: filterStatuses[filter] }),
// Пока что-то обрабатывается — обновляем чаще, чтобы статус ехал в UI.
refetchInterval: (query) =>
query.state.data?.items.some((a) => a.status === 'Processing' || a.status === 'Pending')
@@ -70,7 +72,13 @@ export function MediaPanel() {
<div className="flex flex-wrap items-center justify-between gap-2">
<div className="flex items-center gap-3">
<h2 className="crt-glow text-xl font-semibold">{t('admin.media.title')}</h2>
<Select value={filter} onValueChange={(v) => setFilter(v as MediaFilter)}>
<Select
value={filter}
onValueChange={(v) => {
setPage(1)
setFilter(v as MediaFilter)
}}
>
<SelectTrigger className="w-40">
<SelectValue />
</SelectTrigger>
@@ -158,6 +166,12 @@ export function MediaPanel() {
</tbody>
</table>
</div>
<Pager
page={page}
totalPages={data ? Math.max(1, Math.ceil(data.total / PAGE_SIZE)) : 1}
onChange={setPage}
/>
</div>
)
}