Files
FEDEO/pages/email/new.vue
florianfederspiel 30da08689d Implemented new Backend in E-Mail Sending
Implemented Blob Return Method for File Download
2025-09-12 17:42:24 +02:00

344 lines
8.3 KiB
Vue

<script setup>
//TODO: BACKENDCHANGE EMAIL SENDING
const supabase = useSupabaseClient()
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()
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
//console.log(loadedDocuments.value)
if(loadedDocuments.value.length > 0) {
console.log(loadedDocuments.value[0])
emailData.value.subject = loadedDocuments.value[0].createddocument.title
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 {data,error} = await supabase.storage.from("filesdev").download(doc.path)
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"
})
}
const res = await useNuxtApp().$api("/api/emailasuser/send",{
method: "POST",
body: body,
})
console.log(res)
/*const { data, error } = await supabase.functions.invoke('send_email', {
body
})*/
if(!res.success) {
toast.add({title: "Fehler beim Absenden der E-Mail", color: "rose"})
} else {
//router.push("/")
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="emailAddress"
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>