feat: implement activity feed module with dynamic filtering, state management, and asset selection components
This commit is contained in:
@@ -1,7 +1,6 @@
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
import { Box, Typography, Button, Paper, LinearProgress } from '@mui/material';
|
||||
import WarningAmberIcon from '@mui/icons-material/WarningAmber';
|
||||
import { Box, Typography, Button, Paper } from '@mui/material';
|
||||
import { activityFeedsService } from '../../api/activityFeedsService';
|
||||
import { TopFilterBar } from '../../components/common/TopFilterBar';
|
||||
import { useFeedStore } from '../../store/feedStore';
|
||||
@@ -78,6 +77,7 @@ export const Dashboard: React.FC = () => {
|
||||
batchAudited: anomalies.filter((a: any) => a.IsAudited === 1).length,
|
||||
batchPending: anomalies.filter((a: any) => a.IsAudited === 0).length,
|
||||
batchAnomaliesFound: anomalies.filter((a: any) => a.Audit_status === 1).length,
|
||||
firstPendingIndex: anomalies.findIndex((a: any) => a.IsAudited === 0)
|
||||
};
|
||||
setStats(newStats);
|
||||
// Persist to store cache so re-mounting the Dashboard skips this fetch
|
||||
@@ -169,82 +169,19 @@ export const Dashboard: React.FC = () => {
|
||||
</Paper>
|
||||
</Box>
|
||||
|
||||
{/* Active Batch Progress */}
|
||||
<Paper sx={{ p: 3, bgcolor: '#0f172a', border: '1px solid #1e293b', borderRadius: 2, mb: 3 }}>
|
||||
<Box sx={{ display: 'flex', justifyContent: 'space-between', mb: 1 }}>
|
||||
<Typography variant="subtitle2" sx={{ fontWeight: 'bold', color: '#f8fafc' }}>Active Batch Progress</Typography>
|
||||
<Typography variant="body2" sx={{ color: '#94a3b8' }}>{stats.batchAudited} / {stats.batchTotal} completed</Typography>
|
||||
</Box>
|
||||
<LinearProgress
|
||||
variant="determinate"
|
||||
value={progressPercent}
|
||||
sx={{
|
||||
height: 10,
|
||||
borderRadius: 5,
|
||||
bgcolor: '#1e293b',
|
||||
'& .MuiLinearProgress-bar': { bgcolor: '#3b82f6', borderRadius: 5 }
|
||||
}}
|
||||
/>
|
||||
<Box sx={{ display: 'flex', justifyContent: 'space-between', mt: 1 }}>
|
||||
<Typography variant="caption" sx={{ color: '#64748b' }}>{progressPercent}% complete</Typography>
|
||||
<Typography variant="caption" sx={{ color: '#64748b' }}>~{Math.ceil(stats.batchPending / 50)} sessions remaining at 50/session</Typography>
|
||||
</Box>
|
||||
</Paper>
|
||||
|
||||
{/* Session Mechanics Explanation Box */}
|
||||
<Paper sx={{
|
||||
p: 3,
|
||||
bgcolor: 'rgba(30, 41, 59, 0.4)',
|
||||
border: '1px solid rgba(148, 163, 184, 0.1)',
|
||||
borderRadius: 3,
|
||||
mb: 3,
|
||||
backdropFilter: 'blur(8px)'
|
||||
}}>
|
||||
<Typography variant="subtitle2" sx={{ fontWeight: 'bold', color: '#60a5fa', mb: 2, textTransform: 'uppercase', letterSpacing: 0.5 }}>
|
||||
Audit Workflow & Session Mechanics
|
||||
</Typography>
|
||||
<Box sx={{ display: 'grid', gridTemplateColumns: { xs: '1fr', md: '1fr 1fr 1fr' }, gap: 2.5, mb: 1 }}>
|
||||
<Box>
|
||||
<Typography variant="caption" sx={{ color: '#94a3b8', display: 'block', mb: 0.5, fontWeight: 'bold' }}>
|
||||
1. GLOBAL SITE POOL
|
||||
</Typography>
|
||||
<Typography variant="body2" sx={{ color: '#f8fafc' }}>
|
||||
There are <b style={{ color: '#3b82f6' }}>{loading ? '...' : stats.globalTotal.toLocaleString()}</b> total items matching your active filter criteria on this site.
|
||||
</Typography>
|
||||
</Box>
|
||||
<Box>
|
||||
<Typography variant="caption" sx={{ color: '#94a3b8', display: 'block', mb: 0.5, fontWeight: 'bold' }}>
|
||||
2. ACTIVE WORK BATCH
|
||||
</Typography>
|
||||
<Typography variant="body2" sx={{ color: '#f8fafc' }}>
|
||||
An active queue of up to <b style={{ color: '#10b981' }}>{loading ? '...' : stats.batchTotal}</b> items is loaded into your immediate workspace for auditing.
|
||||
</Typography>
|
||||
</Box>
|
||||
<Box>
|
||||
<Typography variant="caption" sx={{ color: '#94a3b8', display: 'block', mb: 0.5, fontWeight: 'bold' }}>
|
||||
3. BITE-SIZED SESSIONS (50 items)
|
||||
</Typography>
|
||||
<Typography variant="body2" sx={{ color: '#f8fafc' }}>
|
||||
To keep image downloads fast and prevent browser lag, you audit in sessions of <b>50 items</b>.
|
||||
You have <b style={{ color: '#facc15' }}>~{loading ? '...' : Math.ceil(stats.batchPending / 50)} sessions</b> remaining.
|
||||
</Typography>
|
||||
</Box>
|
||||
</Box>
|
||||
</Paper>
|
||||
|
||||
{/* Warning Box */}
|
||||
<Paper sx={{ p: 2, px: 3, bgcolor: '#450a0a', border: '1px solid #7f1d1d', borderRadius: 2, mb: 4, display: 'flex', alignItems: 'center', gap: 1 }}>
|
||||
<WarningAmberIcon sx={{ color: '#ef4444', fontSize: 20 }} />
|
||||
<Typography variant="body1" sx={{ color: '#f8fafc' }}>
|
||||
<Typography component="span" sx={{ color: '#ef4444', fontWeight: 'bold' }}>Priority items</Typography> will appear first in the session queue
|
||||
</Typography>
|
||||
</Paper>
|
||||
|
||||
{/* Start Button */}
|
||||
<Button
|
||||
variant="contained"
|
||||
fullWidth
|
||||
onClick={() => navigate('/audit-session', { state: { isReviewMode: stats.batchPending === 0 } })}
|
||||
onClick={() => navigate('/audit-session', {
|
||||
state: {
|
||||
isReviewMode: stats.batchPending === 0,
|
||||
startPage: stats.firstPendingIndex !== undefined && stats.firstPendingIndex !== -1 ? Math.floor(stats.firstPendingIndex / 50) : 0
|
||||
}
|
||||
})}
|
||||
disabled={stats.batchTotal === 0}
|
||||
sx={{
|
||||
py: 2,
|
||||
@@ -264,10 +201,9 @@ export const Dashboard: React.FC = () => {
|
||||
: `Start Session — Audit Next ${Math.min(stats.batchPending, 50)} Items`}
|
||||
</Button>
|
||||
|
||||
{/* Footer links */}
|
||||
<Box sx={{ display: 'flex', justifyContent: 'space-between', mt: 2 }}>
|
||||
{/* Footer */}
|
||||
<Box sx={{ mt: 2 }}>
|
||||
<Typography variant="caption" sx={{ color: '#475569' }}>Keyboard shortcuts available inside the audit view</Typography>
|
||||
<Typography variant="caption" sx={{ color: '#64748b', textDecoration: 'underline', cursor: 'pointer', '&:hover': { color: '#f8fafc' } }}>Reset demo data</Typography>
|
||||
</Box>
|
||||
|
||||
</Box>
|
||||
|
||||
Reference in New Issue
Block a user