feat: Add invitation email and improve email templates
- Add invitation email service with Slovak diacritics - Move certificate email HTML template to separate file - Add invitation email HTML/TXT templates - Remove template caching for development flexibility - Add send invitation endpoint (POST /registracie/:id/send-invitation) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -306,3 +306,22 @@ export const sendCertificateEmail = async (req, res, next) => {
|
||||
next(error);
|
||||
}
|
||||
};
|
||||
|
||||
// ==================== INVITATION EMAIL ====================
|
||||
|
||||
export const sendInvitationEmail = async (req, res, next) => {
|
||||
try {
|
||||
const { registraciaId } = req.params;
|
||||
const userId = req.user.id;
|
||||
const { sendInvitationEmail: sendInvitation } = await import('../services/ai-kurzy/invitation-email.service.js');
|
||||
|
||||
const result = await sendInvitation(parseInt(registraciaId), userId);
|
||||
|
||||
res.json({
|
||||
data: result,
|
||||
message: result.message,
|
||||
});
|
||||
} catch (error) {
|
||||
next(error);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -180,4 +180,12 @@ router.post(
|
||||
aiKurzyController.sendCertificateEmail
|
||||
);
|
||||
|
||||
// ==================== INVITATION EMAIL ====================
|
||||
|
||||
router.post(
|
||||
'/registracie/:registraciaId/send-invitation',
|
||||
validateParams(registraciaIdSchema),
|
||||
aiKurzyController.sendInvitationEmail
|
||||
);
|
||||
|
||||
export default router;
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import fs from 'fs/promises';
|
||||
import path from 'path';
|
||||
import { fileURLToPath } from 'url';
|
||||
import axios from 'axios';
|
||||
import { db } from '../../config/database.js';
|
||||
import { prilohy, registracie, ucastnici, kurzy, emailAccounts, userEmailAccounts } from '../../db/schema.js';
|
||||
@@ -9,6 +10,14 @@ import { logger } from '../../utils/logger.js';
|
||||
import { jmapRequest, getMailboxes, getIdentities } from '../jmap/client.js';
|
||||
import { getJmapConfig } from '../jmap/config.js';
|
||||
|
||||
const __filename = fileURLToPath(import.meta.url);
|
||||
const __dirname = path.dirname(__filename);
|
||||
|
||||
// Template paths
|
||||
const TEMPLATES_DIR = path.join(__dirname, '../../templates/emails');
|
||||
const CERTIFICATE_EMAIL_HTML_TEMPLATE = path.join(TEMPLATES_DIR, 'certificate-email.html');
|
||||
const CERTIFICATE_EMAIL_TEXT_TEMPLATE = path.join(TEMPLATES_DIR, 'certificate-email.txt');
|
||||
|
||||
/**
|
||||
* Format date to Slovak locale
|
||||
*/
|
||||
@@ -21,136 +30,40 @@ const formatDate = (date) => {
|
||||
}).format(new Date(date));
|
||||
};
|
||||
|
||||
/**
|
||||
* Load email templates (fresh load each time for development flexibility)
|
||||
*/
|
||||
const loadTemplates = async () => {
|
||||
const htmlTemplate = await fs.readFile(CERTIFICATE_EMAIL_HTML_TEMPLATE, 'utf-8');
|
||||
const textTemplate = await fs.readFile(CERTIFICATE_EMAIL_TEXT_TEMPLATE, 'utf-8');
|
||||
return { htmlTemplate, textTemplate };
|
||||
};
|
||||
|
||||
/**
|
||||
* Replace template placeholders with actual values
|
||||
*/
|
||||
const replaceTemplatePlaceholders = (template, data) => {
|
||||
return template
|
||||
.replace(/\{\{participantName\}\}/g, data.participantName || '')
|
||||
.replace(/\{\{courseName\}\}/g, data.courseName || '')
|
||||
.replace(/\{\{courseDate\}\}/g, data.courseDate || '')
|
||||
.replace(/\{\{courseType\}\}/g, data.courseType || 'Kurz');
|
||||
};
|
||||
|
||||
/**
|
||||
* Generate HTML email template for certificate notification
|
||||
*/
|
||||
export const generateCertificateEmailHtml = ({ participantName, courseName, courseDate, courseType }) => {
|
||||
return `
|
||||
<!DOCTYPE html>
|
||||
<html lang="sk">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Certifikát o absolvovaní kurzu</title>
|
||||
</head>
|
||||
<body style="margin: 0; padding: 0; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif; background-color: #f8fafc;">
|
||||
<table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%" style="background-color: #f8fafc;">
|
||||
<tr>
|
||||
<td style="padding: 40px 20px;">
|
||||
<table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%" style="max-width: 600px; margin: 0 auto; background-color: #ffffff; border-radius: 16px; box-shadow: 0 4px 20px rgba(0, 0, 0, 0.08);">
|
||||
|
||||
<!-- Header with gradient -->
|
||||
<tr>
|
||||
<td style="padding: 40px 40px 30px 40px; text-align: center; background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); border-radius: 16px 16px 0 0;">
|
||||
<div style="margin-bottom: 16px;">
|
||||
<span style="font-size: 48px;">🎓</span>
|
||||
</div>
|
||||
<h1 style="margin: 0; font-size: 26px; font-weight: 700; color: #ffffff; letter-spacing: -0.5px;">
|
||||
Gratulujeme k úspešnému absolvovaniu!
|
||||
</h1>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<!-- Content -->
|
||||
<tr>
|
||||
<td style="padding: 40px;">
|
||||
<p style="margin: 0 0 24px 0; font-size: 17px; color: #334155; line-height: 1.7;">
|
||||
Vážený/á <strong style="color: #1e293b;">${participantName}</strong>,
|
||||
</p>
|
||||
|
||||
<p style="margin: 0 0 28px 0; font-size: 16px; color: #475569; line-height: 1.7;">
|
||||
Srdečne Vám ďakujeme za účasť na našom kurze. Úspešne ste ho absolvovali a s potešením Vám zasielame Váš certifikát.
|
||||
</p>
|
||||
|
||||
<!-- Course Details Card -->
|
||||
<table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%" style="background: linear-gradient(135deg, #f0f9ff 0%, #e0f2fe 100%); border-radius: 12px; border: 1px solid #bae6fd; margin-bottom: 28px;">
|
||||
<tr>
|
||||
<td style="padding: 24px;">
|
||||
<table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%">
|
||||
<tr>
|
||||
<td style="padding-bottom: 16px;">
|
||||
<span style="display: inline-block; padding: 6px 14px; background-color: #0ea5e9; color: #ffffff; font-size: 11px; font-weight: 600; border-radius: 20px; text-transform: uppercase; letter-spacing: 0.5px;">
|
||||
${courseType || 'Kurz'}
|
||||
</span>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<h2 style="margin: 0 0 12px 0; font-size: 20px; font-weight: 700; color: #0c4a6e;">
|
||||
${courseName}
|
||||
</h2>
|
||||
<p style="margin: 0; font-size: 14px; color: #0369a1;">
|
||||
<span style="display: inline-block; margin-right: 8px;">📅</span>
|
||||
${courseDate}
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<!-- Certificate note -->
|
||||
<div style="background-color: #fefce8; border-radius: 10px; padding: 16px 20px; margin-bottom: 28px; border-left: 4px solid #eab308;">
|
||||
<p style="margin: 0; font-size: 14px; color: #713f12; line-height: 1.6;">
|
||||
<strong>📎 Príloha:</strong> Váš certifikát nájdete v prílohe tohto emailu vo formáte PDF.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<p style="margin: 0 0 8px 0; font-size: 16px; color: #475569; line-height: 1.7;">
|
||||
Prajeme Vám veľa úspechov pri uplatňovaní nových vedomostí v praxi!
|
||||
</p>
|
||||
|
||||
<p style="margin: 24px 0 0 0; font-size: 16px; color: #334155;">
|
||||
S pozdravom,<br>
|
||||
<strong style="color: #1e293b;">Tím AI Kurzov</strong>
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<!-- Footer -->
|
||||
<tr>
|
||||
<td style="padding: 24px 40px; background-color: #f1f5f9; border-top: 1px solid #e2e8f0; border-radius: 0 0 16px 16px;">
|
||||
<p style="margin: 0; font-size: 12px; color: #64748b; text-align: center; line-height: 1.6;">
|
||||
Táto správa bola automaticky vygenerovaná.<br>
|
||||
V prípade otázok nás neváhajte kontaktovať.
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</body>
|
||||
</html>
|
||||
`.trim();
|
||||
export const generateCertificateEmailHtml = async ({ participantName, courseName, courseDate, courseType }) => {
|
||||
const { htmlTemplate } = await loadTemplates();
|
||||
return replaceTemplatePlaceholders(htmlTemplate, { participantName, courseName, courseDate, courseType });
|
||||
};
|
||||
|
||||
/**
|
||||
* Generate plain text version of the certificate email
|
||||
*/
|
||||
export const generateCertificateEmailText = ({ participantName, courseName, courseDate, courseType }) => {
|
||||
return `
|
||||
Vážený/á ${participantName},
|
||||
|
||||
Srdečne Vám ďakujeme za účasť na našom kurze. Úspešne ste ho absolvovali a s potešením Vám zasielame Váš certifikát.
|
||||
|
||||
KURZ: ${courseName}
|
||||
TYP: ${courseType || 'Kurz'}
|
||||
DÁTUM: ${courseDate}
|
||||
|
||||
Váš certifikát nájdete v prílohe tohto emailu vo formáte PDF.
|
||||
|
||||
Prajeme Vám veľa úspechov pri uplatňovaní nových vedomostí v praxi!
|
||||
|
||||
S pozdravom,
|
||||
Tím AI Kurzov
|
||||
|
||||
---
|
||||
Táto správa bola automaticky vygenerovaná.
|
||||
V prípade otázok nás neváhajte kontaktovať.
|
||||
`.trim();
|
||||
export const generateCertificateEmailText = async ({ participantName, courseName, courseDate, courseType }) => {
|
||||
const { textTemplate } = await loadTemplates();
|
||||
return replaceTemplatePlaceholders(textTemplate, { participantName, courseName, courseDate, courseType });
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -410,8 +323,8 @@ export const sendCertificateEmail = async (prilohaId, userId) => {
|
||||
courseType: registration.kurzTyp,
|
||||
};
|
||||
|
||||
const htmlBody = generateCertificateEmailHtml(emailData);
|
||||
const textBody = generateCertificateEmailText(emailData);
|
||||
const htmlBody = await generateCertificateEmailHtml(emailData);
|
||||
const textBody = await generateCertificateEmailText(emailData);
|
||||
const subject = `Certifikát o absolvovaní kurzu: ${registration.kurzNazov}`;
|
||||
|
||||
// Get JMAP config
|
||||
|
||||
253
src/services/ai-kurzy/invitation-email.service.js
Normal file
253
src/services/ai-kurzy/invitation-email.service.js
Normal file
@@ -0,0 +1,253 @@
|
||||
import fs from 'fs/promises';
|
||||
import path from 'path';
|
||||
import { fileURLToPath } from 'url';
|
||||
import axios from 'axios';
|
||||
import { db } from '../../config/database.js';
|
||||
import { registracie, ucastnici, kurzy, emailAccounts, userEmailAccounts } from '../../db/schema.js';
|
||||
import { eq, and } from 'drizzle-orm';
|
||||
import { NotFoundError, BadRequestError } from '../../utils/errors.js';
|
||||
import { logger } from '../../utils/logger.js';
|
||||
import { jmapRequest, getMailboxes, getIdentities } from '../jmap/client.js';
|
||||
import { getJmapConfig } from '../jmap/config.js';
|
||||
|
||||
const __filename = fileURLToPath(import.meta.url);
|
||||
const __dirname = path.dirname(__filename);
|
||||
|
||||
// Template paths
|
||||
const TEMPLATES_DIR = path.join(__dirname, '../../templates/emails');
|
||||
const INVITATION_EMAIL_HTML_TEMPLATE = path.join(TEMPLATES_DIR, 'invitation-email.html');
|
||||
const INVITATION_EMAIL_TEXT_TEMPLATE = path.join(TEMPLATES_DIR, 'invitation-email.txt');
|
||||
|
||||
/**
|
||||
* Format date to Slovak locale
|
||||
*/
|
||||
const formatDate = (date) => {
|
||||
if (!date) return '';
|
||||
return new Intl.DateTimeFormat('sk-SK', {
|
||||
day: 'numeric',
|
||||
month: 'long',
|
||||
year: 'numeric',
|
||||
}).format(new Date(date));
|
||||
};
|
||||
|
||||
/**
|
||||
* Load email templates (fresh load each time for development flexibility)
|
||||
*/
|
||||
const loadTemplates = async () => {
|
||||
const htmlTemplate = await fs.readFile(INVITATION_EMAIL_HTML_TEMPLATE, 'utf-8');
|
||||
const textTemplate = await fs.readFile(INVITATION_EMAIL_TEXT_TEMPLATE, 'utf-8');
|
||||
return { htmlTemplate, textTemplate };
|
||||
};
|
||||
|
||||
/**
|
||||
* Replace template placeholders with actual values
|
||||
*/
|
||||
const replaceTemplatePlaceholders = (template, data) => {
|
||||
return template
|
||||
.replace(/\{\{courseName\}\}/g, data.courseName || '')
|
||||
.replace(/\{\{courseDate\}\}/g, data.courseDate || '');
|
||||
};
|
||||
|
||||
/**
|
||||
* Generate HTML email template for invitation
|
||||
*/
|
||||
export const generateInvitationEmailHtml = async ({ courseName, courseDate }) => {
|
||||
const { htmlTemplate } = await loadTemplates();
|
||||
return replaceTemplatePlaceholders(htmlTemplate, { courseName, courseDate });
|
||||
};
|
||||
|
||||
/**
|
||||
* Generate plain text version of the invitation email
|
||||
*/
|
||||
export const generateInvitationEmailText = async ({ courseName, courseDate }) => {
|
||||
const { textTemplate } = await loadTemplates();
|
||||
return replaceTemplatePlaceholders(textTemplate, { courseName, courseDate });
|
||||
};
|
||||
|
||||
/**
|
||||
* Send email via JMAP
|
||||
*/
|
||||
const sendEmailViaJmap = async (jmapConfig, to, subject, htmlBody, textBody) => {
|
||||
logger.info(`Odosielam pozvánku emailom na: ${to}`);
|
||||
|
||||
// Get mailboxes
|
||||
const mailboxes = await getMailboxes(jmapConfig);
|
||||
const sentMailbox = mailboxes.find((m) => m.role === 'sent' || m.name === 'Sent');
|
||||
|
||||
if (!sentMailbox) {
|
||||
throw new Error('Priečinok Odoslané nebol nájdený');
|
||||
}
|
||||
|
||||
// Create email
|
||||
const createResponse = await jmapRequest(jmapConfig, [
|
||||
[
|
||||
'Email/set',
|
||||
{
|
||||
accountId: jmapConfig.accountId,
|
||||
create: {
|
||||
draft: {
|
||||
mailboxIds: {
|
||||
[sentMailbox.id]: true,
|
||||
},
|
||||
from: [{ email: jmapConfig.username }],
|
||||
to: [{ email: to }],
|
||||
subject: subject,
|
||||
bodyStructure: {
|
||||
type: 'multipart/alternative',
|
||||
subParts: [
|
||||
{
|
||||
type: 'text/plain',
|
||||
partId: 'text',
|
||||
},
|
||||
{
|
||||
type: 'text/html',
|
||||
partId: 'html',
|
||||
},
|
||||
],
|
||||
},
|
||||
bodyValues: {
|
||||
html: { value: htmlBody },
|
||||
text: { value: textBody },
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
'set1',
|
||||
],
|
||||
]);
|
||||
|
||||
const createResult = createResponse.methodResponses[0][1];
|
||||
const createdEmailId = createResult.created?.draft?.id;
|
||||
|
||||
if (!createdEmailId) {
|
||||
logger.error('Nepodarilo sa vytvoriť email', createResult.notCreated?.draft);
|
||||
throw new Error('Nepodarilo sa vytvoriť email');
|
||||
}
|
||||
|
||||
// Get user identity
|
||||
const identities = await getIdentities(jmapConfig);
|
||||
const identity = identities.find((i) => i.email === jmapConfig.username) || identities[0];
|
||||
|
||||
if (!identity) {
|
||||
throw new Error('Nenašla sa identita pre odosielanie emailov');
|
||||
}
|
||||
|
||||
// Submit the email
|
||||
const submitResponse = await jmapRequest(jmapConfig, [
|
||||
[
|
||||
'EmailSubmission/set',
|
||||
{
|
||||
accountId: jmapConfig.accountId,
|
||||
create: {
|
||||
submission: {
|
||||
emailId: createdEmailId,
|
||||
identityId: identity.id,
|
||||
},
|
||||
},
|
||||
},
|
||||
'submit1',
|
||||
],
|
||||
]);
|
||||
|
||||
const submissionId = submitResponse.methodResponses[0][1].created?.submission?.id;
|
||||
|
||||
if (!submissionId) {
|
||||
const error = submitResponse.methodResponses[0][1].notCreated?.submission;
|
||||
logger.error('Nepodarilo sa odoslať email', error);
|
||||
throw new Error('Nepodarilo sa odoslať email');
|
||||
}
|
||||
|
||||
logger.success(`Email s pozvánkou úspešne odoslaný`);
|
||||
return { success: true, submissionId };
|
||||
};
|
||||
|
||||
/**
|
||||
* Send invitation email to participant
|
||||
* @param {number} registraciaId - ID of the registration
|
||||
* @param {number} userId - ID of the user sending the email (for getting email account)
|
||||
*/
|
||||
export const sendInvitationEmail = async (registraciaId, userId) => {
|
||||
// Get registration with participant and course info
|
||||
const [registration] = await db
|
||||
.select({
|
||||
id: registracie.id,
|
||||
ucastnikMeno: ucastnici.meno,
|
||||
ucastnikPriezvisko: ucastnici.priezvisko,
|
||||
ucastnikTitul: ucastnici.titul,
|
||||
ucastnikEmail: ucastnici.email,
|
||||
kurzNazov: kurzy.nazov,
|
||||
kurzTyp: kurzy.typKurzu,
|
||||
kurzDatumOd: kurzy.datumOd,
|
||||
kurzDatumDo: kurzy.datumDo,
|
||||
})
|
||||
.from(registracie)
|
||||
.leftJoin(ucastnici, eq(registracie.ucastnikId, ucastnici.id))
|
||||
.leftJoin(kurzy, eq(registracie.kurzId, kurzy.id))
|
||||
.where(eq(registracie.id, registraciaId))
|
||||
.limit(1);
|
||||
|
||||
if (!registration) {
|
||||
throw new NotFoundError('Registrácia nenájdená');
|
||||
}
|
||||
|
||||
if (!registration.ucastnikEmail) {
|
||||
throw new BadRequestError('Účastník nemá zadaný email');
|
||||
}
|
||||
|
||||
// Get email account for sending (through userEmailAccounts join table)
|
||||
const [emailAccountResult] = await db
|
||||
.select({
|
||||
id: emailAccounts.id,
|
||||
email: emailAccounts.email,
|
||||
emailPassword: emailAccounts.emailPassword,
|
||||
jmapAccountId: emailAccounts.jmapAccountId,
|
||||
isActive: emailAccounts.isActive,
|
||||
})
|
||||
.from(userEmailAccounts)
|
||||
.innerJoin(emailAccounts, eq(userEmailAccounts.emailAccountId, emailAccounts.id))
|
||||
.where(and(eq(userEmailAccounts.userId, userId), eq(emailAccounts.isActive, true)))
|
||||
.limit(1);
|
||||
|
||||
if (!emailAccountResult) {
|
||||
throw new BadRequestError('Nemáte nastavený aktívny emailový účet pre odosielanie');
|
||||
}
|
||||
|
||||
const emailAccount = emailAccountResult;
|
||||
|
||||
// Build course date string
|
||||
const courseDate = registration.kurzDatumOd
|
||||
? registration.kurzDatumDo && registration.kurzDatumDo !== registration.kurzDatumOd
|
||||
? `${formatDate(registration.kurzDatumOd)} - ${formatDate(registration.kurzDatumDo)}`
|
||||
: formatDate(registration.kurzDatumOd)
|
||||
: '';
|
||||
|
||||
// Generate email content
|
||||
const emailData = {
|
||||
courseName: registration.kurzNazov || 'Kurz',
|
||||
courseDate,
|
||||
};
|
||||
|
||||
const htmlBody = await generateInvitationEmailHtml(emailData);
|
||||
const textBody = await generateInvitationEmailText(emailData);
|
||||
const subject = `Pozvánka na školenie: ${registration.kurzNazov}`;
|
||||
|
||||
// Get JMAP config
|
||||
const jmapConfig = getJmapConfig(emailAccount, true);
|
||||
|
||||
// Send email
|
||||
await sendEmailViaJmap(
|
||||
jmapConfig,
|
||||
registration.ucastnikEmail,
|
||||
subject,
|
||||
htmlBody,
|
||||
textBody
|
||||
);
|
||||
|
||||
logger.success(`Pozvánka odoslaná na ${registration.ucastnikEmail}`);
|
||||
|
||||
return {
|
||||
success: true,
|
||||
message: `Pozvánka bola odoslaná na ${registration.ucastnikEmail}`,
|
||||
recipientEmail: registration.ucastnikEmail,
|
||||
};
|
||||
};
|
||||
129
src/templates/emails/certificate-email.html
Normal file
129
src/templates/emails/certificate-email.html
Normal file
@@ -0,0 +1,129 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="sk">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Certifikát o absolvovaní kurzu</title>
|
||||
</head>
|
||||
<body style="margin: 0; padding: 0; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif; background-color: #f5f5f5;">
|
||||
<table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%" style="background-color: #f5f5f5;">
|
||||
<tr>
|
||||
<td style="padding: 32px 16px;">
|
||||
<table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%" style="max-width: 600px; margin: 0 auto; background-color: #ffffff; border-radius: 16px; overflow: hidden; box-shadow: 0 4px 24px rgba(0, 0, 0, 0.12);">
|
||||
|
||||
<!-- Header with Logo -->
|
||||
<tr>
|
||||
<td style="background: linear-gradient(135deg, #0f172a 0%, #1e293b 100%); padding: 48px 32px; text-align: center;">
|
||||
<table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%">
|
||||
<tr>
|
||||
<td style="text-align: center; padding-bottom: 28px;">
|
||||
<img src="https://www.slovensko.ai/wp-content/uploads/2024/07/2LOGO_slovensko_AI_1_b-2048x434.png" alt="Slovensko.AI" style="height: 48px; max-width: 280px;" />
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<div style="width: 60px; height: 60px; background: linear-gradient(135deg, #10b981 0%, #059669 100%); border-radius: 16px; margin: 0 auto 20px auto; text-align: center; line-height: 60px; font-size: 28px;">
|
||||
🎓
|
||||
</div>
|
||||
<h1 style="margin: 0; font-size: 28px; font-weight: 700; color: #ffffff; letter-spacing: -0.5px;">
|
||||
Gratulujeme k úspešnému absolvovaniu!
|
||||
</h1>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<!-- Content -->
|
||||
<tr>
|
||||
<td style="padding: 40px 32px;">
|
||||
<p style="margin: 0 0 24px 0; font-size: 17px; color: #334155; line-height: 1.7;">
|
||||
Vážený/á <strong style="color: #0f172a;">{{participantName}}</strong>,
|
||||
</p>
|
||||
|
||||
<p style="margin: 0 0 28px 0; font-size: 16px; color: #475569; line-height: 1.7;">
|
||||
Srdečne Vám ďakujeme za účasť na našom kurze. Úspešne ste ho absolvovali a s potešením Vám zasielame Váš certifikát.
|
||||
</p>
|
||||
|
||||
<!-- Course Details Card -->
|
||||
<table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%" style="background: linear-gradient(135deg, #ecfdf5 0%, #d1fae5 100%); border-radius: 16px; border: 1px solid #a7f3d0; margin-bottom: 28px; overflow: hidden;">
|
||||
<tr>
|
||||
<td style="background: linear-gradient(135deg, #10b981 0%, #059669 100%); padding: 12px 24px;">
|
||||
<span style="display: inline-block; font-size: 12px; font-weight: 700; color: rgba(255,255,255,0.9); text-transform: uppercase; letter-spacing: 1px;">
|
||||
{{courseType}}
|
||||
</span>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="padding: 24px;">
|
||||
<h2 style="margin: 0 0 12px 0; font-size: 22px; font-weight: 700; color: #064e3b;">
|
||||
{{courseName}}
|
||||
</h2>
|
||||
<p style="margin: 0; font-size: 15px; color: #065f46;">
|
||||
<span style="display: inline-block; margin-right: 8px;">📅</span>
|
||||
{{courseDate}}
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<!-- Certificate note -->
|
||||
<table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%" style="background: linear-gradient(135deg, #fef3c7 0%, #fde68a 100%); border-radius: 12px; margin-bottom: 28px;">
|
||||
<tr>
|
||||
<td style="padding: 20px 24px;">
|
||||
<table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%">
|
||||
<tr>
|
||||
<td width="40" style="vertical-align: top;">
|
||||
<div style="width: 36px; height: 36px; background-color: #f59e0b; border-radius: 10px; text-align: center; line-height: 36px; font-size: 18px;">
|
||||
📎
|
||||
</div>
|
||||
</td>
|
||||
<td style="vertical-align: middle; padding-left: 16px;">
|
||||
<p style="margin: 0; font-size: 15px; color: #78350f; line-height: 1.5;">
|
||||
<strong>Príloha:</strong> Váš certifikát nájdete v prílohe tohto e-mailu vo formáte PDF.
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<p style="margin: 0 0 8px 0; font-size: 16px; color: #475569; line-height: 1.7;">
|
||||
Prajeme Vám veľa úspechov pri uplatňovaní nových vedomostí v praxi!
|
||||
</p>
|
||||
|
||||
<p style="margin: 28px 0 0 0; font-size: 16px; color: #334155;">
|
||||
S pozdravom,<br>
|
||||
<strong style="color: #0f172a;">Tím Slovensko.AI</strong>
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<!-- Footer -->
|
||||
<tr>
|
||||
<td style="background: linear-gradient(135deg, #0f172a 0%, #1e293b 100%); padding: 28px 32px;">
|
||||
<table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%">
|
||||
<tr>
|
||||
<td style="text-align: center;">
|
||||
<p style="margin: 0 0 12px 0; font-size: 12px; color: #94a3b8;">
|
||||
Táto správa bola automaticky vygenerovaná.<br>
|
||||
V prípade otázok nás neváhajte kontaktovať.
|
||||
</p>
|
||||
<p style="margin: 0;">
|
||||
<a href="mailto:info@slovensko.ai" style="color: #10b981; text-decoration: none; font-size: 13px; font-weight: 600;">info@slovensko.ai</a>
|
||||
<span style="color: #475569; margin: 0 8px;">|</span>
|
||||
<a href="https://www.slovensko.ai" style="color: #10b981; text-decoration: none; font-size: 13px; font-weight: 600;">www.slovensko.ai</a>
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</body>
|
||||
</html>
|
||||
20
src/templates/emails/certificate-email.txt
Normal file
20
src/templates/emails/certificate-email.txt
Normal file
@@ -0,0 +1,20 @@
|
||||
Vážený/á {{participantName}},
|
||||
|
||||
Srdečne Vám ďakujeme za účasť na našom kurze. Úspešne ste ho absolvovali a s potešením Vám zasielame Váš certifikát.
|
||||
|
||||
KURZ: {{courseName}}
|
||||
TYP: {{courseType}}
|
||||
DÁTUM: {{courseDate}}
|
||||
|
||||
Váš certifikát nájdete v prílohe tohto e-mailu vo formáte PDF.
|
||||
|
||||
Prajeme Vám veľa úspechov pri uplatňovaní nových vedomostí v praxi!
|
||||
|
||||
S pozdravom,
|
||||
Tím Slovensko.AI
|
||||
|
||||
---
|
||||
Táto správa bola automaticky vygenerovaná.
|
||||
V prípade otázok nás neváhajte kontaktovať.
|
||||
|
||||
info@slovensko.ai | www.slovensko.ai
|
||||
351
src/templates/emails/invitation-email.html
Normal file
351
src/templates/emails/invitation-email.html
Normal file
@@ -0,0 +1,351 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="sk">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Pozvánka na kurz</title>
|
||||
</head>
|
||||
<body style="margin: 0; padding: 0; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif; background-color: #f5f5f5;">
|
||||
<table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%" style="background-color: #f5f5f5;">
|
||||
<tr>
|
||||
<td style="padding: 32px 16px;">
|
||||
<table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%" style="max-width: 600px; margin: 0 auto; background-color: #ffffff; border-radius: 16px; overflow: hidden; box-shadow: 0 4px 24px rgba(0, 0, 0, 0.12);">
|
||||
|
||||
<!-- Header with Logo -->
|
||||
<tr>
|
||||
<td style="background: linear-gradient(135deg, #0f172a 0%, #1e293b 100%); padding: 48px 32px; text-align: center;">
|
||||
<table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%">
|
||||
<tr>
|
||||
<td style="text-align: center; padding-bottom: 28px;">
|
||||
<img src="https://www.slovensko.ai/wp-content/uploads/2024/07/2LOGO_slovensko_AI_1_b-2048x434.png" alt="Slovensko.AI" style="height: 48px; max-width: 280px;" />
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<div style="width: 60px; height: 4px; background: linear-gradient(90deg, #10b981 0%, #34d399 100%); margin: 0 auto 24px auto; border-radius: 2px;"></div>
|
||||
<h1 style="margin: 0; font-size: 32px; font-weight: 700; color: #ffffff; letter-spacing: -0.5px;">
|
||||
Pozvánka na školenie
|
||||
</h1>
|
||||
<p style="margin: 12px 0 0 0; font-size: 15px; color: #94a3b8;">
|
||||
Všetky organizačné informácie
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<!-- Greeting -->
|
||||
<tr>
|
||||
<td style="padding: 36px 32px 24px 32px;">
|
||||
<p style="margin: 0 0 16px 0; font-size: 17px; color: #334155; line-height: 1.6;">
|
||||
Dobrý deň,
|
||||
</p>
|
||||
<p style="margin: 0; font-size: 16px; color: #475569; line-height: 1.7;">
|
||||
pripravili sme pre Vás súhrn všetkých potrebných organizačných informácií k Vášmu kurzu. <strong style="color: #334155;">Potvrďte nám prosím prečítanie tohto e-mailu.</strong>
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<!-- Course Info Card -->
|
||||
<tr>
|
||||
<td style="padding: 0 32px;">
|
||||
<table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%" style="background: linear-gradient(135deg, #f8fafc 0%, #f1f5f9 100%); border-radius: 16px; border: 1px solid #e2e8f0; overflow: hidden;">
|
||||
<!-- Course Header -->
|
||||
<tr>
|
||||
<td style="background: linear-gradient(135deg, #10b981 0%, #059669 100%); padding: 16px 24px;">
|
||||
<p style="margin: 0; font-size: 11px; font-weight: 700; color: rgba(255,255,255,0.8); text-transform: uppercase; letter-spacing: 1px;">
|
||||
Kurz
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="padding: 24px;">
|
||||
<!-- Course Name -->
|
||||
<h2 style="margin: 0 0 20px 0; font-size: 24px; font-weight: 700; color: #0f172a; line-height: 1.3;">
|
||||
{{courseName}}
|
||||
</h2>
|
||||
|
||||
<!-- Date & Time Row -->
|
||||
<table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%">
|
||||
<tr>
|
||||
<td width="50%" style="vertical-align: top; padding-right: 12px;">
|
||||
<div style="background-color: #ffffff; border-radius: 12px; padding: 16px; border: 1px solid #e2e8f0;">
|
||||
<p style="margin: 0 0 4px 0; font-size: 11px; font-weight: 600; color: #64748b; text-transform: uppercase; letter-spacing: 0.5px;">
|
||||
📅 Termín
|
||||
</p>
|
||||
<p style="margin: 0; font-size: 17px; font-weight: 700; color: #0f172a;">
|
||||
{{courseDate}}
|
||||
</p>
|
||||
</div>
|
||||
</td>
|
||||
<td width="50%" style="vertical-align: top; padding-left: 12px;">
|
||||
<div style="background-color: #ffffff; border-radius: 12px; padding: 16px; border: 1px solid #e2e8f0;">
|
||||
<p style="margin: 0 0 4px 0; font-size: 11px; font-weight: 600; color: #64748b; text-transform: uppercase; letter-spacing: 0.5px;">
|
||||
🕑 Čas
|
||||
</p>
|
||||
<p style="margin: 0; font-size: 17px; font-weight: 700; color: #0f172a;">
|
||||
09:00 - 15:00
|
||||
</p>
|
||||
<p style="margin: 4px 0 0 0; font-size: 13px; color: #64748b;">
|
||||
+ Diskusia
|
||||
</p>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<!-- Format Info -->
|
||||
<div style="margin-top: 20px; padding: 16px; background-color: #ffffff; border-radius: 12px; border: 1px solid #e2e8f0;">
|
||||
<p style="margin: 0 0 4px 0; font-size: 11px; font-weight: 600; color: #64748b; text-transform: uppercase; letter-spacing: 0.5px;">
|
||||
🎓 Forma školenia
|
||||
</p>
|
||||
<p style="margin: 0; font-size: 15px; color: #334155; line-height: 1.6;">
|
||||
Školenie sa bude konať <strong>prezenčne</strong>. Program bude pozostávať z výukových blokov, s prestávkami 10-15 minút a jednou 45-60 minútovou obedovou prestávkou.
|
||||
</p>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<!-- Tip Box -->
|
||||
<tr>
|
||||
<td style="padding: 24px 32px;">
|
||||
<table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%" style="background: linear-gradient(135deg, #fef3c7 0%, #fde68a 100%); border-radius: 12px; overflow: hidden;">
|
||||
<tr>
|
||||
<td style="padding: 20px 24px;">
|
||||
<table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%">
|
||||
<tr>
|
||||
<td width="40" style="vertical-align: top;">
|
||||
<div style="width: 36px; height: 36px; background-color: #f59e0b; border-radius: 10px; text-align: center; line-height: 36px; font-size: 18px;">
|
||||
💡
|
||||
</div>
|
||||
</td>
|
||||
<td style="vertical-align: top; padding-left: 16px;">
|
||||
<p style="margin: 0 0 4px 0; font-size: 14px; font-weight: 700; color: #92400e;">
|
||||
Tip pre lepší zážitok
|
||||
</p>
|
||||
<p style="margin: 0; font-size: 14px; color: #78350f; line-height: 1.5;">
|
||||
Odporúčame priniesť si vlastný notebook. Budete si môcť vyskúšať AI priamo v akcii počas praktických úloh. V cene školenia je občerstvenie (káva, čaj).
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<!-- Location Section -->
|
||||
<tr>
|
||||
<td style="padding: 0 32px;">
|
||||
<table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%" style="background: linear-gradient(135deg, #ecfdf5 0%, #d1fae5 100%); border-radius: 16px; border: 1px solid #a7f3d0; overflow: hidden;">
|
||||
<tr>
|
||||
<td style="padding: 24px;">
|
||||
<table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%">
|
||||
<tr>
|
||||
<td width="48" style="vertical-align: top;">
|
||||
<div style="width: 44px; height: 44px; background: linear-gradient(135deg, #10b981 0%, #059669 100%); border-radius: 12px; text-align: center; line-height: 44px; font-size: 20px;">
|
||||
📍
|
||||
</div>
|
||||
</td>
|
||||
<td style="vertical-align: top; padding-left: 16px;">
|
||||
<p style="margin: 0 0 4px 0; font-size: 11px; font-weight: 700; color: #059669; text-transform: uppercase; letter-spacing: 1px;">
|
||||
Miesto konania
|
||||
</p>
|
||||
<p style="margin: 0 0 4px 0; font-size: 20px; font-weight: 700; color: #064e3b;">
|
||||
INBOX SK s.r.o.
|
||||
</p>
|
||||
<p style="margin: 0; font-size: 15px; color: #065f46; line-height: 1.5;">
|
||||
Seberíniho 1, Bratislava<br>
|
||||
<strong>7. poschodie vpravo</strong>
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<!-- Transport Section -->
|
||||
<tr>
|
||||
<td style="padding: 24px 32px;">
|
||||
<h3 style="margin: 0 0 20px 0; font-size: 18px; font-weight: 700; color: #0f172a;">
|
||||
🚌 Doprava a parkovanie
|
||||
</h3>
|
||||
|
||||
<!-- Transport Options -->
|
||||
<table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%" style="background-color: #f8fafc; border-radius: 12px; border: 1px solid #e2e8f0;">
|
||||
<tr>
|
||||
<td style="padding: 20px;">
|
||||
<table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%">
|
||||
<tr>
|
||||
<td style="padding-bottom: 16px; border-bottom: 1px solid #e2e8f0;">
|
||||
<table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%">
|
||||
<tr>
|
||||
<td width="36" style="vertical-align: top;">
|
||||
<div style="width: 28px; height: 28px; background: linear-gradient(135deg, #3b82f6 0%, #2563eb 100%); border-radius: 8px; text-align: center; line-height: 28px; font-size: 14px; color: #ffffff; font-weight: 700;">
|
||||
B
|
||||
</div>
|
||||
</td>
|
||||
<td style="vertical-align: top; padding-left: 12px;">
|
||||
<p style="margin: 0; font-size: 14px; color: #334155;">
|
||||
<strong>Autobusom:</strong> Nevädzová (66, 75, 96), Tomášikova (50)
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="padding: 16px 0; border-bottom: 1px solid #e2e8f0;">
|
||||
<table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%">
|
||||
<tr>
|
||||
<td width="36" style="vertical-align: top;">
|
||||
<div style="width: 28px; height: 28px; background: linear-gradient(135deg, #ec4899 0%, #db2777 100%); border-radius: 8px; text-align: center; line-height: 28px; font-size: 14px; color: #ffffff; font-weight: 700;">
|
||||
T
|
||||
</div>
|
||||
</td>
|
||||
<td style="vertical-align: top; padding-left: 12px;">
|
||||
<p style="margin: 0; font-size: 14px; color: #334155;">
|
||||
<strong>Trolejbusom:</strong> Gagarinova (71, 72)
|
||||
</p>
|
||||
<p style="margin: 4px 0 0 0; font-size: 13px; color: #64748b;">
|
||||
Z Hlavnej stanice trolejbus 71, z Autobusovej stanice trolejbus 72
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="padding: 16px 0; border-bottom: 1px solid #e2e8f0;">
|
||||
<table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%">
|
||||
<tr>
|
||||
<td width="36" style="vertical-align: top;">
|
||||
<div style="width: 28px; height: 28px; background: linear-gradient(135deg, #eab308 0%, #ca8a04 100%); border-radius: 8px; text-align: center; line-height: 28px; font-size: 14px; color: #ffffff; font-weight: 700;">
|
||||
E
|
||||
</div>
|
||||
</td>
|
||||
<td style="vertical-align: top; padding-left: 12px;">
|
||||
<p style="margin: 0; font-size: 14px; color: #334155;">
|
||||
<strong>Električkou:</strong> Tomášikova (9)
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="padding-top: 16px;">
|
||||
<table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%">
|
||||
<tr>
|
||||
<td width="36" style="vertical-align: top;">
|
||||
<div style="width: 28px; height: 28px; background: linear-gradient(135deg, #64748b 0%, #475569 100%); border-radius: 8px; text-align: center; line-height: 28px; font-size: 14px; color: #ffffff; font-weight: 700;">
|
||||
A
|
||||
</div>
|
||||
</td>
|
||||
<td style="vertical-align: top; padding-left: 12px;">
|
||||
<p style="margin: 0; font-size: 14px; color: #334155;">
|
||||
<strong>Autom:</strong> GPS N 48° 09" 13.295', E 17° 09" 53.773'
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<!-- Parking Info -->
|
||||
<table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%" style="margin-top: 16px; background: linear-gradient(135deg, #fef2f2 0%, #fee2e2 100%); border-radius: 12px; border: 1px solid #fecaca;">
|
||||
<tr>
|
||||
<td style="padding: 20px;">
|
||||
<p style="margin: 0 0 12px 0; font-size: 14px; font-weight: 700; color: #991b1b;">
|
||||
🚗 Parkovanie
|
||||
</p>
|
||||
<ul style="margin: 0; padding: 0 0 0 20px; font-size: 14px; color: #7f1d1d; line-height: 1.7;">
|
||||
<li style="margin-bottom: 6px;">Parkovisko pri budove: <strong>3,70 EUR/hod</strong> (15 min zadarmo)</li>
|
||||
<li style="margin-bottom: 6px;">Hotel Bratislava: <strong>10 EUR/celý deň</strong></li>
|
||||
<li style="margin-bottom: 6px;"><strong>PAAS zóna Ružinov-Pošeň:</strong> 1,50 EUR/hod (od 12:00) - zaparkujete na uliciach Obilná, Jašíkova, Andreja Mráza, Seberíniho, Babušková</li>
|
||||
<li>Parkovisko pred budovou je určené pre nájomníkov, nie pre hostí</li>
|
||||
</ul>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<!-- Map Button -->
|
||||
<tr>
|
||||
<td style="padding: 8px 32px 32px 32px; text-align: center;">
|
||||
<a href="https://www.google.sk/maps/place/Seber%C3%ADniho+482%2F1,+821+04+Bratislava/@48.1537526,17.1627419,17z"
|
||||
style="display: inline-block; padding: 16px 32px; background: linear-gradient(135deg, #10b981 0%, #059669 100%); color: #ffffff; text-decoration: none; font-size: 15px; font-weight: 700; border-radius: 12px; letter-spacing: 0.3px; box-shadow: 0 4px 14px rgba(16, 185, 129, 0.4);">
|
||||
🗺 Zobraziť na mape
|
||||
</a>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<!-- Closing Message -->
|
||||
<tr>
|
||||
<td style="padding: 0 32px 40px 32px; text-align: center;">
|
||||
<div style="width: 60px; height: 4px; background: linear-gradient(90deg, #10b981 0%, #34d399 100%); margin: 0 auto 20px auto; border-radius: 2px;"></div>
|
||||
<p style="margin: 0; font-size: 20px; font-weight: 700; color: #0f172a;">
|
||||
Tešíme sa na Vás!
|
||||
</p>
|
||||
<p style="margin: 8px 0 0 0; font-size: 15px; color: #64748b;">
|
||||
Prajeme Vám veľa úspechov pri školení.
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<!-- Footer -->
|
||||
<tr>
|
||||
<td style="background: linear-gradient(135deg, #0f172a 0%, #1e293b 100%); padding: 32px;">
|
||||
<table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%">
|
||||
<tr>
|
||||
<td style="text-align: center;">
|
||||
<p style="margin: 0 0 16px 0; font-size: 12px; color: #94a3b8;">
|
||||
Tento e-mail je odosielaný účastníkom školenia pred jeho začatím.
|
||||
</p>
|
||||
<table role="presentation" cellspacing="0" cellpadding="0" border="0" style="margin: 0 auto;">
|
||||
<tr>
|
||||
<td style="padding-right: 24px; border-right: 1px solid #334155;">
|
||||
<p style="margin: 0; font-size: 12px; color: #cbd5e1;">
|
||||
INBOX SK s.r.o.<br>
|
||||
Seberíniho 1, 821 03 Bratislava
|
||||
</p>
|
||||
</td>
|
||||
<td style="padding-left: 24px;">
|
||||
<p style="margin: 0; font-size: 12px; color: #cbd5e1;">
|
||||
+421 950 608 326<br>
|
||||
<a href="mailto:info@slovensko.ai" style="color: #10b981; text-decoration: none;">info@slovensko.ai</a>
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<p style="margin: 20px 0 0 0; font-size: 11px; color: #64748b;">
|
||||
IČO: 44813295 | IČ DPH: SK2022842657 | 2621117083/1100 (TatraBanka)
|
||||
</p>
|
||||
<p style="margin: 16px 0 0 0;">
|
||||
<a href="https://www.slovensko.ai" style="color: #10b981; text-decoration: none; font-size: 12px; font-weight: 600;">www.slovensko.ai</a>
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</body>
|
||||
</html>
|
||||
52
src/templates/emails/invitation-email.txt
Normal file
52
src/templates/emails/invitation-email.txt
Normal file
@@ -0,0 +1,52 @@
|
||||
Dobrý deň,
|
||||
|
||||
pripravili sme pre Vás súhrn všetkých potrebných organizačných informácií k Vášmu kurzu.
|
||||
Potvrďte nám prosím prečítanie tohto e-mailu.
|
||||
|
||||
═══════════════════════════════════════════════════════════
|
||||
|
||||
KURZ: {{courseName}}
|
||||
TERMÍN: {{courseDate}}
|
||||
ČAS: 09:00 - 15:00 + Diskusia
|
||||
|
||||
Školenie sa bude konať prezenčne. Program bude pozostávať z výukových blokov, s prestávkami 10-15 minút a jednou 45-60 minútovou obedovou prestávkou.
|
||||
|
||||
TIP: Pre ešte lepší zážitok zo školenia odporúčame priniesť si vlastný notebook. V cene školenia je občerstvenie (káva, čaj).
|
||||
|
||||
═══════════════════════════════════════════════════════════
|
||||
|
||||
MIESTO KONANIA:
|
||||
INBOX SK s.r.o.
|
||||
Seberíniho 1, Bratislava
|
||||
7. poschodie vpravo
|
||||
|
||||
═══════════════════════════════════════════════════════════
|
||||
|
||||
DOPRAVA:
|
||||
• Autobusom: Nevädzová (66, 75, 96), Tomášikova (50)
|
||||
• Trolejbusom: Gagarinova (71, 72)
|
||||
Z Hlavnej stanice trolejbus 71, z Autobusovej stanice trolejbus 72
|
||||
• Električkou: Tomášikova (9)
|
||||
• Autom: GPS N 48° 09" 13.295', E 17° 09" 53.773'
|
||||
|
||||
PARKOVANIE:
|
||||
• Parkovisko pri budove: 3,70 EUR/hod (15 min zadarmo)
|
||||
• Hotel Bratislava: 10 EUR/celý deň
|
||||
• PAAS zóna Ružinov-Pošeň: 1,50 EUR/hod (od 12:00)
|
||||
Zaparkujete na uliciach Obilná, Jašíkova, Andreja Mráza, Seberíniho, Babušková
|
||||
• Parkovisko pred budovou je určené pre nájomníkov, nie pre hostí
|
||||
|
||||
MAPA: https://www.google.sk/maps/place/Seber%C3%ADniho+482%2F1,+821+04+Bratislava/@48.1537526,17.1627419,17z
|
||||
|
||||
═══════════════════════════════════════════════════════════
|
||||
|
||||
Tešíme sa na Vás!
|
||||
Prajeme Vám veľa úspechov pri školení.
|
||||
|
||||
---
|
||||
Tento e-mail je odosielaný účastníkom školenia pred jeho začatím.
|
||||
|
||||
INBOX SK s.r.o., Seberíniho 1, 821 03 Bratislava
|
||||
Kontakt: +421 950 608 326, info@slovensko.ai
|
||||
www.slovensko.ai
|
||||
IČO: 44813295 | IČ DPH: SK2022842657 | 2621117083/1100 (TatraBanka)
|
||||
Reference in New Issue
Block a user