Vistas
Aqui vamos a crear la siguiente parte de vistas de nuestro mini sitio de noticias.Creamos el archivo comunicadores.jsx
import './App.css';
import React, { useState, useEffect } from "react";
import { DataTable } from "primereact/datatable";
import { Column } from "primereact/column";
import { Outlet } from "react-router-dom";
import axios from "axios";
import Menu2 from "./Menu2"
function Comunicadores() {
const [comunicadores,setComunicadores] = useState([])
useEffect(()=>{
axios
.get("http://localhost:8888/api/usuarios")
.then((res) => setComunicadores(res.data));
},[]);
return (
<>
<
header className = "App-header" >
<Menu2/>
<div className="flex justify-content-center">
<div className="card">
<h5 className="text-center">Ver Comunicadores</h5>
<DataTable
value={comunicadores}
responsiveLayout="scroll"
paginatorTemplate="FirstPageLink PrevPageLink PageLinks NextPageLink LastPageLink CurrentPageReport RowsPerPageDropdown"
dataKey="email"
paginator
emptyMessage="No existen comunicadores"
className="datatable-responsive"
currentPageReportTemplate="Mostrando {first} to {last} of {totalRecords} communicadores"
rows={10}
>
<Column field="nombre" sortable header="Nombre"></Column>
<Column field="apellidoPaterno" sortable header="apellidoPaterno"></Column>
<Column field="apellidoMaterno" sortable header="apellidoMaterno"></Column>
<Column field="email" sortable header="Usuario"></Column>
</DataTable>
</div>
</div>
</header>
<Outlet/>
</>
);
}
export default Comunicadores;
Creamos el archivo Noticias.jsx
import './App.css';
import React, { useState, useEffect } from "react";
import { useLocation, useNavigate } from 'react-router-dom';
import { Button } from 'primereact/button';
import { Form, Field } from 'react-final-form';
import { classNames } from 'primereact/utils';
import { InputText } from 'primereact/inputtext';
import { Dialog } from 'primereact/dialog';
import { InputTextarea } from 'primereact/inputtextarea';
import { Outlet } from "react-router-dom";
import { Calendar } from 'primereact/calendar';
import { addLocale } from 'primereact/api';
import { Badge } from 'primereact/badge';
import { MultiSelect } from 'primereact/multiselect';
import axios from "axios";
import Menu2 from "./Menu2"
function Noticias() {
const { state } = useLocation();
let today = new Date();
const [tipoNoticia,setTipoNoticia] = useState(null);
const [showMessage, setShowMessage] = useState(false);
const [showMessage2, setShowMessage2] = useState(false);
const [estado,setEstado]=useState({value:''})
const [notiData,setNotiData]=useState({
});
const [formData, setFormData] = useState({});
const navigate = useNavigate();
const validate = (data) => {
let errors = {};
if (!data.tituloNoticia) {
errors.tituloNoticia = 'El título de la noticia es requerido';
}
if (!data.descripcionNoticia) {
errors.descripcionNoticia = 'La descripción es requerida';
}
if (!data.fechaPublicacion) {
errors.fechaPublicacion = 'La fecha de publicación requerida o debe ser igual o mayor que hoy';
}
if (!data.tipoNoticia) {
errors.tipoNoticia = 'El tipo de noticia es requerido';
}
return errors;
};
const handleChange=(event)=> {
this.setEstado({value: event.target.value});
}
const onSubmit = (data, form) => {
console.log(data.tipoNoticia);
setFormData(data);
const config = {
headers: {
"Content-type":"application/json"
}
};
axios.post('http://localhost:8888/api/noticia',data)
.then((res)=>{
navigate('/Upload', {
replace: true,
state: {
logged: true,
nombre: state.nombre,
apellidoPaterno: state.apellidoPaterno,
tituloNoticia:res.data.nk.tituloNoticia,
fechaPublicacion:res.data.nk.fechaPublicacion,
comunicador:res.data.comunicador
},
});
});
form.restart();
};
const isFormFieldValid = (meta) => !!(meta.touched && meta.error);
const getFormErrorMessage = (meta) => {
return isFormFieldValid(meta) && <small className="p-error">{meta.error}</small>;
};
const noticias = [
{ nombre: 'Finanzas', codigo: 'Finanzas' },
{ nombre: 'Nota Roja', codigo: 'Nota Roja' },
{ nombre: 'Deportes', codigo: 'Deportes' },
{ nombre: 'Espectáculos', codigo: 'Espectáculos' },
{ nombre: 'Cultura', codigo: 'Cultura' },
{ nombre: 'Entretenimiento', codigo: 'Entretenimiento' },
{ nombre: 'Política', codigo: 'Política' },
{ nombre: 'Tecnología', codigo: 'Tecnología' }
];
const dialogFooter = <div className="flex justify-content-center"><Button label="OK" className="p-button-text" autoFocus onClick={() => setShowMessage(false) } /></div>;
const dialogFooter2 = <div className="flex justify-content-center"><Button label="OK" className="p-button-text" autoFocus onClick={() => setShowMessage2(false) } /></div>;
addLocale('es', {
firstDayOfWeek: 1,
dayNames: ['domingo', 'lunes', 'martes', 'miércoles', 'jueves', 'viernes', 'sábado'],
dayNamesShort: ['dom', 'lun', 'mar', 'mié', 'jue', 'vie', 'sáb'],
dayNamesMin: ['D', 'L', 'M', 'X', 'J', 'V', 'S'],
monthNames: ['enero', 'febrero', 'marzo', 'abril', 'mayo', 'junio', 'julio', 'agosto', 'septiembre', 'octubre', 'noviembre', 'diciembre'],
monthNamesShort: ['ene', 'feb', 'mar', 'abr', 'may', 'jun', 'jul', 'ago', 'sep', 'oct', 'nov', 'dic'],
today: 'Hoy',
clear: 'Limpiar'
})
return (
<>
<
header className = "App-header" >
<Menu2/>
<div className="form-demo">
<Dialog visible={showMessage} onHide={() => setShowMessage(false)} position="top" footer={dialogFooter} showHeader={false} breakpoints={{ '960px': '80vw' }} style={{ width: '30vw' }}>
<div className="flex align-items-center flex-column pt-6 px-3">
<i className="pi pi-check-circle" style={{ fontSize: '5rem', color: 'var(--green-500)' }}></i>
<h5>En hora buena</h5>
<p style={{ lineHeight: 1.5, textIndent: '1rem' }}>
<b> noticia a ha sido agregada correctamente</b>.
</p>
</div>
</Dialog>
<Dialog visible={showMessage2} onHide={() => setShowMessage2(false)} position="top" footer={dialogFooter2} showHeader={false} breakpoints={{ '960px': '80vw' }} style={{ width: '30vw' }}>
<div className="flex align-items-center flex-column pt-6 px-3">
<i className="pi pi-check-circle" style={{ fontSize: '5rem', color: 'var(--green-500)' }}></i>
<h5>Lo sentimos</h5>
<p style={{ lineHeight: 1.5, textIndent: '1rem' }}>
Tu password o usuario es incorrecto.
</p>
</div>
</Dialog>
<div className="flex justify-content-center">
<div className="card">
<Badge value = "Agregar Noticia" > </Badge>
<Form onSubmit={onSubmit} initialValues={{comunicador:state.nombre+' '+state.apellidoPaterno,
tituloNoticia: '',descripcionNoticia:'',fechaPublicacion:null,tipoNoticia:null}} validate={validate} render={({ handleSubmit }) => (
<form onSubmit={handleSubmit} className="p-fluid">
<Field name="comunicador" render={({ input, meta }) => (
<div className="field">
<span className="p-float-label">
<InputText id="comunicador" {...input} autoFocus className={classNames({ 'p-invalid': isFormFieldValid(meta) })} disabled />
<label htmlFor="comunicador" >Comunicador</label>
</span>
</div>
)} />
<Field name="tituloNoticia" render={({ input, meta }) => (
<div className="field">
<span className="p-float-label">
<InputText id="tituloNoticia" {...input} autoFocus className={classNames({ 'p-invalid': isFormFieldValid(meta) })} />
<label htmlFor="tituloNoticia" className={classNames({ 'p-error': isFormFieldValid(meta) })}>Título de la noticia*</label>
</span>
{getFormErrorMessage(meta)}
</div>
)} />
<Field name="descripcionNoticia" render={({ input, meta }) => (
<div className="field">
<span className="p-float-label">
<InputTextarea id='descripcionNoticia' {...input} autoFocus className={classNames({ 'p-invalid': isFormFieldValid(meta) })} rows={10} cols={50}
></InputTextarea>
<label htmlFor="descripcionNoticia" className={classNames({ 'p-error': isFormFieldValid(meta) })}>Descripción de la noticia*</label>
</span>
{getFormErrorMessage(meta)}
</div>
)} />
<Field name="fechaPublicacion" render={({ input, meta }) => (
<div className="field">
<span className="p-float-label">
<Calendar id='fechaPublicacion' {...input} autoFocus className={classNames({ 'p-invalid': isFormFieldValid(meta) })}
locale="es" minDate={today} ></Calendar>
<label htmlFor="fechaPublicacion" className={classNames({ 'p-error': isFormFieldValid(meta) })}>Fecha de Publicación*</label>
</span>
{getFormErrorMessage(meta)}
</div>
)} />
<Field name="tipoNoticia" render={({ input, meta }) => (
<div className="field">
<span className="p-float-label">
<MultiSelect id="tipoNoticia" value={tipoNoticia} options={noticias} onChange={(e) => setTipoNoticia(e.value)}
optionLabel='nombre' optionValue='codigo' {...input} autoFocus className={classNames({ 'p-invalid': isFormFieldValid(meta) })} placeholder="Seleccona tipo de noticias" selectionLimit={1} />
<label htmlFor="tipoNoticia" className={classNames({ 'p-error': isFormFieldValid(meta) })}>Tipo de Noticia*</label>
</span>
{getFormErrorMessage(meta)}
</div>
)} />
<Button type="submit" label="Registrar" className="mt-2" />
</form>
)} />
</div>
</div>
</div>
</header>
<Outlet/>
</>
);
}
export default Noticias;
Creamos el archivo UploadEvidencia.jsx
import { Badge } from 'primereact/badge';
import React, { useRef, useState } from 'react';
import { Outlet} from "react-router-dom";
import { useLocation, useNavigate } from 'react-router-dom';
import { classNames } from 'primereact/utils';
import { Form, Field } from 'react-final-form';
import { Toast } from 'primereact/toast';
import { FileUpload } from 'primereact/fileupload';
import { ProgressBar } from 'primereact/progressbar';
import { Button } from 'primereact/button';
import axios from 'axios';
import { Tooltip } from 'primereact/tooltip';
import { Tag } from 'primereact/tag';
function UploadEvidencia(){
const { state } = useLocation();
const [selectedFile, setSelectedFile] = useState(null);
const [evidencia, setEvidencia] = useState({
tituloNoticia:state.tituloNoticia,
fechaPublicacion:state.fechaPublicacion,
comunicador:state.comunicador
});
const navigate = useNavigate();
const handleFileChange = (e) => {
setSelectedFile(e.target.files[0]);
};
const validate = (data) => {
let errors = {};
if (data.file != null) {
errors.file = 'No has cargado la evidencia';
}
return errors;
};
const onSubmit = (data, form) => {
const config = {
headers: {
'content-type': 'multipart/form-data'
}
}
const formData = new FormData();
console.log(evidencia.tituloNoticia);
console.log(evidencia.comunicador);
console.log(evidencia.fechaPublicacion);
formData.append('file',selectedFile)
formData.append('titulo',evidencia.tituloNoticia);
formData.append('fecha',evidencia.fechaPublicacion);
formData.append('comunicador',evidencia.comunicador);
axios.post('http://localhost:8888/api/uploadToGoogleDrive',formData,config
).then((res)=>{
navigate('/Noticias', {
replace: true,
state: {
logged: true,
nombre: state.nombre,
apellidoPaterno: state.apellidoPaterno
},
});
});
};
const isFormFieldValid = (meta) => !!(meta.touched && meta.error);
const getFormErrorMessage = (meta) => {
return isFormFieldValid(meta) && <small className="p-error">{meta.error}</small>;
};
return (
<>
<
header className = "App-header" >
<div className="form-demo">
<div className="flex justify-content-center">
<div className="card">
<Badge value = "Agregar Evidencia" > </Badge>
<div className="field">
<input type="file" accept="image/*" onChange={handleFileChange} style={{backgroundColor:"#ADD8E6"}} />
<button onClick={onSubmit} disabled={!selectedFile} style={{backgroundColor:"#ADD8E6"}}>
Subir Imagen
</button>
</div>
</div>
</div>
</div>
</header>
<Outlet/>
</>
);
}
export default UploadEvidencia;