Просмотр исходного кода

feat(email-plugin): Improve styling of email templates

Michael Bromley 6 лет назад
Родитель
Сommit
8f0c6e7a38

+ 4 - 0
packages/dev-server/dev-config.ts

@@ -62,6 +62,10 @@ export const devConfig: VendureConfig = {
             templatePath: path.join(__dirname, '../email-plugin/templates'),
             outputPath: path.join(__dirname, 'test-emails'),
             mailboxPort: 5003,
+            globalTemplateVars: {
+                verifyEmailAddressUrl: 'http://localhost:8080/verify',
+                passwordResetUrl: 'http://localhost:8080/password-reset',
+            },
         }),
         new AdminUiPlugin({
             port: 5001,

+ 2 - 8
packages/email-plugin/src/default-email-handlers.ts

@@ -16,20 +16,14 @@ export const emailVerificationHandler = new EmailEventListener('email-verificati
     .on(AccountRegistrationEvent)
     .setRecipient(event => event.user.identifier)
     .setSubject(`Please verify your email address`)
-    .setTemplateVars(event => ({
-        user: event.user,
-        verifyUrl: 'verify',
-    }))
+    .setTemplateVars(event => ({ user: event.user }))
     .setMockEvent(mockAccountRegistrationEvent);
 
 export const passwordResetHandler = new EmailEventListener('password-reset')
     .on(PasswordResetEvent)
     .setRecipient(event => event.user.identifier)
     .setSubject(`Forgotten password reset`)
-    .setTemplateVars(event => ({
-        user: event.user,
-        passwordResetUrl: 'reset-password',
-    }))
+    .setTemplateVars(event => ({ user: event.user }))
     .setMockEvent(mockPasswordResetEvent);
 
 export const defaultEmailHandlers = [

+ 11 - 4
packages/email-plugin/src/dev-mailbox.ts

@@ -39,10 +39,17 @@ export class DevMailbox {
                     res.send({ success: false, error: `No mock event registered for type "${type}"`});
                     return;
                 }
-                this.handleMockEventFn(handler, { ...handler.mockEvent, ctx: this.createRequestContext(languageCode) });
-                res.send({ success: true });
+                try {
+                    await this.handleMockEventFn(handler, { ...handler.mockEvent, ctx: this.createRequestContext(languageCode) });
+                    res.send({ success: true });
+                } catch (e) {
+                    res.statusCode = 500;
+                    res.send({success: false, error: e.message });
+                }
+                return;
+            } else {
+                res.send({success: false, error: `Mock email generation not set up.`});
             }
-            res.send({ success: false, error: `Mock email generation not set up.` });
         });
         server.get('/item/:id', async (req, res) => {
             const fileName = req.params.id;
@@ -74,7 +81,7 @@ export class DevMailbox {
             });
         }
         contents.sort((a, b) => {
-            return a.date > b.date ? -1 : 1;
+            return +new Date(b.date) - +new Date(a.date);
         });
         return contents;
     }

+ 3 - 3
packages/email-plugin/src/handlebars-mjml-generator.ts

@@ -20,12 +20,12 @@ export class HandlebarsMjmlGenerator implements EmailGenerator {
     generate(
         subject: string,
         template: string,
-        templateContext: any,
+        templateVars: any,
     ) {
         const compiledSubject = Handlebars.compile(subject);
         const compiledTemplate = Handlebars.compile(template);
-        const subjectResult = compiledSubject(templateContext);
-        const mjml = compiledTemplate(templateContext);
+        const subjectResult = compiledSubject(templateVars);
+        const mjml = compiledTemplate(templateVars);
         const body = mjml2html(mjml).html;
         return { subject: subjectResult, body };
     }

+ 15 - 15
packages/email-plugin/src/mock-events.ts

@@ -27,24 +27,24 @@ export const mockOrderStateTransitionEvent = new OrderStateTransitionEvent(
             id: '3',
             firstName: 'Test',
             lastName: 'Customer',
-            emailAddress: 'test.customer@email.com',
+            emailAddress: 'test@test.com',
         }),
         lines: [
             new OrderLine({
                 id: '5',
                 featuredAsset: {
-                    preview: 'http://localhost:3000/assets/mikkel-bech-748940-unsplash__49__preview.jpg',
+                    preview: 'http://localhost:3000/assets/alexandru-acea-686569-unsplash__preview.jpg',
                 },
                 productVariant: new ProductVariant({
-                    id: '3',
-                    name: 'en Intelligent Cotton Salad Small',
-                    sku: '5x7ss',
+                    id: '2',
+                    name: 'Curvy Monitor 24 inch',
+                    sku: 'C24F390',
                 }),
                 items: [
                     new OrderItem({
                         id: '6',
-                        unitPrice: 745,
-                        unitPriceIncludesTax: false,
+                        unitPrice: 14374,
+                        unitPriceIncludesTax: true,
                         taxRate: 20,
                         pendingAdjustments: [],
                     }),
@@ -53,26 +53,26 @@ export const mockOrderStateTransitionEvent = new OrderStateTransitionEvent(
             new OrderLine({
                 id: '6',
                 featuredAsset: {
-                    preview: 'http://localhost:3000/assets/mikkel-bech-748940-unsplash__49__preview.jpg',
+                    preview: 'http://localhost:3000/assets/vincent-botta-736919-unsplash__preview.jpg',
                 },
                 productVariant: new ProductVariant({
                     id: '4',
-                    name: 'en Intelligent Cotton Salad Large',
-                    sku: '5x7ss',
+                    name: 'Hard Drive 1TB',
+                    sku: 'IHD455T1',
                 }),
                 items: [
                     new OrderItem({
                         id: '7',
-                        unitPrice: 745,
-                        unitPriceIncludesTax: false,
+                        unitPrice: 3799,
+                        unitPriceIncludesTax: true,
                         taxRate: 20,
                         pendingAdjustments: [],
                     }),
                 ],
             }),
         ],
-        subTotal: 1788,
-        subTotalBeforeTax: 1490,
+        subTotal: 18173,
+        subTotalBeforeTax: 15144,
         shipping: 1000,
         shippingMethod: {
             code: 'express-flat-rate',
@@ -80,7 +80,7 @@ export const mockOrderStateTransitionEvent = new OrderStateTransitionEvent(
             id: '2',
         },
         shippingAddress: {
-            fullName: 'Horacio Franecki',
+            fullName: 'Test Customer',
             company: '',
             streetLine1: '6000 Pagac Land',
             streetLine2: '',

+ 3 - 9
packages/email-plugin/templates/email-verification/body.hbs

@@ -2,23 +2,17 @@
 
 <mj-section background-color="#fafafa">
     <mj-column>
-
-        <mj-text font-style="italic"
-                 font-size="20px"
-                 font-family="Helvetica Neue"
-                 color="#626262">Verify Your Email Address</mj-text>
-
         <mj-text color="#525252">
-            Thank you for creating an account with [company name]! Click the button below to complete the registration process:
+            Thank you for creating an account. Click the button below to verify this email address and
+            complete the registration process:
         </mj-text>
 
         <mj-button font-family="Helvetica"
                    background-color="#f45e43"
                    color="white"
-                   href="{{ verifyUrl }}?token={{ user.verificationToken }}">
+                   href="{{ verifyEmailAddressUrl }}?token={{ user.verificationToken }}">
             Verify Me!
         </mj-button>
-
     </mj-column>
 </mj-section>
 

+ 50 - 18
packages/email-plugin/templates/order-confirmation/body.hbs

@@ -1,40 +1,72 @@
 {{> header title="Order Receipt" }}
 
-<mj-section background-color="#fafafa">
-    <mj-column>
-
-        <mj-text font-style="italic"
-                 font-size="20px"
-                 font-family="Helvetica Neue"
-                 color="#626262">Order Confirmation</mj-text>
+<mj-raw>
+    <style type="text/css">
+    .callout {
+        background-color: #375a67;
+        padding: 15px 0;
+    }
+    .callout-large > div {
+        text-align: center !important;
+        color: #fff !important;
+        font-size: 16px !important;
+        font-weight: bold;
+        padding: 0;
+    }
+    .callout-small > div {
+        text-align: center !important;
+        color: #fff !important;
+        font-size: 14px !important;
+        padding: 0;
+    }
+    ul.address {
+        list-style-type: none;
+        padding: 0;
+    }
+    tr.order-row td {
+        border-bottom: 1px dashed #eee;
+    }
+    tr.order-row td:last-child {
+        text-align: center;
+    }
+    tr.total-row {
+        font-weight: bold;
+    }
+    .bg-off-white {
+        background-color: #f5f5f5;
+    }
+    </style>
+</mj-raw>
 
-        <mj-text color="#525252">
+<mj-section css-class="bg-off-white">
+    <mj-column>
+        <mj-text>
             Dear {{ order.customer.firstName }} {{ order.customer.lastName }},
         </mj-text>
-        <mj-text color="#525252">
+        <mj-text>
             Thank you for your order!
         </mj-text>
-
     </mj-column>
 </mj-section>
 
-<mj-section background-color="#568feb" padding-bottom="15px" padding-top="15">
+
+<mj-section css-class="callout">
     <mj-column>
-        <mj-text align="center" color="#FFF" font-size="15px" padding-left="25px" padding-right="25px" padding-bottom="0px" padding-top="20"><strong>Order Code</strong></mj-text>
-        <mj-text align="center" color="#FFF" font-size="13px" padding-left="25px" padding-right="25px" padding-bottom="20px" padding-top="10">{{ order.code }}</mj-text>
+        <mj-text css-class="callout-large"><strong>Order Code</strong></mj-text>
+        <mj-text css-class="callout-small">{{ order.code }}</mj-text>
     </mj-column>
     <mj-column>
-        <mj-text align="center" color="#FFF" font-size="15px" padding-left="25px" padding-right="25px" padding-bottom="0px" padding-top="20"><strong>Order Date</strong></mj-text>
-        <mj-text align="center" color="#FFF" font-size="13px" padding-left="25px" padding-right="25px" padding-bottom="20px" padding-top="10">{{ formatDate order.orderPlacedAt }}</mj-text>
+        <mj-text css-class="callout-large"><strong>Order Date</strong></mj-text>
+        <mj-text css-class="callout-small">{{ formatDate order.orderPlacedAt }}</mj-text>
     </mj-column>
     <mj-column>
-        <mj-text align="center" color="#FFF" font-size="15px" padding-left="25px" padding-right="25px" padding-bottom="0px" padding-top="20"><strong>Total Price</strong></mj-text>
-        <mj-text align="center" color="#FFF" font-size="13px" padding-left="25px" padding-right="25px" padding-bottom="20px" padding-top="10">${{ formatMoney order.total }}</mj-text>
+        <mj-text css-class="callout-large"><strong>Total Price</strong></mj-text>
+        <mj-text css-class="callout-small">${{ formatMoney order.total }}</mj-text>
     </mj-column>
 </mj-section>
 
 
-<mj-section background-color="#f5f5f5">
+<mj-section css-class="bg-off-white">
     <mj-column>
         <mj-text>
             {{#with order.shippingAddress }}

+ 4 - 3
packages/email-plugin/templates/partials/footer.hbs

@@ -1,8 +1,9 @@
 <!--suppress ALL -->
-<mj-section background-color="#568feb" padding-bottom="5px" padding-top="0">
+<mj-section background-color="#375a67">
     <mj-column width="100%">
-        <mj-text align="center" color="#FFF" >
-            <span style="font-size:15px">Footer text</span></mj-text>
+        <mj-text align="center" color="#eee">
+            <span>[footer text]</span>
+        </mj-text>
     </mj-column>
 </mj-section>
 </mj-body>

+ 4 - 18
packages/email-plugin/templates/partials/header.hbs

@@ -3,30 +3,16 @@
         <mj-title>{{ title }}</mj-title>
         <mj-style inline="inline">
             h3 {
-            font-size: 18px;
-            color: #555;
-            font-weight: normal;
-            }
-            ul.address {
-            list-style-type: none;
-            padding: 0;
-            }
-            tr.order-row td {
-            border-bottom: 1px dashed #eee;
-            }
-            tr.order-row td:last-child {
-            text-align: center;
-            }
-            tr.total-row {
-            font-weight: bold;
+                font-size: 18px;
+                color: #555;
+                font-weight: normal;
             }
         </mj-style>
     </mj-head>
 
     <mj-body>
-        <!-- Company Header -->
         <mj-section background-color="#f0f0f0">
             <mj-column>
-                <mj-text>Company Header</mj-text>
+                <mj-text>[company header]</mj-text>
             </mj-column>
         </mj-section>

+ 0 - 6
packages/email-plugin/templates/password-reset/body.hbs

@@ -2,12 +2,6 @@
 
 <mj-section background-color="#fafafa">
     <mj-column>
-
-        <mj-text font-style="italic"
-                 font-size="20px"
-                 font-family="Helvetica Neue"
-                 color="#626262">Verify Your Email Address</mj-text>
-
         <mj-text color="#525252">
             Someone requested a new password for your account.
         </mj-text>