update manyyyyyyyyy
This commit is contained in:
@@ -1,9 +1,9 @@
|
||||
import { Module } from '@nestjs/common'
|
||||
import { UserSchema } from './user.schema'
|
||||
import { MessageModule } from '../Message/message.module'
|
||||
|
||||
import { ChatroomModule } from '../ChatRoom/chatroom.module'
|
||||
@Module({
|
||||
imports: [MessageModule],
|
||||
imports: [MessageModule, ChatroomModule],
|
||||
providers: [UserSchema],
|
||||
exports: [UserSchema],
|
||||
})
|
||||
|
||||
@@ -1,33 +1,26 @@
|
||||
import { Inject, Injectable, Logger } from '@nestjs/common'
|
||||
import { Pothos, PothosRef, PothosSchema, SchemaBuilderToken } from '@smatch-corp/nestjs-pothos'
|
||||
import {
|
||||
Pothos,
|
||||
PothosRef,
|
||||
PothosSchema,
|
||||
SchemaBuilderToken,
|
||||
} from '@smatch-corp/nestjs-pothos'
|
||||
import { Builder, SchemaContext } from '../Graphql/graphql.builder'
|
||||
import { PrismaService } from '../Prisma/prisma.service'
|
||||
import { clerkClient } from '@clerk/express'
|
||||
import { UnauthorizedException } from '@nestjs/common'
|
||||
import { MailService } from '../Mail/mail.service'
|
||||
import { MessageSchema } from 'src/Message/message.schema'
|
||||
import { ChatRoom, Message, MessageContextType, MessageType, Role } from '@prisma/client'
|
||||
import {
|
||||
ChatRoom,
|
||||
Message,
|
||||
MessageContextType,
|
||||
MessageType,
|
||||
Role,
|
||||
} from '@prisma/client'
|
||||
import { PubSubEvent } from 'src/common/pubsub/pubsub-event'
|
||||
import { DateTimeUtils } from 'src/common/utils/datetime.utils'
|
||||
import { JsonValue } from '@prisma/client/runtime/library'
|
||||
import { z } from 'zod'
|
||||
|
||||
type UserWithChatRooms = {
|
||||
name: string
|
||||
id: string
|
||||
email: string
|
||||
phoneNumber: string | null
|
||||
bankBin: string | null
|
||||
bankAccountNumber: string | null
|
||||
packageValue: number
|
||||
role: Role
|
||||
avatarUrl: string | null
|
||||
createdAt: Date
|
||||
updatedAt: Date
|
||||
customerChatRoom?: ChatRoom[]
|
||||
mentorChatRoom?: ChatRoom[]
|
||||
}
|
||||
|
||||
import { ChatroomSchema } from '../ChatRoom/chatroom.schema'
|
||||
@Injectable()
|
||||
export class UserSchema extends PothosSchema {
|
||||
constructor(
|
||||
@@ -35,6 +28,7 @@ export class UserSchema extends PothosSchema {
|
||||
private readonly prisma: PrismaService,
|
||||
private readonly mailService: MailService,
|
||||
private readonly messageSchema: MessageSchema,
|
||||
private readonly chatRoomSchema: ChatroomSchema,
|
||||
) {
|
||||
super()
|
||||
}
|
||||
@@ -128,6 +122,30 @@ export class UserSchema extends PothosSchema {
|
||||
})
|
||||
}
|
||||
|
||||
@PothosRef()
|
||||
recentChatActivity() {
|
||||
return this.builder.simpleObject('RecentChatActivity', {
|
||||
fields: (t) => ({
|
||||
chatRoom: t.field({
|
||||
type: this.chatRoomSchema.chatRoom(),
|
||||
description: 'The chat room.',
|
||||
}),
|
||||
lastActivity: t.field({
|
||||
type: 'DateTime',
|
||||
description: 'The last activity of the chat room.',
|
||||
}),
|
||||
sender: t.field({
|
||||
type: this.user(),
|
||||
description: 'The sender of the message.',
|
||||
}),
|
||||
message: t.field({
|
||||
type: this.messageSchema.message(),
|
||||
description: 'The last message of the chat room.',
|
||||
}),
|
||||
}),
|
||||
})
|
||||
}
|
||||
|
||||
// Query section
|
||||
@Pothos()
|
||||
init(): void {
|
||||
@@ -160,40 +178,73 @@ export class UserSchema extends PothosSchema {
|
||||
}),
|
||||
me: t.prismaField({
|
||||
description: 'Retrieve the current user in context.',
|
||||
type: this.user() || 'Json',
|
||||
args: {
|
||||
includeChatRoom: t.arg({ type: 'Boolean', required: false }),
|
||||
},
|
||||
type: this.user(),
|
||||
resolve: async (_query, _root, _args, ctx) => {
|
||||
if (ctx.isSubscription) {
|
||||
throw new Error('Not allowed')
|
||||
}
|
||||
let user = ctx.http.me as UserWithChatRooms
|
||||
return ctx.http.me
|
||||
},
|
||||
}),
|
||||
|
||||
if (!user?.name) {
|
||||
throw new Error('User not found')
|
||||
}
|
||||
if (_args.includeChatRoom) {
|
||||
const customerChatRoom = await this.prisma.chatRoom.findMany({
|
||||
where: {
|
||||
OR: [{ customerId: ctx.http.me?.id }, { mentorId: ctx.http.me?.id }],
|
||||
},
|
||||
distinct: ['id'],
|
||||
orderBy: {
|
||||
lastActivity: 'desc',
|
||||
},
|
||||
})
|
||||
user = {
|
||||
...user,
|
||||
customerChatRoom,
|
||||
}
|
||||
}
|
||||
return user
|
||||
recentChatActivity: t.field({
|
||||
description: 'Retrieve the recent chat activity of the current user.',
|
||||
type: [this.recentChatActivity()],
|
||||
args: {
|
||||
take: t.arg({ type: 'Int', required: false }),
|
||||
},
|
||||
resolve: async (_parent, args, ctx) => {
|
||||
if (ctx.isSubscription) throw new Error('Not allowed')
|
||||
const me = ctx.http.me
|
||||
if (!me) throw new Error('User not found')
|
||||
|
||||
// get chat rooms that the user is a part of
|
||||
const chatRooms = await this.prisma.chatRoom.findMany({
|
||||
where: {
|
||||
OR: [{ customerId: me.id }, { mentorId: me.id }],
|
||||
},
|
||||
orderBy: {
|
||||
lastActivity: 'desc',
|
||||
},
|
||||
take: args.take ?? 10,
|
||||
})
|
||||
|
||||
// get the last message for each chat room
|
||||
const lastMessages = await Promise.all(
|
||||
chatRooms.map(async (chatRoom) => {
|
||||
const lastMessage = await this.prisma.message.findFirst({
|
||||
where: {
|
||||
chatRoomId: chatRoom.id,
|
||||
},
|
||||
orderBy: {
|
||||
sentAt: 'desc',
|
||||
},
|
||||
})
|
||||
|
||||
if (!lastMessage) return null
|
||||
|
||||
const sender = lastMessage.senderId
|
||||
? await this.prisma.user.findUnique({
|
||||
where: { id: lastMessage.senderId },
|
||||
})
|
||||
: undefined
|
||||
|
||||
return {
|
||||
chatRoom: chatRoom,
|
||||
lastActivity: lastMessage.sentAt,
|
||||
sender: sender,
|
||||
message: lastMessage,
|
||||
}
|
||||
}),
|
||||
)
|
||||
|
||||
return lastMessages.filter((msg) => msg !== null)
|
||||
},
|
||||
}),
|
||||
|
||||
users: t.prismaField({
|
||||
description: 'Retrieve a list of users with optional filtering, ordering, and pagination.',
|
||||
description:
|
||||
'Retrieve a list of users with optional filtering, ordering, and pagination.',
|
||||
type: [this.user()],
|
||||
args: this.builder.generator.findManyArgs('User'),
|
||||
resolve: async (query, _root, args) => {
|
||||
@@ -325,9 +376,10 @@ export class UserSchema extends PothosSchema {
|
||||
}
|
||||
|
||||
const buffer = Buffer.concat(chunks)
|
||||
const { id: userId, imageUrl } = await clerkClient.users.updateUserProfileImage(id, {
|
||||
file: new Blob([buffer]),
|
||||
})
|
||||
const { id: userId, imageUrl } =
|
||||
await clerkClient.users.updateUserProfileImage(id, {
|
||||
file: new Blob([buffer]),
|
||||
})
|
||||
await this.prisma.user.update({
|
||||
where: { id: userId },
|
||||
data: {
|
||||
@@ -405,9 +457,14 @@ export class UserSchema extends PothosSchema {
|
||||
throw new Error(`User ${args.email} not found`)
|
||||
}
|
||||
// send email
|
||||
await this.mailService.sendTemplateEmail([args.email], 'Thông báo chọn lựa quản trị viên cho người điều hành', 'ModeratorInvitation', {
|
||||
USER_NAME: user.name,
|
||||
})
|
||||
await this.mailService.sendTemplateEmail(
|
||||
[args.email],
|
||||
'Thông báo chọn lựa quản trị viên cho người điều hành',
|
||||
'ModeratorInvitation',
|
||||
{
|
||||
USER_NAME: user.name,
|
||||
},
|
||||
)
|
||||
return 'Invited'
|
||||
})
|
||||
},
|
||||
@@ -444,7 +501,10 @@ export class UserSchema extends PothosSchema {
|
||||
},
|
||||
})
|
||||
// publish message
|
||||
await ctx.http.pubSub.publish(`${PubSubEvent.NEW_MESSAGE}.${message.recipientId}`, message)
|
||||
await ctx.http.pubSub.publish(
|
||||
`${PubSubEvent.NEW_MESSAGE}.${message.recipientId}`,
|
||||
message,
|
||||
)
|
||||
return message
|
||||
},
|
||||
}),
|
||||
@@ -459,7 +519,9 @@ export class UserSchema extends PothosSchema {
|
||||
const {
|
||||
websocket: { pubSub },
|
||||
} = ctx
|
||||
return pubSub.asyncIterator([`${PubSubEvent.NEW_MESSAGE}.${ctx.websocket.me?.id}`]) as unknown as AsyncIterable<Message>
|
||||
return pubSub.asyncIterator([
|
||||
`${PubSubEvent.NEW_MESSAGE}.${ctx.websocket.me?.id}`,
|
||||
]) as unknown as AsyncIterable<Message>
|
||||
},
|
||||
resolve: async (payload: Message) => payload,
|
||||
}),
|
||||
|
||||
Reference in New Issue
Block a user