143 lines
3.9 KiB
Vue
143 lines
3.9 KiB
Vue
<template>
|
|
<v-card variant="flat" class="mb-6">
|
|
<v-card-title class="text-h6 d-flex align-center pb-4">
|
|
<v-icon class="mr-2" color="primary">mdi-email</v-icon>
|
|
Email Communication
|
|
</v-card-title>
|
|
<v-card-text class="pt-2">
|
|
<!-- Show credentials setup if not connected -->
|
|
<EmailCredentialsSetup
|
|
v-if="!isConnected"
|
|
@connected="onEmailConnected"
|
|
/>
|
|
|
|
<!-- Show email interface if connected -->
|
|
<template v-else>
|
|
<div class="mb-4">
|
|
<v-chip color="success" variant="tonal" size="small">
|
|
<v-icon start>mdi-check-circle</v-icon>
|
|
Connected as: {{ connectedEmail }}
|
|
</v-chip>
|
|
<v-btn
|
|
variant="text"
|
|
size="small"
|
|
class="ml-2"
|
|
@click="disconnect"
|
|
>
|
|
Disconnect
|
|
</v-btn>
|
|
</div>
|
|
|
|
<!-- Email Composer -->
|
|
<EmailComposer
|
|
ref="emailComposer"
|
|
:interest="interest"
|
|
@sent="onEmailSent"
|
|
@eoiGenerated="onEoiGenerated"
|
|
class="mb-4"
|
|
/>
|
|
|
|
<!-- Email Thread View -->
|
|
<EmailThreadView
|
|
ref="threadView"
|
|
:interest="interest"
|
|
@reply-to-email="onReplyToEmail"
|
|
/>
|
|
</template>
|
|
</v-card-text>
|
|
</v-card>
|
|
</template>
|
|
|
|
<script lang="ts" setup>
|
|
import { ref, onMounted } from 'vue';
|
|
import type { Interest } from '@/utils/types';
|
|
import EmailCredentialsSetup from './EmailCredentialsSetup.vue';
|
|
import EmailComposer from './EmailComposer.vue';
|
|
import EmailThreadView from './EmailThreadView.vue';
|
|
|
|
interface Props {
|
|
interest: Interest;
|
|
}
|
|
|
|
interface Emits {
|
|
(e: 'interestUpdated'): void;
|
|
}
|
|
|
|
const props = defineProps<Props>();
|
|
const emit = defineEmits<Emits>();
|
|
|
|
const isConnected = ref(false);
|
|
const connectedEmail = ref('');
|
|
const threadView = ref<InstanceType<typeof EmailThreadView>>();
|
|
const emailComposer = ref<InstanceType<typeof EmailComposer>>();
|
|
|
|
const checkConnection = () => {
|
|
// Check if we have a session and connected email
|
|
const sessionId = sessionStorage.getItem('emailSessionId');
|
|
const email = sessionStorage.getItem('connectedEmail');
|
|
|
|
if (sessionId && email) {
|
|
isConnected.value = true;
|
|
connectedEmail.value = email;
|
|
} else {
|
|
// Clear any partial session data
|
|
sessionStorage.removeItem('emailSessionId');
|
|
sessionStorage.removeItem('connectedEmail');
|
|
isConnected.value = false;
|
|
connectedEmail.value = '';
|
|
}
|
|
};
|
|
|
|
const onEmailConnected = (email: string) => {
|
|
isConnected.value = true;
|
|
connectedEmail.value = email;
|
|
};
|
|
|
|
const onEmailSent = (messageId: string) => {
|
|
// Reload email threads after sending
|
|
threadView.value?.reloadEmails();
|
|
};
|
|
|
|
const onEoiGenerated = () => {
|
|
// Emit event to parent to refresh interest data
|
|
emit('interestUpdated');
|
|
};
|
|
|
|
const onReplyToEmail = (email: any, thread: any) => {
|
|
// Extract the original sender's email address
|
|
const replyTo = email.direction === 'received' ? email.from : email.to;
|
|
const cleanEmail = replyTo.match(/<(.+)>/)?.[1] || replyTo;
|
|
|
|
// Prepare reply content with quote
|
|
const quotedContent = email.body
|
|
.split('\n')
|
|
.map((line: string) => `> ${line}`)
|
|
.join('\n');
|
|
|
|
const replyBody = `\n\n\nOn ${new Date(email.timestamp).toLocaleString()}, ${email.from} wrote:\n${quotedContent}`;
|
|
|
|
// Pre-fill the composer with reply data
|
|
if (emailComposer.value) {
|
|
(emailComposer.value as any).setReplyData({
|
|
to: cleanEmail,
|
|
subject: thread.subject.startsWith('Re: ') ? thread.subject : `Re: ${thread.subject}`,
|
|
body: replyBody
|
|
});
|
|
}
|
|
};
|
|
|
|
const disconnect = () => {
|
|
// Clear session storage
|
|
sessionStorage.removeItem('emailSessionId');
|
|
sessionStorage.removeItem('connectedEmail');
|
|
|
|
// Reset state
|
|
isConnected.value = false;
|
|
connectedEmail.value = '';
|
|
};
|
|
|
|
onMounted(() => {
|
|
checkConnection();
|
|
});
|
|
</script>
|