feat: melhora página de perfil e integra preferências de notificação
- Atualiza cores das badges para padrão cyan do projeto - Adiciona degradê no header do card de perfil - Implementa upload de foto de perfil via API Convex - Integra notificações do Convex com preferências do usuário - Cria API /api/notifications/send para verificar preferências - Melhora layout das páginas de login/recuperação com degradê - Adiciona badge "Helpdesk" e título "Raven" consistente 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
1bc08d3a5f
commit
ab7dfa81ca
8 changed files with 543 additions and 59 deletions
|
|
@ -2464,10 +2464,13 @@ export const create = mutation({
|
|||
if (typeof schedulerRunAfter === "function") {
|
||||
await schedulerRunAfter(0, api.ticketNotifications.sendTicketCreatedEmail, {
|
||||
to: requesterEmail,
|
||||
userId: String(requester._id),
|
||||
userName: requester.name ?? undefined,
|
||||
ticketId: String(id),
|
||||
reference: nextRef,
|
||||
subject,
|
||||
priority: args.priority,
|
||||
tenantId: args.tenantId,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
@ -2870,15 +2873,19 @@ export const addComment = mutation({
|
|||
await ctx.db.patch(args.ticketId, { updatedAt: now, ...responsePatch });
|
||||
// Notificação por e-mail: comentário público para o solicitante
|
||||
try {
|
||||
const snapshotEmail = (ticketDoc.requesterSnapshot as { email?: string } | undefined)?.email
|
||||
const requesterSnapshot = ticketDoc.requesterSnapshot as { email?: string; name?: string } | undefined
|
||||
const snapshotEmail = requesterSnapshot?.email
|
||||
if (requestedVisibility === "PUBLIC" && snapshotEmail && String(ticketDoc.requesterId) !== String(args.authorId)) {
|
||||
const schedulerRunAfter = ctx.scheduler?.runAfter
|
||||
if (typeof schedulerRunAfter === "function") {
|
||||
await schedulerRunAfter(0, api.ticketNotifications.sendPublicCommentEmail, {
|
||||
to: snapshotEmail,
|
||||
userId: ticketDoc.requesterId ? String(ticketDoc.requesterId) : undefined,
|
||||
userName: requesterSnapshot?.name ?? undefined,
|
||||
ticketId: String(ticketDoc._id),
|
||||
reference: ticketDoc.reference ?? 0,
|
||||
subject: ticketDoc.subject ?? "",
|
||||
tenantId: ticketDoc.tenantId,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
@ -3146,16 +3153,21 @@ export async function resolveTicketHandler(
|
|||
|
||||
// Notificação por e-mail: encerramento do chamado
|
||||
try {
|
||||
const requesterDoc = await ctx.db.get(ticketDoc.requesterId)
|
||||
const email = (requesterDoc as Doc<"users"> | null)?.email || (ticketDoc.requesterSnapshot as { email?: string } | undefined)?.email || null
|
||||
const requesterDoc = await ctx.db.get(ticketDoc.requesterId) as Doc<"users"> | null
|
||||
const requesterSnapshot = ticketDoc.requesterSnapshot as { email?: string; name?: string } | undefined
|
||||
const email = requesterDoc?.email || requesterSnapshot?.email || null
|
||||
const userName = requesterDoc?.name || requesterSnapshot?.name || undefined
|
||||
if (email) {
|
||||
const schedulerRunAfter = ctx.scheduler?.runAfter
|
||||
if (typeof schedulerRunAfter === "function") {
|
||||
await schedulerRunAfter(0, api.ticketNotifications.sendResolvedEmail, {
|
||||
to: email,
|
||||
userId: ticketDoc.requesterId ? String(ticketDoc.requesterId) : undefined,
|
||||
userName,
|
||||
ticketId: String(ticketId),
|
||||
reference: ticketDoc.reference ?? 0,
|
||||
subject: ticketDoc.subject ?? "",
|
||||
tenantId: ticketDoc.tenantId,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue