@clink/emails 1.0.3 → 1.0.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/build-emails.d.ts +1 -0
- package/dist/build-emails.js +101 -0
- package/dist/html/supplier/order-received/da.html +39 -0
- package/dist/html/supplier/order-received/en.html +39 -0
- package/dist/index.d.ts +13 -0
- package/{src → dist}/templates/supplier/order-received/da.json +1 -0
- package/{src → dist}/templates/supplier/order-received/en.json +2 -1
- package/package.json +4 -1
- package/src/build-emails.ts +0 -114
- package/src/index.ts +0 -92
- package/tsconfig.json +0 -15
- /package/{src → dist}/layouts/base.mjml +0 -0
- /package/{src → dist}/templates/supplier/order-received/template.mjml +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const fs_1 = __importDefault(require("fs"));
|
|
7
|
+
const path_1 = __importDefault(require("path"));
|
|
8
|
+
const mjml_1 = __importDefault(require("mjml"));
|
|
9
|
+
const repoRoot = path_1.default.join(__dirname, '..');
|
|
10
|
+
const templatesSrcRoot = path_1.default.join(repoRoot, 'src', 'templates');
|
|
11
|
+
const templatesRoot = path_1.default.join(__dirname, 'templates');
|
|
12
|
+
const htmlRoot = path_1.default.join(__dirname, 'html');
|
|
13
|
+
function ensureDir(dir) {
|
|
14
|
+
if (!fs_1.default.existsSync(dir)) {
|
|
15
|
+
fs_1.default.mkdirSync(dir, { recursive: true });
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
function copyDir(src, dest) {
|
|
19
|
+
if (!fs_1.default.existsSync(src))
|
|
20
|
+
return;
|
|
21
|
+
ensureDir(dest);
|
|
22
|
+
const entries = fs_1.default.readdirSync(src, { withFileTypes: true });
|
|
23
|
+
for (const entry of entries) {
|
|
24
|
+
const srcPath = path_1.default.join(src, entry.name);
|
|
25
|
+
const destPath = path_1.default.join(dest, entry.name);
|
|
26
|
+
if (entry.isDirectory()) {
|
|
27
|
+
copyDir(srcPath, destPath);
|
|
28
|
+
}
|
|
29
|
+
else {
|
|
30
|
+
fs_1.default.copyFileSync(srcPath, destPath);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
function read(file) {
|
|
35
|
+
return fs_1.default.readFileSync(file, 'utf8');
|
|
36
|
+
}
|
|
37
|
+
function write(file, content) {
|
|
38
|
+
fs_1.default.mkdirSync(path_1.default.dirname(file), { recursive: true });
|
|
39
|
+
fs_1.default.writeFileSync(file, content);
|
|
40
|
+
}
|
|
41
|
+
function replaceLocaleTokens(mjml, dict) {
|
|
42
|
+
let output = mjml;
|
|
43
|
+
for (const [key, value] of Object.entries(dict)) {
|
|
44
|
+
output = output.split(`[[${key}]]`).join(value);
|
|
45
|
+
}
|
|
46
|
+
return output;
|
|
47
|
+
}
|
|
48
|
+
function getDirectories(root) {
|
|
49
|
+
if (!fs_1.default.existsSync(root))
|
|
50
|
+
return [];
|
|
51
|
+
return fs_1.default
|
|
52
|
+
.readdirSync(root, { withFileTypes: true })
|
|
53
|
+
.filter(d => d.isDirectory())
|
|
54
|
+
.map(d => d.name);
|
|
55
|
+
}
|
|
56
|
+
function getLocaleFiles(templateDir) {
|
|
57
|
+
if (!fs_1.default.existsSync(templateDir))
|
|
58
|
+
return [];
|
|
59
|
+
return fs_1.default
|
|
60
|
+
.readdirSync(templateDir, { withFileTypes: true })
|
|
61
|
+
.filter(f => f.isFile() && f.name.endsWith('.json'))
|
|
62
|
+
.map(f => f.name);
|
|
63
|
+
}
|
|
64
|
+
function buildTemplate(audience, templateName, localeFile) {
|
|
65
|
+
const locale = localeFile.replace(/\.json$/, '');
|
|
66
|
+
const templateDir = path_1.default.join(templatesRoot, audience, templateName);
|
|
67
|
+
const contentPath = path_1.default.join(templateDir, 'template.mjml');
|
|
68
|
+
const translationsPath = path_1.default.join(templateDir, localeFile);
|
|
69
|
+
if (!fs_1.default.existsSync(contentPath))
|
|
70
|
+
return;
|
|
71
|
+
const baseTemplatePath = path_1.default.join(__dirname, 'layouts', 'base.mjml');
|
|
72
|
+
const baseTemplate = read(baseTemplatePath);
|
|
73
|
+
const content = read(contentPath);
|
|
74
|
+
const translations = JSON.parse(read(translationsPath));
|
|
75
|
+
const localizedContent = replaceLocaleTokens(content, translations);
|
|
76
|
+
let mjmlSource = baseTemplate;
|
|
77
|
+
mjmlSource = mjmlSource.replace('%CONTENT%', localizedContent);
|
|
78
|
+
mjmlSource = replaceLocaleTokens(mjmlSource, translations);
|
|
79
|
+
const { html } = (0, mjml_1.default)(mjmlSource, { minify: true });
|
|
80
|
+
const outPath = path_1.default.join(htmlRoot, audience, templateName, `${locale}.html`);
|
|
81
|
+
write(outPath, html);
|
|
82
|
+
}
|
|
83
|
+
function buildAll() {
|
|
84
|
+
copyDir(templatesSrcRoot, templatesRoot);
|
|
85
|
+
const layoutsSrcRoot = path_1.default.join(repoRoot, 'src', 'layouts');
|
|
86
|
+
const layoutsRoot = path_1.default.join(__dirname, 'layouts');
|
|
87
|
+
copyDir(layoutsSrcRoot, layoutsRoot);
|
|
88
|
+
const audiences = getDirectories(templatesRoot);
|
|
89
|
+
for (const audience of audiences) {
|
|
90
|
+
const audienceDir = path_1.default.join(templatesRoot, audience);
|
|
91
|
+
const templateNames = getDirectories(audienceDir);
|
|
92
|
+
for (const templateName of templateNames) {
|
|
93
|
+
const templateDir = path_1.default.join(audienceDir, templateName);
|
|
94
|
+
const localeFiles = getLocaleFiles(templateDir);
|
|
95
|
+
for (const localeFile of localeFiles) {
|
|
96
|
+
buildTemplate(audience, templateName, localeFile);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
buildAll();
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
<!doctype html><html lang="und" dir="auto" xmlns="http://www.w3.org/1999/xhtml" xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office"><head><title></title><!--[if !mso]><!--><meta http-equiv="X-UA-Compatible" content="IE=edge"><!--<![endif]--><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><meta name="viewport" content="width=device-width,initial-scale=1"><style type="text/css">#outlook a { padding:0; }
|
|
2
|
+
body { margin:0;padding:0;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%; }
|
|
3
|
+
table, td { border-collapse:collapse;mso-table-lspace:0pt;mso-table-rspace:0pt; }
|
|
4
|
+
img { border:0;height:auto;line-height:100%; outline:none;text-decoration:none;-ms-interpolation-mode:bicubic; }
|
|
5
|
+
p { display:block;margin:13px 0; }</style><!--[if mso]>
|
|
6
|
+
<noscript>
|
|
7
|
+
<xml>
|
|
8
|
+
<o:OfficeDocumentSettings>
|
|
9
|
+
<o:AllowPNG/>
|
|
10
|
+
<o:PixelsPerInch>96</o:PixelsPerInch>
|
|
11
|
+
</o:OfficeDocumentSettings>
|
|
12
|
+
</xml>
|
|
13
|
+
</noscript>
|
|
14
|
+
<![endif]--><!--[if lte mso 11]>
|
|
15
|
+
<style type="text/css">
|
|
16
|
+
.mj-outlook-group-fix { width:100% !important; }
|
|
17
|
+
</style>
|
|
18
|
+
<![endif]--><!--[if !mso]><!--><link href="undefined" rel="stylesheet" type="text/css"><style type="text/css">@import url(undefined);</style><!--<![endif]--><style type="text/css">@media only screen and (min-width:480px) {
|
|
19
|
+
.mj-column-per-100 { width:100% !important; max-width: 100%; }
|
|
20
|
+
}</style><style media="screen and (min-width:480px)">.moz-text-html .mj-column-per-100 { width:100% !important; max-width: 100%; }</style><style type="text/css">@media only screen and (max-width:479px) {
|
|
21
|
+
table.mj-full-width-mobile { width: 100% !important; }
|
|
22
|
+
td.mj-full-width-mobile { width: auto !important; }
|
|
23
|
+
}</style><style type="text/css">.body-bordered { border-radius: 24px; max-width: 600px; margin: 0 auto;
|
|
24
|
+
outline: none; /* Ensure the border is visible */ } @media (min-width:
|
|
25
|
+
600px) { .body-bordered { border-radius: 24px; max-width: 600px; margin: 0
|
|
26
|
+
auto; margin-top: 40px; outline: 1px solid #D6D6D6 !important; } }
|
|
27
|
+
.discountBox div { border-width: 1px; border-style: dashed; border-color:
|
|
28
|
+
#FCBC42; }</style></head><body style="word-spacing:normal;"><div aria-roledescription="email" class="body-bordered" role="article" lang="und" dir="auto"><!--[if mso | IE]><table align="center" border="0" cellpadding="0" cellspacing="0" class="" role="presentation" style="width:600px;" width="600" bgcolor="#ffffff" ><tr><td style="line-height:0px;font-size:0px;mso-line-height-rule:exactly;"><![endif]--><div style="background:#ffffff;background-color:#ffffff;margin:0px auto;max-width:600px;"><table align="center" border="0" cellpadding="0" cellspacing="0" role="presentation" style="background:#ffffff;background-color:#ffffff;width:100%;"><tbody><tr><td style="direction:ltr;font-size:0px;padding:12px 0px;text-align:center;"><!--[if mso | IE]><table role="presentation" border="0" cellpadding="0" cellspacing="0"><tr><td class="" width="600px" ><table align="center" border="0" cellpadding="0" cellspacing="0" class="" role="presentation" style="width:600px;" width="600" ><tr><td style="line-height:0px;font-size:0px;mso-line-height-rule:exactly;"><![endif]--><div style="margin:0px auto;max-width:600px;"><table align="center" border="0" cellpadding="0" cellspacing="0" role="presentation" style="width:100%;"><tbody><tr><td style="direction:ltr;font-size:0px;padding:24px 0px 0px;text-align:center;"><!--[if mso | IE]><table role="presentation" border="0" cellpadding="0" cellspacing="0"><tr><td class="" style="vertical-align:top;width:600px;" ><![endif]--><div class="mj-column-per-100 mj-outlook-group-fix" style="font-size:0px;text-align:left;direction:ltr;display:inline-block;vertical-align:top;width:100%;"><table border="0" cellpadding="0" cellspacing="0" role="presentation" style="vertical-align:top;" width="100%"><tbody><tr><td align="left" style="font-size:0px;padding:0px 24px 8px;word-break:break-word;"><table border="0" cellpadding="0" cellspacing="0" role="presentation" style="border-collapse:collapse;border-spacing:0px;"><tbody><tr><td style="width:40px;"><img alt="Nuento" src="https://ik.imagekit.io/nuento/logo/Logomark_Uj47FzOvV.png" style="border:0;display:block;outline:none;text-decoration:none;height:40px;width:100%;font-size:16px;" width="40" height="40"></td></tr></tbody></table></td></tr></tbody></table></div><!--[if mso | IE]></td></tr></table><![endif]--></td></tr></tbody></table></div><!--[if mso | IE]></td></tr></table></td></tr><tr><td class="" width="600px" ><table align="center" border="0" cellpadding="0" cellspacing="0" class="" role="presentation" style="width:600px;" width="600" ><tr><td style="line-height:0px;font-size:0px;mso-line-height-rule:exactly;"><![endif]--><div style="margin:0px auto;max-width:600px;"><table align="center" border="0" cellpadding="0" cellspacing="0" role="presentation" style="width:100%;"><tbody><tr><td style="direction:ltr;font-size:0px;padding:0px;text-align:center;"><!--[if mso | IE]><table role="presentation" border="0" cellpadding="0" cellspacing="0"><tr><td class="" style="vertical-align:top;width:600px;" ><![endif]--><div class="mj-column-per-100 mj-outlook-group-fix" style="font-size:0px;text-align:left;direction:ltr;display:inline-block;vertical-align:top;width:100%;"><table border="0" cellpadding="0" cellspacing="0" role="presentation" style="vertical-align:top;" width="100%"><tbody><tr><td align="left" style="font-size:0px;padding:0px 24px;word-break:break-word;"><div style="font-family:Arial, sans-serif;font-size:16px;line-height:24px;text-align:left;color:#222730;"><p style="line-height: 24px; margin: 16px
|
|
29
|
+
0px;">Hej {{ catering.contact.name }},</p><p style="line-height: 24px; margin: 16px
|
|
30
|
+
0px;">Du har modtaget en ny bestilling via Nuento med ordrenr. {{ catering_order.id8digit }}.</p></div></td></tr></tbody></table></div><!--[if mso | IE]></td></tr></table><![endif]--></td></tr></tbody></table></div><!--[if mso | IE]></td></tr></table></td></tr><tr><td class="" width="600px" ><table align="center" border="0" cellpadding="0" cellspacing="0" class="" role="presentation" style="width:600px;" width="600" ><tr><td style="line-height:0px;font-size:0px;mso-line-height-rule:exactly;"><![endif]--><div style="margin:0px auto;max-width:600px;"><table align="center" border="0" cellpadding="0" cellspacing="0" role="presentation" style="width:100%;"><tbody><tr><td style="direction:ltr;font-size:0px;padding:0px;text-align:center;"><!--[if mso | IE]><table role="presentation" border="0" cellpadding="0" cellspacing="0"><tr><td class="" style="vertical-align:top;width:600px;" ><![endif]--><div class="mj-column-per-100 mj-outlook-group-fix" style="font-size:0px;text-align:left;direction:ltr;display:inline-block;vertical-align:top;width:100%;"><table border="0" cellpadding="0" cellspacing="0" role="presentation" style="vertical-align:top;" width="100%"><tbody><tr><td align="left" class="btn-link" style="font-size:0px;padding:10px 25px;word-break:break-word;"><table border="0" cellpadding="0" cellspacing="0" role="presentation" style="border-collapse:separate;line-height:100%;"><tbody><tr><td align="center" bgcolor="#11141A" role="presentation" style="border:none;border-radius:999px;cursor:auto;mso-padding-alt:10px 25px;background:#11141A;" valign="middle"><a href="{{{ catering_order.approvalUrl }}}" style="background-color: #FA3232; align: left; display: inline-block; background: #11141A; color: #ffffff; font-family: Arial, sans-serif; font-size: 16px; font-weight: normal; line-height: 24px; margin: 0; text-decoration: none; text-transform: none; padding: 10px 25px; mso-padding-alt: 0px; border-radius: 999px;" target="_blank">Svar på ordre</a></td></tr></tbody></table></td></tr></tbody></table></div><!--[if mso | IE]></td></tr></table><![endif]--></td></tr></tbody></table></div><!--[if mso | IE]></td></tr></table></td></tr><![endif]--> {{#if catering_order.paymentLinkName}}<!--[if mso | IE]><tr><td class="" width="600px" ><table align="center" border="0" cellpadding="0" cellspacing="0" class="" role="presentation" style="width:600px;" width="600" ><tr><td style="line-height:0px;font-size:0px;mso-line-height-rule:exactly;"><![endif]--><div style="margin:0px auto;max-width:600px;"><table align="center" border="0" cellpadding="0" cellspacing="0" role="presentation" style="width:100%;"><tbody><tr><td style="direction:ltr;font-size:0px;padding:0px;text-align:center;"><!--[if mso | IE]><table role="presentation" border="0" cellpadding="0" cellspacing="0"><tr><td class="" style="vertical-align:top;width:600px;" ><![endif]--><div class="mj-column-per-100 mj-outlook-group-fix" style="font-size:0px;text-align:left;direction:ltr;display:inline-block;vertical-align:top;width:100%;"><table border="0" cellpadding="0" cellspacing="0" role="presentation" style="vertical-align:top;" width="100%"><tbody><tr><td align="left" style="font-size:0px;padding:0px 24px;word-break:break-word;"><div style="font-family:Arial, sans-serif;font-size:16px;line-height:24px;text-align:left;color:#222730;"><p style="line-height: 24px; margin: 16px
|
|
31
|
+
0px;">Ordren er blevet gennemført på baggrund af et bestillingslink med følgende betegnelse:</p></div></td></tr></tbody></table></div><!--[if mso | IE]></td></tr></table><![endif]--></td></tr></tbody></table></div><!--[if mso | IE]></td></tr></table></td></tr><tr><td class="" width="600px" ><table align="center" border="0" cellpadding="0" cellspacing="0" class="" role="presentation" style="width:600px;" width="600" ><tr><td style="line-height:0px;font-size:0px;mso-line-height-rule:exactly;"><![endif]--><div style="margin:0px auto;max-width:600px;"><table align="center" border="0" cellpadding="0" cellspacing="0" role="presentation" style="width:100%;"><tbody><tr><td style="direction:ltr;font-size:0px;padding:0px;padding-bottom:10px;padding-left:16px;padding-right:16px;padding-top:10px;text-align:center;"><!--[if mso | IE]><table role="presentation" border="0" cellpadding="0" cellspacing="0"><tr><td class="" style="vertical-align:top;width:568px;" ><![endif]--><div class="mj-column-per-100 mj-outlook-group-fix" style="font-size:0px;text-align:left;direction:ltr;display:inline-block;vertical-align:top;width:100%;"><table border="0" cellpadding="0" cellspacing="0" role="presentation" style="background-color:#E6F7FF;border-radius:8px;vertical-align:top;border-collapse:separate;" width="100%"><tbody><tr><td align="center" style="font-size:0px;padding:0px 24px;word-break:break-word;"><div style="font-family:Arial, sans-serif;font-size:16px;line-height:24px;text-align:center;color:#222730;"><p style="line-height: 24px; margin: 16px
|
|
32
|
+
0px;"><i style="line-height: 24px;">{{{catering_order.paymentLinkName}}}</i></p></div></td></tr></tbody></table></div><!--[if mso | IE]></td></tr></table><![endif]--></td></tr></tbody></table></div><!--[if mso | IE]></td></tr></table></td></tr><![endif]--> {{/if}}<!--[if mso | IE]><tr><td class="" width="600px" ><table align="center" border="0" cellpadding="0" cellspacing="0" class="" role="presentation" style="width:600px;" width="600" ><tr><td style="line-height:0px;font-size:0px;mso-line-height-rule:exactly;"><![endif]--><div style="margin:0px auto;max-width:600px;"><table align="center" border="0" cellpadding="0" cellspacing="0" role="presentation" style="width:100%;"><tbody><tr><td style="direction:ltr;font-size:0px;padding:0px;padding-bottom:10px;padding-top:10px;text-align:center;"><!--[if mso | IE]><table role="presentation" border="0" cellpadding="0" cellspacing="0"><tr><td class="" style="vertical-align:top;width:600px;" ><![endif]--><div class="mj-column-per-100 mj-outlook-group-fix" style="font-size:0px;text-align:left;direction:ltr;display:inline-block;vertical-align:top;width:100%;"><table border="0" cellpadding="0" cellspacing="0" role="presentation" style="vertical-align:top;" width="100%"><tbody><tr><td align="left" style="font-size:0px;padding:0px 24px;word-break:break-word;"><div style="font-family:Arial, sans-serif;font-size:16px;line-height:24px;text-align:left;color:#222730;"><p style="line-height: 24px; margin: 16px
|
|
33
|
+
0px;"><font size="4">Levering {{ catering_order.selectedDate }} til spisetid kl. {{ catering_order.selectedTime }}</font></p><p style="line-height: 24px; margin: 16px
|
|
34
|
+
0px;"><font size="4">Samlet ordrestørrelse</font><br><font size="4"><b style="line-height: 24px;">{{ invoice.price.total }}</b></font></p></div></td></tr></tbody></table></div><!--[if mso | IE]></td></tr></table><![endif]--></td></tr></tbody></table></div><!--[if mso | IE]></td></tr></table></td></tr><tr><td class="" width="600px" ><table align="center" border="0" cellpadding="0" cellspacing="0" class="" role="presentation" style="width:600px;" width="600" ><tr><td style="line-height:0px;font-size:0px;mso-line-height-rule:exactly;"><![endif]--><div style="margin:0px auto;max-width:600px;"><table align="center" border="0" cellpadding="0" cellspacing="0" role="presentation" style="width:100%;"><tbody><tr><td style="direction:ltr;font-size:0px;padding:0px;text-align:center;"><!--[if mso | IE]><table role="presentation" border="0" cellpadding="0" cellspacing="0"><tr><td class="" style="vertical-align:top;width:600px;" ><![endif]--><div class="mj-column-per-100 mj-outlook-group-fix" style="font-size:0px;text-align:left;direction:ltr;display:inline-block;vertical-align:top;width:100%;"><table border="0" cellpadding="0" cellspacing="0" role="presentation" style="vertical-align:top;" width="100%"><tbody><tr><td align="center" style="font-size:0px;padding:16px 0px 8px 0px;word-break:break-word;"><p style="line-height: 24px; border-top: solid 1px #dadada; font-size: 1px; margin: 0px auto; width: 100%;"></p><!--[if mso | IE]><table align="center" border="0" cellpadding="0" cellspacing="0" style="border-top:solid 1px #dadada;font-size:1px;margin:0px auto;width:600px;" role="presentation" width="600px" ><tr><td style="height:0;line-height:0;">
|
|
35
|
+
</td></tr></table><![endif]--></td></tr></tbody></table></div><!--[if mso | IE]></td></tr></table><![endif]--></td></tr></tbody></table></div><!--[if mso | IE]></td></tr></table></td></tr><tr><td class="" width="600px" ><table align="center" border="0" cellpadding="0" cellspacing="0" class="" role="presentation" style="width:600px;" width="600" ><tr><td style="line-height:0px;font-size:0px;mso-line-height-rule:exactly;"><![endif]--><div style="margin:0px auto;max-width:600px;"><table align="center" border="0" cellpadding="0" cellspacing="0" role="presentation" style="width:100%;"><tbody><tr><td style="direction:ltr;font-size:0px;padding:0px;padding-bottom:10px;padding-top:10px;text-align:center;"><!--[if mso | IE]><table role="presentation" border="0" cellpadding="0" cellspacing="0"><tr><td class="" style="vertical-align:top;width:600px;" ><![endif]--><div class="mj-column-per-100 mj-outlook-group-fix" style="font-size:0px;text-align:left;direction:ltr;display:inline-block;vertical-align:top;width:100%;"><table border="0" cellpadding="0" cellspacing="0" role="presentation" style="vertical-align:top;" width="100%"><tbody><tr><td align="left" style="font-size:0px;padding:0px 24px;word-break:break-word;"><div style="font-family:Arial, sans-serif;font-size:16px;line-height:24px;text-align:left;color:#222730;"><p style="line-height: 24px; margin: 16px
|
|
36
|
+
0px;"><font size="4"><b style="line-height: 24px;">Har du brug for hjælp?</b></font></p><p style="line-height: 24px; margin: 16px
|
|
37
|
+
0px;">Så tøv ikke med at kontakte os.</p><p style="line-height: 24px; margin: 16px
|
|
38
|
+
0px;">{{ support.email }}<br><a href="tel:{{ support.phone }}" style="line-height: 24px; text-decoration: underline;">{{ support.phone }}</a></p></div></td></tr></tbody></table></div><!--[if mso | IE]></td></tr></table><![endif]--></td></tr></tbody></table></div><!--[if mso | IE]></td></tr></table></td></tr><tr><td class="" width="600px" ><table align="center" border="0" cellpadding="0" cellspacing="0" class="" role="presentation" style="width:600px;" width="600" ><tr><td style="line-height:0px;font-size:0px;mso-line-height-rule:exactly;"><![endif]--><div style="margin:0px auto;max-width:600px;"><table align="center" border="0" cellpadding="0" cellspacing="0" role="presentation" style="width:100%;"><tbody><tr><td style="direction:ltr;font-size:0px;padding:0px;text-align:center;"><!--[if mso | IE]><table role="presentation" border="0" cellpadding="0" cellspacing="0"><tr><td class="" style="vertical-align:top;width:600px;" ><![endif]--><div class="mj-column-per-100 mj-outlook-group-fix" style="font-size:0px;text-align:left;direction:ltr;display:inline-block;vertical-align:top;width:100%;"><table border="0" cellpadding="0" cellspacing="0" role="presentation" style="vertical-align:top;" width="100%"><tbody><tr><td align="center" style="font-size:0px;padding:16px 0px 8px 0px;word-break:break-word;"><p style="line-height: 24px; border-top: solid 1px #dadada; font-size: 1px; margin: 0px auto; width: 100%;"></p><!--[if mso | IE]><table align="center" border="0" cellpadding="0" cellspacing="0" style="border-top:solid 1px #dadada;font-size:1px;margin:0px auto;width:600px;" role="presentation" width="600px" ><tr><td style="height:0;line-height:0;">
|
|
39
|
+
</td></tr></table><![endif]--></td></tr></tbody></table></div><!--[if mso | IE]></td></tr></table><![endif]--></td></tr></tbody></table></div><!--[if mso | IE]></td></tr></table></td></tr><tr><td class="" width="600px" ><table align="center" border="0" cellpadding="0" cellspacing="0" class="" role="presentation" style="width:600px;" width="600" ><tr><td style="line-height:0px;font-size:0px;mso-line-height-rule:exactly;"><![endif]--><div style="margin:0px auto;max-width:600px;"><table align="center" border="0" cellpadding="0" cellspacing="0" role="presentation" style="width:100%;"><tbody><tr><td style="direction:ltr;font-size:0px;padding:0px;text-align:center;"><!--[if mso | IE]><table role="presentation" border="0" cellpadding="0" cellspacing="0"><tr><td class="" style="vertical-align:top;width:600px;" ><![endif]--><div class="mj-column-per-100 mj-outlook-group-fix" style="font-size:0px;text-align:left;direction:ltr;display:inline-block;vertical-align:top;width:100%;"><table border="0" cellpadding="0" cellspacing="0" role="presentation" style="vertical-align:top;" width="100%"><tbody><tr><td align="left" style="font-size:0px;padding:24px 24px 0px;word-break:break-word;"><div style="font-family:Arial, sans-serif;font-size:16px;line-height:24px;text-align:left;color:#222730;"><b style="line-height: 24px;">Sendt fra</b><br>Nuento Denmark ApS, CVR 39000725<br>Lundeborgvej 4, 9220 Aalborg</div></td></tr></tbody></table></div><!--[if mso | IE]></td></tr></table><![endif]--></td></tr></tbody></table></div><!--[if mso | IE]></td></tr></table></td></tr><tr><td class="" width="600px" ><table align="center" border="0" cellpadding="0" cellspacing="0" class="" role="presentation" style="width:600px;" width="600" ><tr><td style="line-height:0px;font-size:0px;mso-line-height-rule:exactly;"><![endif]--><div style="margin:0px auto;max-width:600px;"><table align="center" border="0" cellpadding="0" cellspacing="0" role="presentation" style="width:100%;"><tbody><tr><td style="direction:ltr;font-size:0px;padding:32px 0px 0px;text-align:center;"><!--[if mso | IE]><table role="presentation" border="0" cellpadding="0" cellspacing="0"><tr><td class="" style="vertical-align:top;width:600px;" ><![endif]--><div class="mj-column-per-100 mj-outlook-group-fix" style="font-size:0px;text-align:left;direction:ltr;display:inline-block;vertical-align:top;width:100%;"><table border="0" cellpadding="0" cellspacing="0" role="presentation" style="vertical-align:top;" width="100%"><tbody><tr><td align="left" style="font-size:0px;padding:0px 24px 24px;word-break:break-word;"><table border="0" cellpadding="0" cellspacing="0" role="presentation" style="border-collapse:collapse;border-spacing:0px;"><tbody><tr><td style="width:118px;"><img alt="Nuento" src="https://ik.imagekit.io/nuento/logo/logo-40_5iYF6s3Jp.png" style="border:0;display:block;outline:none;text-decoration:none;height:40px;width:100%;font-size:16px;" width="118" height="40"></td></tr></tbody></table></td></tr></tbody></table></div><!--[if mso | IE]></td></tr></table><![endif]--></td></tr></tbody></table></div><!--[if mso | IE]></td></tr></table></td></tr></table><![endif]--></td></tr></tbody></table></div><!--[if mso | IE]></td></tr></table><![endif]--></div></body></html>
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
<!doctype html><html lang="und" dir="auto" xmlns="http://www.w3.org/1999/xhtml" xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office"><head><title></title><!--[if !mso]><!--><meta http-equiv="X-UA-Compatible" content="IE=edge"><!--<![endif]--><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><meta name="viewport" content="width=device-width,initial-scale=1"><style type="text/css">#outlook a { padding:0; }
|
|
2
|
+
body { margin:0;padding:0;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%; }
|
|
3
|
+
table, td { border-collapse:collapse;mso-table-lspace:0pt;mso-table-rspace:0pt; }
|
|
4
|
+
img { border:0;height:auto;line-height:100%; outline:none;text-decoration:none;-ms-interpolation-mode:bicubic; }
|
|
5
|
+
p { display:block;margin:13px 0; }</style><!--[if mso]>
|
|
6
|
+
<noscript>
|
|
7
|
+
<xml>
|
|
8
|
+
<o:OfficeDocumentSettings>
|
|
9
|
+
<o:AllowPNG/>
|
|
10
|
+
<o:PixelsPerInch>96</o:PixelsPerInch>
|
|
11
|
+
</o:OfficeDocumentSettings>
|
|
12
|
+
</xml>
|
|
13
|
+
</noscript>
|
|
14
|
+
<![endif]--><!--[if lte mso 11]>
|
|
15
|
+
<style type="text/css">
|
|
16
|
+
.mj-outlook-group-fix { width:100% !important; }
|
|
17
|
+
</style>
|
|
18
|
+
<![endif]--><!--[if !mso]><!--><link href="undefined" rel="stylesheet" type="text/css"><style type="text/css">@import url(undefined);</style><!--<![endif]--><style type="text/css">@media only screen and (min-width:480px) {
|
|
19
|
+
.mj-column-per-100 { width:100% !important; max-width: 100%; }
|
|
20
|
+
}</style><style media="screen and (min-width:480px)">.moz-text-html .mj-column-per-100 { width:100% !important; max-width: 100%; }</style><style type="text/css">@media only screen and (max-width:479px) {
|
|
21
|
+
table.mj-full-width-mobile { width: 100% !important; }
|
|
22
|
+
td.mj-full-width-mobile { width: auto !important; }
|
|
23
|
+
}</style><style type="text/css">.body-bordered { border-radius: 24px; max-width: 600px; margin: 0 auto;
|
|
24
|
+
outline: none; /* Ensure the border is visible */ } @media (min-width:
|
|
25
|
+
600px) { .body-bordered { border-radius: 24px; max-width: 600px; margin: 0
|
|
26
|
+
auto; margin-top: 40px; outline: 1px solid #D6D6D6 !important; } }
|
|
27
|
+
.discountBox div { border-width: 1px; border-style: dashed; border-color:
|
|
28
|
+
#FCBC42; }</style></head><body style="word-spacing:normal;"><div aria-roledescription="email" class="body-bordered" role="article" lang="und" dir="auto"><!--[if mso | IE]><table align="center" border="0" cellpadding="0" cellspacing="0" class="" role="presentation" style="width:600px;" width="600" bgcolor="#ffffff" ><tr><td style="line-height:0px;font-size:0px;mso-line-height-rule:exactly;"><![endif]--><div style="background:#ffffff;background-color:#ffffff;margin:0px auto;max-width:600px;"><table align="center" border="0" cellpadding="0" cellspacing="0" role="presentation" style="background:#ffffff;background-color:#ffffff;width:100%;"><tbody><tr><td style="direction:ltr;font-size:0px;padding:12px 0px;text-align:center;"><!--[if mso | IE]><table role="presentation" border="0" cellpadding="0" cellspacing="0"><tr><td class="" width="600px" ><table align="center" border="0" cellpadding="0" cellspacing="0" class="" role="presentation" style="width:600px;" width="600" ><tr><td style="line-height:0px;font-size:0px;mso-line-height-rule:exactly;"><![endif]--><div style="margin:0px auto;max-width:600px;"><table align="center" border="0" cellpadding="0" cellspacing="0" role="presentation" style="width:100%;"><tbody><tr><td style="direction:ltr;font-size:0px;padding:24px 0px 0px;text-align:center;"><!--[if mso | IE]><table role="presentation" border="0" cellpadding="0" cellspacing="0"><tr><td class="" style="vertical-align:top;width:600px;" ><![endif]--><div class="mj-column-per-100 mj-outlook-group-fix" style="font-size:0px;text-align:left;direction:ltr;display:inline-block;vertical-align:top;width:100%;"><table border="0" cellpadding="0" cellspacing="0" role="presentation" style="vertical-align:top;" width="100%"><tbody><tr><td align="left" style="font-size:0px;padding:0px 24px 8px;word-break:break-word;"><table border="0" cellpadding="0" cellspacing="0" role="presentation" style="border-collapse:collapse;border-spacing:0px;"><tbody><tr><td style="width:40px;"><img alt="Nuento" src="https://ik.imagekit.io/nuento/logo/Logomark_Uj47FzOvV.png" style="border:0;display:block;outline:none;text-decoration:none;height:40px;width:100%;font-size:16px;" width="40" height="40"></td></tr></tbody></table></td></tr></tbody></table></div><!--[if mso | IE]></td></tr></table><![endif]--></td></tr></tbody></table></div><!--[if mso | IE]></td></tr></table></td></tr><tr><td class="" width="600px" ><table align="center" border="0" cellpadding="0" cellspacing="0" class="" role="presentation" style="width:600px;" width="600" ><tr><td style="line-height:0px;font-size:0px;mso-line-height-rule:exactly;"><![endif]--><div style="margin:0px auto;max-width:600px;"><table align="center" border="0" cellpadding="0" cellspacing="0" role="presentation" style="width:100%;"><tbody><tr><td style="direction:ltr;font-size:0px;padding:0px;text-align:center;"><!--[if mso | IE]><table role="presentation" border="0" cellpadding="0" cellspacing="0"><tr><td class="" style="vertical-align:top;width:600px;" ><![endif]--><div class="mj-column-per-100 mj-outlook-group-fix" style="font-size:0px;text-align:left;direction:ltr;display:inline-block;vertical-align:top;width:100%;"><table border="0" cellpadding="0" cellspacing="0" role="presentation" style="vertical-align:top;" width="100%"><tbody><tr><td align="left" style="font-size:0px;padding:0px 24px;word-break:break-word;"><div style="font-family:Arial, sans-serif;font-size:16px;line-height:24px;text-align:left;color:#222730;"><p style="line-height: 24px; margin: 16px
|
|
29
|
+
0px;">Hi {{ catering.contact.name }},</p><p style="line-height: 24px; margin: 16px
|
|
30
|
+
0px;">You have received a new order via Nuento with order no. {{ catering_order.id8digit }}.</p></div></td></tr></tbody></table></div><!--[if mso | IE]></td></tr></table><![endif]--></td></tr></tbody></table></div><!--[if mso | IE]></td></tr></table></td></tr><tr><td class="" width="600px" ><table align="center" border="0" cellpadding="0" cellspacing="0" class="" role="presentation" style="width:600px;" width="600" ><tr><td style="line-height:0px;font-size:0px;mso-line-height-rule:exactly;"><![endif]--><div style="margin:0px auto;max-width:600px;"><table align="center" border="0" cellpadding="0" cellspacing="0" role="presentation" style="width:100%;"><tbody><tr><td style="direction:ltr;font-size:0px;padding:0px;text-align:center;"><!--[if mso | IE]><table role="presentation" border="0" cellpadding="0" cellspacing="0"><tr><td class="" style="vertical-align:top;width:600px;" ><![endif]--><div class="mj-column-per-100 mj-outlook-group-fix" style="font-size:0px;text-align:left;direction:ltr;display:inline-block;vertical-align:top;width:100%;"><table border="0" cellpadding="0" cellspacing="0" role="presentation" style="vertical-align:top;" width="100%"><tbody><tr><td align="left" class="btn-link" style="font-size:0px;padding:10px 25px;word-break:break-word;"><table border="0" cellpadding="0" cellspacing="0" role="presentation" style="border-collapse:separate;line-height:100%;"><tbody><tr><td align="center" bgcolor="#11141A" role="presentation" style="border:none;border-radius:999px;cursor:auto;mso-padding-alt:10px 25px;background:#11141A;" valign="middle"><a href="{{{ catering_order.approvalUrl }}}" style="background-color: #FA3232; align: left; display: inline-block; background: #11141A; color: #ffffff; font-family: Arial, sans-serif; font-size: 16px; font-weight: normal; line-height: 24px; margin: 0; text-decoration: none; text-transform: none; padding: 10px 25px; mso-padding-alt: 0px; border-radius: 999px;" target="_blank">Respond to order</a></td></tr></tbody></table></td></tr></tbody></table></div><!--[if mso | IE]></td></tr></table><![endif]--></td></tr></tbody></table></div><!--[if mso | IE]></td></tr></table></td></tr><![endif]--> {{#if catering_order.paymentLinkName}}<!--[if mso | IE]><tr><td class="" width="600px" ><table align="center" border="0" cellpadding="0" cellspacing="0" class="" role="presentation" style="width:600px;" width="600" ><tr><td style="line-height:0px;font-size:0px;mso-line-height-rule:exactly;"><![endif]--><div style="margin:0px auto;max-width:600px;"><table align="center" border="0" cellpadding="0" cellspacing="0" role="presentation" style="width:100%;"><tbody><tr><td style="direction:ltr;font-size:0px;padding:0px;text-align:center;"><!--[if mso | IE]><table role="presentation" border="0" cellpadding="0" cellspacing="0"><tr><td class="" style="vertical-align:top;width:600px;" ><![endif]--><div class="mj-column-per-100 mj-outlook-group-fix" style="font-size:0px;text-align:left;direction:ltr;display:inline-block;vertical-align:top;width:100%;"><table border="0" cellpadding="0" cellspacing="0" role="presentation" style="vertical-align:top;" width="100%"><tbody><tr><td align="left" style="font-size:0px;padding:0px 24px;word-break:break-word;"><div style="font-family:Arial, sans-serif;font-size:16px;line-height:24px;text-align:left;color:#222730;"><p style="line-height: 24px; margin: 16px
|
|
31
|
+
0px;">The order was placed using an order link with the following label:</p></div></td></tr></tbody></table></div><!--[if mso | IE]></td></tr></table><![endif]--></td></tr></tbody></table></div><!--[if mso | IE]></td></tr></table></td></tr><tr><td class="" width="600px" ><table align="center" border="0" cellpadding="0" cellspacing="0" class="" role="presentation" style="width:600px;" width="600" ><tr><td style="line-height:0px;font-size:0px;mso-line-height-rule:exactly;"><![endif]--><div style="margin:0px auto;max-width:600px;"><table align="center" border="0" cellpadding="0" cellspacing="0" role="presentation" style="width:100%;"><tbody><tr><td style="direction:ltr;font-size:0px;padding:0px;padding-bottom:10px;padding-left:16px;padding-right:16px;padding-top:10px;text-align:center;"><!--[if mso | IE]><table role="presentation" border="0" cellpadding="0" cellspacing="0"><tr><td class="" style="vertical-align:top;width:568px;" ><![endif]--><div class="mj-column-per-100 mj-outlook-group-fix" style="font-size:0px;text-align:left;direction:ltr;display:inline-block;vertical-align:top;width:100%;"><table border="0" cellpadding="0" cellspacing="0" role="presentation" style="background-color:#E6F7FF;border-radius:8px;vertical-align:top;border-collapse:separate;" width="100%"><tbody><tr><td align="center" style="font-size:0px;padding:0px 24px;word-break:break-word;"><div style="font-family:Arial, sans-serif;font-size:16px;line-height:24px;text-align:center;color:#222730;"><p style="line-height: 24px; margin: 16px
|
|
32
|
+
0px;"><i style="line-height: 24px;">{{{catering_order.paymentLinkName}}}</i></p></div></td></tr></tbody></table></div><!--[if mso | IE]></td></tr></table><![endif]--></td></tr></tbody></table></div><!--[if mso | IE]></td></tr></table></td></tr><![endif]--> {{/if}}<!--[if mso | IE]><tr><td class="" width="600px" ><table align="center" border="0" cellpadding="0" cellspacing="0" class="" role="presentation" style="width:600px;" width="600" ><tr><td style="line-height:0px;font-size:0px;mso-line-height-rule:exactly;"><![endif]--><div style="margin:0px auto;max-width:600px;"><table align="center" border="0" cellpadding="0" cellspacing="0" role="presentation" style="width:100%;"><tbody><tr><td style="direction:ltr;font-size:0px;padding:0px;padding-bottom:10px;padding-top:10px;text-align:center;"><!--[if mso | IE]><table role="presentation" border="0" cellpadding="0" cellspacing="0"><tr><td class="" style="vertical-align:top;width:600px;" ><![endif]--><div class="mj-column-per-100 mj-outlook-group-fix" style="font-size:0px;text-align:left;direction:ltr;display:inline-block;vertical-align:top;width:100%;"><table border="0" cellpadding="0" cellspacing="0" role="presentation" style="vertical-align:top;" width="100%"><tbody><tr><td align="left" style="font-size:0px;padding:0px 24px;word-break:break-word;"><div style="font-family:Arial, sans-serif;font-size:16px;line-height:24px;text-align:left;color:#222730;"><p style="line-height: 24px; margin: 16px
|
|
33
|
+
0px;"><font size="4">Delivery on {{ catering_order.selectedDate }} at {{ catering_order.selectedTime }}</font></p><p style="line-height: 24px; margin: 16px
|
|
34
|
+
0px;"><font size="4">Total order amount</font><br><font size="4"><b style="line-height: 24px;">{{ invoice.price.total }}</b></font></p></div></td></tr></tbody></table></div><!--[if mso | IE]></td></tr></table><![endif]--></td></tr></tbody></table></div><!--[if mso | IE]></td></tr></table></td></tr><tr><td class="" width="600px" ><table align="center" border="0" cellpadding="0" cellspacing="0" class="" role="presentation" style="width:600px;" width="600" ><tr><td style="line-height:0px;font-size:0px;mso-line-height-rule:exactly;"><![endif]--><div style="margin:0px auto;max-width:600px;"><table align="center" border="0" cellpadding="0" cellspacing="0" role="presentation" style="width:100%;"><tbody><tr><td style="direction:ltr;font-size:0px;padding:0px;text-align:center;"><!--[if mso | IE]><table role="presentation" border="0" cellpadding="0" cellspacing="0"><tr><td class="" style="vertical-align:top;width:600px;" ><![endif]--><div class="mj-column-per-100 mj-outlook-group-fix" style="font-size:0px;text-align:left;direction:ltr;display:inline-block;vertical-align:top;width:100%;"><table border="0" cellpadding="0" cellspacing="0" role="presentation" style="vertical-align:top;" width="100%"><tbody><tr><td align="center" style="font-size:0px;padding:16px 0px 8px 0px;word-break:break-word;"><p style="line-height: 24px; border-top: solid 1px #dadada; font-size: 1px; margin: 0px auto; width: 100%;"></p><!--[if mso | IE]><table align="center" border="0" cellpadding="0" cellspacing="0" style="border-top:solid 1px #dadada;font-size:1px;margin:0px auto;width:600px;" role="presentation" width="600px" ><tr><td style="height:0;line-height:0;">
|
|
35
|
+
</td></tr></table><![endif]--></td></tr></tbody></table></div><!--[if mso | IE]></td></tr></table><![endif]--></td></tr></tbody></table></div><!--[if mso | IE]></td></tr></table></td></tr><tr><td class="" width="600px" ><table align="center" border="0" cellpadding="0" cellspacing="0" class="" role="presentation" style="width:600px;" width="600" ><tr><td style="line-height:0px;font-size:0px;mso-line-height-rule:exactly;"><![endif]--><div style="margin:0px auto;max-width:600px;"><table align="center" border="0" cellpadding="0" cellspacing="0" role="presentation" style="width:100%;"><tbody><tr><td style="direction:ltr;font-size:0px;padding:0px;padding-bottom:10px;padding-top:10px;text-align:center;"><!--[if mso | IE]><table role="presentation" border="0" cellpadding="0" cellspacing="0"><tr><td class="" style="vertical-align:top;width:600px;" ><![endif]--><div class="mj-column-per-100 mj-outlook-group-fix" style="font-size:0px;text-align:left;direction:ltr;display:inline-block;vertical-align:top;width:100%;"><table border="0" cellpadding="0" cellspacing="0" role="presentation" style="vertical-align:top;" width="100%"><tbody><tr><td align="left" style="font-size:0px;padding:0px 24px;word-break:break-word;"><div style="font-family:Arial, sans-serif;font-size:16px;line-height:24px;text-align:left;color:#222730;"><p style="line-height: 24px; margin: 16px
|
|
36
|
+
0px;"><font size="4"><b style="line-height: 24px;">Need help?</b></font></p><p style="line-height: 24px; margin: 16px
|
|
37
|
+
0px;">Don't hesitate to contact us.</p><p style="line-height: 24px; margin: 16px
|
|
38
|
+
0px;">{{ support.email }}<br><a href="tel:{{ support.phone }}" style="line-height: 24px; text-decoration: underline;">{{ support.phone }}</a></p></div></td></tr></tbody></table></div><!--[if mso | IE]></td></tr></table><![endif]--></td></tr></tbody></table></div><!--[if mso | IE]></td></tr></table></td></tr><tr><td class="" width="600px" ><table align="center" border="0" cellpadding="0" cellspacing="0" class="" role="presentation" style="width:600px;" width="600" ><tr><td style="line-height:0px;font-size:0px;mso-line-height-rule:exactly;"><![endif]--><div style="margin:0px auto;max-width:600px;"><table align="center" border="0" cellpadding="0" cellspacing="0" role="presentation" style="width:100%;"><tbody><tr><td style="direction:ltr;font-size:0px;padding:0px;text-align:center;"><!--[if mso | IE]><table role="presentation" border="0" cellpadding="0" cellspacing="0"><tr><td class="" style="vertical-align:top;width:600px;" ><![endif]--><div class="mj-column-per-100 mj-outlook-group-fix" style="font-size:0px;text-align:left;direction:ltr;display:inline-block;vertical-align:top;width:100%;"><table border="0" cellpadding="0" cellspacing="0" role="presentation" style="vertical-align:top;" width="100%"><tbody><tr><td align="center" style="font-size:0px;padding:16px 0px 8px 0px;word-break:break-word;"><p style="line-height: 24px; border-top: solid 1px #dadada; font-size: 1px; margin: 0px auto; width: 100%;"></p><!--[if mso | IE]><table align="center" border="0" cellpadding="0" cellspacing="0" style="border-top:solid 1px #dadada;font-size:1px;margin:0px auto;width:600px;" role="presentation" width="600px" ><tr><td style="height:0;line-height:0;">
|
|
39
|
+
</td></tr></table><![endif]--></td></tr></tbody></table></div><!--[if mso | IE]></td></tr></table><![endif]--></td></tr></tbody></table></div><!--[if mso | IE]></td></tr></table></td></tr><tr><td class="" width="600px" ><table align="center" border="0" cellpadding="0" cellspacing="0" class="" role="presentation" style="width:600px;" width="600" ><tr><td style="line-height:0px;font-size:0px;mso-line-height-rule:exactly;"><![endif]--><div style="margin:0px auto;max-width:600px;"><table align="center" border="0" cellpadding="0" cellspacing="0" role="presentation" style="width:100%;"><tbody><tr><td style="direction:ltr;font-size:0px;padding:0px;text-align:center;"><!--[if mso | IE]><table role="presentation" border="0" cellpadding="0" cellspacing="0"><tr><td class="" style="vertical-align:top;width:600px;" ><![endif]--><div class="mj-column-per-100 mj-outlook-group-fix" style="font-size:0px;text-align:left;direction:ltr;display:inline-block;vertical-align:top;width:100%;"><table border="0" cellpadding="0" cellspacing="0" role="presentation" style="vertical-align:top;" width="100%"><tbody><tr><td align="left" style="font-size:0px;padding:24px 24px 0px;word-break:break-word;"><div style="font-family:Arial, sans-serif;font-size:16px;line-height:24px;text-align:left;color:#222730;"><b style="line-height: 24px;">Sendt fra</b><br>Nuento Denmark ApS, CVR 39000725<br>Lundeborgvej 4, 9220 Aalborg</div></td></tr></tbody></table></div><!--[if mso | IE]></td></tr></table><![endif]--></td></tr></tbody></table></div><!--[if mso | IE]></td></tr></table></td></tr><tr><td class="" width="600px" ><table align="center" border="0" cellpadding="0" cellspacing="0" class="" role="presentation" style="width:600px;" width="600" ><tr><td style="line-height:0px;font-size:0px;mso-line-height-rule:exactly;"><![endif]--><div style="margin:0px auto;max-width:600px;"><table align="center" border="0" cellpadding="0" cellspacing="0" role="presentation" style="width:100%;"><tbody><tr><td style="direction:ltr;font-size:0px;padding:32px 0px 0px;text-align:center;"><!--[if mso | IE]><table role="presentation" border="0" cellpadding="0" cellspacing="0"><tr><td class="" style="vertical-align:top;width:600px;" ><![endif]--><div class="mj-column-per-100 mj-outlook-group-fix" style="font-size:0px;text-align:left;direction:ltr;display:inline-block;vertical-align:top;width:100%;"><table border="0" cellpadding="0" cellspacing="0" role="presentation" style="vertical-align:top;" width="100%"><tbody><tr><td align="left" style="font-size:0px;padding:0px 24px 24px;word-break:break-word;"><table border="0" cellpadding="0" cellspacing="0" role="presentation" style="border-collapse:collapse;border-spacing:0px;"><tbody><tr><td style="width:118px;"><img alt="Nuento" src="https://ik.imagekit.io/nuento/logo/logo-40_5iYF6s3Jp.png" style="border:0;display:block;outline:none;text-decoration:none;height:40px;width:100%;font-size:16px;" width="118" height="40"></td></tr></tbody></table></td></tr></tbody></table></div><!--[if mso | IE]></td></tr></table><![endif]--></td></tr></tbody></table></div><!--[if mso | IE]></td></tr></table></td></tr></table><![endif]--></td></tr></tbody></table></div><!--[if mso | IE]></td></tr></table><![endif]--></div></body></html>
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export type Locale = 'da' | 'en';
|
|
2
|
+
export type Audience = 'buyer' | 'supplier';
|
|
3
|
+
export type EmailTemplate = {
|
|
4
|
+
subject: string;
|
|
5
|
+
html: string;
|
|
6
|
+
};
|
|
7
|
+
export type TemplateDefinition = {
|
|
8
|
+
audience: string;
|
|
9
|
+
template: string;
|
|
10
|
+
locales: string[];
|
|
11
|
+
};
|
|
12
|
+
export declare function listTemplates(): TemplateDefinition[];
|
|
13
|
+
export declare function getEmailTemplate(audience: Audience, template: string, locale: Locale): EmailTemplate;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
+
"subject": "Ny ordre modtaget - Ordre #{{ catering_order.id8digit }}",
|
|
2
3
|
"intro_greeting": "Hej {{ catering.contact.name }},",
|
|
3
4
|
"intro_body": "Du har modtaget en ny bestilling via Nuento med ordrenr. {{ catering_order.id8digit }}.",
|
|
4
5
|
"button_reply": "Svar på ordre",
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
+
"subject": "New order received - Order #{{ catering_order.id8digit }}",
|
|
2
3
|
"intro_greeting": "Hi {{ catering.contact.name }},",
|
|
3
4
|
"intro_body": "You have received a new order via Nuento with order no. {{ catering_order.id8digit }}.",
|
|
4
5
|
"button_reply": "Respond to order",
|
|
@@ -6,5 +7,5 @@
|
|
|
6
7
|
"delivery_line": "Delivery on {{ catering_order.selectedDate }} at {{ catering_order.selectedTime }}",
|
|
7
8
|
"total_label": "Total order amount",
|
|
8
9
|
"support_heading": "Need help?",
|
|
9
|
-
"support_body": "Don
|
|
10
|
+
"support_body": "Don't hesitate to contact us."
|
|
10
11
|
}
|
package/package.json
CHANGED
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@clink/emails",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.5",
|
|
4
4
|
"main": "dist/index.js",
|
|
5
5
|
"types": "dist/index.d.ts",
|
|
6
|
+
"files": [
|
|
7
|
+
"dist/**/*"
|
|
8
|
+
],
|
|
6
9
|
"scripts": {
|
|
7
10
|
"build": "tsc && node dist/build-emails.js",
|
|
8
11
|
"prepublishOnly": "yarn build"
|
package/src/build-emails.ts
DELETED
|
@@ -1,114 +0,0 @@
|
|
|
1
|
-
import fs from 'fs'
|
|
2
|
-
import path from 'path'
|
|
3
|
-
import mjml2html from 'mjml'
|
|
4
|
-
|
|
5
|
-
const repoRoot = path.join(__dirname, '..')
|
|
6
|
-
const templatesSrcRoot = path.join(repoRoot, 'src', 'templates')
|
|
7
|
-
const templatesRoot = path.join(__dirname, 'templates')
|
|
8
|
-
const htmlRoot = path.join(__dirname, 'html')
|
|
9
|
-
|
|
10
|
-
function ensureDir(dir: string) {
|
|
11
|
-
if (!fs.existsSync(dir)) {
|
|
12
|
-
fs.mkdirSync(dir, {recursive: true})
|
|
13
|
-
}
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
function copyDir(src: string, dest: string) {
|
|
17
|
-
if (!fs.existsSync(src)) return
|
|
18
|
-
ensureDir(dest)
|
|
19
|
-
const entries = fs.readdirSync(src, {withFileTypes: true})
|
|
20
|
-
for (const entry of entries) {
|
|
21
|
-
const srcPath = path.join(src, entry.name)
|
|
22
|
-
const destPath = path.join(dest, entry.name)
|
|
23
|
-
if (entry.isDirectory()) {
|
|
24
|
-
copyDir(srcPath, destPath)
|
|
25
|
-
} else {
|
|
26
|
-
fs.copyFileSync(srcPath, destPath)
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
function read(file: string) {
|
|
32
|
-
return fs.readFileSync(file, 'utf8')
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
function write(file: string, content: string) {
|
|
36
|
-
fs.mkdirSync(path.dirname(file), {recursive: true})
|
|
37
|
-
fs.writeFileSync(file, content)
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
function replaceLocaleTokens(mjml: string, dict: Record<string, string>) {
|
|
41
|
-
let output = mjml
|
|
42
|
-
for (const [key, value] of Object.entries(dict)) {
|
|
43
|
-
output = output.split(`[[${key}]]`).join(value)
|
|
44
|
-
}
|
|
45
|
-
return output
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
function getDirectories(root: string) {
|
|
49
|
-
if (!fs.existsSync(root)) return []
|
|
50
|
-
return fs
|
|
51
|
-
.readdirSync(root, {withFileTypes: true})
|
|
52
|
-
.filter(d => d.isDirectory())
|
|
53
|
-
.map(d => d.name)
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
function getLocaleFiles(templateDir: string) {
|
|
57
|
-
if (!fs.existsSync(templateDir)) return []
|
|
58
|
-
return fs
|
|
59
|
-
.readdirSync(templateDir, {withFileTypes: true})
|
|
60
|
-
.filter(f => f.isFile() && f.name.endsWith('.json'))
|
|
61
|
-
.map(f => f.name)
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
function buildTemplate(
|
|
65
|
-
audience: string,
|
|
66
|
-
templateName: string,
|
|
67
|
-
localeFile: string,
|
|
68
|
-
) {
|
|
69
|
-
const locale = localeFile.replace(/\.json$/, '')
|
|
70
|
-
const templateDir = path.join(templatesRoot, audience, templateName)
|
|
71
|
-
const contentPath = path.join(templateDir, 'template.mjml')
|
|
72
|
-
const translationsPath = path.join(templateDir, localeFile)
|
|
73
|
-
if (!fs.existsSync(contentPath)) return
|
|
74
|
-
|
|
75
|
-
const baseTemplatePath = path.join(__dirname, 'layouts', 'base.mjml')
|
|
76
|
-
const baseTemplate = read(baseTemplatePath)
|
|
77
|
-
const content = read(contentPath)
|
|
78
|
-
const translations = JSON.parse(read(translationsPath)) as Record<
|
|
79
|
-
string,
|
|
80
|
-
string
|
|
81
|
-
>
|
|
82
|
-
|
|
83
|
-
const localizedContent = replaceLocaleTokens(content, translations)
|
|
84
|
-
|
|
85
|
-
let mjmlSource = baseTemplate
|
|
86
|
-
mjmlSource = mjmlSource.replace('%CONTENT%', localizedContent)
|
|
87
|
-
mjmlSource = replaceLocaleTokens(mjmlSource, translations)
|
|
88
|
-
|
|
89
|
-
const {html} = mjml2html(mjmlSource, {minify: true})
|
|
90
|
-
const outPath = path.join(htmlRoot, audience, templateName, `${locale}.html`)
|
|
91
|
-
write(outPath, html)
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
function buildAll() {
|
|
95
|
-
copyDir(templatesSrcRoot, templatesRoot)
|
|
96
|
-
const layoutsSrcRoot = path.join(repoRoot, 'src', 'layouts')
|
|
97
|
-
const layoutsRoot = path.join(__dirname, 'layouts')
|
|
98
|
-
copyDir(layoutsSrcRoot, layoutsRoot)
|
|
99
|
-
|
|
100
|
-
const audiences = getDirectories(templatesRoot)
|
|
101
|
-
for (const audience of audiences) {
|
|
102
|
-
const audienceDir = path.join(templatesRoot, audience)
|
|
103
|
-
const templateNames = getDirectories(audienceDir)
|
|
104
|
-
for (const templateName of templateNames) {
|
|
105
|
-
const templateDir = path.join(audienceDir, templateName)
|
|
106
|
-
const localeFiles = getLocaleFiles(templateDir)
|
|
107
|
-
for (const localeFile of localeFiles) {
|
|
108
|
-
buildTemplate(audience, templateName, localeFile)
|
|
109
|
-
}
|
|
110
|
-
}
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
buildAll()
|
package/src/index.ts
DELETED
|
@@ -1,92 +0,0 @@
|
|
|
1
|
-
import fs from 'fs'
|
|
2
|
-
import path from 'path'
|
|
3
|
-
|
|
4
|
-
export type Locale = 'da' | 'en'
|
|
5
|
-
export type Audience = 'buyer' | 'supplier'
|
|
6
|
-
|
|
7
|
-
export type EmailTemplate = {
|
|
8
|
-
subject: string
|
|
9
|
-
html: string
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
export type TemplateDefinition = {
|
|
13
|
-
audience: string
|
|
14
|
-
template: string
|
|
15
|
-
locales: string[]
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
const templatesRoot = path.join(__dirname, 'templates')
|
|
19
|
-
const htmlRoot = path.join(__dirname, 'html')
|
|
20
|
-
|
|
21
|
-
function getDirectories(root: string) {
|
|
22
|
-
if (!fs.existsSync(root)) return []
|
|
23
|
-
return fs
|
|
24
|
-
.readdirSync(root, {withFileTypes: true})
|
|
25
|
-
.filter(d => d.isDirectory())
|
|
26
|
-
.map(d => d.name)
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
function getLocalesForTemplate(audience: string, template: string) {
|
|
30
|
-
const dir = path.join(templatesRoot, audience, template)
|
|
31
|
-
if (!fs.existsSync(dir)) return []
|
|
32
|
-
return fs
|
|
33
|
-
.readdirSync(dir, {withFileTypes: true})
|
|
34
|
-
.filter(f => f.isFile() && f.name.endsWith('.json'))
|
|
35
|
-
.map(f => f.name.replace(/\.json$/, ''))
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
export function listTemplates(): TemplateDefinition[] {
|
|
39
|
-
const result: TemplateDefinition[] = []
|
|
40
|
-
const audiences = getDirectories(templatesRoot)
|
|
41
|
-
for (const audience of audiences) {
|
|
42
|
-
const audienceDir = path.join(templatesRoot, audience)
|
|
43
|
-
const templates = getDirectories(audienceDir)
|
|
44
|
-
for (const template of templates) {
|
|
45
|
-
const locales = getLocalesForTemplate(audience, template)
|
|
46
|
-
result.push({audience, template, locales})
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
return result
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
export function getEmailTemplate(
|
|
53
|
-
audience: Audience,
|
|
54
|
-
template: string,
|
|
55
|
-
locale: Locale,
|
|
56
|
-
): EmailTemplate {
|
|
57
|
-
const translationsPath = path.join(
|
|
58
|
-
templatesRoot,
|
|
59
|
-
audience,
|
|
60
|
-
template,
|
|
61
|
-
`${locale}.json`,
|
|
62
|
-
)
|
|
63
|
-
const htmlPath = path.join(htmlRoot, audience, template, `${locale}.html`)
|
|
64
|
-
|
|
65
|
-
if (!fs.existsSync(translationsPath)) {
|
|
66
|
-
throw new Error(
|
|
67
|
-
`Missing translations for audience="${audience}" template="${template}" locale="${locale}"`,
|
|
68
|
-
)
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
if (!fs.existsSync(htmlPath)) {
|
|
72
|
-
throw new Error(
|
|
73
|
-
`Missing HTML for audience="${audience}" template="${template}" locale="${locale}". Did you run the build step?`,
|
|
74
|
-
)
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
const translations = JSON.parse(
|
|
78
|
-
fs.readFileSync(translationsPath, 'utf8'),
|
|
79
|
-
) as Record<string, string>
|
|
80
|
-
const html = fs.readFileSync(htmlPath, 'utf8')
|
|
81
|
-
|
|
82
|
-
if (typeof translations.subject !== 'string') {
|
|
83
|
-
throw new Error(
|
|
84
|
-
`Translations for audience="${audience}" template="${template}" locale="${locale}" do not contain a "subject" key`,
|
|
85
|
-
)
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
return {
|
|
89
|
-
subject: translations.subject,
|
|
90
|
-
html,
|
|
91
|
-
}
|
|
92
|
-
}
|
package/tsconfig.json
DELETED
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"compilerOptions": {
|
|
3
|
-
"target": "es2020",
|
|
4
|
-
"module": "commonjs",
|
|
5
|
-
"rootDir": "src",
|
|
6
|
-
"outDir": "dist",
|
|
7
|
-
"declaration": true,
|
|
8
|
-
"declarationMap": false,
|
|
9
|
-
"emitDeclarationOnly": false,
|
|
10
|
-
"strict": true,
|
|
11
|
-
"esModuleInterop": true,
|
|
12
|
-
"resolveJsonModule": true
|
|
13
|
-
},
|
|
14
|
-
"include": ["src"]
|
|
15
|
-
}
|
|
File without changes
|
|
File without changes
|