mirror of
https://github.com/Sea-Haven-Industries/proposal-system.git
synced 2026-10-03 12:43:17 +00:00
Add role-aware dashboard stats and recent proposals
GetStatsAsync now returns global counts for admins/sysadmins instead of filtering by submitter. Dashboard recent proposals query uses mine=false for admins so they see all proposals, not just their own.
This commit is contained in:
parent
edb557fb23
commit
ef052a81ac
2 changed files with 12 additions and 7 deletions
|
|
@ -376,10 +376,12 @@ public class ProposalService : IProposalService
|
||||||
|
|
||||||
public async Task<ProposalStatsResponse> GetStatsAsync(CancellationToken ct = default)
|
public async Task<ProposalStatsResponse> GetStatsAsync(CancellationToken ct = default)
|
||||||
{
|
{
|
||||||
var userId = _currentUser.UserId;
|
var query = _db.Proposals.AsQueryable();
|
||||||
|
|
||||||
var counts = await _db.Proposals
|
if (_currentUser.Role == UserRole.Dispatcher)
|
||||||
.Where(p => p.SubmittedById == userId)
|
query = query.Where(p => p.SubmittedById == _currentUser.UserId);
|
||||||
|
|
||||||
|
var counts = await query
|
||||||
.GroupBy(_ => 1)
|
.GroupBy(_ => 1)
|
||||||
.Select(g => new
|
.Select(g => new
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -24,8 +24,9 @@ import SendIcon from '@mui/icons-material/Send';
|
||||||
import { proposalsApi, type ProposalListItem, type ProposalStats } from '../../lib/api/proposals';
|
import { proposalsApi, type ProposalListItem, type ProposalStats } from '../../lib/api/proposals';
|
||||||
import { QUERY_KEYS } from '../../constants/queryKeys';
|
import { QUERY_KEYS } from '../../constants/queryKeys';
|
||||||
import { STATUS_COLORS, STATUS_LABELS, PRIORITY_ROW_SX } from '../../constants';
|
import { STATUS_COLORS, STATUS_LABELS, PRIORITY_ROW_SX } from '../../constants';
|
||||||
import { formatCurrency, formatDate } from '../../lib/format';
|
import { formatBidAmount, formatDate } from '../../lib/format';
|
||||||
import { useDocumentTitle } from '../../hooks/useDocumentTitle';
|
import { useDocumentTitle } from '../../hooks/useDocumentTitle';
|
||||||
|
import { useAuth } from '../../hooks/useAuth';
|
||||||
|
|
||||||
function KpiCard({ icon, label, value }: { icon: React.ReactNode; label: string; value: string }) {
|
function KpiCard({ icon, label, value }: { icon: React.ReactNode; label: string; value: string }) {
|
||||||
return (
|
return (
|
||||||
|
|
@ -46,10 +47,12 @@ function KpiCard({ icon, label, value }: { icon: React.ReactNode; label: string;
|
||||||
export default function Dashboard() {
|
export default function Dashboard() {
|
||||||
useDocumentTitle('Dashboard');
|
useDocumentTitle('Dashboard');
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
|
const { user } = useAuth();
|
||||||
|
const isAdmin = user?.role === 'Admin' || user?.role === 'SysAdmin';
|
||||||
|
|
||||||
const { data: recentData, isLoading: recentLoading, error: recentError } = useQuery<{ items: ProposalListItem[]; totalCount: number }>({
|
const { data: recentData, isLoading: recentLoading, error: recentError } = useQuery<{ items: ProposalListItem[]; totalCount: number }>({
|
||||||
queryKey: [QUERY_KEYS.proposals, 'dashboard-recent'],
|
queryKey: [QUERY_KEYS.proposals, 'dashboard-recent', isAdmin],
|
||||||
queryFn: () => proposalsApi.getAll({ page: 1, pageSize: 5, mine: true }),
|
queryFn: () => proposalsApi.getAll({ page: 1, pageSize: 5, mine: !isAdmin }),
|
||||||
});
|
});
|
||||||
|
|
||||||
const { data: stats, isLoading: statsLoading } = useQuery<ProposalStats>({
|
const { data: stats, isLoading: statsLoading } = useQuery<ProposalStats>({
|
||||||
|
|
@ -153,7 +156,7 @@ export default function Dashboard() {
|
||||||
<TableCell>
|
<TableCell>
|
||||||
<Chip label={STATUS_LABELS[row.status] || row.status} size="small" color={STATUS_COLORS[row.status] || 'default'} />
|
<Chip label={STATUS_LABELS[row.status] || row.status} size="small" color={STATUS_COLORS[row.status] || 'default'} />
|
||||||
</TableCell>
|
</TableCell>
|
||||||
<TableCell align="right">{formatCurrency(row.totalBidAmount)}</TableCell>
|
<TableCell align="right">{formatBidAmount(row.totalBidAmount)}</TableCell>
|
||||||
<TableCell>{formatDate(row.submittedAt)}</TableCell>
|
<TableCell>{formatDate(row.submittedAt)}</TableCell>
|
||||||
</TableRow>
|
</TableRow>
|
||||||
))}
|
))}
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue