feat: router.back() navigation, read-only evaluation view, auth audit logging
All checks were successful
Build and Push Docker Image / build (push) Successful in 7m53s

- Convert all Back buttons platform-wide (38 files) to use router.back()
  for natural browser-back behavior regardless of entry point
- Add read-only view for submitted evaluations in closed rounds with
  blue banner, disabled inputs, and contextual back navigation
- Add auth audit logs: MAGIC_LINK_SENT, PASSWORD_RESET_LINK_CLICKED,
  PASSWORD_RESET_LINK_EXPIRED, PASSWORD_RESET_LINK_INVALID
- Learning Hub links navigate in same window for all roles
- Update settings descriptions to reflect all-user scope

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-06 14:25:56 +01:00
parent a556732b46
commit a1e758bc39
44 changed files with 398 additions and 384 deletions

View File

@@ -2,6 +2,7 @@
import Link from 'next/link'
import type { Route } from 'next'
import { useRouter } from 'next/navigation'
import { trpc } from '@/lib/trpc/client'
import {
Card,
@@ -43,6 +44,7 @@ import {
import { cn, formatDate, formatDateOnly } from '@/lib/utils'
export function ObserverProjectDetail({ projectId }: { projectId: string }) {
const router = useRouter()
const { data, isLoading } = trpc.analytics.getProjectDetail.useQuery(
{ id: projectId },
{ refetchInterval: 30_000 },
@@ -78,8 +80,8 @@ export function ObserverProjectDetail({ projectId }: { projectId: string }) {
<CardContent className="flex flex-col items-center justify-center py-12 text-center">
<AlertCircle className="h-12 w-12 text-destructive/50" />
<p className="mt-2 font-medium">Project Not Found</p>
<Button asChild className="mt-4">
<Link href={'/observer' as Route}>Back to Dashboard</Link>
<Button className="mt-4" onClick={() => router.back()}>
Back
</Button>
</CardContent>
</Card>
@@ -152,11 +154,9 @@ export function ObserverProjectDetail({ projectId }: { projectId: string }) {
return (
<div className="space-y-6">
{/* Back button */}
<Button variant="ghost" size="sm" className="gap-1.5 -ml-2 text-muted-foreground" asChild>
<Link href={'/observer/projects' as Route}>
<ArrowLeft className="h-3.5 w-3.5" />
Back to Projects
</Link>
<Button variant="ghost" size="sm" className="gap-1.5 -ml-2 text-muted-foreground" onClick={() => router.back()}>
<ArrowLeft className="h-3.5 w-3.5" />
Back
</Button>
{/* Project Header */}