Feat: Agregar soporte para envío de Contacts, Polls y Events
All checks were successful
build-and-deploy / build-and-deploy (push) Successful in 1m8s

- Backend: Nuevo soporte en endpoint /send para tipos contact, poll, event
- UI: Modales para crear y enviar contactos, encuestas y eventos
- Visualización: Componentes MessagePoll y MessageEvent para mostrar mensajes recibidos
- Tipos: Agregar PollInfo, EventInfo y tipo 'event' a MessageType
This commit is contained in:
2025-12-04 12:06:35 -06:00
parent 48f23c512b
commit cb846d0c56
10 changed files with 1443 additions and 46 deletions

View File

@@ -174,6 +174,24 @@
<p class="text-white font-medium">Suelta los archivos aquí</p>
</div>
</div>
<!-- Contact Send Modal -->
<MessagesContactSendModal
v-model:open="showContactModal"
@send="handleSendContact"
/>
<!-- Poll Send Modal -->
<MessagesPollSendModal
v-model:open="showPollModal"
@send="handleSendPoll"
/>
<!-- Event Send Modal -->
<MessagesEventSendModal
v-model:open="showEventModal"
@send="handleSendEvent"
/>
</div>
</template>
@@ -190,9 +208,37 @@ const props = withDefaults(defineProps<Props>(), {
replyingTo: null
})
interface ContactInfo {
displayName: string
phoneNumber: string
organization?: string
}
interface PollData {
name: string
options: string[]
selectableCount: number
}
interface EventData {
name: string
startDate: string
endDate?: string
description?: string
location?: {
name?: string
address?: string
latitude?: number
longitude?: number
}
}
const emit = defineEmits<{
send: [content: string, files: File[], caption: string, quotedId?: string, stickerModes?: boolean[]]
sendVoice: [audioFile: File]
sendContact: [contacts: ContactInfo[], quotedId?: string]
sendPoll: [poll: PollData, quotedId?: string]
sendEvent: [event: EventData, quotedId?: string]
cancelReply: []
typing: []
recording: [isRecording: boolean]
@@ -212,6 +258,11 @@ const isDragging = ref(false)
const stickerModes = ref<boolean[]>([])
const showDebug = ref(false)
// Modal states
const showContactModal = ref(false)
const showPollModal = ref(false)
const showEventModal = ref(false)
// File size limits (in bytes) - should match server
const MAX_SIZES: Record<string, number> = {
image: 16 * 1024 * 1024, // 16 MB
@@ -317,6 +368,21 @@ const attachmentMenuItems = [
label: 'Documento',
icon: 'i-lucide-file',
onSelect: () => documentInput.value?.click()
}],
[{
label: 'Contacto',
icon: 'i-lucide-user',
onSelect: () => showContactModal.value = true
}],
[{
label: 'Encuesta',
icon: 'i-lucide-bar-chart-2',
onSelect: () => showPollModal.value = true
}],
[{
label: 'Evento',
icon: 'i-lucide-calendar',
onSelect: () => showEventModal.value = true
}]
]
@@ -441,5 +507,20 @@ const formatDuration = (seconds: number): string => {
const getTypePlaceholder = (type: MessageType): string => {
return getMessageTypePlaceholder(type)
}
// Handle contact send from modal
const handleSendContact = (contacts: ContactInfo[]) => {
emit('sendContact', contacts, props.replyingTo?.messageId)
}
// Handle poll send from modal
const handleSendPoll = (poll: PollData) => {
emit('sendPoll', poll, props.replyingTo?.messageId)
}
// Handle event send from modal
const handleSendEvent = (eventData: EventData) => {
emit('sendEvent', eventData, props.replyingTo?.messageId)
}
</script>