fix: enforce read-only restrictions for viewer role across 5 pages

Audit and fix viewer (read-only) user permissions:
- Dashboard: hide health score refresh buttons
- Accounts: hide investment edit icons
- Invoices: hide Apply Late Fees and Generate Invoices buttons
- Capital Planning: disable drag-and-drop, hide grip handles and edit buttons
- Investment Planning: hide AI Recommendations refresh button

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-09 09:59:20 -04:00
parent 3bf6b8c6c9
commit 9d137a40d3
5 changed files with 60 additions and 42 deletions

View File

@@ -18,7 +18,7 @@ import {
} from '@tabler/icons-react';
import { useState, useCallback } from 'react';
import { useQuery, useQueryClient } from '@tanstack/react-query';
import { useAuthStore } from '../../stores/authStore';
import { useAuthStore, useIsReadOnly } from '../../stores/authStore';
import api from '../../services/api';
interface HealthScore {
@@ -311,6 +311,7 @@ interface DashboardData {
export function DashboardPage() {
const currentOrg = useAuthStore((s) => s.currentOrg);
const isReadOnly = useIsReadOnly();
const queryClient = useQueryClient();
// Track whether a refresh is in progress (per score type) for async polling
@@ -424,7 +425,7 @@ export function DashboardPage() {
</ThemeIcon>
}
isRefreshing={operatingRefreshing}
onRefresh={handleRefreshOperating}
onRefresh={!isReadOnly ? handleRefreshOperating : undefined}
lastFailed={!!healthScores?.operating_last_failed}
/>
<HealthScoreCard
@@ -436,7 +437,7 @@ export function DashboardPage() {
</ThemeIcon>
}
isRefreshing={reserveRefreshing}
onRefresh={handleRefreshReserve}
onRefresh={!isReadOnly ? handleRefreshReserve : undefined}
lastFailed={!!healthScores?.reserve_last_failed}
/>
</SimpleGrid>