feat: member profile pages with clickable links from all member lists
All checks were successful
Build and Push Docker Image / build (push) Successful in 8m51s
All checks were successful
Build and Push Docker Image / build (push) Successful in 8m51s
- Member detail page (/admin/members/[id]) now shows: - Profile details card (nationality, country, institution, bio) - Team memberships / projects with links to project pages - Jury groups with role (Chair/Member/Observer) - All roles including Applicant, Award Master, Audience in role selector - Project detail page team members now show: - Nationality, institution, country inline - Names are clickable links to member profile pages - Members list: names are clickable links to profile pages (all tabs) - Applicants tab: added nationality and institution columns - Backend: user.get includes teamMemberships and juryGroupMemberships - Backend: project.getFullDetail includes nationality/country/institution Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -354,19 +354,19 @@ export function MembersContent() {
|
||||
/>
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
<div className="flex items-center gap-3">
|
||||
<Link href={`/admin/members/${user.id}`} className="flex items-center gap-3 hover:opacity-80">
|
||||
<UserAvatar
|
||||
user={user}
|
||||
avatarUrl={(user as Record<string, unknown>).avatarUrl as string | undefined}
|
||||
size="sm"
|
||||
/>
|
||||
<div>
|
||||
<p className="font-medium">{user.name || 'Unnamed'}</p>
|
||||
<p className="font-medium hover:underline">{user.name || 'Unnamed'}</p>
|
||||
<p className="text-sm text-muted-foreground">
|
||||
{user.email}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</Link>
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
<div className="flex flex-wrap gap-1">
|
||||
@@ -460,14 +460,14 @@ export function MembersContent() {
|
||||
avatarUrl={(user as Record<string, unknown>).avatarUrl as string | undefined}
|
||||
size="md"
|
||||
/>
|
||||
<div>
|
||||
<CardTitle className="text-base">
|
||||
<Link href={`/admin/members/${user.id}`}>
|
||||
<CardTitle className="text-base hover:underline">
|
||||
{user.name || 'Unnamed'}
|
||||
</CardTitle>
|
||||
<CardDescription className="text-xs">
|
||||
{user.email}
|
||||
</CardDescription>
|
||||
</div>
|
||||
</Link>
|
||||
</div>
|
||||
<div className="flex flex-col items-end gap-1.5">
|
||||
<Badge variant={statusColors[user.status] || 'secondary'}>
|
||||
@@ -695,6 +695,8 @@ function ApplicantsTabContent({ search, searchInput, setSearchInput }: { search:
|
||||
</TableHead>
|
||||
<TableHead>Applicant</TableHead>
|
||||
<TableHead>Project</TableHead>
|
||||
<TableHead>Nationality</TableHead>
|
||||
<TableHead>Institution</TableHead>
|
||||
<TableHead>Status</TableHead>
|
||||
<TableHead>Last Login</TableHead>
|
||||
</TableRow>
|
||||
@@ -709,10 +711,10 @@ function ApplicantsTabContent({ search, searchInput, setSearchInput }: { search:
|
||||
/>
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
<div>
|
||||
<p className="font-medium">{user.name || 'Unnamed'}</p>
|
||||
<Link href={`/admin/members/${user.id}`} className="block">
|
||||
<p className="font-medium hover:underline">{user.name || 'Unnamed'}</p>
|
||||
<p className="text-sm text-muted-foreground">{user.email}</p>
|
||||
</div>
|
||||
</Link>
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
{user.projectName ? (
|
||||
@@ -721,6 +723,12 @@ function ApplicantsTabContent({ search, searchInput, setSearchInput }: { search:
|
||||
<span className="text-sm text-muted-foreground">-</span>
|
||||
)}
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
<span className="text-sm">{user.nationality || <span className="text-muted-foreground">-</span>}</span>
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
<span className="text-sm">{user.institution || <span className="text-muted-foreground">-</span>}</span>
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
<div className="flex items-center gap-2">
|
||||
<Badge variant={statusColors[user.status] || 'secondary'}>
|
||||
|
||||
Reference in New Issue
Block a user