Files
sistema_base/apps/web/feactures/surveys/components/admin/question-config-modal.tsx

245 lines
6.8 KiB
TypeScript

// Modal para configurar cada pregunta individual
// Funcionalidades:
// - Configuración específica según el tipo de pregunta
// - Para títulos: solo contenido
// - Para preguntas simples: texto de la pregunta
// - Para preguntas con opciones: texto y lista de opciones
// - Switch para hacer la pregunta obligatoria/opcional
'use client';
import { Button } from '@repo/shadcn/button';
import {
Dialog,
DialogContent,
DialogFooter,
DialogHeader,
DialogTitle,
} from '@repo/shadcn/dialog';
import {
Form,
FormControl,
FormField,
FormItem,
FormLabel,
FormMessage,
} from '@repo/shadcn/form';
import { Input } from '@repo/shadcn/input';
import { Switch } from '@repo/shadcn/switch';
import { useEffect } from 'react';
import { useFieldArray, useForm } from 'react-hook-form';
import { QuestionType } from '../../schemas/survey';
import { Plus, Trash2 } from 'lucide-react';
interface QuestionConfigModalProps {
isOpen: boolean;
onClose: () => void;
question: any;
onSave: (config: any) => void;
}
export function QuestionConfigModal({
isOpen,
onClose,
question,
onSave,
}: QuestionConfigModalProps) {
const form = useForm({
defaultValues: {
content: '',
question: '',
required: false,
options: [{ id: '1', text: '' }],
},
});
const { fields, append, remove } = useFieldArray({
control: form.control,
name: 'options',
});
useEffect(() => {
if (question) {
form.reset({
content: question.content || '',
question: question.question || '',
required: question.required || false,
options: question.options || [{ id: '1', text: '' }],
});
}
}, [question, form]);
const handleSubmit = (data: any) => {
const config = {
...question,
...data,
};
// Remove options if not needed
if (![
QuestionType.MULTIPLE_CHOICE,
QuestionType.SINGLE_CHOICE,
QuestionType.SELECT
].includes(question.type)) {
delete config.options;
}
// Remove content if not a title
if (question.type !== QuestionType.TITLE) {
delete config.content;
}
onSave(config);
};
const renderFields = () => {
switch (question?.type) {
case QuestionType.TITLE:
return (
<FormField
control={form.control}
name="content"
render={({ field }) => (
<FormItem>
<FormLabel>Contenido del Título</FormLabel>
<FormControl>
<Input {...field} />
</FormControl>
<FormMessage />
</FormItem>
)}
/>
);
case QuestionType.SIMPLE:
return (
<FormField
control={form.control}
name="question"
render={({ field }) => (
<FormItem>
<FormLabel>Pregunta</FormLabel>
<FormControl>
<Input {...field} />
</FormControl>
<FormMessage />
</FormItem>
)}
/>
);
case QuestionType.MULTIPLE_CHOICE:
case QuestionType.SINGLE_CHOICE:
case QuestionType.SELECT:
return (
<>
<FormField
control={form.control}
name="question"
render={({ field }) => (
<FormItem>
<FormLabel>Pregunta</FormLabel>
<FormControl>
<Input {...field} />
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<div className="space-y-4">
<div className="flex justify-between items-center">
<FormLabel>Opciones</FormLabel>
<Button
type="button"
variant="outline"
size="sm"
onClick={() => append({ id: `${fields.length + 1}`, text: '' })}
>
<Plus className="h-4 w-4 mr-2" />
Agregar Opción
</Button>
</div>
<div className="max-h-[200px] overflow-y-auto pr-2 space-y-4">
{fields.map((field, index) => (
<div key={field.id} className="flex gap-2">
<FormField
control={form.control}
name={`options.${index}.text`}
render={({ field }) => (
<FormItem className="flex-1">
<FormControl>
<Input {...field} placeholder={`Opción ${index + 1}`} />
</FormControl>
<FormMessage />
</FormItem>
)}
/>
{fields.length > 1 && (
<Button
type="button"
variant="ghost"
size="icon"
onClick={() => remove(index)}
>
<Trash2 className="h-4 w-4" />
</Button>
)}
</div>
))}
</div>
</div>
</>
);
}
};
return (
<Dialog open={isOpen} onOpenChange={onClose}>
<DialogContent
className="max-w-2xl"
aria-describedby="question-config-description"
>
<div id="question-config-description" className="sr-only">
Configuración de la pregunta de la encuesta
</div>
<DialogHeader>
<DialogTitle>Configurar Pregunta</DialogTitle>
</DialogHeader>
<Form {...form}>
<form onSubmit={form.handleSubmit(handleSubmit)} className="space-y-6">
{renderFields()}
{question?.type !== QuestionType.TITLE && (
<FormField
control={form.control}
name="required"
render={({ field }) => (
<FormItem className="flex items-center justify-between rounded-lg border p-3">
<div className="space-y-0.5">
<FormLabel>Respuesta Obligatoria</FormLabel>
</div>
<FormControl>
<Switch
checked={field.value}
onCheckedChange={field.onChange}
/>
</FormControl>
</FormItem>
)}
/>
)}
<DialogFooter>
<Button type="button" variant="outline" onClick={onClose}>
Cancelar
</Button>
<Button type="submit">Guardar</Button>
</DialogFooter>
</form>
</Form>
</DialogContent>
</Dialog>
);
}