image scanning and asset edit

This commit is contained in:
2026-07-14 14:20:24 +05:30
parent 8c6c26bc8e
commit 08307119da
4 changed files with 180 additions and 12 deletions

View File

@@ -5,7 +5,7 @@ import {
ToggleButton, Button, CircularProgress, TablePagination, Typography, Chip, Tooltip,
} from '@mui/material';
import { adminService } from '../../api/adminService';
import type { MissingMediaRecord, MissingMediaSummary } from '../../api/adminService';
import type { MissingMediaRecord, MissingMediaSummary, MissingMediaFilter } from '../../api/adminService';
import { accountService } from '../../api/accountService';
import { useToastStore } from '../../store/toastStore';
@@ -27,6 +27,7 @@ export const MissingMedia: React.FC = () => {
const [organizations, setOrganizations] = useState<Organization[]>([]);
const [dbName, setDbName] = useState('');
const [type, setType] = useState<'audits' | 'rectification'>('audits');
const [missing, setMissing] = useState<'all' | MissingMediaFilter>('all');
const [records, setRecords] = useState<MissingMediaRecord[]>([]);
const [summary, setSummary] = useState<MissingMediaSummary | null>(null);
const [total, setTotal] = useState(0);
@@ -53,23 +54,27 @@ export const MissingMedia: React.FC = () => {
try {
const result = await adminService.getMissingMedia({
dbName, type, limit: PAGE_SIZE, offset: page * PAGE_SIZE,
...(missing !== 'all' ? { missing } : {}),
});
setRecords(result.records);
setTotal(result.total);
setSummary(result.summary);
// A recheck under an active filter can shrink the filtered total below
// the current page - snap back instead of stranding on an empty page.
if (page > 0 && result.total <= page * PAGE_SIZE) setPage(0);
} catch {
useToastStore.getState().showToast('Failed to load missing-media records.', 'error');
} finally {
setLoading(false);
}
}, [dbName, type, page]);
}, [dbName, type, page, missing]);
useEffect(() => { load(); }, [load]);
useEffect(() => {
setPage(0);
setSelectedIds(new Set());
}, [dbName, type]);
}, [dbName, type, missing]);
const toggleRow = (id: number) => {
setSelectedIds((prev) => {
@@ -119,6 +124,13 @@ export const MissingMedia: React.FC = () => {
<ToggleButton value="rectification">Rectification</ToggleButton>
</ToggleButtonGroup>
<ToggleButtonGroup value={missing} exclusive onChange={(_, v) => v && setMissing(v)} size="small">
<ToggleButton value="all">All</ToggleButton>
<ToggleButton value="image">Image missing</ToggleButton>
<ToggleButton value="video">Video missing</ToggleButton>
<ToggleButton value="both">Both missing</ToggleButton>
</ToggleButtonGroup>
<Button
variant="contained"
disabled={selectedIds.size === 0 || selectedIds.size > 50 || rechecking}
@@ -136,6 +148,7 @@ export const MissingMedia: React.FC = () => {
{summaryChip('Not checked yet', summary?.neverChecked, 'default')}
{summaryChip('Image missing', summary?.missingImage, 'error')}
{summaryChip('Video missing', summary?.missingVideo, 'warning')}
{summaryChip('Both missing', summary?.missingBoth, 'error')}
{summaryChip('Gave up (24h of retries)', summary?.gaveUp, 'info')}
</Box>
@@ -167,7 +180,9 @@ export const MissingMedia: React.FC = () => {
{records.length === 0 && (
<TableRow>
<TableCell colSpan={9} align="center" sx={{ color: 'text.secondary' }}>
No pending records with missing media everything is auditable. 🎉
{missing !== 'all'
? 'No records match this filter.'
: 'No pending records with missing media — everything is auditable. 🎉'}
</TableCell>
</TableRow>
)}