feat: add complex user invitation and management features

- Implemented complex member and invitation schemas using Zod for validation.
- Created new API endpoints for inviting, accepting, revoking, and canceling complex user invitations.
- Developed handlers for managing complex users, including listing, inviting, revoking, and canceling invitations.
- Added frontend components for displaying and managing complex users and invitations.
- Introduced session storage management for pending invitations.
- Integrated Gravatar for user avatars based on email.
- Created database migration for complex invitations table.
This commit is contained in:
Jose Selesan
2026-04-22 15:30:04 -03:00
parent 5f2a7fd494
commit 6ad4fc9ee9
37 changed files with 1935 additions and 78 deletions

View File

@@ -1,14 +1,24 @@
import { createHash } from 'node:crypto';
import type { User } from '@/lib/auth';
import { resolveAvatarUrl } from '@/lib/avatar';
import { db } from '@/lib/prisma';
import type { UserProfile } from '@repo/api-contract';
function getGravatarUrl(email: string): string {
const hash = createHash('md5').update(email.trim().toLowerCase()).digest('hex');
return `https://www.gravatar.com/avatar/${hash}?d=identicon`;
}
export async function getUserProfile(user: User, complexId?: string): Promise<UserProfile> {
const dbUser = await db.user.findUnique({
where: { id: user.id },
select: {
id: true,
name: true,
email: true,
image: true,
createdAt: true,
},
});
if (!dbUser) {
throw new Error('User not found.');
}
let role = 'member';
if (complexId) {
@@ -27,11 +37,14 @@ export async function getUserProfile(user: User, complexId?: string): Promise<Us
}
return {
id: user.id,
fullName: user.name,
email: user.email,
id: dbUser.id,
fullName: dbUser.name,
email: dbUser.email,
role,
avatarUrl: user.image || getGravatarUrl(user.email),
createdAt: user.createdAt.toISOString(),
avatarUrl: resolveAvatarUrl({
email: dbUser.email,
image: dbUser.image,
}),
createdAt: dbUser.createdAt.toISOString(),
};
}