130 lines
		
	
	
		
			4.3 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
		
		
			
		
	
	
			130 lines
		
	
	
		
			4.3 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
|  | import React, { useState, useEffect } from 'react'; | ||
|  | import { | ||
|  |     Modal, Box, Typography, TextField, Button, CircularProgress, Alert, | ||
|  |     FormControlLabel, Checkbox | ||
|  | } from '@mui/material'; | ||
|  | import type { PubliSeccionDto } from '../../../models/dtos/Distribucion/PubliSeccionDto'; | ||
|  | import type { CreatePubliSeccionDto } from '../../../models/dtos/Distribucion/CreatePubliSeccionDto'; | ||
|  | import type { UpdatePubliSeccionDto } from '../../../models/dtos/Distribucion/UpdatePubliSeccionDto'; | ||
|  | 
 | ||
|  | const modalStyle = { /* ... (mismo estilo) ... */ | ||
|  |     position: 'absolute' as 'absolute', | ||
|  |     top: '50%', | ||
|  |     left: '50%', | ||
|  |     transform: 'translate(-50%, -50%)', | ||
|  |     width: { xs: '90%', sm: 450 }, | ||
|  |     bgcolor: 'background.paper', | ||
|  |     border: '2px solid #000', | ||
|  |     boxShadow: 24, | ||
|  |     p: 4, | ||
|  | }; | ||
|  | 
 | ||
|  | interface PubliSeccionFormModalProps { | ||
|  |   open: boolean; | ||
|  |   onClose: () => void; | ||
|  |   onSubmit: (data: CreatePubliSeccionDto | UpdatePubliSeccionDto, idSeccion?: number) => Promise<void>; | ||
|  |   idPublicacion: number; // Siempre necesario para la creación
 | ||
|  |   initialData?: PubliSeccionDto | null; | ||
|  |   errorMessage?: string | null; | ||
|  |   clearErrorMessage: () => void; | ||
|  | } | ||
|  | 
 | ||
|  | const PubliSeccionFormModal: React.FC<PubliSeccionFormModalProps> = ({ | ||
|  |   open, | ||
|  |   onClose, | ||
|  |   onSubmit, | ||
|  |   idPublicacion, | ||
|  |   initialData, | ||
|  |   errorMessage, | ||
|  |   clearErrorMessage | ||
|  | }) => { | ||
|  |   const [nombre, setNombre] = useState(''); | ||
|  |   const [estado, setEstado] = useState(true); // Default a activa
 | ||
|  | 
 | ||
|  |   const [loading, setLoading] = useState(false); | ||
|  |   const [localErrorNombre, setLocalErrorNombre] = useState<string | null>(null); | ||
|  | 
 | ||
|  |   const isEditing = Boolean(initialData); | ||
|  | 
 | ||
|  |   useEffect(() => { | ||
|  |     if (open) { | ||
|  |         setNombre(initialData?.nombre || ''); | ||
|  |         setEstado(initialData ? initialData.estado : true); | ||
|  |         setLocalErrorNombre(null); | ||
|  |         clearErrorMessage(); | ||
|  |     } | ||
|  |   }, [open, initialData, clearErrorMessage]); | ||
|  | 
 | ||
|  |   const validate = (): boolean => { | ||
|  |     let isValid = true; | ||
|  |     if (!nombre.trim()) { | ||
|  |         setLocalErrorNombre('El nombre de la sección es obligatorio.'); | ||
|  |         isValid = false; | ||
|  |     } | ||
|  |     return isValid; | ||
|  |   }; | ||
|  | 
 | ||
|  |   const handleInputChange = () => { | ||
|  |     if (localErrorNombre) setLocalErrorNombre(null); | ||
|  |     if (errorMessage) clearErrorMessage(); | ||
|  |   }; | ||
|  | 
 | ||
|  |   const handleSubmit = async (event: React.FormEvent<HTMLFormElement>) => { | ||
|  |     event.preventDefault(); | ||
|  |     clearErrorMessage(); | ||
|  |     if (!validate()) return; | ||
|  | 
 | ||
|  |     setLoading(true); | ||
|  |     try { | ||
|  |       if (isEditing && initialData) { | ||
|  |         const dataToSubmit: UpdatePubliSeccionDto = { nombre, estado }; | ||
|  |         await onSubmit(dataToSubmit, initialData.idSeccion); | ||
|  |       } else { | ||
|  |         const dataToSubmit: CreatePubliSeccionDto = { | ||
|  |             idPublicacion, // Viene de props
 | ||
|  |             nombre, | ||
|  |             estado | ||
|  |         }; | ||
|  |         await onSubmit(dataToSubmit); | ||
|  |       } | ||
|  |       onClose(); | ||
|  |     } catch (error: any) { | ||
|  |       console.error("Error en submit de PubliSeccionFormModal:", error); | ||
|  |       // El error de API se maneja en la página
 | ||
|  |     } finally { | ||
|  |        setLoading(false); | ||
|  |     } | ||
|  |   }; | ||
|  | 
 | ||
|  |   return ( | ||
|  |     <Modal open={open} onClose={onClose}> | ||
|  |       <Box sx={modalStyle}> | ||
|  |         <Typography variant="h6" component="h2" gutterBottom> | ||
|  |           {isEditing ? 'Editar Sección' : 'Agregar Nueva Sección'} | ||
|  |         </Typography> | ||
|  |         <Box component="form" onSubmit={handleSubmit} sx={{ mt: 1 }}> | ||
|  |             <TextField label="Nombre de la Sección" value={nombre} required | ||
|  |                 onChange={(e) => {setNombre(e.target.value); handleInputChange();}} | ||
|  |                 margin="dense" fullWidth error={!!localErrorNombre} helperText={localErrorNombre || ''} | ||
|  |                 disabled={loading} autoFocus | ||
|  |             /> | ||
|  |             <FormControlLabel | ||
|  |                 control={<Checkbox checked={estado} onChange={(e) => setEstado(e.target.checked)} disabled={loading}/>} | ||
|  |                 label="Activa" sx={{mt:1}} | ||
|  |             /> | ||
|  | 
 | ||
|  |           {errorMessage && <Alert severity="error" sx={{ mt: 2, width: '100%' }}>{errorMessage}</Alert>} | ||
|  | 
 | ||
|  |           <Box sx={{ mt: 3, display: 'flex', justifyContent: 'flex-end', gap: 1 }}> | ||
|  |             <Button onClick={onClose} color="secondary" disabled={loading}>Cancelar</Button> | ||
|  |             <Button type="submit" variant="contained" disabled={loading}> | ||
|  |               {loading ? <CircularProgress size={24} /> : (isEditing ? 'Guardar Cambios' : 'Agregar Sección')} | ||
|  |             </Button> | ||
|  |           </Box> | ||
|  |         </Box> | ||
|  |       </Box> | ||
|  |     </Modal> | ||
|  |   ); | ||
|  | }; | ||
|  | 
 | ||
|  | export default PubliSeccionFormModal; |