Files
whatsappNucleo/app/components/messages/PollSendModal.vue
josedario87 cb846d0c56
All checks were successful
build-and-deploy / build-and-deploy (push) Successful in 1m8s
Feat: Agregar soporte para envío de Contacts, Polls y Events
- 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
2025-12-04 12:06:35 -06:00

202 lines
5.1 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">Crear Encuesta</h3>
<UButton
variant="ghost"
icon="i-lucide-x"
size="sm"
@click="isOpen = false"
/>
</div>
</template>
<div class="space-y-4">
<!-- Poll question -->
<div>
<label class="block text-sm font-medium text-[var(--wa-text-muted)] mb-1">
Pregunta
</label>
<UInput
v-model="pollName"
placeholder="¿Cuál es tu opción favorita?"
icon="i-lucide-help-circle"
/>
</div>
<!-- Options -->
<div>
<label class="block text-sm font-medium text-[var(--wa-text-muted)] mb-2">
Opciones (mínimo 2, máximo 12)
</label>
<div class="space-y-2">
<div
v-for="(option, index) in options"
:key="index"
class="flex items-center gap-2"
>
<span class="text-sm text-[var(--wa-text-muted)] w-6">
{{ index + 1 }}.
</span>
<UInput
v-model="options[index]"
:placeholder="`Opción ${index + 1}`"
class="flex-1"
/>
<UButton
v-if="options.length > 2"
variant="ghost"
icon="i-lucide-x"
size="xs"
color="error"
@click="removeOption(index)"
/>
</div>
</div>
<UButton
v-if="options.length < 12"
variant="outline"
icon="i-lucide-plus"
size="sm"
class="mt-2"
@click="addOption"
>
Agregar opción
</UButton>
</div>
<!-- Allow multiple selection -->
<div class="flex items-center justify-between p-3 rounded-lg bg-[var(--wa-bg-light)]">
<div>
<p class="text-sm font-medium text-white">Selección múltiple</p>
<p class="text-xs text-[var(--wa-text-muted)]">
Permitir seleccionar más de una opción
</p>
</div>
<USwitch v-model="allowMultiple" />
</div>
<!-- Max selections (only if multiple) -->
<div v-if="allowMultiple" class="flex items-center gap-3">
<label class="text-sm text-[var(--wa-text-muted)]">
Máximo de selecciones:
</label>
<UInput
v-model.number="maxSelections"
type="number"
:min="1"
:max="validOptions.length"
class="w-20"
/>
</div>
</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"
>
Crear encuesta
</UButton>
</div>
</template>
</UCard>
</template>
</UModal>
</template>
<script setup lang="ts">
interface PollData {
name: string
options: string[]
selectableCount: number
}
const isOpen = defineModel<boolean>('open', { default: false })
const emit = defineEmits<{
send: [poll: PollData]
}>()
const isSending = ref(false)
const pollName = ref('')
const options = ref<string[]>(['', ''])
const allowMultiple = ref(false)
const maxSelections = ref(1)
const validOptions = computed(() =>
options.value.filter(o => o.trim())
)
const isValid = computed(() => {
return pollName.value.trim() && validOptions.value.length >= 2
})
const addOption = () => {
if (options.value.length < 12) {
options.value.push('')
}
}
const removeOption = (index: number) => {
if (options.value.length > 2) {
options.value.splice(index, 1)
}
}
const handleSend = async () => {
if (!isValid.value) return
isSending.value = true
try {
const poll: PollData = {
name: pollName.value.trim(),
options: validOptions.value,
selectableCount: allowMultiple.value
? Math.min(maxSelections.value, validOptions.value.length)
: 1
}
emit('send', poll)
// Reset form
resetForm()
isOpen.value = false
} finally {
isSending.value = false
}
}
const resetForm = () => {
pollName.value = ''
options.value = ['', '']
allowMultiple.value = false
maxSelections.value = 1
}
// Reset form when modal opens
watch(isOpen, (open) => {
if (open) {
resetForm()
}
})
// Adjust max selections when options change
watch(validOptions, (opts) => {
if (maxSelections.value > opts.length) {
maxSelections.value = opts.length || 1
}
})
</script>