tzmail 1.0.0

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.
Files changed (56) hide show
  1. package/README.md +5091 -0
  2. package/dist/core/enums/template-part.enum.d.ts +7 -0
  3. package/dist/core/enums/template-part.enum.d.ts.map +1 -0
  4. package/dist/core/enums/template-part.enum.js +10 -0
  5. package/dist/core/enums/theme.enum.d.ts +8 -0
  6. package/dist/core/enums/theme.enum.d.ts.map +1 -0
  7. package/dist/core/enums/theme.enum.js +11 -0
  8. package/dist/core/interfaces/email.interface.d.ts +32 -0
  9. package/dist/core/interfaces/email.interface.d.ts.map +1 -0
  10. package/dist/core/interfaces/email.interface.js +2 -0
  11. package/dist/core/interfaces/template.interface.d.ts +56 -0
  12. package/dist/core/interfaces/template.interface.d.ts.map +1 -0
  13. package/dist/core/interfaces/template.interface.js +2 -0
  14. package/dist/factories/email-factory.d.ts +34 -0
  15. package/dist/factories/email-factory.d.ts.map +1 -0
  16. package/dist/factories/email-factory.js +52 -0
  17. package/dist/factories/template-factory.d.ts +15 -0
  18. package/dist/factories/template-factory.d.ts.map +1 -0
  19. package/dist/factories/template-factory.js +96 -0
  20. package/dist/index.d.ts +15 -0
  21. package/dist/index.d.ts.map +1 -0
  22. package/dist/index.js +265 -0
  23. package/dist/services/attachment.service.d.ts +48 -0
  24. package/dist/services/attachment.service.d.ts.map +1 -0
  25. package/dist/services/attachment.service.js +93 -0
  26. package/dist/services/email.service.d.ts +31 -0
  27. package/dist/services/email.service.d.ts.map +1 -0
  28. package/dist/services/email.service.js +58 -0
  29. package/dist/services/template.service.d.ts +180 -0
  30. package/dist/services/template.service.d.ts.map +1 -0
  31. package/dist/services/template.service.js +507 -0
  32. package/dist/templates/base/template-builder.d.ts +23 -0
  33. package/dist/templates/base/template-builder.d.ts.map +1 -0
  34. package/dist/templates/base/template-builder.js +676 -0
  35. package/dist/templates/themes/corporate.theme.d.ts +65 -0
  36. package/dist/templates/themes/corporate.theme.d.ts.map +1 -0
  37. package/dist/templates/themes/corporate.theme.js +109 -0
  38. package/dist/templates/themes/minimal.theme.d.ts +70 -0
  39. package/dist/templates/themes/minimal.theme.d.ts.map +1 -0
  40. package/dist/templates/themes/minimal.theme.js +114 -0
  41. package/dist/templates/themes/modern.theme.d.ts +38 -0
  42. package/dist/templates/themes/modern.theme.d.ts.map +1 -0
  43. package/dist/templates/themes/modern.theme.js +81 -0
  44. package/dist/templates/themes/monokai.theme.d.ts +29 -0
  45. package/dist/templates/themes/monokai.theme.d.ts.map +1 -0
  46. package/dist/templates/themes/monokai.theme.js +73 -0
  47. package/dist/templates/themes/system.theme.d.ts +50 -0
  48. package/dist/templates/themes/system.theme.d.ts.map +1 -0
  49. package/dist/templates/themes/system.theme.js +54 -0
  50. package/dist/templates/themes/theme.interface.d.ts +42 -0
  51. package/dist/templates/themes/theme.interface.d.ts.map +1 -0
  52. package/dist/templates/themes/theme.interface.js +2 -0
  53. package/dist/tests/template.service.test.d.ts +1 -0
  54. package/dist/tests/template.service.test.d.ts.map +1 -0
  55. package/dist/tests/template.service.test.js +1 -0
  56. package/package.json +46 -0
@@ -0,0 +1,676 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.TemplateBuilder = void 0;
4
+ class TemplateBuilder {
5
+ constructor(theme, config, variant) {
6
+ this.template = '';
7
+ this.theme = theme;
8
+ this.config = config;
9
+ this.variant = variant;
10
+ }
11
+ buildHeader(content) {
12
+ var _a;
13
+ if (!((_a = this.config.header) === null || _a === void 0 ? void 0 : _a.show))
14
+ return this;
15
+ const colors = this.variant === 'light' ? this.theme.light : this.theme.dark;
16
+ const isMonokai = this.theme.id === 'monokai';
17
+ const isModern = this.theme.id === 'modern';
18
+ const isCorporate = this.theme.id === 'corporate';
19
+ const isMinimal = this.theme.id === 'minimal';
20
+ let headerStyles = `
21
+ background-color: ${colors.background};
22
+ padding: ${this.theme.spacing.lg} ${this.theme.spacing.xl};
23
+ `;
24
+ // styles específicos para tema Corporate
25
+ if (isCorporate) {
26
+ const corporate = this.theme;
27
+ headerStyles += `
28
+ border-bottom: ${corporate.borderStyle.width.medium} solid ${corporate.corporateColors.gold};
29
+ box-shadow: ${corporate.elevation.shadow};
30
+ text-transform: ${corporate.branding.textTransform.uppercase};
31
+ letter-spacing: ${corporate.branding.letterSpacing.wide};
32
+ `;
33
+ }
34
+ // styles específicos para tema Minimal
35
+ if (isMinimal) {
36
+ const minimal = this.theme;
37
+ headerStyles += `
38
+ border-bottom: ${minimal.borderStyle.width.thin} solid ${colors.border};
39
+ padding: ${minimal.spacing.lg} ${minimal.spacing.xl};
40
+ `;
41
+ }
42
+ // styles existentes para outros temas
43
+ else if (isModern) {
44
+ headerStyles += `
45
+ border-bottom: 1px solid ${colors.border};
46
+ backdrop-filter: blur(${this.theme.glassmorphism.blur});
47
+ box-shadow: 0 1px 3px rgba(0, 0, 0, 0.05);
48
+ `;
49
+ }
50
+ else if (isMonokai) {
51
+ headerStyles += `
52
+ border-bottom: 2px solid ${colors.primary};
53
+ box-shadow: ${this.theme.effects.shadow};
54
+ transition: ${this.theme.effects.transition};
55
+ `;
56
+ }
57
+ else {
58
+ headerStyles += `
59
+ border-bottom: 1px solid ${colors.border};
60
+ `;
61
+ }
62
+ const logoHtml = this.buildLogo();
63
+ this.template += `
64
+ <table width="100%" cellpadding="0" cellspacing="0" role="presentation">
65
+ <tr>
66
+ <td style="${headerStyles}" align="center">
67
+
68
+ ${logoHtml}
69
+
70
+ ${content ? `
71
+ <table width="100%" cellpadding="0" cellspacing="0" role="presentation">
72
+ <tr>
73
+ <td style="
74
+ padding-top: ${this.theme.spacing.md};
75
+ ${isCorporate ? 'font-family: serif;' : ''}
76
+ ${isMinimal ? 'font-weight: 300;' : ''}
77
+ ">
78
+ ${content}
79
+ </td>
80
+ </tr>
81
+ </table>
82
+ ` : ''}
83
+
84
+ </td>
85
+ </tr>
86
+ </table>
87
+ `;
88
+ return this;
89
+ }
90
+ buildLogo() {
91
+ var _a;
92
+ const logo = (_a = this.config.header) === null || _a === void 0 ? void 0 : _a.logo;
93
+ if (!logo)
94
+ return '';
95
+ const colors = this.variant === 'light' ? this.theme.light : this.theme.dark;
96
+ const isMonokai = this.theme.id === 'monokai';
97
+ const isModern = this.theme.id === 'modern';
98
+ const isCorporate = this.theme.id === 'corporate';
99
+ const isMinimal = this.theme.id === 'minimal';
100
+ if (logo.type === 'text') {
101
+ let textStyles = `
102
+ font-size: ${this.theme.typography.fontSizes.xlarge};
103
+ font-weight: ${this.theme.typography.fontWeights.bold};
104
+ color: ${colors.primary};
105
+ `;
106
+ // styles para tema Corporate
107
+ if (isCorporate) {
108
+ const corporate = this.theme;
109
+ textStyles += `
110
+ font-family: 'Playfair Display', serif;
111
+ letter-spacing: ${corporate.branding.letterSpacing.wider};
112
+ text-transform: ${corporate.branding.textTransform.uppercase};
113
+ color: ${corporate.corporateColors.gold};
114
+ `;
115
+ }
116
+ // styles para tema Minimal
117
+ else if (isMinimal) {
118
+ textStyles += `
119
+ font-weight: 500;
120
+ letter-spacing: -0.5px;
121
+ color: ${colors.text};
122
+ `;
123
+ }
124
+ // styles existentes
125
+ else if (isMonokai) {
126
+ textStyles += `
127
+ letter-spacing: -0.5px;
128
+ text-shadow: ${this.theme.effects.glow};
129
+ `;
130
+ }
131
+ else if (isModern) {
132
+ textStyles += `
133
+ background: ${this.theme.gradients.primary};
134
+ -webkit-background-clip: text;
135
+ -webkit-text-fill-color: transparent;
136
+ background-clip: text;
137
+ `;
138
+ }
139
+ return `<div style="${textStyles}">${logo.text || 'Logo'}</div>`;
140
+ }
141
+ if (logo.type === 'image') {
142
+ let imageStyles = `
143
+ height: ${logo.size === 'small' ? '30px' : logo.size === 'large' ? '100px' : '60px'};
144
+ width: auto;
145
+ `;
146
+ if (isModern) {
147
+ imageStyles += `
148
+ border-radius: ${this.theme.borderStyle.radius.small};
149
+ transition: ${this.theme.animations.hover};
150
+ `;
151
+ }
152
+ else if (isCorporate) {
153
+ imageStyles += `
154
+ border-radius: ${this.theme.borderStyle.radius.small};
155
+ `;
156
+ }
157
+ return `<img src="${logo.imageUrl}" alt="${logo.alt || 'Logo'}" style="${imageStyles}" />`;
158
+ }
159
+ return '';
160
+ }
161
+ buildBody(content) {
162
+ const colors = this.variant === 'light' ? this.theme.light : this.theme.dark;
163
+ const isMonokai = this.theme.id === 'monokai';
164
+ const isModern = this.theme.id === 'modern';
165
+ const isCorporate = this.theme.id === 'corporate';
166
+ const isMinimal = this.theme.id === 'minimal';
167
+ let bodyStyles = `
168
+ padding: ${this.theme.spacing.xl}!important;
169
+ background-color: ${colors.background};
170
+ color: ${colors.text};
171
+ font-family: ${this.theme.typography.fontFamily};
172
+ font-size: ${this.theme.typography.fontSizes.medium};
173
+ line-height: ${isMinimal ? 1.7 : 1.6};
174
+ `;
175
+ // styles para tema Corporate
176
+ if (isCorporate) {
177
+ const corporate = this.theme;
178
+ bodyStyles += `
179
+ border-left: 4px solid ${corporate.corporateColors.gold};
180
+ margin: ${this.theme.spacing.md} 0;
181
+ box-shadow: ${corporate.elevation.card};
182
+ `;
183
+ }
184
+ // styles para tema Minimal
185
+ else if (isMinimal) {
186
+ bodyStyles += `
187
+ padding: ${this.theme.spacing.xl} ${this.theme.spacing.lg}!important;
188
+ max-width: ${this.theme.layout.contentWidth};
189
+ margin: 0 auto;
190
+ `;
191
+ }
192
+ // styles existentes
193
+ else if (isModern) {
194
+ bodyStyles += `
195
+ border-radius: ${this.theme.borderStyle.radius.medium};
196
+ margin: ${this.theme.spacing.md};
197
+ `;
198
+ }
199
+ else if (isMonokai) {
200
+ bodyStyles += `
201
+ border-left: 4px solid ${colors.primary};
202
+ margin: ${this.theme.spacing.md} 0;
203
+ `;
204
+ }
205
+ // Processar conteúdo com formatação específica
206
+ let processedContent = content;
207
+ if (isCorporate) {
208
+ processedContent = this.formatCorporateContent(content);
209
+ }
210
+ else if (isMinimal) {
211
+ processedContent = this.formatMinimalContent(content);
212
+ }
213
+ else if (isMonokai && content.includes('<code>')) {
214
+ processedContent = this.highlightCode(content);
215
+ }
216
+ this.template += `
217
+ <table width="100%" cellpadding="0" cellspacing="0" role="presentation" style="background-color: #ffffff; padding: 10px;">
218
+ <tr>
219
+ <td style="${bodyStyles}">
220
+ ${processedContent}
221
+ </td>
222
+ </tr>
223
+ </table>
224
+ `;
225
+ return this;
226
+ }
227
+ formatCorporateContent(content) {
228
+ // add els corporativos como citações e destaques
229
+ return content
230
+ .replace(/<blockquote>(.*?)<\/blockquote>/g, (match, quote) => {
231
+ const corporate = this.theme;
232
+ return `<blockquote style="
233
+ border-left: 4px solid ${corporate.corporateColors.gold};
234
+ margin: ${this.theme.spacing.md} 0;
235
+ padding: ${this.theme.spacing.md}!important;
236
+ font-style: italic;
237
+ color: ${corporate.light.textMuted};
238
+ ">${quote}</blockquote>`;
239
+ })
240
+ .replace(/<highlight>(.*?)<\/highlight>/g, (match, text) => {
241
+ const corporate = this.theme;
242
+ return `<span style="
243
+ background: linear-gradient(120deg, ${corporate.corporateColors.gold}20 0%, ${corporate.corporateColors.gold}20 40%, transparent 60%);
244
+ padding: 0 ${this.theme.spacing.xs}!important;
245
+ font-weight: bold;
246
+ ">${text}</span>`;
247
+ });
248
+ }
249
+ formatMinimalContent(content) {
250
+ const minimal = this.theme;
251
+ // fmt minimalista - remove styles desnecessários
252
+ return content
253
+ .replace(/<h[1-6]>/g, (match) => {
254
+ var _a;
255
+ const level = ((_a = match.match(/h([1-6])/)) === null || _a === void 0 ? void 0 : _a[1]) || '2';
256
+ const size = {
257
+ '1': '24px',
258
+ '2': '20px',
259
+ '3': '18px',
260
+ '4': '16px',
261
+ '5': '14px',
262
+ '6': '13px'
263
+ }[level];
264
+ return `<h${level} style="
265
+ font-size: ${size};
266
+ font-weight: 500;
267
+ margin: ${minimal.spacing.lg} 0 ${minimal.spacing.md} 0;
268
+ line-height: 1.3;
269
+ ">`;
270
+ })
271
+ .replace(/<p>/g, `<p style="margin: 0 0 ${minimal.layout.paragraphSpacing} 0;">`);
272
+ }
273
+ highlightCode(content) {
274
+ const monokai = this.theme;
275
+ return content.replace(/<code>(.*?)<\/code>/g, (match, code) => {
276
+ return `<pre style="
277
+ background: ${monokai.dark.background};
278
+ color: ${monokai.dark.text};
279
+ padding: ${this.theme.spacing.md}!important;
280
+ border-radius: ${monokai.borderStyle.radius};
281
+ overflow-x: auto;
282
+ font-family: ${this.theme.typography.fontFamily};
283
+ font-size: 13px;
284
+ line-height: 1.5;
285
+ "><code>${this.applySyntaxHighlighting(code, monokai)}</code></pre>`;
286
+ });
287
+ }
288
+ applySyntaxHighlighting(code, monokai) {
289
+ // smp highlighting para demonstração
290
+ const keywords = ['function', 'const', 'let', 'var', 'if', 'else', 'return', 'import', 'from'];
291
+ let highlighted = code;
292
+ keywords.forEach(keyword => {
293
+ const regex = new RegExp(`\\b(${keyword})\\b`, 'g');
294
+ highlighted = highlighted.replace(regex, `<span style="color: ${monokai.codeHighlight.keyword}">$1</span>`);
295
+ });
296
+ // strs
297
+ highlighted = highlighted.replace(/'([^']*)'/g, `<span style="color: ${monokai.codeHighlight.string}">'$1'</span>`);
298
+ highlighted = highlighted.replace(/"([^"]*)"/g, `<span style="color: ${monokai.codeHighlight.string}">"$1"</span>`);
299
+ // nums
300
+ highlighted = highlighted.replace(/\b(\d+)\b/g, `<span style="color: ${monokai.codeHighlight.number}">$1</span>`);
301
+ // funcs
302
+ highlighted = highlighted.replace(/\b([a-zA-Z_][a-zA-Z0-9_]*)\s*\(/g, `<span style="color: ${monokai.codeHighlight.function}">$1</span>(`);
303
+ return highlighted;
304
+ }
305
+ buildButton(text, url, variant = 'primary') {
306
+ const colors = this.variant === 'light' ? this.theme.light : this.theme.dark;
307
+ const isModern = this.theme.id === 'modern';
308
+ const isMonokai = this.theme.id === 'monokai';
309
+ const isCorporate = this.theme.id === 'corporate';
310
+ const isMinimal = this.theme.id === 'minimal';
311
+ let buttonColor = variant === 'primary' ? colors.primary : colors.secondary;
312
+ let buttonStyles = `
313
+ display: inline-block;
314
+ padding: 12px 24px!important;
315
+ background-color: ${buttonColor};
316
+ color: white;
317
+ text-decoration: none;
318
+ font-weight: ${this.theme.typography.fontWeights.medium};
319
+ margin: ${this.theme.spacing.md} 0;
320
+ `;
321
+ // styles para tema Corporate
322
+ if (isCorporate) {
323
+ const corporate = this.theme;
324
+ buttonStyles += `
325
+ border-radius: ${corporate.borderStyle.radius.small};
326
+ text-transform: ${corporate.branding.textTransform.uppercase};
327
+ letter-spacing: ${corporate.branding.letterSpacing.wide};
328
+ transition: all 0.3s ease;
329
+ &:hover {
330
+ transform: translateY(-2px);
331
+ box-shadow: ${corporate.elevation.hover};
332
+ }
333
+ `;
334
+ }
335
+ // styles para tema Minimal
336
+ else if (isMinimal) {
337
+ buttonStyles += `
338
+ border-radius: 0;
339
+ border: 1px solid ${buttonColor};
340
+ background-color: transparent;
341
+ color: ${buttonColor};
342
+ padding: 10px 20px!important;
343
+ transition: all 0.2s ease;
344
+ &:hover {
345
+ background-color: ${buttonColor};
346
+ color: white;
347
+ }
348
+ `;
349
+ }
350
+ // styles existentes
351
+ else if (isModern) {
352
+ buttonStyles += `
353
+ background: ${this.theme.gradients.primary};
354
+ border-radius: ${this.theme.borderStyle.radius.medium};
355
+ transition: ${this.theme.animations.hover};
356
+ box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
357
+ `;
358
+ }
359
+ else if (isMonokai) {
360
+ buttonStyles += `
361
+ border: 2px solid ${buttonColor};
362
+ border-radius: ${this.theme.borderStyle.radius};
363
+ transition: ${this.theme.effects.transition};
364
+ &:hover {
365
+ transform: translateY(-2px);
366
+ box-shadow: ${this.theme.effects.glow};
367
+ }
368
+ `;
369
+ }
370
+ else {
371
+ buttonStyles += `
372
+ border-radius: 4px;
373
+ `;
374
+ }
375
+ this.template += `
376
+ <table width="100%" style="padding: 10px;" cellpadding="0" cellspacing="0" role="presentation">
377
+ <tr>
378
+ <td align="center">
379
+
380
+ <table cellpadding="0" cellspacing="0" role="presentation">
381
+ <tr>
382
+ <td style="${buttonStyles}">
383
+ <a href="${url}" style="
384
+ text-decoration: none;
385
+ color: inherit;
386
+ display: inline-block;
387
+ font-weight: ${this.theme.typography.fontWeights.bold};
388
+ padding: 12px 24px;
389
+ ">
390
+ ${text}
391
+ </a>
392
+ </td>
393
+ </tr>
394
+ </table>
395
+
396
+ </td>
397
+ </tr>
398
+ </table>
399
+ `;
400
+ return this;
401
+ }
402
+ buildFooter() {
403
+ var _a, _b, _c;
404
+ if (!((_a = this.config.footer) === null || _a === void 0 ? void 0 : _a.show))
405
+ return this;
406
+ const colors = this.variant === 'light' ? this.theme.light : this.theme.dark;
407
+ const isModern = this.theme.id === 'modern';
408
+ const isMonokai = this.theme.id === 'monokai';
409
+ const isCorporate = this.theme.id === 'corporate';
410
+ const isMinimal = this.theme.id === 'minimal';
411
+ let footerStyles = `
412
+ background-color: ${colors.background};
413
+ border-top: 1px solid ${colors.border};
414
+ padding: ${this.theme.spacing.lg} ${this.theme.spacing.xl}!important;
415
+ text-align: center;
416
+ font-size: ${this.theme.typography.fontSizes.small};
417
+ color: ${colors.textMuted};
418
+ `;
419
+ // styles para tema Corporate
420
+ if (isCorporate) {
421
+ const corporate = this.theme;
422
+ footerStyles += `
423
+ border-top: 2px solid ${corporate.corporateColors.gold};
424
+ font-size: 11px;
425
+ letter-spacing: ${corporate.branding.letterSpacing.normal};
426
+ `;
427
+ }
428
+ // styles para tema Minimal
429
+ else if (isMinimal) {
430
+ footerStyles += `
431
+ border-top: 1px solid ${colors.border};
432
+ padding: ${this.theme.spacing.lg}!important;
433
+ font-size: 12px;
434
+ `;
435
+ }
436
+ // styles existentes
437
+ else if (isModern) {
438
+ footerStyles += `
439
+ backdrop-filter: blur(${this.theme.glassmorphism.blur});
440
+ border-radius: ${this.theme.borderStyle.radius.small};
441
+ `;
442
+ }
443
+ else if (isMonokai) {
444
+ footerStyles += `
445
+ border-top-width: 2px;
446
+ border-top-color: ${colors.primary};
447
+ `;
448
+ }
449
+ const footerLinks = this.buildFooterLinks();
450
+ const socialLinks = this.buildSocialLinks();
451
+ this.template += `
452
+ <table width="100%" cellpadding="0" cellspacing="0" role="presentation">
453
+ <tr>
454
+ <td style="${footerStyles}" align="center">
455
+
456
+ ${footerLinks}
457
+
458
+ ${socialLinks}
459
+
460
+ ${((_b = this.config.footer) === null || _b === void 0 ? void 0 : _b.copyrightText) ? `
461
+ <table width="100%" cellpadding="0" cellspacing="0" role="presentation">
462
+ <tr>
463
+ <td style="
464
+ padding-top: ${this.theme.spacing.md};
465
+ font-family: Arial, sans-serif;
466
+ font-size: 12px;
467
+ color: ${colors.textMuted};
468
+ text-align: center;
469
+ ">
470
+ ${this.config.footer.copyrightText}
471
+ </td>
472
+ </tr>
473
+ </table>
474
+ ` : ''}
475
+
476
+ ${((_c = this.config.footer) === null || _c === void 0 ? void 0 : _c.unsubscribeText) ? `
477
+ <table width="100%" cellpadding="0" cellspacing="0" role="presentation">
478
+ <tr>
479
+ <td style="
480
+ padding-top: ${this.theme.spacing.sm};
481
+ text-align: center;
482
+ font-family: Arial, sans-serif;
483
+ font-size: 12px;
484
+ ">
485
+ <a href="#" style="
486
+ color: ${colors.textMuted};
487
+ text-decoration: underline;
488
+ ">
489
+ ${this.config.footer.unsubscribeText}
490
+ </a>
491
+ </td>
492
+ </tr>
493
+ </table>
494
+ ` : ''}
495
+
496
+ </td>
497
+ </tr>
498
+ </table>
499
+ `;
500
+ return this;
501
+ }
502
+ buildFooterLinks() {
503
+ var _a, _b;
504
+ if (!((_b = (_a = this.config.footer) === null || _a === void 0 ? void 0 : _a.links) === null || _b === void 0 ? void 0 : _b.length))
505
+ return '';
506
+ const colors = this.variant === 'light' ? this.theme.light : this.theme.dark;
507
+ const isModern = this.theme.id === 'modern';
508
+ const isCorporate = this.theme.id === 'corporate';
509
+ const isMinimal = this.theme.id === 'minimal';
510
+ let linkStyles = `
511
+ color: ${colors.textMuted};
512
+ text-decoration: none;
513
+ margin: 0 ${this.theme.spacing.sm};
514
+ `;
515
+ if (isModern) {
516
+ linkStyles += `
517
+ transition: ${this.theme.animations.hover};
518
+ &:hover {
519
+ color: ${colors.primary};
520
+ transform: translateY(-1px);
521
+ }
522
+ `;
523
+ }
524
+ else if (isCorporate) {
525
+ linkStyles += `
526
+ text-transform: uppercase;
527
+ font-size: 11px;
528
+ letter-spacing: 0.5px;
529
+ &:hover {
530
+ color: ${this.theme.corporateColors.gold};
531
+ }
532
+ `;
533
+ }
534
+ else if (isMinimal) {
535
+ linkStyles += `
536
+ &:hover {
537
+ text-decoration: underline;
538
+ }
539
+ `;
540
+ }
541
+ return `
542
+ <table width="100%" cellpadding="0" cellspacing="0" role="presentation">
543
+ <tr>
544
+ <td style="padding-bottom: ${this.theme.spacing.lg};" align="center">
545
+
546
+ <table cellpadding="0" cellspacing="0" role="presentation">
547
+ <tr>
548
+ ${this.config.footer.links.map(link => `
549
+ <td style="padding: 0 8px;">
550
+ <a href="${link.url}" style="${linkStyles}">
551
+ ${link.text}
552
+ </a>
553
+ </td>
554
+ `).join('')}
555
+ </tr>
556
+ </table>
557
+
558
+ </td>
559
+ </tr>
560
+ </table>
561
+ `;
562
+ }
563
+ buildSocialLinks() {
564
+ var _a, _b;
565
+ if (!((_b = (_a = this.config.footer) === null || _a === void 0 ? void 0 : _a.socialLinks) === null || _b === void 0 ? void 0 : _b.length))
566
+ return '';
567
+ return `
568
+ <table width="100%" cellpadding="0" cellspacing="0" role="presentation">
569
+ <tr>
570
+ <td align="center" style="padding: ${this.theme.spacing.md} 0;">
571
+
572
+ <table cellpadding="0" cellspacing="0" role="presentation">
573
+ <tr>
574
+ ${this.config.footer.socialLinks.map(link => `
575
+ <td style="padding: 0 6px;">
576
+ <a href="${link.url}" target="_blank">
577
+ <img
578
+ src="${this.getSocialIcon(link.platform)}"
579
+ width="20"
580
+ height="20"
581
+ alt="${link.platform}"
582
+ style="display: block; border: 0;"
583
+ />
584
+ </a>
585
+ </td>
586
+ `).join('')}
587
+ </tr>
588
+ </table>
589
+
590
+ </td>
591
+ </tr>
592
+ </table>
593
+ `;
594
+ }
595
+ getSocialIcon(platform) {
596
+ const icons = {
597
+ facebook: 'https://cdn.simpleicons.org/facebook/1877F2',
598
+ twitter: 'https://cdn.simpleicons.org/x/1DA1F2',
599
+ github: 'https://cdn.simpleicons.org/github/000000',
600
+ instagram: 'https://cdn.simpleicons.org/instagram/E4405F',
601
+ youtube: 'https://cdn.simpleicons.org/youtube/FF0000',
602
+ discord: 'https://cdn.simpleicons.org/discord/5865F2',
603
+ reddit: 'https://cdn.simpleicons.org/reddit/FF4500',
604
+ pinterest: 'https://cdn.simpleicons.org/pinterest/BD081C',
605
+ tiktok: 'https://cdn.simpleicons.org/tiktok/000000',
606
+ gitlab: 'https://cdn.simpleicons.org/gitlab/FC6D26',
607
+ stackoverflow: 'https://cdn.simpleicons.org/stackoverflow/F58025',
608
+ medium: 'https://cdn.simpleicons.org/medium/000000',
609
+ dribbble: 'https://cdn.simpleicons.org/dribbble/EA4C89',
610
+ behance: 'https://cdn.simpleicons.org/behance/1769FF',
611
+ telegram: 'https://cdn.simpleicons.org/telegram/26A5E4'
612
+ };
613
+ return icons[platform] || 'https://cdn.simpleicons.org/virginmedia/5865F2';
614
+ }
615
+ build() {
616
+ const isModern = this.theme.id === 'modern';
617
+ const isMonokai = this.theme.id === 'monokai';
618
+ const isCorporate = this.theme.id === 'corporate';
619
+ const isMinimal = this.theme.id === 'minimal';
620
+ let wrapperStyles = 'margin: 0; padding: 0;';
621
+ let containerStyles = `max-width: ${isMinimal ? '640px' : '600px'}; margin: 0 auto;`;
622
+ if (isModern) {
623
+ containerStyles += `
624
+ border-radius: ${this.theme.borderStyle.radius.large};
625
+ overflow: hidden;
626
+ box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.02);
627
+ `;
628
+ }
629
+ else if (isMonokai) {
630
+ containerStyles += `
631
+ border: 1px solid ${this.theme.light.border};
632
+ border-radius: ${this.theme.borderStyle.radius};
633
+ `;
634
+ }
635
+ else if (isCorporate) {
636
+ containerStyles += `
637
+ border: 1px solid ${this.theme.light.border};
638
+ box-shadow: ${this.theme.elevation.card};
639
+ `;
640
+ }
641
+ else if (isMinimal) {
642
+ containerStyles += `
643
+ border: none;
644
+ `;
645
+ }
646
+ const backgroundColor = this.variant === 'light' ? '#f5f5f5' : '#1a1a1a';
647
+ const finalBackgroundColor = isMinimal ? (this.variant === 'light' ? '#ffffff' : '#000000') : backgroundColor;
648
+ return `
649
+ <!DOCTYPE html>
650
+ <html>
651
+ <head>
652
+ <meta charset="utf-8">
653
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
654
+ <title>Email Template</title>
655
+ <style>
656
+ @media only screen and (max-width: 600px) {
657
+ .container {
658
+ width: 100% !important;
659
+ }
660
+ .button {
661
+ display: block !important;
662
+ width: 100% !important;
663
+ }
664
+ }
665
+ </style>
666
+ </head>
667
+ <body style="${wrapperStyles}">
668
+ <div class="container" style="${containerStyles} background-color: ${finalBackgroundColor};">
669
+ ${this.template}
670
+ </div>
671
+ </body>
672
+ </html>
673
+ `;
674
+ }
675
+ }
676
+ exports.TemplateBuilder = TemplateBuilder;