email service and template using resend

This commit is contained in:
2026-05-18 20:47:05 +07:00
parent f0ce22bbb8
commit bf5c97c442
16 changed files with 1152 additions and 2 deletions
+30
View File
@@ -13,6 +13,8 @@ import { revalidatePath } from "next/cache";
import { tripStoredInstantFromYmd } from "@/lib/trip-dates";
import { requireActiveUser } from "@/lib/auth-guards";
import { auditLog } from "@/server/services/audit-log.service";
import { emailService } from "@/lib/email/send";
import { prisma } from "@/lib/prisma";
export async function createTripAction(formData: FormData) {
const session = await getServerSession(authOptions);
@@ -172,6 +174,9 @@ export async function confirmParticipantAction(
participantId,
session.user.id
);
void notifyBookingApproved(participantId);
revalidatePath(`/trips/${tripId}`);
revalidatePath("/trips");
revalidatePath("/");
@@ -182,6 +187,31 @@ export async function confirmParticipantAction(
}
}
async function notifyBookingApproved(participantId: string) {
const participant = await prisma.tripParticipant.findUnique({
where: { id: participantId },
include: {
user: { select: { email: true, name: true } },
trip: { select: { id: true, title: true } },
booking: { select: { id: true, amount: true } },
},
});
if (!participant || !participant.booking) return;
await emailService.send({
to: participant.user.email,
idempotencyKey: `booking_approved-${participant.booking.id}`,
template: {
template: "booking_approved",
data: {
userName: participant.user.name,
tripTitle: participant.trip.title,
tripId: participant.trip.id,
amount: participant.booking.amount,
},
},
});
}
export async function rejectParticipantAction(
tripId: string,
participantId: string