Skip to content

Commit

Permalink
Merge pull request #271 from ungdev/dev
Browse files Browse the repository at this point in the history
merge Master
  • Loading branch information
Suboyyy authored Dec 4, 2024
2 parents 1347e25 + 5d7f19a commit 026271d
Show file tree
Hide file tree
Showing 8 changed files with 52 additions and 42 deletions.
Binary file added assets/email/backgrounds/ticket.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file removed assets/email/backgrounds/ticket_1.jpg
Binary file not shown.
Binary file removed assets/email/backgrounds/ticket_2.jpg
Binary file not shown.
Binary file removed assets/email/backgrounds/ticket_3.jpg
Binary file not shown.
9 changes: 4 additions & 5 deletions src/services/email/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { readFile } from 'fs/promises';
import { render } from 'mustache';
import nodemailer from 'nodemailer';
import { Log } from '@prisma/client';
import { EmailAttachement, RawUser, MailQuery, User } from '../../types';
import { RawUser, MailQuery, User } from '../../types';
import env from '../../utils/env';
import logger from '../../utils/logger';
import type { Component, Mail, SerializedMail } from './types';
Expand Down Expand Up @@ -41,6 +41,7 @@ export const serialize = async (content: Mail) => {
typeof text === 'string' ? escapeText(text) : text.map(inflate).join(''),
},
),
attachments: content.attachments,
};
};

Expand Down Expand Up @@ -100,16 +101,15 @@ export const transporter = nodemailer.createTransport(emailOptions);
* ]
* }))
*/
export const sendEmail = async (mail: SerializedMail, attachments?: EmailAttachement[]) => {
export const sendEmail = async (mail: SerializedMail) => {
const from = `${env.email.sender.name} <${env.email.sender.address}>`;

try {
await transporter.sendMail({
from,
to: mail.to,
subject: mail.subject,
html: mail.html,
attachments,
attachments: mail.attachments,
});

logger.info(`Email sent to ${mail.to}`);
Expand Down Expand Up @@ -162,7 +162,6 @@ export const sendMailsFromTemplate = async (template: string, targets: any[]) =>
console.info(`\tMails envoyés: ${results.delivered}\n\tMails non envoyés: ${results.undelivered}`);
return results;
}

return sendEmail(await mailTemplate(targets[0]));
} catch (error) {
logger.error('Error while sending emails', error);
Expand Down
30 changes: 18 additions & 12 deletions src/services/email/templates/tickets.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { RawUser, TransactionState } from '../../../types';
import { serialize } from '..';
import database from '../../database';
import { generateTicket } from '../../../utils/ticket';
import logger from '../../../utils/logger';

export const generateTicketsEmail = async (user: Omit<RawUser, 'permissions'>) =>
serialize({
Expand Down Expand Up @@ -49,19 +50,24 @@ export const generateTicketsEmail = async (user: Omit<RawUser, 'permissions'>) =
},
],
attachments: await (async () => {
const cartItem = await database.cartItem.findFirst({
where: {
cart: {
paidAt: {
not: null,
try {
const cartItem = await database.cartItem.findFirst({
where: {
cart: {
paidAt: {
not: null,
},
transactionState: TransactionState.paid,
},
transactionState: TransactionState.paid,
itemId: `ticket-${user.type}`,
forUserId: user.id,
},
itemId: `ticket-${user.type}`,
forUserId: user.id,
},
include: { item: true, forUser: true },
});
return [await generateTicket(cartItem)];
include: { item: true, forUser: true },
});
return [await generateTicket(cartItem)];
} catch (error) {
logger.error(error);
return [];
}
})(),
});
1 change: 1 addition & 0 deletions src/services/email/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,4 +71,5 @@ export declare interface SerializedMail {
to: string;
subject: string;
html: string;
attachments?: EmailAttachement[];
}
54 changes: 29 additions & 25 deletions src/utils/ticket.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,25 +5,21 @@ import { encrypt } from './helpers';
import { fetchTeamWithTournament } from '../operations/team';
import { DetailedCartItem, EmailAttachement, UserType } from '../types';

const ticketsDesignAmount = 3;

const loadImage = () => {
const random = Math.floor(Math.random() * ticketsDesignAmount) + 1;
return `data:image/jpg;base64,${readFileSync(`assets/email/backgrounds/ticket_${random}.jpg`, 'base64')}`;
};
const loadImage = () => `data:image/png;base64,${readFileSync(`assets/email/backgrounds/ticket.png`, 'base64')}`;

export const generateTicket = async (cartItem: DetailedCartItem): Promise<EmailAttachement> => {
// Define the parameters for the function
const fontFamily = 'assets/email/font.ttf';
const fontSize = 24;
const qrCodeSize = 182;
const qrCodeX = 35;
const qrCodeY = 567;
const bottomLine = 842 - 150; // sponsors height substracted to ticket height
const fontSize = 75;
const qrCodeSize = 751;
const qrCodeX = 100;
const qrCodeY = 197;
const width = 3949;
const height = 1604;
const textX = qrCodeX + qrCodeSize / 2;
const lineSpaceCorrection = 22;

const user = cartItem.forUser;
const fullName = `${user.firstname} ${user.lastname}`;

const background = loadImage();

Expand Down Expand Up @@ -56,26 +52,34 @@ export const generateTicket = async (cartItem: DetailedCartItem): Promise<EmailA

const pdf = await new Promise<Buffer>((resolve, reject) => {
// Create the document and the background
const document = new PDFkit({ size: 'A4', margin: 0, layout: 'portrait' });
document.image(background, 0, 0, { width: 595, height: 842 });
const document = new PDFkit({ size: [width, height], margin: 0, layout: 'portrait' });
document.rect(0, 0, width, height).fillColor('#17124A').fill();

document.image(background, 0, 0, { width, height });

// Define a text format
const textFormat = document.font(fontFamily).fill([255, 255, 255]).fontSize(fontSize);
const textFormat = document.font(fontFamily).fill([0, 0, 0]).fontSize(fontSize);

// Place the tournament name under the qrCode with the same margin as the qrcode
textFormat.text(tournoiText, qrCodeX + qrCodeSize + lineSpaceCorrection, bottomLine);
const tournamentNameWidth = document.widthOfString(tournoiText);
textFormat.text(tournoiText, textX - tournamentNameWidth / 2, qrCodeY + qrCodeSize + lineSpaceCorrection);

// Place the full name of the user
textFormat.text(fullName, qrCodeX + qrCodeSize + lineSpaceCorrection, bottomLine - lineSpaceCorrection * 4 - 15);
// Place the first name of the user
const firstName = user.firstname;
const firstNameWidth = document.widthOfString(firstName);
textFormat.text(firstName, textX - firstNameWidth / 2, 0);

// Place the text containing the seat
if (user.place)
textFormat.text(
`Place ${user.place}`,
qrCodeX + qrCodeSize + lineSpaceCorrection,
bottomLine - lineSpaceCorrection * 2 - 7,
);
// Place the last name of the user
const lastName = user.lastname;
const lastNameWidth = document.widthOfString(lastName);
textFormat.text(lastName, textX - lastNameWidth / 2, fontSize + lineSpaceCorrection - 10);

// Place the text containing the seat
if (user.place) {
const place = `Place ${user.place}`;
const placeWidth = document.widthOfString(place);
textFormat.text(place, textX - placeWidth / 2, height - fontSize - lineSpaceCorrection * 4);
}
// Place the QR Code
document.image(qrcode, qrCodeX, qrCodeY, { width: qrCodeSize });

Expand Down

0 comments on commit 026271d

Please sign in to comment.