feat: implement user profile pages with comment avatar links

Added user profile feature allowing authenticated users to view profiles of other users. Key changes:

**New Routes:**
- `/users/[id]/+page.server.ts` - Server-side load function with authentication guard and user data fetching
- `/users/[id]/+page.svelte` - User profile UI component displaying avatar, stats, and bio

**Features:**
- Authentication required - redirects to /login if not authenticated
- Shows user display name (first_name + last_name or email fallback)
- Displays join date, location, and description
- Statistics: comments count and likes count
- "Edit Profile" button visible only for own profile (links to /me)
- Responsive layout with avatar placeholder for users without profile images

**Comment Integration:**
- Updated video comment section to link user avatars to their profiles
- Added hover effects on avatars (ring-primary/40 transition)
- Username in comments now clickable and links to `/users/[id]`

**Translations:**
- Added `profile` section to en.ts locales with:
  - member_since: "Member since {date}"
  - comments: "Comments"
  - likes: "Likes"
  - edit: "Edit Profile"
  - activity: "Activity"

**Design:**
- Simplified layout (no cover banner) compared to model profiles
- Peony background with card-based UI
- Primary color theme with gradient accents
- Consistent with existing site design patterns

This creates a clear distinction between:
- Model profiles (`/models/[slug]`) - public, content-focused
- User profiles (`/users/[id]`) - authenticated only, viewer-focused

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Valknar XXX
2025-10-28 12:54:45 +01:00
parent 9503f8d0aa
commit 74e68c32dc
4 changed files with 212 additions and 17 deletions

View File

@@ -442,26 +442,28 @@ let showPlayer = $state(false);
<div class="space-y-4">
{#each data.comments as comment}
<div class="flex gap-3">
<Avatar
class="h-8 w-8 ring-2 ring-accent/20 transition-all duration-200"
>
<AvatarImage
src={getAssetUrl(
comment.user_created.avatar as string,
'mini'
)}
alt={comment.user_created.artist_name}
/>
<AvatarFallback
class="bg-gradient-to-br from-primary to-accent text-primary-foreground text-xs font-semibold transition-all duration-200"
<a href="/users/{comment.user_created.id}" class="flex-shrink-0">
<Avatar
class="h-8 w-8 ring-2 ring-accent/20 hover:ring-primary/40 transition-all duration-200 cursor-pointer"
>
{getUserInitials(data.authStatus.user!.artist_name)}
</AvatarFallback>
</Avatar>
<AvatarImage
src={getAssetUrl(
comment.user_created.avatar as string,
'mini'
)}
alt={comment.user_created.artist_name}
/>
<AvatarFallback
class="bg-gradient-to-br from-primary to-accent text-primary-foreground text-xs font-semibold transition-all duration-200"
>
{getUserInitials(comment.user_created.artist_name)}
</AvatarFallback>
</Avatar>
</a>
<div class="flex-1">
<div class="flex items-center gap-2 mb-1">
<span class="font-medium text-sm"
>{comment.user_created.artist_name}</span
<a href="/users/{comment.user_created.id}" class="font-medium text-sm hover:text-primary transition-colors"
>{comment.user_created.artist_name}</a
>
<span class="text-xs text-muted-foreground"
>{timeAgo.format(