Implemented e-mail notification trigger.
This commit is contained in:
38
pages/admin/emails/+Page.vue
Normal file
38
pages/admin/emails/+Page.vue
Normal file
@@ -0,0 +1,38 @@
|
||||
<script setup>
|
||||
import { inject } from 'vue';
|
||||
|
||||
import Admin from '#/components/admin/admin.vue';
|
||||
|
||||
const { pageProps } = inject('pageContext');
|
||||
|
||||
const { templates } = pageProps;
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<Admin class="page">
|
||||
<ul
|
||||
v-if="templates.length > 0"
|
||||
class="menu"
|
||||
>
|
||||
<li v-for="template in templates" :key="template">
|
||||
<a
|
||||
:href="`/admin/emails/${template}`"
|
||||
class="link"
|
||||
>{{ template }}</a>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<p v-else>No e-mail templates found in components/emails.</p>
|
||||
</Admin>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.menu {
|
||||
margin: 0;
|
||||
|
||||
.link {
|
||||
display: block;
|
||||
padding: .25rem;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
18
pages/admin/emails/+onBeforeRender.js
Normal file
18
pages/admin/emails/+onBeforeRender.js
Normal file
@@ -0,0 +1,18 @@
|
||||
import { render } from 'vike/abort';
|
||||
|
||||
import { listEmailTemplates } from '#/src/email-templates.js';
|
||||
|
||||
export default function onBeforeRender(pageContext) {
|
||||
if (!pageContext.user || pageContext.user.role === 'user') {
|
||||
throw render(404);
|
||||
}
|
||||
|
||||
return {
|
||||
pageContext: {
|
||||
title: 'E-mail Previews',
|
||||
pageProps: {
|
||||
templates: listEmailTemplates(),
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
70
pages/admin/emails/@template/+Page.vue
Normal file
70
pages/admin/emails/@template/+Page.vue
Normal file
@@ -0,0 +1,70 @@
|
||||
<script setup>
|
||||
import { inject } from 'vue';
|
||||
|
||||
import Admin from '#/components/admin/admin.vue';
|
||||
|
||||
const { pageProps } = inject('pageContext');
|
||||
|
||||
const {
|
||||
template,
|
||||
html,
|
||||
text,
|
||||
error,
|
||||
} = pageProps;
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<Admin class="page">
|
||||
<div class="header">
|
||||
<h2 class="heading">{{ template }}</h2>
|
||||
</div>
|
||||
|
||||
<p v-if="error" class="error">Failed to render template: {{ error }}</p>
|
||||
|
||||
<template v-else>
|
||||
<iframe
|
||||
:srcdoc="html"
|
||||
class="frame"
|
||||
title="E-mail preview"
|
||||
/>
|
||||
|
||||
<details v-if="text" class="text">
|
||||
<summary>Plain-text version</summary>
|
||||
<pre>{{ text }}</pre>
|
||||
</details>
|
||||
</template>
|
||||
</Admin>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.header {
|
||||
display: flex;
|
||||
align-items: baseline;
|
||||
gap: 1rem;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
.error {
|
||||
color: var(--warn);
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.frame {
|
||||
width: 100%;
|
||||
min-height: 60rem;
|
||||
border: solid 1px var(--shadow-weak-30);
|
||||
border-radius: .5rem;
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
.text {
|
||||
margin-top: 1rem;
|
||||
|
||||
pre {
|
||||
white-space: pre-wrap;
|
||||
padding: 1rem;
|
||||
background: var(--background-dark-20);
|
||||
border-radius: .5rem;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
38
pages/admin/emails/@template/+onBeforeRender.js
Normal file
38
pages/admin/emails/@template/+onBeforeRender.js
Normal file
@@ -0,0 +1,38 @@
|
||||
import { render } from 'vike/abort';
|
||||
|
||||
import { emailTemplates, listEmailTemplates } from '#/src/email-templates.js';
|
||||
|
||||
export default async function onBeforeRender(pageContext) {
|
||||
if (!pageContext.user || pageContext.user.role === 'user') {
|
||||
throw render(404);
|
||||
}
|
||||
|
||||
const { template } = pageContext.routeParams;
|
||||
|
||||
if (!listEmailTemplates().includes(template)) {
|
||||
throw render(404);
|
||||
}
|
||||
|
||||
let html = null;
|
||||
let text = null;
|
||||
let error = null;
|
||||
|
||||
try {
|
||||
({ html, text } = await emailTemplates.render(`${template}.vue`));
|
||||
}
|
||||
catch (renderError) {
|
||||
error = renderError.message;
|
||||
}
|
||||
|
||||
return {
|
||||
pageContext: {
|
||||
title: `E-mail Preview: ${template}`,
|
||||
pageProps: {
|
||||
template,
|
||||
html,
|
||||
text,
|
||||
error,
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
18
pages/admin/emails/@template/+route.js
Normal file
18
pages/admin/emails/@template/+route.js
Normal file
@@ -0,0 +1,18 @@
|
||||
import { match } from 'path-to-regexp';
|
||||
|
||||
const path = '/admin/emails/:template';
|
||||
const urlMatch = match(path, { decode: decodeURIComponent });
|
||||
|
||||
export default (pageContext) => {
|
||||
const matched = urlMatch(pageContext.urlPathname);
|
||||
|
||||
if (matched) {
|
||||
return {
|
||||
routeParams: {
|
||||
template: matched.params.template,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
return false;
|
||||
};
|
||||
Reference in New Issue
Block a user