From d7f011894081d134e11e0fea07e97e00c93e3b7d Mon Sep 17 00:00:00 2001 From: Matt Date: Thu, 5 Feb 2026 13:45:34 +0100 Subject: [PATCH] Add user tag editing and improve member error display - Display actual error message in member detail page instead of generic Member not found - Add debug logging to user.get query to help diagnose issues - Add expertise tags editing for users in profile settings page - Update user.updateProfile mutation to accept expertiseTags Co-Authored-By: Claude Opus 4.5 --- src/app/(admin)/admin/members/[id]/page.tsx | 13 +++++-- src/app/(settings)/settings/profile/page.tsx | 40 ++++++++++++++++++++ src/server/routers/user.ts | 26 +++++++++---- 3 files changed, 67 insertions(+), 12 deletions(-) diff --git a/src/app/(admin)/admin/members/[id]/page.tsx b/src/app/(admin)/admin/members/[id]/page.tsx index 0d855eb..b1dc794 100644 --- a/src/app/(admin)/admin/members/[id]/page.tsx +++ b/src/app/(admin)/admin/members/[id]/page.tsx @@ -50,7 +50,7 @@ export default function MemberDetailPage() { const router = useRouter() const userId = params.id as string - const { data: user, isLoading, refetch } = trpc.user.get.useQuery({ id: userId }) + const { data: user, isLoading, error, refetch } = trpc.user.get.useQuery({ id: userId }) const updateUser = trpc.user.update.useMutation() const sendInvitation = trpc.user.sendInvitation.useMutation() @@ -121,14 +121,19 @@ export default function MemberDetailPage() { ) } - if (!user) { + if (error || !user) { return (
- Member not found + Error Loading Member - The member you're looking for does not exist. + {error?.message || 'The member you\'re looking for does not exist.'} + {process.env.NODE_ENV === 'development' && ( +
+ User ID: {userId} +
+ )}
+
+ + + {/* Change Password */} diff --git a/src/server/routers/user.ts b/src/server/routers/user.ts index e3f0da4..51a37d4 100644 --- a/src/server/routers/user.ts +++ b/src/server/routers/user.ts @@ -78,10 +78,11 @@ export const userRouter = router({ bio: z.string().max(1000).optional(), phoneNumber: z.string().max(20).optional().nullable(), notificationPreference: z.enum(['EMAIL', 'WHATSAPP', 'BOTH', 'NONE']).optional(), + expertiseTags: z.array(z.string()).max(15).optional(), }) ) .mutation(async ({ ctx, input }) => { - const { bio, ...directFields } = input + const { bio, expertiseTags, ...directFields } = input // If bio is provided, merge it into metadataJson let metadataJson: Prisma.InputJsonValue | undefined @@ -99,6 +100,7 @@ export const userRouter = router({ data: { ...directFields, ...(metadataJson !== undefined && { metadataJson }), + ...(expertiseTags !== undefined && { expertiseTags }), }, }) }), @@ -241,14 +243,22 @@ export const userRouter = router({ get: adminProcedure .input(z.object({ id: z.string() })) .query(async ({ ctx, input }) => { - return ctx.prisma.user.findUniqueOrThrow({ - where: { id: input.id }, - include: { - _count: { - select: { assignments: true, mentorAssignments: true }, + console.log('[user.get] Fetching user:', input.id) + try { + const user = await ctx.prisma.user.findUniqueOrThrow({ + where: { id: input.id }, + include: { + _count: { + select: { assignments: true, mentorAssignments: true }, + }, }, - }, - }) + }) + console.log('[user.get] Found user:', user.email) + return user + } catch (error) { + console.error('[user.get] Error fetching user:', input.id, error) + throw error + } }), /**