178 lines
6.0 KiB
Vue
178 lines
6.0 KiB
Vue
|
|
<template>
|
||
|
|
<div class="border rounded-lg p-4 bg-gray-50">
|
||
|
|
<h3 class="text-lg font-semibold mb-4">EOI Management</h3>
|
||
|
|
|
||
|
|
<!-- Generate EOI Button -->
|
||
|
|
<div v-if="!hasEOI" class="mb-4">
|
||
|
|
<button
|
||
|
|
@click="generateEOI"
|
||
|
|
:disabled="isGenerating"
|
||
|
|
class="bg-blue-600 text-white px-4 py-2 rounded hover:bg-blue-700 disabled:opacity-50 disabled:cursor-not-allowed"
|
||
|
|
>
|
||
|
|
{{ isGenerating ? 'Generating EOI...' : 'Generate EOI' }}
|
||
|
|
</button>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
<!-- EOI Status Badge -->
|
||
|
|
<div v-if="hasEOI" class="mb-4">
|
||
|
|
<span class="inline-flex items-center px-3 py-1 rounded-full text-sm font-medium"
|
||
|
|
:class="{
|
||
|
|
'bg-yellow-100 text-yellow-800': interest['EOI Status'] === 'Waiting for Signatures',
|
||
|
|
'bg-green-100 text-green-800': interest['EOI Status'] === 'Signed',
|
||
|
|
'bg-gray-100 text-gray-800': interest['EOI Status'] === 'Awaiting Further Details'
|
||
|
|
}">
|
||
|
|
{{ interest['EOI Status'] }}
|
||
|
|
</span>
|
||
|
|
<span v-if="interest['EOI Time Sent']" class="ml-2 text-sm text-gray-600">
|
||
|
|
Sent: {{ formatDate(interest['EOI Time Sent']) }}
|
||
|
|
</span>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
<!-- Signature Links -->
|
||
|
|
<div v-if="hasEOI" class="space-y-3">
|
||
|
|
<div class="border rounded p-3 bg-white">
|
||
|
|
<div class="flex justify-between items-center">
|
||
|
|
<div>
|
||
|
|
<span class="font-medium">Client Signature Link</span>
|
||
|
|
<span class="text-sm text-gray-500 ml-2">({{ interest['Full Name'] }})</span>
|
||
|
|
</div>
|
||
|
|
<button
|
||
|
|
@click="copyLink(interest['Signature Link Client'])"
|
||
|
|
class="text-blue-600 hover:text-blue-800 text-sm flex items-center"
|
||
|
|
>
|
||
|
|
<svg class="w-4 h-4 mr-1" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z" />
|
||
|
|
</svg>
|
||
|
|
Copy
|
||
|
|
</button>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
<div class="border rounded p-3 bg-white">
|
||
|
|
<div class="flex justify-between items-center">
|
||
|
|
<div>
|
||
|
|
<span class="font-medium">CC Signature Link</span>
|
||
|
|
<span class="text-sm text-gray-500 ml-2">(Oscar Faragher)</span>
|
||
|
|
</div>
|
||
|
|
<button
|
||
|
|
@click="copyLink(interest['Signature Link CC'])"
|
||
|
|
class="text-blue-600 hover:text-blue-800 text-sm flex items-center"
|
||
|
|
>
|
||
|
|
<svg class="w-4 h-4 mr-1" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z" />
|
||
|
|
</svg>
|
||
|
|
Copy
|
||
|
|
</button>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
<div class="border rounded p-3 bg-white">
|
||
|
|
<div class="flex justify-between items-center">
|
||
|
|
<div>
|
||
|
|
<span class="font-medium">Developer Signature Link</span>
|
||
|
|
<span class="text-sm text-gray-500 ml-2">(David Mizrahi)</span>
|
||
|
|
</div>
|
||
|
|
<button
|
||
|
|
@click="copyLink(interest['Signature Link Developer'])"
|
||
|
|
class="text-blue-600 hover:text-blue-800 text-sm flex items-center"
|
||
|
|
>
|
||
|
|
<svg class="w-4 h-4 mr-1" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z" />
|
||
|
|
</svg>
|
||
|
|
Copy
|
||
|
|
</button>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
<!-- Regenerate Button -->
|
||
|
|
<div v-if="hasEOI && interest['EOI Status'] !== 'Signed'" class="mt-4">
|
||
|
|
<button
|
||
|
|
@click="generateEOI"
|
||
|
|
:disabled="isGenerating"
|
||
|
|
class="text-sm text-gray-600 hover:text-gray-800 underline"
|
||
|
|
>
|
||
|
|
Regenerate EOI
|
||
|
|
</button>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
</template>
|
||
|
|
|
||
|
|
<script setup lang="ts">
|
||
|
|
import type { Interest } from '~/utils/types';
|
||
|
|
|
||
|
|
const props = defineProps<{
|
||
|
|
interest: Interest;
|
||
|
|
}>();
|
||
|
|
|
||
|
|
const emit = defineEmits<{
|
||
|
|
'eoi-generated': [data: { signingLinks: Record<string, string> }];
|
||
|
|
'update': [];
|
||
|
|
}>();
|
||
|
|
|
||
|
|
const { showToast } = useToast();
|
||
|
|
const isGenerating = ref(false);
|
||
|
|
|
||
|
|
const hasEOI = computed(() => {
|
||
|
|
return !!(props.interest['Signature Link Client'] ||
|
||
|
|
props.interest['Signature Link CC'] ||
|
||
|
|
props.interest['Signature Link Developer']);
|
||
|
|
});
|
||
|
|
|
||
|
|
const generateEOI = async () => {
|
||
|
|
isGenerating.value = true;
|
||
|
|
|
||
|
|
try {
|
||
|
|
const response = await $fetch<{
|
||
|
|
success: boolean;
|
||
|
|
documentId: string | number;
|
||
|
|
clientSigningUrl: string;
|
||
|
|
signingLinks: Record<string, string>;
|
||
|
|
}>('/api/email/generate-eoi-document', {
|
||
|
|
method: 'POST',
|
||
|
|
headers: {
|
||
|
|
'x-tag': '094ut234'
|
||
|
|
},
|
||
|
|
body: {
|
||
|
|
interestId: props.interest.Id.toString()
|
||
|
|
}
|
||
|
|
});
|
||
|
|
|
||
|
|
if (response.success) {
|
||
|
|
showToast(response.documentId === 'existing'
|
||
|
|
? 'EOI already exists - signature links retrieved'
|
||
|
|
: 'EOI generated successfully');
|
||
|
|
|
||
|
|
emit('eoi-generated', { signingLinks: response.signingLinks });
|
||
|
|
emit('update'); // Trigger parent to refresh data
|
||
|
|
}
|
||
|
|
} catch (error: any) {
|
||
|
|
console.error('Failed to generate EOI:', error);
|
||
|
|
showToast(error.data?.statusMessage || 'Failed to generate EOI');
|
||
|
|
} finally {
|
||
|
|
isGenerating.value = false;
|
||
|
|
}
|
||
|
|
};
|
||
|
|
|
||
|
|
const copyLink = (link: string | undefined) => {
|
||
|
|
if (!link) return;
|
||
|
|
|
||
|
|
navigator.clipboard.writeText(link).then(() => {
|
||
|
|
showToast('Signature link copied to clipboard');
|
||
|
|
}).catch(() => {
|
||
|
|
showToast('Failed to copy link');
|
||
|
|
});
|
||
|
|
};
|
||
|
|
|
||
|
|
const formatDate = (dateString: string) => {
|
||
|
|
const date = new Date(dateString);
|
||
|
|
return date.toLocaleString('en-US', {
|
||
|
|
month: 'short',
|
||
|
|
day: 'numeric',
|
||
|
|
year: 'numeric',
|
||
|
|
hour: '2-digit',
|
||
|
|
minute: '2-digit'
|
||
|
|
});
|
||
|
|
};
|
||
|
|
</script>
|