Merge branch 'dev' into US-26-ModificarÁreaComún

This commit is contained in:
Mariela 2022-08-30 16:57:35 -06:00
commit bc684f7950
6 changed files with 536 additions and 121 deletions

View File

@ -468,38 +468,7 @@ export class AppController {
}
// #==== API Payment
@Post('payment/createPayment')
createPayment(
@Body('date_payment') date_payment: Date,
@Body('mount') mount: number,
@Body('description') description: string,
@Body('period') period: string,
@Body('status') status: string,
@Body('user_id') user_id: string,
@Body('communty_id') communty_id: string,
) {
return this.appService.createPayment(
date_payment,
mount,
description,
period,
status,
user_id,
communty_id,
);
}
@Get('payment/allPayments')
allPayments() {
return this.appService.allPayments();
}
@Get('payment/find/:dni')
findPayment(@Param('dni') paramPaymentDNI: string) {
return this.appService.findPayment(paramPaymentDNI);
}
// #==== API Reservation
@ -541,7 +510,13 @@ export class AppController {
return this.appService.findReservations(community_id);
}
@Delete('reservation/deleteReservation/:id')
deleteReservation(@Param('id') id: string) {
return this.appService.deleteReservation(id);
}
// #==== API Post
@Post('post/createPost')
@ -554,6 +529,16 @@ export class AppController {
return this.appService.createPost(post, date_entry, user_id, community_id);
}
@Put('post/updatePost/:id')
updatePost(
@Param('id') id: string,
@Body('post') post: string,
@Body('user_id') user_id: string,
@Body('community_id') community_id: string,
) {
return this.appService.updatePost(id, post, user_id, community_id);
}
@Get('post/allPosts')
allPosts() {
return this.appService.allPosts();

View File

@ -540,7 +540,7 @@ export class AppService {
const pattern = { cmd: 'createGuest' };
const payload = {
name: name, last_name: last_name, dni: dni, number_plate: number_plate, phone: phone,
status: status,tenant_id:tenant_id, community_id:community_id,date_entry: date_entry
status: status, tenant_id: tenant_id, community_id: community_id, date_entry: date_entry
};
return this.clientGuestApp
.send<string>(pattern, payload)
@ -571,55 +571,17 @@ export class AppService {
.send<string>(pattern, payload)
.pipe(map((message: string) => ({ message })));
}
// ====================== PAYMENTS ===============================
//POST parameter from API
createPayment(
date_payment: Date,
mount: number,
description: string,
period: string,
status: string,
user_id: string,
communty_id: string,
) {
const pattern = { cmd: 'createPayment' };
const payload = {
date_payment: date_payment, mount: mount, description: description,
period: period, status: status, user_id: user_id, communty_id: communty_id
};
return this.clientPaymentApp
.send<string>(pattern, payload)
.pipe(map((message: string) => ({ message })));
}
allPayments() {
const pattern = { cmd: 'findAllPayments' };
const payload = {};
return this.clientPaymentApp
.send<string>(pattern, payload)
.pipe(map((message: string) => ({ message })));
}
//GET parameter from API
findPayment(paramPaymentId: string) {
const pattern = { cmd: 'findOnePayment' };
const payload = { id: paramPaymentId };
return this.clientPaymentApp
.send<string>(pattern, payload)
.pipe(map((message: string) => ({ message })));
}
// ====================== RESERVATIONS ===============================
//POST parameter from API
createReservation(date: string, time: string, status: string,
date_entry: Date, user_id: string, common_area_id: string,
date_entry: Date, user_id: string, common_area_id: string,
common_area_name: string, community_id: string) {
const pattern = { cmd: 'createReservation' };
const payload = {
date: date, time: time, status: status,
date_entry: date_entry, user_id: user_id, common_area_id: common_area_id,
date_entry: date_entry, user_id: user_id, common_area_id: common_area_id,
common_area_name: common_area_name, community_id: community_id
};
return this.clientReservationApp
@ -652,6 +614,15 @@ export class AppService {
.pipe(map((message: string) => ({ message })));
}
//DELETE parameter from API
deleteReservation(paramReservationId: string) {
const pattern = { cmd: 'removeReservation' };
const payload = { id: paramReservationId };
return this.clientReservationApp
.send<string>(pattern, payload)
.pipe(map((message: string) => ({ message })));
}
// ====================== POSTS ===============================
//POST parameter from API
@ -667,6 +638,16 @@ export class AppService {
.pipe(map((message: string) => ({ message })));
}
updatePost(id: string, post: string, user_id: string, community_id: string) {
const pattern = { cmd: 'updatePost' };
const payload = {
post: post, id: id, user_id: user_id, community_id: community_id
};
return this.clientPostApp
.send<string>(pattern, payload)
.pipe(map((message: string) => ({ message })));
}
allPosts() {
const pattern = { cmd: 'findAllPosts' };
const payload = {};

View File

@ -34,6 +34,7 @@ import GuardasSeguridad from './components/GuardasSeguridad';
import Communities from './components/ComunidadViviendas';
import Inquilinos from './components/Inquilinos';
import RegistroComunicado from './components/RegistroComunicado';
import InvitadosComunidad from './components/InvitadosComunidad';
import "../node_modules/bootstrap/dist/css/bootstrap.min.css";
import Crud from './pages/Crud';
@ -202,10 +203,9 @@ const App = () => {
icon: PrimeIcons.BUILDING,
to: '/areasComunes',
},
{ label: 'Comunicados', icon: PrimeIcons.COMMENTS, to: '/registroComunicado' },
{ label: 'Invitados', icon: PrimeIcons.USERS, to: '/invitadosComunidad' },
{ label: 'Reservaciones', icon: PrimeIcons.CALENDAR, to: '/reservaciones'},
{ label: 'Comunicados', icon: PrimeIcons.COMMENTS, to: '/registroComunicado'},
]
},
]
@ -471,6 +471,7 @@ const App = () => {
<Route path="/areasComunes" component={AreasComunes} />
<Route path="/reservaciones" component={Reservaciones} />
<Route path="/registroComunicado" component={RegistroComunicado} />
<Route path="/invitadosComunidad" component={InvitadosComunidad} />
</>
)
} else {

View File

@ -0,0 +1,219 @@
import React, { useEffect, useState, useRef } from 'react';
import { InputText } from 'primereact/inputtext';
import { Button } from 'primereact/button';
import { DataTable } from 'primereact/datatable';
import { Column } from 'primereact/column';
import { Toast } from 'primereact/toast';
import { Dialog } from 'primereact/dialog';
import { Toolbar } from 'primereact/toolbar';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { faUserAlt } from '@fortawesome/free-solid-svg-icons';
import { faPhoneAlt } from '@fortawesome/free-solid-svg-icons';
import { faAt } from '@fortawesome/free-solid-svg-icons';
import { faIdCardAlt } from '@fortawesome/free-solid-svg-icons';
import { faCircleQuestion } from '@fortawesome/free-solid-svg-icons';
import { useCookies } from 'react-cookie';
import classNames from 'classnames';
const InvitadosComunidad = () => {
const [cookies] = useCookies();
const [globalFilter, setGlobalFilter] = useState(null);
const [invitados, setInvitados] = useState([]);
const [selectedInvitados, setSelectedInvitados] = useState([]);
const tableRef = useRef(null);
const toastRef = useRef(null);
const getInvitados = async () => {
await fetch(`http://localhost:4000/guest/allGuests`, {
method: 'GET',
})
.then((response) => response.json())
.then((data) => data.message)
.then((data) => {
data = data.filter(
(invitado) => invitado.community === cookies.community_id,
);
setInvitados(data);
});
};
useEffect(() => {
getInvitados();
}, [getInvitados, invitados]);
const leftToolbarTemplate = () => {
return (
<React.Fragment>
<div className="my-2">
<p>Boton Eliminar aqui</p>
</div>
</React.Fragment>
);
};
const rightToolbarTemplate = () => {
return (
<React.Fragment>
<Button
label="Exportar"
icon="pi pi-upload"
className="p-button-help"
/>
</React.Fragment>
);
};
const headerName = (
<>
<p>
{' '}
<FontAwesomeIcon icon={faUserAlt} style={{ color: '#C08135' }} /> Nombre
</p>
</>
);
const headerTenant = (
<>
<p>
{' '}
<FontAwesomeIcon icon={faUserAlt} style={{ color: '#C08135' }} /> Inquilino
</p>
</>
);
const headerLastName = (
<>
<p>
{' '}
<FontAwesomeIcon icon={faUserAlt} style={{ color: '#D7A86E' }} />{' '}
Apellido(s)
</p>
</>
);
const headerPlate = (
<p>
{' '}
<FontAwesomeIcon icon={faIdCardAlt} style={{ color: '#C08135' }} />{' '}
Placa
</p>
);
const headerDNI = (
<p>
{' '}
<FontAwesomeIcon icon={faIdCardAlt} style={{ color: '#C08135' }} />{' '}
Identificación
</p>
);
const headerEmail = (
<>
<p>
{' '}
<FontAwesomeIcon icon={faAt} style={{ color: '#D7A86E' }} /> Correo
Electrónico
</p>
</>
);
const headerPhone = (
<>
<p>
{' '}
<FontAwesomeIcon icon={faPhoneAlt} style={{ color: '#C08135' }} />{' '}
Teléfono
</p>
</>
);
const headerTemplate = (
<div className="flex flex-column md:flex-row md:justify-content-between md:align-items-center">
<h5 className="m-0">Invitados</h5>
<span className="block mt-2 md:mt-0 p-input-icon-left">
<i className="pi pi-search" />
<InputText
type="search"
onInput={(e) => setGlobalFilter(e.target.value)}
placeholder="Buscar..."
/>
</span>
</div>
);
return (
<div className="grid">
<div className="col-12">
<Toast ref={toastRef} />
<div className="card">
<Toolbar
className="mb-4"
left={leftToolbarTemplate}
right={rightToolbarTemplate}
/>
<DataTable
ref={tableRef}
value={invitados}
dataKey="_id"
paginator
rows={10}
selection={selectedInvitados}
onSelectionChange={(e) => setSelectedInvitados(e.value)}
scrollable
scrollHeight="500px"
scrollWidth="100%"
scrollDirection="both"
header={headerTemplate}
rowsPerPageOptions={[10, 20, 30]}
className="datatable-responsive mt-3"
paginatorTemplate="FirstPageLink PrevPageLink PageLinks NextPageLink LastPageLink CurrentPageReport RowsPerPageDropdown"
currentPageReportTemplate="{currentPage} de {totalPages}"
globalFilter={globalFilter}
emptyMessageTemplate="No se encontraron invitados"
>
<Column field="name" header="Nombre" sortable header={headerName} />
<Column
field="last_name"
header="Apellido"
sortable
header={headerLastName}
/>
<Column field="dni" header="DNI" sortable header={headerDNI} />
<Column
field="number_plate"
header="Placa"
sortable
header={headerPlate}
/>
<Column
field="telefono"
header="Teléfono"
sortable
header={headerPhone}
/>
<Column
field="email"
header="Email"
sortable
header={headerEmail}
/>
<Column
field="date_entry"
header="Fecha de registro"
sortable
header={headerName}
/>
<Column
field="tenant_name"
header="Inquilino"
sortable
header={headerTenant}
/>
</DataTable>
</div>
</div>
</div>
);
};
export default React.memo(InvitadosComunidad);

View File

@ -16,7 +16,7 @@ import classNames from 'classnames';
const RegistroComunicado = () => {
let emptyComunicado = {
const emptyComunicado = {
_id: null,
post: '',
user_id: '',
@ -29,6 +29,7 @@ const RegistroComunicado = () => {
const [comunicado, setComunicado] = useState(emptyComunicado);
const [comunicados, setComunicados] = useState([]);
const [saveButtonLabel, setSaveButtonLabel] = useState('Registrar');
const [comunicadoId, setComunicadoId] = useState(null);
const [showDeleteDialog, setShowDeleteDialog] = useState(false);
const [submitted, setSubmitted] = useState(false);
@ -48,31 +49,60 @@ const RegistroComunicado = () => {
}
const saveComunicado = () => {
var data = {
post: document.getElementById('txt_comunicado').value,
user_id: cookies.id,
community_id: cookies.community_id
};
if (comunicado._id === null) {
var data = {
post: comunicado.post,
user_id: cookies.id,
community_id: cookies.community_id
};
fetch('http://localhost:4000/post/createPost', {
cache: 'no-cache',
method: 'POST',
body: JSON.stringify(data),
headers: {
'Content-Type': 'application/json'
}
}).then((response) => {
if (response.status != 201)
console.log('Ocurrió un error con el servicio: ' + response.status);
else
return response.json();
}).then((_response) => {
fetch('http://localhost:4000/post/createPost', {
cache: 'no-cache',
method: 'POST',
body: JSON.stringify(data),
headers: {
'Content-Type': 'application/json'
}
}).then((response) => {
if (response.status != 201)
console.log('Ocurrió un error con el servicio: ' + response.status);
else
return response.json();
}).then((_response) => {
setComunicado(emptyComunicado);
listaComunis();
}).catch(
err => console.log('Ocurrió un error con el fetch', err)
);
} else {
const data = {
_id: comunicado._id,
post: comunicado.post,
user_id: comunicado.user_id,
community_id: comunicado.community_id
};
}).catch(
err => console.log('Ocurrió un error con el fetch', err)
);
fetch(`http://localhost:4000/post/updatePost/${comunicado._id}`, {
cache: 'no-cache',
method: 'PUT',
body: JSON.stringify(data),
headers: {
'Content-Type': 'application/json'
}
}).then((response) => {
if (response.status != 200)
console.log('Ocurrió un error con el servicio: ' + response.status);
else
return response.json();
}).then((_response) => {
setComunicado(emptyComunicado);
setSaveButtonLabel('Registrar');
listaComunis();
}).catch(
err => console.log('Ocurrió un error con el fetch', err)
);
}
}
const header = (
<React.Fragment>
<div className="flex flex-column md:flex-row md:justify-content-between md:align-items-center">
@ -111,9 +141,27 @@ const RegistroComunicado = () => {
)
}
const edit = (rowData) => {
setComunicado(rowData);
setComunicadoId(rowData._id);
setSaveButtonLabel('Actualizar');
}
const cancelEdit = () => {
setComunicado(emptyComunicado);
setSaveButtonLabel('Registrar');
setComunicadoId(null);
}
const actions = (rowData) => {
return (
<div className="actions">
<Button
icon="pi pi-pencil"
className="p-button-rounded p-button-success mt-2 mx-2"
onClick={() => edit(rowData)}
title="Editar"
/>
<Button
icon='pi pi-trash'
className='p-button-rounded p-button-danger mt-2 mx-2'
@ -167,7 +215,7 @@ const RegistroComunicado = () => {
>
<div className="flex align-items-center justify-content-center">
<i className="pi pi-exclamation-triangle mr-3" style={{ fontSize: '2rem' }} />
{comunicado && <span>¿Estás seguro que desea eliminar el aviso "<b>{comunicado.post}</b>"?</span>}
{comunicado && <span>¿Está seguro que desea eliminar el aviso "<b>{comunicado.post}</b>"?</span>}
</div>
</Dialog>
<Toolbar className="mb-4" left={leftToolbarTemplate} right={rightToolbarTemplate}></Toolbar>
@ -200,11 +248,35 @@ const RegistroComunicado = () => {
<span className="p-inputgroup-addon p-button p-icon-input-khaki">
<i className="pi pi-pencil"></i>
</span>
<InputTextarea id="txt_comunicado" rows="4" />
<InputTextarea
value={comunicado.post}
placeholder="Ingrese el contenido del comunicado"
onChange={(e) => setComunicado({ ...comunicado, post: e.target.value })}
id="txt_comunicado"
type="text"
autoResize
rows={5}
cols={50}
/>
</div>
</div>
</div>
<Button label="Registrar" onClick={saveComunicado} />
<div style={{
display: "flex",
justifyContent: "center",
gap: "10px",
width: "100%"
}}>
<Button
label={`${saveButtonLabel}`}
onClick={saveComunicado}
/>
{saveButtonLabel === 'Actualizar' && (
<Button
label="Cancelar"
onClick={cancelEdit}
className="p-button-danger" />)}
</div>
</div>
</div>
</div>

View File

@ -48,7 +48,6 @@ const Reservations = () => {
const [saveButtonTitle, setSaveButtonTitle] = useState("Registrar")
const [reservationDialog, setReservationDialog] = useState(false);
const [dateMax, setDateMax] = useState();
const [tenants, setTenants] = useState([]);
async function tenantsList(id) {
@ -94,7 +93,9 @@ const Reservations = () => {
(val) => val.status != -1,
)
data.map((item) => {
item.date = formatDateString(item.date)
item.date = formatDateString(item.date)
if (item.status == '1') {
item.status_text = 'Activo';
} else if (item.status == '0') {
@ -133,7 +134,7 @@ const Reservations = () => {
let _reservation = { ...reservation };
if (_reservation.date && _reservation.time && tenantId && areaId
&& !validationTime()
&& !validationTime()
&& !validationIsSameUser() && !validationIsReservation()) {
_reservation.common_area_name = areas.find(item => item._id == areaId).name;
let tenant = tenants.find(item => item._id == tenantId);
@ -141,7 +142,7 @@ const Reservations = () => {
_reservation.user_id = tenantId;
_reservation.common_area_id = areaId;
_reservation.community_id = cookies.community_id;
_reservation.date = formatDateString(_reservation.date)
if (_reservation.status == '1') {
_reservation.status_text = 'Activo';
@ -160,8 +161,10 @@ const Reservations = () => {
if (response.status !== 200 && response.status !== 201)
console.log(`Hubo un error en el servicio: ${response.status}`)
else return response.json()
}).then(() => {
_reservations.push(_reservation);
}).then((response) => {
let _r = response.message;
_r.date = formatDateString(_r.date)
_reservations.push(_r);
setReservations(_reservations)
toast.current.show({
severity: 'success',
@ -174,7 +177,7 @@ const Reservations = () => {
setAreaId('')
setTenantId('')
})
} else {
setSubmitted(true);
}
@ -221,8 +224,87 @@ const Reservations = () => {
setReservation(emptyReservation);
setReservationDialog(true);
setSubmitted(false);
};
const hideDeleteReservationDialog = () => {
setDeleteReservationDialog(false);
};
const hideDeleteReservationsDialog = () => {
setDeleteReservationsDialog(false);
};
const deleteReservation = () => {
fetch('http://localhost:4000/reservation/deleteReservation/' + reservation._id, {
cache: 'no-cache',
method: 'DELETE',
headers: {
'Content-Type': 'application/json',
},
})
.then(function (response) {
if (response.status != 201 || response.status != 200)
console.log('Ocurrió un error con el servicio: ' + response.status);
else return response.json();
})
.then(function (response) {
let _reservation = reservations.filter(
(val) => (val._id !== reservation._id),
);
setReservations(_reservation);
setDeleteReservationDialog(false);
setReservation(emptyReservation);
toast.current.show({
severity: 'success',
summary: 'Éxito',
detail: 'Reservación Eliminada',
life: 3000,
});
})
.catch((err) => {
console.log('Ocurrió un error con el fetch', err);
toast.current.show({
severity: 'danger',
summary: 'Error',
detail: 'Reservación no se pudo Eliminar',
life: 3000,
});
});
};
const deleteSelectedReservations = () => {
let _reservations = reservations.filter(
(val) => (!selectedReservations.includes(val)),
);
selectedReservations.map((item) => {
fetch('http://localhost:4000/reservation/deleteReservation/' + item._id, {
cache: 'no-cache',
method: 'DELETE',
headers: {
'Content-Type': 'application/json',
},
});
});
_reservations = _reservations.filter(
(val) => val.status != -1,
)
setReservations(_reservations);
setDeleteReservationsDialog(false);
setSelectedReservations(null);
toast.current.show({
severity: 'success',
summary: 'Éxito',
detail: 'Reservaciones Eliminadas',
life: 3000,
});
};
const leftToolbarTemplate = () => {
return (
<React.Fragment>
@ -268,7 +350,41 @@ const Reservations = () => {
</>
);
const deleteReservationDialogFooter = (
<>
<Button
label="No"
icon="pi pi-times"
className="p-button-text"
onClick={hideDeleteReservationDialog}
/>
<Button
label="Yes"
icon="pi pi-check"
className="p-button-text"
onClick={deleteReservation}
/>
</>
);
const deleteReservationsDialogFooter = (
<>
<Button
label="No"
icon="pi pi-times"
className="p-button-text"
onClick={hideDeleteReservationsDialog}
/>
<Button
label="Yes"
icon="pi pi-check"
className="p-button-text"
onClick={deleteSelectedReservations}
/>
</>
);
const header = (
<div className="flex flex-column md:flex-row md:justify-content-between md:align-items-center">
<h5 className="m-0">
@ -408,17 +524,17 @@ const Reservations = () => {
}
function validationIsReservation() {
if(reservation.date && reservation.time && areaId){
if (reservation.date && reservation.time && areaId) {
let date1 = new Date(reservation.date).toJSON().split('T')[0];
let date2 = date1.split('-')[2] + '-' + date1.split('-')[1] + '-' +date1.split('-')[0];
let date2 = date1.split('-')[2] + '-' + date1.split('-')[1] + '-' + date1.split('-')[0];
let booked = reservations.filter(item => item.common_area_id == areaId
&& item.date == date2
&& item.date == date2
&& item.time == reservation.time);
if (booked.length > 0) {
return true;
} else {
return false;
}
@ -426,16 +542,16 @@ const Reservations = () => {
}
function validationIsSameUser() {
if(reservation.date && tenantId && areaId){
if (reservation.date && tenantId && areaId) {
let date1 = new Date(reservation.date).toJSON().split('T')[0];
let date2 = date1.split('-')[2] + '-' + date1.split('-')[1] + '-' +date1.split('-')[0];
let date2 = date1.split('-')[2] + '-' + date1.split('-')[1] + '-' + date1.split('-')[0];
let booked = reservations.filter(item => item.common_area_id == areaId
&& item.date == date2
&& item.date == date2
&& item.user_id == tenantId);
if (booked.length >= 2) {
return true;
} else {
return false;
}
@ -694,6 +810,47 @@ const Reservations = () => {
</div>
)}
</Dialog>
<Dialog
visible={deleteReservationDialog}
style={{ width: '450px' }}
header="Confirmar"
modal
footer={deleteReservationDialogFooter}
onHide={hideDeleteReservationDialog}
>
<div className="flex align-items-center justify-content-center">
<i
className="pi pi-exclamation-triangle mr-3"
style={{ fontSize: '2rem' }}
/>
{reservation && (
<span>
¿Estás seguro que desea eliminar la reservación de <b>{reservation.user_name}</b>?
</span>
)}
</div>
</Dialog>
<Dialog
visible={deleteReservationsDialog}
style={{ width: '450px' }}
header="Confirmar"
modal
footer={deleteReservationsDialogFooter}
onHide={hideDeleteReservationsDialog}
>
<div className="flex align-items-center justify-content-center">
<i
className="pi pi-exclamation-triangle mr-3"
style={{ fontSize: '2rem' }}
/>
{selectedReservations && (
<span>
¿Está seguro eliminar las reservaciones
seleccionadas?
</span>
)}
</div>
</Dialog>
</div>
</div>
</div>