port-nimara-client-portal/components/EmailCommunication.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>