changes
This commit is contained in:
417
app/components/marketing/email/Template.vue
Normal file
417
app/components/marketing/email/Template.vue
Normal file
@@ -0,0 +1,417 @@
|
||||
<template>
|
||||
<div v-if="previewMode">
|
||||
<component
|
||||
:is="'style'"
|
||||
v-html="styles"
|
||||
/>
|
||||
<div class="container py-6 min-h-full">
|
||||
<table
|
||||
role="presentation"
|
||||
cellspacing="0"
|
||||
cellpadding="0"
|
||||
border="0"
|
||||
:style="{
|
||||
width: '100%',
|
||||
maxWidth: '100%',
|
||||
margin: '0 auto',
|
||||
}"
|
||||
>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>
|
||||
<table
|
||||
role="presentation"
|
||||
class="email-container gmail-fix"
|
||||
cellspacing="0"
|
||||
cellpadding="0"
|
||||
border="0"
|
||||
:style="{
|
||||
margin: '0 auto',
|
||||
width: '100%',
|
||||
maxWidth: '680px',
|
||||
backgroundColor: '#ffffff',
|
||||
border: '1px solid #dedede',
|
||||
overflow: 'hidden',
|
||||
}"
|
||||
>
|
||||
<tbody>
|
||||
<tr class="header-row">
|
||||
<td :style="{ padding: '0' }">
|
||||
<div
|
||||
class="header-image"
|
||||
:style="{
|
||||
background: '#f3f4f6',
|
||||
position: 'relative',
|
||||
width: '100%',
|
||||
height: '425px',
|
||||
overflow: 'hidden',
|
||||
}"
|
||||
>
|
||||
<img
|
||||
v-if="hasValidImage"
|
||||
:src="content.imageUrl"
|
||||
alt="image"
|
||||
:style="{
|
||||
width: '100%',
|
||||
height: '100%',
|
||||
objectFit: 'cover',
|
||||
display: 'block',
|
||||
}"
|
||||
/>
|
||||
<div
|
||||
v-else
|
||||
class="is-flex is-justify-content-center is-align-items-center"
|
||||
:style="{
|
||||
height: '100%',
|
||||
background: 'rgba(0, 0, 0, 0.3)',
|
||||
opacity: 0.15,
|
||||
}"
|
||||
>
|
||||
<Icon
|
||||
name="material-symbols:image-outline-rounded"
|
||||
:size="100"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr v-if="content.message">
|
||||
<td
|
||||
class="content-padding"
|
||||
:style="{
|
||||
paddingBottom: '20px',
|
||||
paddingTop: '30px',
|
||||
paddingRight: '25px',
|
||||
paddingLeft: '25px',
|
||||
}"
|
||||
>
|
||||
<div
|
||||
:style="{
|
||||
border: '1px solid #e5e7eb',
|
||||
borderRadius: '12px',
|
||||
backgroundColor: '#ffffff',
|
||||
overflow: 'hidden',
|
||||
}"
|
||||
>
|
||||
<div
|
||||
class="message-content"
|
||||
:style="{
|
||||
padding: '16px',
|
||||
fontSize: '16px',
|
||||
margin: '0',
|
||||
color: '#374151',
|
||||
lineHeight: '1.6',
|
||||
wordBreak: 'break-word',
|
||||
}"
|
||||
>
|
||||
<div
|
||||
class="content"
|
||||
v-html="processedMessage"
|
||||
></div>
|
||||
</div>
|
||||
|
||||
<div
|
||||
v-if="hasValidLinks"
|
||||
:style="{
|
||||
padding: '15px',
|
||||
paddingLeft: '35px',
|
||||
borderTop: '1px solid #e5e7eb',
|
||||
backgroundColor: '#f9fafb',
|
||||
}"
|
||||
>
|
||||
<div>
|
||||
<div
|
||||
v-for="(link, index) in validLinks"
|
||||
:key="index"
|
||||
:style="{ width: '100%', marginBottom: '8px' }"
|
||||
>
|
||||
<ul :style="{ paddingLeft: '20px', margin: 0 }">
|
||||
<li :style="{ listStyleType: 'disc' }">
|
||||
<a
|
||||
:style="{
|
||||
color: '#2563eb!important',
|
||||
fontWeight: '600',
|
||||
textDecoration: 'underline',
|
||||
display: 'inline-block',
|
||||
wordBreak: 'break-word',
|
||||
fontSize: '14px',
|
||||
}"
|
||||
target="_blank"
|
||||
:href="link"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
{{ getLinkText(index) }}
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td
|
||||
class="company-padding"
|
||||
:style="{ paddingBottom: '20px' }"
|
||||
>
|
||||
<div
|
||||
class="company-info"
|
||||
:style="{
|
||||
color: '#ffffff',
|
||||
borderRadius: '12px',
|
||||
}"
|
||||
>
|
||||
<div
|
||||
class="logo-container"
|
||||
:style="{
|
||||
width: '100%',
|
||||
height: '100%',
|
||||
marginBottom: '15px',
|
||||
backgroundColor: '#ffffff',
|
||||
borderRadius: '8px',
|
||||
overflow: 'hidden',
|
||||
}"
|
||||
>
|
||||
<img
|
||||
:src="imageUrl"
|
||||
alt="Utopia Footer"
|
||||
:style="{
|
||||
width: '100%',
|
||||
height: '100%',
|
||||
objectFit: 'cover',
|
||||
display: 'block',
|
||||
}"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<!-- <tr>
|
||||
<td
|
||||
:style="{
|
||||
backgroundColor: '#f9fafb',
|
||||
padding: '20px',
|
||||
borderTop: '1px solid #e5e7eb',
|
||||
textAlign: 'center',
|
||||
}"
|
||||
>
|
||||
<p
|
||||
:style="{
|
||||
color: '#9ca3af',
|
||||
fontSize: '11px',
|
||||
margin: '0',
|
||||
lineHeight: '1.5',
|
||||
}"
|
||||
>
|
||||
©2025 Utopia. Tất cả các quyền được bảo lưu.
|
||||
</p>
|
||||
</td>
|
||||
</tr> -->
|
||||
</tbody>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { imageUrl } from "~/components/marketing/email/Email.utils";
|
||||
|
||||
const props = defineProps({
|
||||
content: Object,
|
||||
previewMode: Boolean,
|
||||
});
|
||||
|
||||
const hasValidLinks = computed(() => {
|
||||
return props.content.linkUrl && props.content.linkUrl.some((link) => link && link.trim() !== "");
|
||||
});
|
||||
|
||||
const hasValidImage = computed(() => {
|
||||
return props.content.imageUrl && props.content.imageUrl.trim() !== "";
|
||||
});
|
||||
|
||||
const replaceKeywords = (content) => {
|
||||
if (!content) return "";
|
||||
|
||||
let replacedContent = content;
|
||||
|
||||
if (props.content.keyword && Array.isArray(props.content.keyword)) {
|
||||
props.content.keyword.forEach((kw) => {
|
||||
if (typeof kw !== "string" && kw.keyword && kw.value) {
|
||||
const regex = new RegExp(`\\{\\{${kw.keyword}\\}\\}`, "g");
|
||||
replacedContent = replacedContent.replace(regex, kw.value);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return replacedContent;
|
||||
};
|
||||
|
||||
const processedMessage = computed(() => replaceKeywords(props.content.message || ""));
|
||||
|
||||
const validLinks = computed(() => {
|
||||
if (!props.content.linkUrl || props.content.linkUrl.length === 0) return [];
|
||||
return props.content.linkUrl.filter((link) => link && link.trim() !== "");
|
||||
});
|
||||
|
||||
const getLinkText = (index) => {
|
||||
return props.content.textLinkUrl && props.content.textLinkUrl[index] && props.content.textLinkUrl[index].trim() !== ""
|
||||
? props.content.textLinkUrl[index]
|
||||
: `Link ${index + 1}`;
|
||||
};
|
||||
|
||||
const styles = `
|
||||
ol{
|
||||
list-style: decimal;
|
||||
}
|
||||
li{
|
||||
list-style: disc;
|
||||
}
|
||||
.greeting-padding{
|
||||
padding: 30px 25px 20px;
|
||||
}
|
||||
|
||||
.content-padding, .company-padding {
|
||||
padding: 0px 25px 20px;
|
||||
}
|
||||
|
||||
.message-content p {
|
||||
margin: 0 0 12px 0;
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
.message-content p:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.message-content strong {
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.message-content em {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.message-content u {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.message-content s {
|
||||
text-decoration: line-through;
|
||||
}
|
||||
|
||||
.message-content ol,
|
||||
.message-content ul {
|
||||
margin: 12px 0;
|
||||
padding-left: 25px;
|
||||
}
|
||||
|
||||
.message-content ol li,
|
||||
.message-content ul li {
|
||||
margin-bottom: 8px;
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
.message-content a {
|
||||
color: #2563eb;
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.message-content h1 {
|
||||
font-size: 28px;
|
||||
font-weight: 700;
|
||||
margin: 20px 0 12px 0;
|
||||
line-height: 1.3;
|
||||
color: #1f2937;
|
||||
}
|
||||
|
||||
.message-content h2 {
|
||||
font-size: 24px;
|
||||
font-weight: 700;
|
||||
margin: 18px 0 12px 0;
|
||||
line-height: 1.3;
|
||||
color: #1f2937;
|
||||
}
|
||||
|
||||
.message-content h3 {
|
||||
font-size: 20px;
|
||||
font-weight: 700;
|
||||
margin: 16px 0 12px 0;
|
||||
line-height: 1.3;
|
||||
color: #1f2937;
|
||||
}
|
||||
|
||||
.message-content .ql-align-center {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.message-content .ql-align-right {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.message-content .ql-align-justify {
|
||||
text-align: justify;
|
||||
}
|
||||
|
||||
.message-content .ql-indent-1 {
|
||||
padding-left: 3em;
|
||||
}
|
||||
|
||||
.message-content .ql-indent-2 {
|
||||
padding-left: 6em;
|
||||
}
|
||||
|
||||
|
||||
@media only screen and (max-width: 768px) {
|
||||
|
||||
.email-container {
|
||||
width: 100% !important;
|
||||
max-width: 100% !important;
|
||||
}
|
||||
|
||||
.greeting-padding{
|
||||
padding: 20px 0 0 0 !important;
|
||||
}
|
||||
|
||||
.content-padding {
|
||||
padding: 20px 0px !important;
|
||||
}
|
||||
.company-padding {
|
||||
padding: 0px 0px 20px 0px !important;
|
||||
}
|
||||
.company-info {
|
||||
padding: 20px 10px !important;
|
||||
}
|
||||
.greeting-title{
|
||||
padding: 10px !important;
|
||||
margin: 0 !important;
|
||||
}
|
||||
|
||||
.header-image {
|
||||
width: 100% !important;
|
||||
height: 250px !important;
|
||||
}
|
||||
.greeting-text {
|
||||
font-size: 12px !important;
|
||||
}
|
||||
.message-text {
|
||||
font-size: 12px !important;
|
||||
}
|
||||
.company-name {
|
||||
font-size: 12px !important;
|
||||
color: #ffffff !important;
|
||||
}
|
||||
.contact-info {
|
||||
font-size: 11px !important;
|
||||
color: #ffffff !important;
|
||||
}
|
||||
}
|
||||
`;
|
||||
</script>
|
||||
Reference in New Issue
Block a user