fix(forum): complete member profiles — counts, avatars, strip AI metadata

This commit is contained in:
2026-06-26 23:46:59 +00:00
parent 4acc068732
commit eb05918960
7 changed files with 133 additions and 81 deletions

View File

@@ -21,11 +21,17 @@ interface ForumCategory {
last_activity_at?: string | null;
}
function profileHref(thread: { author_username?: string | null; author_name: string }): string {
const slug = thread.author_username || thread.author_name;
return `/forum/user/${encodeURIComponent(slug)}`;
}
interface ForumThread {
id: string;
title: string;
author_id?: string | null;
author_name: string;
author_username?: string | null;
reply_count: number;
view_count: number;
last_reply_at: string;
@@ -175,7 +181,7 @@ function TopThreadsWidget({ categoryId }: { categoryId?: string }) {
{thread.title}
</p>
<p className="text-[#475569] font-body text-xs mt-0.5">
<Link href={`/forum/user/${encodeURIComponent(thread.author_name)}`} className="text-[#475569] hover:text-[#1D4ED8] hover:underline" onClick={(e) => e.stopPropagation()}>{thread.author_name}</Link>
<Link href={profileHref(thread)} className="text-[#475569] hover:text-[#1D4ED8] hover:underline" onClick={(e) => e.stopPropagation()}>{thread.author_name}</Link>
{thread.forum_categories && (
<> · <span className="text-[#1D4ED8]">{thread.forum_categories.name}</span></>
)}
@@ -407,7 +413,7 @@ export default function ForumIndexPage() {
<p className="text-[#666] font-body text-xs mt-0.5">
by{' '}
<Link
href={`/profile/${thread.author_id}`}
href={profileHref(thread)}
onClick={e => e.stopPropagation()}
className="text-[#1D4ED8] hover:underline"
>
@@ -530,7 +536,7 @@ export default function ForumIndexPage() {
{thread.title}
</h3>
<p className="text-[#666] font-body text-xs mt-0.5">
by <Link href={`/forum/user/${encodeURIComponent(thread.author_name)}`} className="text-[#888] hover:text-[#1D4ED8] hover:underline" onClick={(e) => e.stopPropagation()}>{thread.author_name}</Link>
by <Link href={profileHref(thread)} className="text-[#888] hover:text-[#1D4ED8] hover:underline" onClick={(e) => e.stopPropagation()}>{thread.author_name}</Link>
{thread.forum_categories && (
<> · <span className="text-[#1D4ED8]">{thread.forum_categories.name}</span></>
)}

View File

@@ -26,11 +26,17 @@ function InThreadAd({ adIndex }: { adIndex: number }) {
);
}
function profileHref(author: { author_username?: string | null; author_name: string }): string {
const slug = author.author_username || author.author_name;
return `/forum/user/${encodeURIComponent(slug)}`;
}
interface ForumThread {
id: string;
title: string;
body: string;
author_name: string;
author_username?: string | null;
status: string;
reply_count: number;
view_count: number;
@@ -45,7 +51,7 @@ interface ForumReply {
id: string;
body: string;
author_name: string;
is_ai_response: boolean;
author_username?: string | null;
upvotes: number;
downvotes: number;
vote_score: number;
@@ -322,7 +328,7 @@ export default function ForumThreadPage() {
<Avatar name={thread.author_name} />
<div className="flex-1 min-w-0">
<div className="flex items-center gap-2 mb-2">
<Link href={`/forum/user/${encodeURIComponent(thread.author_name)}`} className="text-white font-body font-semibold text-sm hover:text-[#1D4ED8] hover:underline">{thread.author_name}</Link>
<Link href={profileHref(thread)} className="text-white font-body font-semibold text-sm hover:text-[#1D4ED8] hover:underline">{thread.author_name}</Link>
<span className="text-[#555] font-body text-xs">·</span>
<span className="text-[#555] font-body text-xs">{timeAgo(thread.created_at)}</span>
<span className="text-[#555] font-body text-xs">·</span>
@@ -353,7 +359,7 @@ export default function ForumThreadPage() {
<Avatar name={reply.author_name} />
<div className="flex-1 min-w-0">
<div className="flex items-center gap-2 mb-2 flex-wrap">
<Link href={`/forum/user/${encodeURIComponent(reply.author_name)}`} className="text-white font-body font-semibold text-sm hover:text-[#1D4ED8] hover:underline">{reply.author_name}</Link>
<Link href={profileHref(reply)} className="text-white font-body font-semibold text-sm hover:text-[#1D4ED8] hover:underline">{reply.author_name}</Link>
<span className="text-[#555] font-body text-xs">·</span>
<span className="text-[#555] font-body text-xs">#{idx + 1}</span>
<span className="text-[#555] font-body text-xs">·</span>

View File

@@ -17,15 +17,14 @@ interface ForumUserProfile {
location_city: string | null;
location_country: string | null;
years_experience: number | null;
ai_persona_archetype: string | null;
expertise_level: string | null;
expertise_tags: string[];
writing_voice: string | null;
signature: string | null;
join_date: string | null;
last_seen_at: string | null;
thread_count: number;
reply_count: number;
post_count: number;
}
interface UserThread {
@@ -47,22 +46,6 @@ interface UserReply {
forum_threads?: { title: string };
}
const ARCHETYPE_LABELS: Record<string, string> = {
audio_engineer: "Audio Engineer",
motion_designer: "Motion Designer",
broadcast_engineer: "Broadcast Engineer",
colorist: "Colorist",
editor: "Editor",
vfx_artist: "VFX Artist",
camera_operator: "Camera Operator",
lighting_designer: "Lighting Designer",
post_supervisor: "Post Supervisor",
gear_specialist: "Gear Specialist",
livestream_producer: "Livestream Producer",
generalist: "Generalist",
video_editor: "Video Editor",
};
function fmtDate(iso: string | null): string {
if (!iso) return "—";
try {
@@ -134,7 +117,6 @@ export default function ForumUserPage() {
const { profile, threads, replies } = data;
const location = [profile.location_city, profile.location_country].filter(Boolean).join(", ");
const archetypeLabel = profile.ai_persona_archetype ? (ARCHETYPE_LABELS[profile.ai_persona_archetype] || profile.ai_persona_archetype) : null;
return (
<>
@@ -171,11 +153,6 @@ export default function ForumUserPage() {
<p className="font-body text-sm text-[#1D4ED8] mt-0.5">@{profile.username}</p>
<div className="flex flex-wrap items-center gap-2 mt-3">
{archetypeLabel && (
<span className="font-body text-[10px] font-bold uppercase tracking-wider text-[#10b981] bg-[#10b981]/10 border border-[#10b981]/40 px-2 py-1 rounded-sm">
{archetypeLabel}
</span>
)}
{profile.expertise_level && (
<span className="font-body text-[10px] font-bold uppercase tracking-wider text-[#a78bfa] bg-[#a78bfa]/10 border border-[#a78bfa]/40 px-2 py-1 rounded-sm">
{profile.expertise_level}
@@ -271,6 +248,7 @@ export default function ForumUserPage() {
<dl className="text-sm space-y-2">
<div><dt className="text-[#666] text-[11px] uppercase tracking-wider">Role</dt><dd className="text-[#0F172A]">{profile.role_title || "—"}</dd></div>
{profile.company && <div><dt className="text-[#666] text-[11px] uppercase tracking-wider">Company</dt><dd className="text-[#0F172A]">{profile.company}</dd></div>}
<div><dt className="text-[#666] text-[11px] uppercase tracking-wider">Posts</dt><dd className="text-[#0F172A]">{profile.post_count}</dd></div>
<div><dt className="text-[#666] text-[11px] uppercase tracking-wider">Threads</dt><dd className="text-[#0F172A]">{profile.thread_count}</dd></div>
<div><dt className="text-[#666] text-[11px] uppercase tracking-wider">Replies</dt><dd className="text-[#0F172A]">{profile.reply_count}</dd></div>
{profile.years_experience && <div><dt className="text-[#666] text-[11px] uppercase tracking-wider">Years in industry</dt><dd className="text-[#0F172A]">{profile.years_experience}</dd></div>}