feat: implement activity feed module with dynamic filtering, state management, and asset selection components

This commit is contained in:
2026-06-22 12:47:01 +05:30
parent 0a35bba378
commit 514a656fa8
11 changed files with 505 additions and 150 deletions

View File

@@ -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>