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
151 lines
3.7 KiB
Vue
151 lines
3.7 KiB
Vue
<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>
|