Comprehensive platform audit: security, UX, performance, and visual polish
Phase 1: Security - status transition validation, Zod tightening, DB indexes, transactions Phase 2: Admin UX - search/filter for awards, learning, partners pages Phase 3: Dashboard - Recent Activity feed, Pending Actions card, quick actions Phase 4: Jury - assignments progress/urgency, autosave indicator, divergence highlighting Phase 5: Portals - observer charts, mentor search, login/onboarding polish Phase 6: Messages preview dialog, CsvExportDialog with column selection Phase 7: Performance - query optimizations, loading skeletons, useDebounce hook Phase 8: Visual - AnimatedCard, hover effects, StatusBadge, empty state CTAs Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -28,7 +28,7 @@ import { UserAvatar } from '@/components/shared/user-avatar'
|
||||
import { UserActions, UserMobileActions } from '@/components/admin/user-actions'
|
||||
import { Pagination } from '@/components/shared/pagination'
|
||||
import { Plus, Users, Search } from 'lucide-react'
|
||||
import { formatDate } from '@/lib/utils'
|
||||
import { formatRelativeTime } from '@/lib/utils'
|
||||
type RoleValue = 'SUPER_ADMIN' | 'PROGRAM_ADMIN' | 'JURY_MEMBER' | 'MENTOR' | 'OBSERVER'
|
||||
|
||||
type TabKey = 'all' | 'jury' | 'mentors' | 'observers' | 'admins'
|
||||
@@ -221,7 +221,9 @@ export function MembersContent() {
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
{user.lastLoginAt ? (
|
||||
formatDate(user.lastLoginAt)
|
||||
<span title={new Date(user.lastLoginAt).toLocaleString()}>
|
||||
{formatRelativeTime(user.lastLoginAt)}
|
||||
</span>
|
||||
) : (
|
||||
<span className="text-muted-foreground">Never</span>
|
||||
)}
|
||||
@@ -280,6 +282,16 @@ export function MembersContent() {
|
||||
: `${(user as unknown as { _count: { mentorAssignments: number; assignments: number } })._count.assignments} assigned`}
|
||||
</span>
|
||||
</div>
|
||||
<div className="flex items-center justify-between text-sm">
|
||||
<span className="text-muted-foreground">Last Login</span>
|
||||
<span>
|
||||
{user.lastLoginAt ? (
|
||||
formatRelativeTime(user.lastLoginAt)
|
||||
) : (
|
||||
<span className="text-muted-foreground">Never</span>
|
||||
)}
|
||||
</span>
|
||||
</div>
|
||||
{user.expertiseTags && user.expertiseTags.length > 0 && (
|
||||
<div className="flex flex-wrap gap-1">
|
||||
{user.expertiseTags.map((tag) => (
|
||||
|
||||
Reference in New Issue
Block a user