mirror of
https://github.com/kikootwo/ReadMeABook.git
synced 2026-06-03 04:40:09 +00:00
Admin requests: paginated API & UI overhaul
Add a paginated Admin Requests API and fully refactor the admin requests UI to support filtering, sorting, pagination, and URL state. - New API: src/app/api/admin/requests/route.ts implements paginated, searchable, filterable, and sortable request listing with proper relation includes and pagination metadata. - Frontend: RecentRequestsTable rewritten to fetch via SWR (authenticatedFetcher), read/write URL query params, debounce search, support status/user filters, sortable columns, page size selector, and full pagination UI; added loading/error states and toast feedback for actions. - Admin page updated to use Suspense and the new RecentRequestsTable (component now fetches its own data). - Settings: deprecated single download-client PUT route now maps updates into the new multi-client format (download_clients JSON), logs deprecation, and invalidates download client manager; settings GET now reads multi-client config for backward compatibility. - Processors: monitor-download and retry-failed-imports updated to use the download-client-manager and new PathMappingConfig shape for path mapping logic. - Minor API/schema updates: request-with-torrent schema extended (indexerId, infoUrl, protocol) and setup complete no longer writes legacy path keys. - Tests updated to reflect API and processor changes. This change centralizes request management on the server, modernizes the UI for large datasets, and migrates download client settings toward a multi-client configuration while keeping backward compatibility.
This commit is contained in:
+19
-17
@@ -13,7 +13,7 @@ import { ActiveDownloadsTable } from './components/ActiveDownloadsTable';
|
||||
import { RecentRequestsTable } from './components/RecentRequestsTable';
|
||||
import { ToastProvider, useToast } from '@/components/ui/Toast';
|
||||
import { formatDistanceToNow } from 'date-fns';
|
||||
import { useState } from 'react';
|
||||
import { useState, Suspense } from 'react';
|
||||
|
||||
interface PendingApprovalRequest {
|
||||
id: string;
|
||||
@@ -303,13 +303,7 @@ function AdminDashboardContent() {
|
||||
}
|
||||
);
|
||||
|
||||
const { data: requestsData, error: requestsError } = useSWR(
|
||||
'/api/admin/requests/recent',
|
||||
authenticatedFetcher,
|
||||
{
|
||||
refreshInterval: 10000,
|
||||
}
|
||||
);
|
||||
// Note: RecentRequestsTable now fetches its own data with filtering/pagination
|
||||
|
||||
const { data: pendingApprovalData } = useSWR(
|
||||
'/api/admin/requests/pending-approval',
|
||||
@@ -327,8 +321,8 @@ function AdminDashboardContent() {
|
||||
}
|
||||
);
|
||||
|
||||
const isLoading = !metrics || !downloadsData || !requestsData;
|
||||
const hasError = metricsError || downloadsError || requestsError;
|
||||
const isLoading = !metrics || !downloadsData;
|
||||
const hasError = metricsError || downloadsError;
|
||||
|
||||
if (hasError) {
|
||||
return (
|
||||
@@ -341,7 +335,6 @@ function AdminDashboardContent() {
|
||||
<p className="text-sm text-red-700 dark:text-red-300 mt-1">
|
||||
{metricsError?.message ||
|
||||
downloadsError?.message ||
|
||||
requestsError?.message ||
|
||||
'Failed to load dashboard data'}
|
||||
</p>
|
||||
</div>
|
||||
@@ -490,15 +483,24 @@ function AdminDashboardContent() {
|
||||
<ActiveDownloadsTable downloads={downloadsData.downloads} />
|
||||
</div>
|
||||
|
||||
{/* Recent Requests */}
|
||||
{/* Request Management */}
|
||||
<div className="mb-8">
|
||||
<h2 className="text-xl font-bold text-gray-900 dark:text-gray-100 mb-4">
|
||||
Recent Requests
|
||||
Request Management
|
||||
</h2>
|
||||
<RecentRequestsTable
|
||||
requests={requestsData.requests}
|
||||
ebookSidecarEnabled={settingsData?.ebook?.enabled || false}
|
||||
/>
|
||||
<Suspense
|
||||
fallback={
|
||||
<div className="bg-white dark:bg-gray-800 rounded-lg border border-gray-200 dark:border-gray-700 p-8">
|
||||
<div className="flex items-center justify-center">
|
||||
<div className="animate-spin rounded-full h-8 w-8 border-b-2 border-blue-600"></div>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
>
|
||||
<RecentRequestsTable
|
||||
ebookSidecarEnabled={settingsData?.ebook?.enabled || false}
|
||||
/>
|
||||
</Suspense>
|
||||
</div>
|
||||
|
||||
{/* Quick Actions */}
|
||||
|
||||
Reference in New Issue
Block a user