Added Frontend
This commit is contained in:
349
frontend/pages/email/new.vue
Normal file
349
frontend/pages/email/new.vue
Normal file
@@ -0,0 +1,349 @@
|
||||
<script setup>
|
||||
//TODO: BACKENDCHANGE EMAIL SENDING
|
||||
const dataStore = useDataStore()
|
||||
const profileStore = useProfileStore()
|
||||
const route = useRoute()
|
||||
const router = useRouter()
|
||||
const toast = useToast()
|
||||
const auth = useAuthStore()
|
||||
|
||||
const emailData = ref({
|
||||
to:"",
|
||||
cc:null,
|
||||
bcc: null,
|
||||
subject: "",
|
||||
html: "",
|
||||
text: "",
|
||||
account: "",
|
||||
})
|
||||
|
||||
const emailAccounts = ref([])
|
||||
const preloadedContent = ref("")
|
||||
const loadedDocuments = ref([])
|
||||
const loaded = ref(false)
|
||||
const noAccountsPresent = ref(false)
|
||||
const setupPage = async () => {
|
||||
//emailAccounts.value = await useEntities("emailAccounts").select()
|
||||
|
||||
emailAccounts.value = await useNuxtApp().$api("/api/email/accounts")
|
||||
|
||||
if(emailAccounts.value.length === 0) {
|
||||
noAccountsPresent.value = true
|
||||
} else {
|
||||
emailData.value.account = emailAccounts.value[0].id
|
||||
|
||||
preloadedContent.value = `<p></p><p></p><p></p>${auth.profile.email_signature || ""}`
|
||||
|
||||
//Check Query
|
||||
if(route.query.to) emailData.value.to = route.query.to
|
||||
if(route.query.cc) emailData.value.cc = route.query.cc
|
||||
if(route.query.bcc) emailData.value.bcc = route.query.bcc
|
||||
if(route.query.subject) emailData.value.to = route.query.subject
|
||||
|
||||
|
||||
if(route.query.loadDocuments) {
|
||||
console.log(JSON.parse(route.query.loadDocuments))
|
||||
const data = await useFiles().selectSomeDocuments(JSON.parse(route.query.loadDocuments))
|
||||
console.log(data)
|
||||
|
||||
if(data) loadedDocuments.value = data
|
||||
|
||||
loadedDocuments.value = await Promise.all(loadedDocuments.value.map(async doc => {
|
||||
|
||||
const document = await useEntities("createddocuments").selectSingle(doc.createddocument)
|
||||
console.log(document)
|
||||
return {
|
||||
...doc,
|
||||
createddocument: document
|
||||
}}))
|
||||
|
||||
//console.log(loadedDocuments.value)
|
||||
|
||||
if(loadedDocuments.value.length > 0) {
|
||||
console.log(loadedDocuments.value[0])
|
||||
emailData.value.subject = `${loadedDocuments.value[0].createddocument.title} von ${auth.activeTenantData.businessInfo.name}`
|
||||
|
||||
if(loadedDocuments.value[0].createddocument.contact && loadedDocuments.value[0].createddocument.contact.email) {
|
||||
console.log("Contact")
|
||||
emailData.value.to = loadedDocuments.value[0].createddocument.contact.email
|
||||
} else if(loadedDocuments.value[0].createddocument.customer && loadedDocuments.value[0].createddocument.customer.infoData.invoiceEmail) {
|
||||
emailData.value.to = loadedDocuments.value[0].createddocument.customer.infoData.invoiceEmail
|
||||
} else if(loadedDocuments.value[0].createddocument.customer && loadedDocuments.value[0].createddocument.customer.infoData.email) {
|
||||
emailData.value.to = loadedDocuments.value[0].createddocument.customer.infoData.email
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
loaded.value = true
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
setupPage()
|
||||
|
||||
const contentChanged = (content) => {
|
||||
emailData.value.html = content.html
|
||||
emailData.value.text = content.text
|
||||
}
|
||||
|
||||
const selectedAttachments = ref([])
|
||||
const renderAttachments = () => {
|
||||
selectedAttachments.value = Array.from(document.getElementById("inputAttachments").files).map(i => {
|
||||
return {
|
||||
filename: i.name,
|
||||
type: i.type
|
||||
}})
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
const toBase64 = file => new Promise((resolve, reject) => {
|
||||
const reader = new FileReader();
|
||||
reader.readAsDataURL(file);
|
||||
reader.onload = () => resolve(reader.result.split(",")[1]);
|
||||
reader.onerror = reject;
|
||||
});
|
||||
|
||||
function blobToBase64(blob) {
|
||||
return new Promise((resolve, _) => {
|
||||
const reader = new FileReader();
|
||||
reader.onloadend = () => resolve(reader.result.split(",")[1]);
|
||||
reader.readAsDataURL(blob);
|
||||
});
|
||||
}
|
||||
|
||||
const sendEmail = async () => {
|
||||
loaded.value = false
|
||||
|
||||
let body = {
|
||||
...emailData.value,
|
||||
attachments: []
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
for await (const file of Array.from(document.getElementById("inputAttachments").files)) {
|
||||
body.attachments.push({
|
||||
filename: file.name,
|
||||
content: await toBase64(file),
|
||||
contentType: file.type,
|
||||
encoding: "base64",
|
||||
contentDisposition: "attachment"
|
||||
})
|
||||
}
|
||||
|
||||
for await (const doc of loadedDocuments.value) {
|
||||
|
||||
|
||||
const res = await useFiles().downloadFile(doc.id, null, true)
|
||||
|
||||
body.attachments.push({
|
||||
filename: doc.path.split("/")[doc.path.split("/").length -1],
|
||||
content: await blobToBase64(res),
|
||||
contentType: res.type,
|
||||
encoding: "base64",
|
||||
contentDisposition: "attachment"
|
||||
})
|
||||
}
|
||||
|
||||
console.log(body)
|
||||
|
||||
const res = await useNuxtApp().$api("/api/email/send",{
|
||||
method: "POST",
|
||||
body: body,
|
||||
})
|
||||
|
||||
console.log(res)
|
||||
|
||||
|
||||
if(!res.success) {
|
||||
toast.add({title: "Fehler beim Absenden der E-Mail", color: "rose"})
|
||||
|
||||
} else {
|
||||
navigateTo("/")
|
||||
toast.add({title: "E-Mail zum Senden eingereiht"})
|
||||
}
|
||||
|
||||
loaded.value = true
|
||||
|
||||
}
|
||||
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
|
||||
<div v-if="noAccountsPresent" class="mx-auto mt-5 flex flex-col justify-center">
|
||||
<span class="font-bold text-2xl">Keine E-Mail Konten vorhanden</span>
|
||||
<UButton
|
||||
@click="router.push(`/settings/emailAccounts`)"
|
||||
class="mx-auto mt-5"
|
||||
>
|
||||
+ E-Mail Konto
|
||||
</UButton>
|
||||
</div>
|
||||
<div v-else>
|
||||
<UProgress animation="carousel" v-if="!loaded" class="mt-5 w-2/3 mx-auto"/>
|
||||
|
||||
<div v-else>
|
||||
<UDashboardNavbar
|
||||
title="Neue E-Mail"
|
||||
>
|
||||
<template #right>
|
||||
<UButton
|
||||
@click="sendEmail"
|
||||
:disabled="!emailData.to || !emailData.subject"
|
||||
>
|
||||
Senden
|
||||
</UButton>
|
||||
</template>
|
||||
|
||||
</UDashboardNavbar>
|
||||
|
||||
|
||||
|
||||
|
||||
<div class="scrollContainer mt-3">
|
||||
<div class="flex-col flex w-full">
|
||||
<UFormGroup
|
||||
label="Absender"
|
||||
>
|
||||
<USelectMenu
|
||||
:options="emailAccounts"
|
||||
option-attribute="email"
|
||||
value-attribute="id"
|
||||
v-model="emailData.account"
|
||||
/>
|
||||
</UFormGroup>
|
||||
<UDivider class="my-3"/>
|
||||
<UFormGroup
|
||||
label="Empfänger"
|
||||
>
|
||||
<UInput
|
||||
class="w-full my-1"
|
||||
v-model="emailData.to"
|
||||
/>
|
||||
</UFormGroup>
|
||||
<UFormGroup
|
||||
label="Kopie"
|
||||
>
|
||||
<UInput
|
||||
class="w-full my-1"
|
||||
v-model="emailData.cc"
|
||||
/>
|
||||
</UFormGroup>
|
||||
<UFormGroup
|
||||
label="Blindkopie"
|
||||
>
|
||||
<UInput
|
||||
class="w-full my-1"
|
||||
placeholder=""
|
||||
v-model="emailData.bcc"
|
||||
/>
|
||||
</UFormGroup>
|
||||
<UFormGroup
|
||||
label="Betreff"
|
||||
>
|
||||
<UInput
|
||||
class="w-full my-1"
|
||||
v-model="emailData.subject"
|
||||
/>
|
||||
</UFormGroup>
|
||||
</div>
|
||||
<UDivider class="my-3"/>
|
||||
<div id="parentAttachments" class="flex flex-col justify-center mt-3">
|
||||
<span class="font-medium mb-2 text-xl">Anhänge</span>
|
||||
<!-- <UIcon
|
||||
name="i-heroicons-paper-clip"
|
||||
class="mx-auto w-10 h-10"
|
||||
/>
|
||||
<span class="text-center text-2xl">Anhänge hochladen</span>-->
|
||||
<UInput
|
||||
id="inputAttachments"
|
||||
type="file"
|
||||
multiple
|
||||
@change="renderAttachments"
|
||||
/>
|
||||
<ul class="mx-5 mt-3">
|
||||
<li
|
||||
class="list-disc"
|
||||
v-for="file in selectedAttachments"
|
||||
> Datei - {{file.filename}}</li>
|
||||
<li
|
||||
class="list-disc"
|
||||
v-for="doc in loadedDocuments"
|
||||
>
|
||||
<span v-if="doc.createddocument">Dokument - {{doc.createddocument.documentNumber}}</span>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
|
||||
<Tiptap
|
||||
class="mt-3"
|
||||
@updateContent="contentChanged"
|
||||
:preloadedContent="preloadedContent"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
|
||||
#parentAttachments {
|
||||
border: 1px dashed #69c350;
|
||||
border-radius: 10px;
|
||||
padding: 1em;
|
||||
}
|
||||
|
||||
|
||||
#inputAttachments {
|
||||
/*
|
||||
display: none;
|
||||
*/
|
||||
display: inline-block;
|
||||
cursor: pointer;
|
||||
opacity: 100;/*
|
||||
width: 100%;
|
||||
height: 5%;
|
||||
position: relative;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;*/
|
||||
}
|
||||
|
||||
#inputAttachments::file-selector-button {
|
||||
background-color: white;
|
||||
border: 1px solid #69c350;
|
||||
border-radius: 5px;
|
||||
padding: 5px 10px 5px 10px;
|
||||
}
|
||||
|
||||
.fileListItem {
|
||||
border: 1px solid #69c350;
|
||||
border-radius: 5px;
|
||||
padding: .5rem;
|
||||
}
|
||||
|
||||
.scrollContainer {
|
||||
overflow-y: scroll;
|
||||
padding-left: 1em;
|
||||
padding-right: 1em;
|
||||
height: 90vh;
|
||||
-ms-overflow-style: none; /* IE and Edge */
|
||||
scrollbar-width: none; /* Firefox */
|
||||
}
|
||||
|
||||
</style>
|
||||
Reference in New Issue
Block a user