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
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:
150
app/components/messages/ContactSendModal.vue
Normal file
150
app/components/messages/ContactSendModal.vue
Normal file
@@ -0,0 +1,150 @@
|
||||
<template>
|
||||
<UModal v-model:open="isOpen">
|
||||
<template #content>
|
||||
<UCard>
|
||||
<template #header>
|
||||
<div class="flex items-center justify-between">
|
||||
<h3 class="text-lg font-semibold text-white">Enviar Contacto</h3>
|
||||
<UButton
|
||||
variant="ghost"
|
||||
icon="i-lucide-x"
|
||||
size="sm"
|
||||
@click="isOpen = false"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<div class="space-y-4">
|
||||
<!-- Contacts list -->
|
||||
<div
|
||||
v-for="(contact, index) in contacts"
|
||||
:key="index"
|
||||
class="p-3 rounded-lg bg-[var(--wa-bg-light)] space-y-3"
|
||||
>
|
||||
<div class="flex items-center justify-between">
|
||||
<span class="text-sm font-medium text-[var(--wa-text-muted)]">
|
||||
Contacto {{ index + 1 }}
|
||||
</span>
|
||||
<UButton
|
||||
v-if="contacts.length > 1"
|
||||
variant="ghost"
|
||||
icon="i-lucide-trash-2"
|
||||
size="xs"
|
||||
color="error"
|
||||
@click="removeContact(index)"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<UInput
|
||||
v-model="contact.displayName"
|
||||
placeholder="Nombre del contacto"
|
||||
icon="i-lucide-user"
|
||||
/>
|
||||
|
||||
<UInput
|
||||
v-model="contact.phoneNumber"
|
||||
placeholder="Número de teléfono (ej: +54911...)"
|
||||
icon="i-lucide-phone"
|
||||
/>
|
||||
|
||||
<UInput
|
||||
v-model="contact.organization"
|
||||
placeholder="Organización (opcional)"
|
||||
icon="i-lucide-building"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<!-- Add contact button -->
|
||||
<UButton
|
||||
v-if="contacts.length < 5"
|
||||
variant="outline"
|
||||
icon="i-lucide-plus"
|
||||
block
|
||||
@click="addContact"
|
||||
>
|
||||
Agregar otro contacto
|
||||
</UButton>
|
||||
</div>
|
||||
|
||||
<template #footer>
|
||||
<div class="flex justify-end gap-2">
|
||||
<UButton variant="ghost" @click="isOpen = false">
|
||||
Cancelar
|
||||
</UButton>
|
||||
<UButton
|
||||
:disabled="!isValid"
|
||||
:loading="isSending"
|
||||
@click="handleSend"
|
||||
>
|
||||
Enviar
|
||||
</UButton>
|
||||
</div>
|
||||
</template>
|
||||
</UCard>
|
||||
</template>
|
||||
</UModal>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
interface ContactInfo {
|
||||
displayName: string
|
||||
phoneNumber: string
|
||||
organization?: string
|
||||
}
|
||||
|
||||
const isOpen = defineModel<boolean>('open', { default: false })
|
||||
|
||||
const emit = defineEmits<{
|
||||
send: [contacts: ContactInfo[]]
|
||||
}>()
|
||||
|
||||
const isSending = ref(false)
|
||||
|
||||
const contacts = ref<ContactInfo[]>([
|
||||
{ displayName: '', phoneNumber: '', organization: '' }
|
||||
])
|
||||
|
||||
const isValid = computed(() => {
|
||||
return contacts.value.every(c =>
|
||||
c.displayName.trim() && c.phoneNumber.trim()
|
||||
)
|
||||
})
|
||||
|
||||
const addContact = () => {
|
||||
if (contacts.value.length < 5) {
|
||||
contacts.value.push({ displayName: '', phoneNumber: '', organization: '' })
|
||||
}
|
||||
}
|
||||
|
||||
const removeContact = (index: number) => {
|
||||
contacts.value.splice(index, 1)
|
||||
}
|
||||
|
||||
const handleSend = async () => {
|
||||
if (!isValid.value) return
|
||||
|
||||
isSending.value = true
|
||||
try {
|
||||
const validContacts = contacts.value.map(c => ({
|
||||
displayName: c.displayName.trim(),
|
||||
phoneNumber: c.phoneNumber.trim(),
|
||||
organization: c.organization?.trim() || undefined
|
||||
}))
|
||||
|
||||
emit('send', validContacts)
|
||||
|
||||
// Reset form
|
||||
contacts.value = [{ displayName: '', phoneNumber: '', organization: '' }]
|
||||
isOpen.value = false
|
||||
} finally {
|
||||
isSending.value = false
|
||||
}
|
||||
}
|
||||
|
||||
// Reset form when modal opens
|
||||
watch(isOpen, (open) => {
|
||||
if (open) {
|
||||
contacts.value = [{ displayName: '', phoneNumber: '', organization: '' }]
|
||||
}
|
||||
})
|
||||
</script>
|
||||
Reference in New Issue
Block a user