fix: implement comprehensive UI/UX and code organization improvements

CSRF Form Enhancements:
- Add optional onError callback prop for better error handling
- Remove CSRF token from console logging for security
- Provide user-friendly error notifications instead of silent failures

Date Filter Optimization:
- Refactor sessions route to avoid object mutation issues
- Build date filters cleanly without relying on spreading existing objects
- Prevent potential undefined startTime mutations

Geographic Threat Map Optimization:
- Extract country names to reusable constants in lib/constants/countries.ts
- Calculate max values once to avoid repeated expensive operations
- Centralize threat level color mapping to eliminate duplicated logic
- Replace repeated color assignments with centralized THREAT_LEVELS configuration

Accessibility Improvements:
- Add keyboard support to audit log table rows (Enter/Space keys)
- Include proper ARIA labels and focus management
- Add tabIndex for screen reader compatibility
- Enhance focus indicators with ring styling

Performance & Code Organization:
- Move COUNTRY_NAMES to shared constants for reusability
- Optimize calculation patterns in threat mapping components
- Reduce redundant logic and improve maintainability
This commit is contained in:
2025-07-13 16:32:57 +02:00
parent efe0a3f79c
commit 33981b87dd
5 changed files with 143 additions and 112 deletions

View File

@ -41,19 +41,20 @@ function buildWhereClause(
}
// Date Range Filter
const dateFilters: { gte?: Date; lt?: Date } = {};
if (startDate) {
whereClause.startTime = {
...((whereClause.startTime as object) || {}),
gte: new Date(startDate),
};
dateFilters.gte = new Date(startDate);
}
if (endDate) {
const inclusiveEndDate = new Date(endDate);
inclusiveEndDate.setDate(inclusiveEndDate.getDate() + 1);
whereClause.startTime = {
...((whereClause.startTime as object) || {}),
lt: inclusiveEndDate,
};
dateFilters.lt = inclusiveEndDate;
}
if (Object.keys(dateFilters).length > 0) {
whereClause.startTime = dateFilters;
}
return whereClause;

View File

@ -367,8 +367,16 @@ export default function AuditLogsPage() {
{auditLogs.map((log) => (
<TableRow
key={log.id}
className="cursor-pointer hover:bg-gray-50"
className="cursor-pointer hover:bg-gray-50 focus:bg-gray-100 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-inset"
onClick={() => setSelectedLog(log)}
onKeyDown={(e) => {
if (e.key === "Enter" || e.key === " ") {
e.preventDefault();
setSelectedLog(log);
}
}}
tabIndex={0}
aria-label={`View details for ${eventTypeLabels[log.eventType] || log.eventType} event`}
>
<TableCell className="font-mono text-sm">
{formatDistanceToNow(new Date(log.timestamp), {