Compare commits

...

22 Commits

Author SHA1 Message Date
Eduardo Quiros 6f6ded53bd
remove extra newlines 2022-07-29 20:35:08 -06:00
Eduardo Quiros 66cfa942e7
use correct class name for input divs 2022-07-29 19:41:45 -06:00
Eduardo Quiros af680149bd
format 2022-07-29 19:41:44 -06:00
Eduardo Quiros b00233cd3b
add extra info to registration 2022-07-29 19:41:44 -06:00
Eduardo Quiros 0479a162c1
Merge pull request #137 from DeimosPr4/issue-error-user-service
fix error user service
2022-07-29 00:35:48 -06:00
Mariela 23a8fa192d fix error en user service 2022-07-29 00:26:41 -06:00
Mariela c498db7937 Merge branch 'dev' into issue-error-user-service 2022-07-29 00:24:49 -06:00
Maria Sánchez 2b9d8ab329
Merge pull request #136 from DeimosPr4/issue-fix-estilo-correos
fix estilo de correos
2022-07-28 20:50:03 -06:00
Mariela 9f0f2fc8ef fix estilo correo de administrador Comunidad 2022-07-27 15:54:31 -06:00
Mariela 969c5c5d59 add estilo al correo de registrar admin comunidad 2022-07-27 03:04:35 -06:00
Eduardo Quiros c574326bcc
Merge pull request #130 from DeimosPr4/UH-updateRegistroAdminComunidad
Cambio de estilo a los guardas de seguridad
2022-07-26 23:05:32 -06:00
Eduardo Quiros 6f827b799c
Merge pull request #135 from DeimosPr4/UH-registroAdminComunidad
registro Comunidad y errores de compilacion
2022-07-26 23:04:52 -06:00
Mariela d1c96e641f fixes errores luego de merch de dev 2022-07-26 22:03:08 -06:00
Mariela 7b435df0e3 Merge branch 'dev' into UH-registroAdminComunidad 2022-07-26 21:01:16 -06:00
Mariela ef3e9fcb56 fix bug envío del correo 2022-07-26 17:07:12 -06:00
Mariela 59d99c1cfb registro de administrador de comunidad
con bug en el envio del correo
2022-07-26 16:59:29 -06:00
Traym17 6871c3f22f
Merge branch 'dev' into UH-updateRegistroAdminComunidad 2022-07-26 16:23:51 -06:00
Traym17 8989178ed7 Cambio de estilo a los guardas de seguridad 2022-07-25 19:03:32 -06:00
Mariela cf0b5c2d27 add validaciones en blanco en inputs 2022-07-25 16:08:00 -06:00
Mariela ce4dc9bf53 crear formulario y llamar comunidades 2022-07-25 00:25:39 -06:00
Mariela 51d76c9841 fixes en administradores de comunidad 2022-07-25 00:17:26 -06:00
Mariela 1629edc32a establecer primero constantes para obtener comunidades 2022-07-24 23:53:28 -06:00
22 changed files with 3306 additions and 4520 deletions

View File

@ -11,22 +11,12 @@ export class AppController {
@Body('last_name') last_name: string, @Body('last_name') last_name: string,
@Body('email') email: string, @Body('email') email: string,
@Body('phone') phone: number, @Body('phone') phone: number,
@Body('password') password: string,
@Body('user_type') user_type: string, @Body('user_type') user_type: string,
@Body('status') status: string, @Body('status') status: string,
@Body('date_entry') date_entry: Date, @Body('date_entry') date_entry: Date,
) { ) {
return this.appService.createAdminSystem( return this.appService.createAdminSystem(dni, name, last_name, email, phone,
dni, user_type, status, date_entry);
name,
last_name,
email,
phone,
password,
user_type,
status,
date_entry,
);
} }
@Post('user/createGuard') @Post('user/createGuard')
@ -37,24 +27,30 @@ export class AppController {
@Body('last_name') last_name: string, @Body('last_name') last_name: string,
@Body('email') email: string, @Body('email') email: string,
@Body('phone') phone: number, @Body('phone') phone: number,
@Body('password') password: string,
@Body('user_type') user_type: string, @Body('user_type') user_type: string,
@Body('status') status: string, @Body('status') status: string,
@Body('date_entry') date_entry: Date, @Body('date_entry') date_entry: Date,
@Body('community_id') community_id: string, @Body('community_id') community_id: string,
) { ) {
return this.appService.createGuard( return this.appService.createGuard(dni, name, last_name, email, phone,
dni, user_type, status, date_entry,community_id);
name, }
last_name,
email, @Post('user/createAdminCommunity')
phone, createAdminCommunity(
password, //Nombre, Apellidos, Correo electrónico, Cédula, Teléfono, Contraseña
user_type, @Body('dni') dni: string,
status, @Body('name') name: string,
date_entry, @Body('last_name') last_name: string,
community_id, @Body('email') email: string,
); @Body('phone') phone: number,
@Body('user_type') user_type: string,
@Body('status') status: string,
@Body('date_entry') date_entry: Date,
@Body('community_id') community_id:string
) {
return this.appService.createAdminCommunity(dni, name, last_name, email, phone,
user_type, status, date_entry,community_id);
} }
@Post('user/createUser') @Post('user/createUser')

View File

@ -54,64 +54,47 @@ export class AppService {
} }
//POST parameter from API //POST parameter from API
createAdminSystem( createAdminSystem(dni: string, name: string, last_name: string, email: string, phone: number
dni: string, , user_type: string, status: string, date_entry: Date) {
name: string,
last_name: string,
email: string,
phone: number,
password: string,
user_type: string,
status: string,
date_entry: Date,
) {
const pattern = { cmd: 'createAdminSystem' }; const pattern = { cmd: 'createAdminSystem' };
const payload = { const payload = {
dni: dni, dni: dni, name: name, last_name: last_name, email: email, phone: phone,
name: name, password: this.generatePassword(), user_type: user_type, status: status, date_entry: date_entry
last_name: last_name,
email: email,
phone: phone,
password: password,
user_type: user_type,
status: status,
date_entry: date_entry,
}; };
return this.clientUserApp return this.clientUserApp
.send<string>(pattern, payload) .send<string>(pattern, payload)
.pipe(map((message: string) => ({ message }))); .pipe(map((message: string) => ({ message })));
} }
createGuard( createGuard(dni: string, name: string, last_name: string, email: string, phone: number
dni: string, , user_type: string, status: string, date_entry: Date, community_id: string) {
name: string,
last_name: string,
email: string,
phone: number,
password: string,
user_type: string,
status: string,
date_entry: Date,
community_id: string,
) {
const pattern = { cmd: 'createGuard' }; const pattern = { cmd: 'createGuard' };
const payload = { const payload = {
dni: dni, dni: dni, name: name, last_name: last_name, email: email, phone: phone,
name: name, password: this.generatePassword(), user_type: user_type, status: status, date_entry: date_entry, community_id
last_name: last_name,
email: email,
phone: phone,
password: password,
user_type: user_type,
status: status,
date_entry: date_entry,
community_id,
}; };
return this.clientUserApp return this.clientUserApp
.send<string>(pattern, payload) .send<string>(pattern, payload)
.pipe(map((message: string) => ({ message }))); .pipe(map((message: string) => ({ message })));
} }
createAdminCommunity(dni: string, name: string, last_name: string, email: string, phone: number
, user_type: string, status: string, date_entry: Date, community_id: string) {
const pattern = { cmd: 'createAdminCommunity' };
const payload = {
dni: dni, name: name, last_name: last_name, email: email, phone: phone,
password: this.generatePassword(), user_type: user_type, status: status, date_entry: date_entry, community_id
};
return this.clientUserApp
.send<string>(pattern, payload)
.pipe(
map((message: string) => ({ message })),
);
}
allUsers() { allUsers() {
const pattern = { cmd: 'findAllUsers' }; const pattern = { cmd: 'findAllUsers' };
const payload = {}; const payload = {};
@ -153,6 +136,7 @@ export class AppService {
.pipe(map((message: string) => ({ message }))); .pipe(map((message: string) => ({ message })));
} }
deleteAdminSystem(id: string) { deleteAdminSystem(id: string) {
const pattern = { cmd: 'deleteAdminSystem' }; const pattern = { cmd: 'deleteAdminSystem' };
const payload = { id: id }; const payload = { id: id };
@ -181,17 +165,8 @@ export class AppService {
// ====================== COMMUNITIES =============================== // ====================== COMMUNITIES ===============================
//POST parameter from API //POST parameter from API
createCommunity( createCommunity(name: string, province: string, canton: string, district: string
name: string, , num_houses: number, phone: string, status: string, date_entry: Date, houses: []) {
province: string,
canton: string,
district: string,
num_houses: number,
phone: string,
status: string,
date_entry: Date,
houses: [],
) {
const pattern = { cmd: 'createCommunity' }; const pattern = { cmd: 'createCommunity' };
const payload = { const payload = {
name: name, name: name,
@ -287,13 +262,8 @@ export class AppService {
) { ) {
const pattern = { cmd: 'createGuest' }; const pattern = { cmd: 'createGuest' };
const payload = { const payload = {
name: name, name: name, last_name: last_name, dni: dni, number_plate: number_plate, phone: phone,
last_name: last_name, status: status, date_entry: date_entry
dni: dni,
number_plate: number_plate,
phone: phone,
status: status,
date_entry: date_entry,
}; };
return this.clientGuestApp return this.clientGuestApp
.send<string>(pattern, payload) .send<string>(pattern, payload)
@ -317,7 +287,7 @@ export class AppService {
.pipe(map((message: string) => ({ message }))); .pipe(map((message: string) => ({ message })));
} }
// ====================== PAYMENTS =============================== // ====================== PAYMENTS ===============================
//POST parameter from API //POST parameter from API
createPayment( createPayment(
@ -331,13 +301,8 @@ export class AppService {
) { ) {
const pattern = { cmd: 'createPayment' }; const pattern = { cmd: 'createPayment' };
const payload = { const payload = {
date_payment: date_payment, date_payment: date_payment, mount: mount, description: description,
mount: mount, period: period, status: status, user_id: user_id, communty_id: communty_id
description: description,
period: period,
status: status,
user_id: user_id,
communty_id: communty_id,
}; };
return this.clientPaymentApp return this.clientPaymentApp
.send<string>(pattern, payload) .send<string>(pattern, payload)
@ -364,22 +329,12 @@ export class AppService {
// ====================== RESERVATIONS =============================== // ====================== RESERVATIONS ===============================
//POST parameter from API //POST parameter from API
createReservation( createReservation(start_time: string, finish_time: string, status: string,
start_time: string, date_entry: Date, user_id: string, common_area_id: string) {
finish_time: string,
status: string,
date_entry: Date,
user_id: string,
common_area_id: string,
) {
const pattern = { cmd: 'createReservation' }; const pattern = { cmd: 'createReservation' };
const payload = { const payload = {
start_time: start_time, start_time: start_time, finish_time: finish_time, status: status,
finish_time: finish_time, date_entry: date_entry, user_id: user_id, common_area_id: common_area_id
status: status,
date_entry: date_entry,
user_id: user_id,
common_area_id: common_area_id,
}; };
return this.clientReservationApp return this.clientReservationApp
.send<string>(pattern, payload) .send<string>(pattern, payload)
@ -406,18 +361,12 @@ export class AppService {
// ====================== POSTS =============================== // ====================== POSTS ===============================
//POST parameter from API //POST parameter from API
createPost( createPost(post: string, date_entry: Date, user_id: string,
post: string, community_id: string) {
date_entry: Date,
user_id: string,
community_id: string,
) {
const pattern = { cmd: 'createPost' }; const pattern = { cmd: 'createPost' };
const payload = { const payload = {
post: post, post: post, date_entry: date_entry, user_id: user_id,
date_entry: date_entry, community_id: community_id
user_id: user_id,
community_id: community_id,
}; };
return this.clientPostApp return this.clientPostApp
.send<string>(pattern, payload) .send<string>(pattern, payload)
@ -444,18 +393,12 @@ export class AppService {
// ====================== COMMNENT POSTS =============================== // ====================== COMMNENT POSTS ===============================
//Comment parameter from API //Comment parameter from API
createComment( createComment(comment: string, date_entry: Date, user_id: string,
comment: string, post_id: string) {
date_entry: Date,
user_id: string,
post_id: string,
) {
const pattern = { cmd: 'createComment' }; const pattern = { cmd: 'createComment' };
const payload = { const payload = {
comment: comment, comment: comment, date_entry: date_entry, user_id: user_id,
date_entry: date_entry, post_id: post_id
user_id: user_id,
post_id: post_id,
}; };
return this.clientPostApp return this.clientPostApp
.send<string>(pattern, payload) .send<string>(pattern, payload)
@ -482,18 +425,12 @@ export class AppService {
// ====================== REPORTS =============================== // ====================== REPORTS ===============================
//Report parameter from API //Report parameter from API
createReport( createReport(action: string, description: string, date_entry: Date,
action: string, user_id: string) {
description: string,
date_entry: Date,
user_id: string,
) {
const pattern = { cmd: 'createReport' }; const pattern = { cmd: 'createReport' };
const payload = { const payload = {
action: action, action: action, description: description, date_entry: date_entry,
description: description, user_id: user_id
date_entry: date_entry,
user_id: user_id,
}; };
return this.clientReportApp return this.clientReportApp
.send<string>(pattern, payload) .send<string>(pattern, payload)
@ -532,4 +469,22 @@ export class AppService {
.send<string>(pattern, payload) .send<string>(pattern, payload)
.pipe(map((message: string) => ({ message }))); .pipe(map((message: string) => ({ message })));
} }
/* Function to generate combination of password */
generatePassword() {
var pass = '';
var str = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' +
'abcdefghijklmnopqrstuvwxyz0123456789@#$';
for (let i = 1; i <= 8; i++) {
var char = Math.floor(Math.random()
* str.length + 1);
pass += str.charAt(char)
}
return pass;
}
} }

View File

@ -19,27 +19,62 @@ export class EmailController {
return response; return response;
} }
@MessagePattern({ cmd: 'html' }) @MessagePattern({ cmd: 'html' })
async postHTMLEmail(@Payload() user: any) { async postHTMLEmail(@Payload() user: any) {
const url = 'http://localhost:3000/'; const url = "http://localhost:3000/";
const image = 'images/email.ong'; const image = "images/email.png";
var response = await this.mailService.sendMail({ var response = await this.mailService.sendMail({
to: user['email'], to: user["email"],
from: 'mbonilla.guti@gmail.com', from: "mbonilla.guti@gmail.com",
subject: 'HTML Dynamic Template', subject: 'HTML Dynamic Template',
template: 'templateEmail', template: 'templateEmail',
context: { context: {
name: user['name'], name: user["name"],
url, url
}, },
attachments: [ attachments: [
{ {
filename: 'email.png', filename: 'email.png',
path: __dirname + '/mails/images/email.png', path: __dirname + '/mails/images/email.png',
cid: 'logo', //my mistake was putting "cid:logo@cid" here! cid: 'logo' //my mistake was putting "cid:logo@cid" here!
}, }
], ]
}); });
return response; return response;
} }
@MessagePattern({ cmd: 'emailCreateUserAdminCommunity' })
async emailCreateUserAdmin(@Payload() user: any) {
const url = "http://localhost:3000/";
const image = "images/email.png";
const logo = "images/Logo Katoikia.png";
var response = await this.mailService.sendMail({
to: user["email"],
from: "mbonilla.guti@gmail.com",
subject: 'Usuario registrado',
template: 'emailCreateUserAdminCommunity',
context: {
name: user["name"],
password: user["password"],
date_entry: user["date_entry"],
email: user["email"],
community_name: user['community_name'],
url
},
attachments: [
{
filename: 'email.png',
path: __dirname + '/mails/images/email.png',
cid: 'image_email' //my mistake was putting "cid:logo@cid" here!
},
{
filename: 'Logo_Katoikia.png',
path: __dirname + '/mails/images/Logo_Katoikia.png',
cid: 'logoKatoikia' //my mistake was putting "cid:logo@cid" here!
}
]
});
return response;
}
} }

View File

@ -0,0 +1,457 @@
<!DOCTYPE html>
<html lang="en" xmlns="http://www.w3.org/1999/xhtml" xmlns:v="urn:schemas-microsoft-com:vml"
xmlns:o="urn:schemas-microsoft-com:office:office">
<head>
<meta charset="utf-8"> <!-- utf-8 works for most cases -->
<meta name="viewport" content="width=device-width"> <!-- Forcing initial-scale shouldn't be necessary -->
<meta http-equiv="X-UA-Compatible" content="IE=edge"> <!-- Use the latest (edge) version of IE rendering engine -->
<meta name="x-apple-disable-message-reformatting"> <!-- Disable auto-scale in iOS 10 Mail entirely -->
<title></title> <!-- The title tag shows in email notifications, like Android 4.4. -->
<link href="https://fonts.googleapis.com/css?family=Lato:300,400,700" rel="stylesheet">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.1.2/css/all.min.css"
integrity="sha512-1sCRPdkRXhBV2PBLUdRb4tMg1w2YPf37qatUFeS7zlBy7jJI8Lf4VHwWfZZfpXtYSLy85pkm9GaYVYMfw5BC1A=="
crossorigin="anonymous" referrerpolicy="no-referrer" />
<!-- CSS Reset : BEGIN -->
<style>
html,
body {
margin: 0 auto !important;
padding: 0 !important;
height: 100% !important;
width: 100% !important;
background: #f1f1f1;
}
/* What it does: Stops email clients resizing small text. */
* {
-ms-text-size-adjust: 100%;
-webkit-text-size-adjust: 100%;
}
/* What it does: Centers email on Android 4.4 */
div[style*="margin: 16px 0"] {
margin: 0 !important;
}
/* What it does: Stops Outlook from adding extra spacing to tables. */
table,
td {
mso-table-lspace: 0pt !important;
mso-table-rspace: 0pt !important;
}
/* What it does: Fixes webkit padding issue. */
table {
border-spacing: 0 !important;
border-collapse: collapse !important;
table-layout: fixed !important;
margin: 0 auto !important;
}
/* What it does: Uses a better rendering method when resizing images in IE. */
img {
-ms-interpolation-mode: bicubic;
}
/* What it does: Prevents Windows 10 Mail from underlining links despite inline CSS. Styles for underlined links should be inline. */
a {
text-decoration: none;
}
/* What it does: A work-around for email clients meddling in triggered links. */
*[x-apple-data-detectors],
/* iOS */
.unstyle-auto-detected-links *,
.aBn {
border-bottom: 0 !important;
cursor: default !important;
color: inherit !important;
text-decoration: none !important;
font-size: inherit !important;
font-family: inherit !important;
font-weight: inherit !important;
line-height: inherit !important;
}
/* What it does: Prevents Gmail from displaying a download button on large, non-linked images. */
.a6S {
display: none !important;
opacity: 0.01 !important;
}
/* What it does: Prevents Gmail from changing the text color in conversation threads. */
.im {
color: inherit !important;
}
/* If the above doesn't work, add a .g-img class to any image in question. */
img.g-img+div {
display: none !important;
}
/* What it does: Removes right gutter in Gmail iOS app: https://github.com/TedGoas/Cerberus/issues/89 */
/* Create one of these media queries for each additional viewport size you'd like to fix */
/* iPhone 4, 4S, 5, 5S, 5C, and 5SE */
@media only screen and (min-device-width: 320px) and (max-device-width: 374px) {
u~div .email-container {
min-width: 320px !important;
}
}
/* iPhone 6, 6S, 7, 8, and X */
@media only screen and (min-device-width: 375px) and (max-device-width: 413px) {
u~div .email-container {
min-width: 375px !important;
}
}
/* iPhone 6+, 7+, and 8+ */
@media only screen and (min-device-width: 414px) {
u~div .email-container {
min-width: 414px !important;
}
}
</style>
<!-- CSS Reset : END -->
<!-- Progressive Enhancements : BEGIN -->
<style>
.primary {
background: #D7A86E;
}
.bg_white {
background: #ffffff;
}
.bg_light {
background: #fafafa;
}
.bg_black {
background: #000000;
}
.bg_dark {
background: rgba(0, 0, 0, .8);
}
.email-section {
padding: 2.5em;
}
/*BUTTON*/
.btn {
padding: 10px 15px;
display: inline-block;
}
.btn.btn-primary {
border-radius: 5px;
background: #D7A86E;
color: #ffffff;
}
.btn.btn-white {
border-radius: 5px;
background: #ffffff;
color: #000000;
}
.btn.btn-white-outline {
border-radius: 5px;
background: transparent;
border: 1px solid #fff;
color: #fff;
}
.btn.btn-black-outline {
border-radius: 0px;
background: transparent;
border: 2px solid #000;
color: #000;
font-weight: 700;
}
h1,
h2,
h3,
h4,
h5,
h6 {
font-family: 'Lato', sans-serif;
color: #000000;
margin-top: 0;
font-weight: 400;
margin-bottom: 12px;
}
body {
font-family: 'Lato', sans-serif;
font-weight: 400;
font-size: 15px;
line-height: 1.8;
color: rgba(0, 0, 0, 0.808);
}
a {
color: #D7A86E;
}
table {}
/*LOGO*/
.logo h1 {
margin: 0;
}
.logo h1 a {
color: #D7A86E;
font-size: 24px;
font-weight: 700;
font-family: 'Lato', sans-serif;
}
/*HERO*/
.hero {
position: relative;
z-index: 0;
}
.hero .text {
color: rgba(0, 0, 0, 0.884);
}
.hero .text h2 {
color: #000;
font-size: 40px;
margin-bottom: 0;
font-weight: 400;
line-height: 1.4;
}
.hero .text h3 {
font-size: 24px;
font-weight: 300;
}
.hero .text h2 span {
font-weight: 600;
color: #D7A86E;
}
/*HEADING SECTION*/
.heading-section {}
.heading-section h2 {
color: #000000;
font-size: 28px;
margin-top: 0;
line-height: 1.4;
font-weight: 400;
}
.heading-section .subheading {
margin-bottom: 20px !important;
display: inline-block;
font-size: 13px;
text-transform: uppercase;
letter-spacing: 2px;
color: rgba(0, 0, 0, .4);
position: relative;
}
.heading-section .subheading::after {
position: absolute;
left: 0;
right: 0;
bottom: -10px;
content: '';
width: 100%;
height: 2px;
background: #D7A86E;
margin: 0 auto;
}
.heading-section-white {
color: rgba(255, 255, 255, .8);
}
.heading-section-white h2 {
line-height: 1;
padding-bottom: 0;
}
.heading-section-white h2 {
color: #ffffff;
}
.heading-section-white .subheading {
margin-bottom: 0;
display: inline-block;
font-size: 13px;
text-transform: uppercase;
letter-spacing: 2px;
color: rgba(255, 255, 255, .4);
}
ul.social {
padding: 0;
}
ul.social li {
display: inline-block;
margin-right: 10px;
}
/*FOOTER*/
.footer {
border-top: 1px solid rgba(0, 0, 0, .05);
color: rgba(0, 0, 0, .5);
}
.footer .heading {
color: #000;
font-size: 20px;
}
.footer ul {
margin: 0;
padding: 0;
}
.footer ul li {
list-style: none;
margin-bottom: 10px;
}
.footer ul li a {
color: rgba(0, 0, 0, 1);
}
@media screen and (max-width: 500px) {}
</style>
</head>
<body width="100%" style="margin: 0; padding: 0 !important; mso-line-height-rule: exactly; background-color: #f1f1f1;">
<center style="width: 100%; background-color: #f1f1f1;">
<div
style="display: none; font-size: 1px;max-height: 0px; max-width: 0px; opacity: 0; overflow: hidden; mso-hide: all; font-family: sans-serif;">
&zwnj;&nbsp;&zwnj;&nbsp;&zwnj;&nbsp;&zwnj;&nbsp;&zwnj;&nbsp;&zwnj;&nbsp;&zwnj;&nbsp;&zwnj;&nbsp;&zwnj;&nbsp;&zwnj;&nbsp;&zwnj;&nbsp;&zwnj;&nbsp;&zwnj;&nbsp;&zwnj;&nbsp;&zwnj;&nbsp;&zwnj;&nbsp;&zwnj;&nbsp;&zwnj;&nbsp;
</div>
<div style="max-width: 600px; margin: 0 auto;" class="email-container">
<!-- BEGIN BODY -->
<table align="center" role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%"
style="margin: auto;">
<tr>
<td valign="top" class="bg_white" style="padding: 1em 2.5em 0 2.5em;">
<table role="presentation" border="0" cellpadding="0" cellspacing="0" width="100%">
<tr>
<td class="logo" style="text-align: right;">
<img src="cid:logoLatoikia" alt="Logo Katoikia"
style="width: 60px; max-width: 60px; height: auto; margin: auto; display: block; float: right;">
</td>
<td class="logo" style="text-align: left;">
<h1><a href="#">Katoikia</a></h1>
</td>
</tr>
</table>
</td>
</tr><!-- end tr -->
<tr>
<td valign="middle" class="hero bg_white" style="padding: 3em 0 2em 0;">
<img src="cid:image_email" alt="Logo Katoikia"
style="width: 150px; max-width: 300px; height: auto; margin: auto; display: block;">
</td>
</tr><!-- end tr -->
<tr>
<td valign="middle" class="hero bg_white" style="padding: 2em 0 4em 0;">
<table>
<tr>
<td>
<div class="text" style="padding: 0 2.5em; text-align: center;">
<h2> Hola , {{ name }} <i class="fa-regular fa-face-smile-wink"
style="color:#D7A86E; font-size: 0.8em; margin-left: 20px;"></i></h2>
<h3>Ha sido registrado como un Administrador General del sitio web Katoikia</h3>
<h4><i class="fa-solid fa-calendar-day"
style="color:#D7A86E; margin-right: 10px;"></i> Fecha de registro
{{date_entry}}</h4>
</div>
<div class="text" style="padding: 0 4em; text-align: left;">
<h3>Estas son sus credenciales:</h3>
<p><i class="fa-regular fa-envelope" style="color:#D7A86E; margin-right: 10px;"></i> Correo electronico: {{email}}</p>
<p><i class="fa-solid fa-key" style="color:#D7A86E; margin-right: 10px;"></i> Password: {{password}}</p>
</div>
<div class="text" style="padding: 0 2.5em; text-align: center;">
<h3>Inicie sesión en el sitio web para poder acceder y disfrutar todos sus
beneficios</h3>
<p><a href="{{ url }}" class="btn btn-primary">Iniciar sesión</a></p>
</div>
</td>
</tr>
</table>
</td>
</tr><!-- end tr -->
<!-- 1 Column Text + Button : END -->
</table>
<table align="center" role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%"
style="margin: auto;">
<td valign="middle" class="bg_light footer email-section">
<table>
<tr>
<td valign="top" width="33.333%" style="padding-top: 20px">
<table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%">
<tr>
<td style="text-align: left; padding-right: 10px">
<h3 class="heading">Acerca de</h3>
<p>Katoikia es su compañero más cercano para poder estar en contacto con sus vecinos y conocer sobre los mejores anuncios sobre su comunidad.</p>
</td>
</tr>
</table>
</td>
<td valign="top" width="33.333%" style="padding-top: 20px">
<table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%">
<tr>
<td style="text-align: left; padding-left: 5px; padding-right: 5px">
<h3 class="heading">Información de contacto</h3>
<ul>
<li><span href="mailto:katoikiaapp@gmail.com" class="text">katoikiaapp@gmail.com</span></li>
</ul>
</td>
</tr>
</table>
</td>
</tr>
</table>
</td>
</tr>
<!-- end: tr -->
<tr>
<td class="bg_light" style="text-align: center">
<p><a href="http://localhost:3000" style="color: rgba(0, 0, 0, 0.8)">katoikiaapp.org</a></p>
</td>
</table>
</div>
</center>
</body>
</html>

View File

@ -0,0 +1,464 @@
<!DOCTYPE html>
<html lang="en" xmlns="http://www.w3.org/1999/xhtml" xmlns:v="urn:schemas-microsoft-com:vml"
xmlns:o="urn:schemas-microsoft-com:office:office">
<head>
<meta charset="utf-8"> <!-- utf-8 works for most cases -->
<meta name="viewport" content="width=device-width"> <!-- Forcing initial-scale shouldn't be necessary -->
<meta http-equiv="X-UA-Compatible" content="IE=edge"> <!-- Use the latest (edge) version of IE rendering engine -->
<meta name="x-apple-disable-message-reformatting"> <!-- Disable auto-scale in iOS 10 Mail entirely -->
<title></title> <!-- The title tag shows in email notifications, like Android 4.4. -->
<link href="https://fonts.googleapis.com/css?family=Lato:300,400,700" rel="stylesheet">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.1.2/css/all.min.css"
integrity="sha512-1sCRPdkRXhBV2PBLUdRb4tMg1w2YPf37qatUFeS7zlBy7jJI8Lf4VHwWfZZfpXtYSLy85pkm9GaYVYMfw5BC1A=="
crossorigin="anonymous" referrerpolicy="no-referrer" />
<!-- CSS Reset : BEGIN -->
<style>
html,
body {
margin: 0 auto !important;
padding: 0 !important;
height: 100% !important;
width: 100% !important;
background: #f1f1f1;
}
/* What it does: Stops email clients resizing small text. */
* {
-ms-text-size-adjust: 100%;
-webkit-text-size-adjust: 100%;
}
/* What it does: Centers email on Android 4.4 */
div[style*="margin: 16px 0"] {
margin: 0 !important;
}
/* What it does: Stops Outlook from adding extra spacing to tables. */
table,
td {
mso-table-lspace: 0pt !important;
mso-table-rspace: 0pt !important;
}
/* What it does: Fixes webkit padding issue. */
table {
border-spacing: 0 !important;
border-collapse: collapse !important;
table-layout: fixed !important;
margin: 0 auto !important;
}
/* What it does: Uses a better rendering method when resizing images in IE. */
img {
-ms-interpolation-mode: bicubic;
}
/* What it does: Prevents Windows 10 Mail from underlining links despite inline CSS. Styles for underlined links should be inline. */
a {
text-decoration: none;
}
/* What it does: A work-around for email clients meddling in triggered links. */
*[x-apple-data-detectors],
/* iOS */
.unstyle-auto-detected-links *,
.aBn {
border-bottom: 0 !important;
cursor: default !important;
color: inherit !important;
text-decoration: none !important;
font-size: inherit !important;
font-family: inherit !important;
font-weight: inherit !important;
line-height: inherit !important;
}
/* What it does: Prevents Gmail from displaying a download button on large, non-linked images. */
.a6S {
display: none !important;
opacity: 0.01 !important;
}
/* What it does: Prevents Gmail from changing the text color in conversation threads. */
.im {
color: inherit !important;
}
/* If the above doesn't work, add a .g-img class to any image in question. */
img.g-img+div {
display: none !important;
}
/* What it does: Removes right gutter in Gmail iOS app: https://github.com/TedGoas/Cerberus/issues/89 */
/* Create one of these media queries for each additional viewport size you'd like to fix */
/* iPhone 4, 4S, 5, 5S, 5C, and 5SE */
@media only screen and (min-device-width: 320px) and (max-device-width: 374px) {
u~div .email-container {
min-width: 320px !important;
}
}
/* iPhone 6, 6S, 7, 8, and X */
@media only screen and (min-device-width: 375px) and (max-device-width: 413px) {
u~div .email-container {
min-width: 375px !important;
}
}
/* iPhone 6+, 7+, and 8+ */
@media only screen and (min-device-width: 414px) {
u~div .email-container {
min-width: 414px !important;
}
}
</style>
<!-- CSS Reset : END -->
<!-- Progressive Enhancements : BEGIN -->
<style>
.primary {
background: #D7A86E;
}
.bg_white {
background: #ffffff;
}
.bg_light {
background: #fafafa;
}
.bg_black {
background: #000000;
}
.bg_dark {
background: rgba(0, 0, 0, .8);
}
.email-section {
padding: 2.5em;
}
/*BUTTON*/
.btn {
padding: 10px 15px;
display: inline-block;
}
.btn.btn-primary {
border-radius: 5px;
background: #D7A86E;
color: #ffffff;
}
.btn.btn-white {
border-radius: 5px;
background: #ffffff;
color: #000000;
}
.btn.btn-white-outline {
border-radius: 5px;
background: transparent;
border: 1px solid #fff;
color: #fff;
}
.btn.btn-black-outline {
border-radius: 0px;
background: transparent;
border: 2px solid #000;
color: #000;
font-weight: 700;
}
h1,
h2,
h3,
h4,
h5,
h6 {
font-family: 'Lato', sans-serif;
color: #000000;
margin-top: 0;
font-weight: 400;
margin-bottom: 12px;
}
body {
font-family: 'Lato', sans-serif;
font-weight: 400;
font-size: 15px;
line-height: 1.8;
color: rgba(0, 0, 0, 0.808);
}
a {
color: #D7A86E;
}
table {}
/*LOGO*/
.logo h1 {
margin: 0;
}
.logo h1 a {
color: #D7A86E;
font-size: 24px;
font-weight: 700;
font-family: 'Lato', sans-serif;
}
/*HERO*/
.hero {
position: relative;
z-index: 0;
}
.hero .text {
color: rgba(0, 0, 0, 0.884);
}
.hero .text h2 {
color: #000;
font-size: 40px;
margin-bottom: 0;
font-weight: 400;
line-height: 1.4;
}
.hero .text h3 {
font-size: 24px;
font-weight: 300;
}
.hero .text h2 span {
font-weight: 600;
color: #D7A86E;
}
/*HEADING SECTION*/
.heading-section {}
.heading-section h2 {
color: #000000;
font-size: 28px;
margin-top: 0;
line-height: 1.4;
font-weight: 400;
}
.heading-section .subheading {
margin-bottom: 20px !important;
display: inline-block;
font-size: 13px;
text-transform: uppercase;
letter-spacing: 2px;
color: rgba(0, 0, 0, .4);
position: relative;
}
.heading-section .subheading::after {
position: absolute;
left: 0;
right: 0;
bottom: -10px;
content: '';
width: 100%;
height: 2px;
background: #D7A86E;
margin: 0 auto;
}
.heading-section-white {
color: rgba(255, 255, 255, .8);
}
.heading-section-white h2 {
line-height: 1;
padding-bottom: 0;
}
.heading-section-white h2 {
color: #ffffff;
}
.heading-section-white .subheading {
margin-bottom: 0;
display: inline-block;
font-size: 13px;
text-transform: uppercase;
letter-spacing: 2px;
color: rgba(255, 255, 255, .4);
}
ul.social {
padding: 0;
}
ul.social li {
display: inline-block;
margin-right: 10px;
}
/*FOOTER*/
.footer {
border-top: 1px solid rgba(0, 0, 0, .05);
color: rgba(0, 0, 0, .5);
}
.footer .heading {
color: #000;
font-size: 20px;
}
.footer ul {
margin: 0;
padding: 0;
}
.footer ul li {
list-style: none;
margin-bottom: 10px;
}
.footer ul li a {
color: rgba(0, 0, 0, 1);
}
@media screen and (max-width: 500px) {}
</style>
</head>
<body width="100%" style="margin: 0; padding: 0 !important; mso-line-height-rule: exactly; background-color: #f1f1f1;">
<center style="width: 100%; background-color: #f1f1f1;">
<div
style="display: none; font-size: 1px;max-height: 0px; max-width: 0px; opacity: 0; overflow: hidden; mso-hide: all; font-family: sans-serif;">
&zwnj;&nbsp;&zwnj;&nbsp;&zwnj;&nbsp;&zwnj;&nbsp;&zwnj;&nbsp;&zwnj;&nbsp;&zwnj;&nbsp;&zwnj;&nbsp;&zwnj;&nbsp;&zwnj;&nbsp;&zwnj;&nbsp;&zwnj;&nbsp;&zwnj;&nbsp;&zwnj;&nbsp;&zwnj;&nbsp;&zwnj;&nbsp;&zwnj;&nbsp;&zwnj;&nbsp;
</div>
<div style="max-width: 600px; margin: 0 auto;" class="email-container">
<!-- BEGIN BODY -->
<table align="center" role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%"
style="margin: auto;">
<tr>
<td valign="top" class="bg_white" style="padding: 1em 2.5em 0 2.5em;">
<table role="presentation" border="0" cellpadding="0" cellspacing="0" width="100%">
<tr>
<td class="logo" style="text-align: right;">
<img src="cid:logoKatoikia" alt="Logo Katoikia"
style="width: 60px; max-width: 60px; height: auto; margin: auto; display: block; float: right;">
</td>
<td class="logo" style="text-align: left;">
<h1><a href="#">Katoikia</a></h1>
</td>
</tr>
</table>
</td>
</tr><!-- end tr -->
<tr>
<td valign="middle" class="hero bg_white" style="padding: 3em 0 2em 0;">
<img src="cid:image_email" alt="Logo Katoikia"
style="width: 150px; max-width: 300px; height: auto; margin: auto; display: block;">
</td>
</tr><!-- end tr -->
<tr>
<td valign="middle" class="hero bg_white" style="padding: 2em 0 4em 0;">
<table>
<tr>
<td>
<div class="text" style="padding: 0 2.5em; text-align: center;">
<h2> Hola , {{ name }} <i class="fa-regular fa-face-smile-wink"
style="color:#D7A86E; font-size: 0.8em; margin-left: 20px;"></i></h2>
<h3>Ha sido registrado como un Administrador de la Comunidad `{{community_name}}`
</h3>
<h4><i class="fa-solid fa-calendar-day"
style="color:#D7A86E; margin-right: 10px;"></i> Fecha de registro
{{date_entry}}</h4>
</div>
<div class="text" style="padding: 0 4em; text-align: left;">
<h3>Estas son sus credenciales:</h3>
<p><i class="fa fa-regular fa-envelope"
style="color:#D7A86E; margin-right: 10px;"></i> Correo electronico:
{{email}}</p>
<p><i class="fa-solid fa-key" style="color:#D7A86E; margin-right: 10px;"></i>
Password: {{password}}</p>
</div>
<div class="text" style="padding: 0 2.5em; text-align: center;">
<h3>Inicie sesión en el sitio web para poder acceder y disfrutar todos sus
beneficios</h3>
<p><a href="{{ url }}" class="btn btn-primary">Iniciar sesión</a></p>
</div>
</td>
</tr>
</table>
</td>
</tr><!-- end tr -->
<!-- 1 Column Text + Button : END -->
</table>
<table align="center" role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%"
style="margin: auto;">
<td valign="middle" class="bg_light footer email-section">
<table>
<tr>
<td valign="top" width="33.333%" style="padding-top: 20px">
<table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%">
<tr>
<td style="text-align: left; padding-right: 10px">
<h3 class="heading">Acerca de</h3>
<p>Katoikia es su compañero más cercano para poder estar en contacto con sus
vecinos y conocer sobre los mejores anuncios sobre su comunidad.</p>
</td>
</tr>
</table>
</td>
<td valign="top" width="33.333%" style="padding-top: 20px">
<table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%">
<tr>
<td style="text-align: left; padding-left: 5px; padding-right: 5px">
<h3 class="heading">Información de contacto</h3>
<ul>
<li><span href="mailto:katoikiaapp@gmail.com"
class="text">katoikiaapp@gmail.com</span></li>
</ul>
</td>
</tr>
</table>
</td>
</tr>
</table>
</td>
</tr>
<!-- end: tr -->
<tr>
<td class="bg_light" style="text-align: center">
<p><a href="http://localhost:3000" style="color: rgba(0, 0, 0, 0.8)">katoikiaapp.org</a></p>
</td>
</table>
</div>
</center>
</body>
</html>

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 66 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

View File

@ -9,9 +9,8 @@ import { map } from 'rxjs/operators';
export class ReportsService { export class ReportsService {
constructor( constructor(
@InjectModel(Report.name) @InjectModel(Report.name)
private readonly reportModel: Model<ReportDocument>, private readonly reportModel: Model<ReportDocument>, //
) // ) {}
{}
async create(report: ReportDocument): Promise<Report> { async create(report: ReportDocument): Promise<Report> {
return this.reportModel.create(report); return this.reportModel.create(report);

File diff suppressed because it is too large Load Diff

View File

@ -29,10 +29,12 @@
"@nestjs/platform-express": "^8.0.0", "@nestjs/platform-express": "^8.0.0",
"@nestjs/swagger": "^5.2.1", "@nestjs/swagger": "^5.2.1",
"buffer": "^5.7.1", "buffer": "^5.7.1",
"class-validator": "^0.13.2",
"cors": "^2.8.5", "cors": "^2.8.5",
"crypto-browserify": "^3.12.0", "crypto-browserify": "^3.12.0",
"md5-typescript": "^1.0.5", "md5-typescript": "^1.0.5",
"mongoose": "^6.4.1", "mongoose": "^6.4.1",
"mongoose-unique-validator": "^3.1.0",
"reflect-metadata": "^0.1.13", "reflect-metadata": "^0.1.13",
"rimraf": "^3.0.2", "rimraf": "^3.0.2",
"rxjs": "^7.2.0", "rxjs": "^7.2.0",

View File

@ -0,0 +1,14 @@
import { ArgumentsHost, Catch, ConflictException, ExceptionFilter } from '@nestjs/common';
import { MongoError } from 'mongodb';
@Catch(MongoError)
export class MongoExceptionFilter implements ExceptionFilter {
catch(exception: MongoError, host: ArgumentsHost) {
switch (exception.code) {
case 11000:
console.log('llave duplicada')
// duplicate exception
// do whatever you want here, for instance send error to client
}
}
}

View File

@ -16,11 +16,12 @@ import { UsersModule } from './users/users.module';
}, },
]), ]),
MongooseModule.forRoot( MongooseModule.forRoot(
`mongodb+srv://proyecto_4:proyecto_4@proyecto4.yv4fb.mongodb.net/servicio_usuarios?retryWrites=true&w=majority`, `mongodb+srv://proyecto_4:proyecto_4@proyecto4.yv4fb.mongodb.net/servicio_usuarios?retryWrites=true&w=majority`
), ),
UsersModule, UsersModule,
], ],
controllers: [], controllers: [],
providers: [], providers: [],
}) })
export class AppModule {} export class AppModule { }

View File

@ -0,0 +1,30 @@
import { Injectable } from "@nestjs/common";
import { Model } from 'mongoose';
import { User, UserDocument } from '../schemas/user.schema';
import { InjectModel } from '@nestjs/mongoose';
import { ValidationArguments, ValidatorConstraint, ValidatorConstraintInterface } from "class-validator";
@ValidatorConstraint({ name: 'UserExists', async: true })
@Injectable()
export class UserExistsRule implements ValidatorConstraintInterface {
constructor(
@InjectModel(User.name) private readonly userModel: Model<UserDocument>,
) {}
async validate(value: string) {
try {
await this.userModel.find({email: value});
} catch (e) {
return false;
}
return true;
}
defaultMessage(args: ValidationArguments) {
return `User doesn't exist`;
}
}

View File

@ -1,23 +1,25 @@
import { Schema, Prop, SchemaFactory } from '@nestjs/mongoose'; import { Schema, Prop, SchemaFactory } from '@nestjs/mongoose';
import { Document } from 'mongoose'; import { Document } from 'mongoose';
var uniqueValidator = require('mongoose-unique-validator');
import { IsEmail, IsNotEmpty, IsString, Validate } from 'class-validator';
export type UserDocument = User & Document; export type UserDocument = User & Document;
@Schema({ collection: 'users' }) @Schema({ collection: 'users'})
export class User { export class User {
@Prop() @Prop({index: true})
dni: string; dni!: string;
@Prop() @Prop({required: true})
name: string; name: string;
@Prop() @Prop({required: true})
last_name: string; last_name: string;
@Prop() @Prop({required: true, unique: true})
email: string; email: string;
@Prop() @Prop({required: true, unique: true})
phone: number; phone: number;
@Prop() @Prop()
@ -37,3 +39,4 @@ export class User {
} }
export const UserSchema = SchemaFactory.createForClass(User); export const UserSchema = SchemaFactory.createForClass(User);
UserSchema.plugin(uniqueValidator);

View File

@ -1,7 +1,8 @@
import { Controller } from '@nestjs/common'; import { Controller, UseFilters } from '@nestjs/common';
import { MessagePattern, Payload } from '@nestjs/microservices'; import { MessagePattern, Payload } from '@nestjs/microservices';
import { User, UserDocument } from '../schemas/user.schema'; import { User, UserDocument } from '../schemas/user.schema';
import { UsersService } from './users.service'; import { UsersService } from './users.service';
import { MongoExceptionFilter } from 'src/MongoExceptionFilter';
@Controller() @Controller()
export class UsersController { export class UsersController {
@ -13,6 +14,7 @@ export class UsersController {
} }
@MessagePattern({ cmd: 'createAdminSystem' }) @MessagePattern({ cmd: 'createAdminSystem' })
@UseFilters(MongoExceptionFilter)
createUserAdmin(@Payload() user: UserDocument) { createUserAdmin(@Payload() user: UserDocument) {
return this.userService.create(user); return this.userService.create(user);
} }
@ -22,6 +24,11 @@ export class UsersController {
return this.userService.create(user); return this.userService.create(user);
} }
@MessagePattern({ cmd: 'createAdminCommunity' })
createAdminCommunity(@Payload() user: UserDocument) {
return this.userService.createAdminCommunity(user);
}
@MessagePattern({ cmd: 'findAllUsers' }) @MessagePattern({ cmd: 'findAllUsers' })
findAll() { findAll() {
return this.userService.findAll(); return this.userService.findAll();
@ -91,4 +98,7 @@ export class UsersController {
return this.userService.deleteAdminSystem(user['id']); return this.userService.deleteAdminSystem(user['id']);
} }
} }

View File

@ -18,7 +18,17 @@ import { ClientsModule, Transport } from '@nestjs/microservices';
}, },
}, },
]), ]),
MongooseModule.forFeature([{ name: User.name, schema: UserSchema }]), ClientsModule.register([
{
name: "SERVICIO_COMUNIDADES",
transport: Transport.TCP,
options: {
host: "127.0.0.1",
port: 3002
}
}
]),
MongooseModule.forFeature([{ name: User.name, schema: UserSchema }]),
], ],
controllers: [UsersController], controllers: [UsersController],
providers: [UsersService], providers: [UsersService],

View File

@ -4,6 +4,7 @@ import { User, UserDocument } from '../schemas/user.schema';
import { InjectModel } from '@nestjs/mongoose'; import { InjectModel } from '@nestjs/mongoose';
import { Md5 } from 'md5-typescript'; import { Md5 } from 'md5-typescript';
import { map } from 'rxjs/operators'; import { map } from 'rxjs/operators';
import { lastValueFrom } from 'rxjs';
import { RpcException, ClientProxy } from '@nestjs/microservices'; import { RpcException, ClientProxy } from '@nestjs/microservices';
@ -11,9 +12,10 @@ import { RpcException, ClientProxy } from '@nestjs/microservices';
export class UsersService { export class UsersService {
constructor( constructor(
@InjectModel(User.name) private readonly userModel: Model<UserDocument>, @InjectModel(User.name) private readonly userModel: Model<UserDocument>,
@Inject('SERVICIO_NOTIFICACIONES') @Inject('SERVICIO_NOTIFICACIONES') private readonly clientNotificationtApp: ClientProxy,
private readonly clientNotificationtApp: ClientProxy, @Inject('SERVICIO_COMUNIDADES') private readonly clientCommunityApp: ClientProxy,
) {}
) { }
private publicKey: string; private publicKey: string;
async create(user: UserDocument): Promise<User> { async create(user: UserDocument): Promise<User> {
let passwordEncriptada = Md5.init(user.password); let passwordEncriptada = Md5.init(user.password);
@ -21,6 +23,42 @@ export class UsersService {
return this.userModel.create(user); return this.userModel.create(user);
} }
async createAdminCommunity(user: UserDocument) {
let password = user.password;
let passwordEncriptada = Md5.init(user.password);
user.password = passwordEncriptada;
this.userModel.create(user)
let community = await this.findCommunity(user.community_id);
user.community_id = community['name'];
const pattern = { cmd: 'emailCreateUserAdminCommunity' };
const payload = { email: user['email'], password: password, name: user['name'],
date_entry: user['date_entry'], community_name: community['name'] };
return this.clientNotificationtApp
.send<string>(pattern, payload)
.pipe(
map((message: string) => ({ message })),
);
}
async findCommunity(community_id: string) {
const pattern = { cmd: 'findOneCommunity' }
const payload = { _id: community_id }
let callback = await this.clientCommunityApp
.send<string>(pattern, payload)
.pipe(
map((response: string) => ({ response }))
)
const finalValue = await lastValueFrom(callback);
return finalValue['response'];
}
async findAll(): Promise<User[]> { async findAll(): Promise<User[]> {
return this.userModel.find().setOptions({ sanitizeFilter: true }).exec(); return this.userModel.find().setOptions({ sanitizeFilter: true }).exec();
} }
@ -106,4 +144,23 @@ export class UsersService {
async deleteAdminSystem(id: string) { async deleteAdminSystem(id: string) {
return this.userModel.deleteOne({ _id: id }).exec(); return this.userModel.deleteOne({ _id: id }).exec();
} }
async validateEmail(email: string) {
let repo1 = this.userModel;
return new Promise<User>((resolve, reject) => {
let repo = repo1;
repo.find({ email: email }).exec((err, res) => {
if (err) {
reject(err);
} else {
if (res.length > 0) {
return res;
}
}
});
});
}
} }

File diff suppressed because it is too large Load Diff

View File

@ -36,9 +36,10 @@ const AdministradoresSistema = () => {
phone: '', phone: '',
password: '', password: '',
user_type: '1', user_type: '1',
status: '', status: '1',
}; };
async function fetchP() { async function fetchP() {
let nombres = await fetch(urlFetch, { method: 'GET' }); let nombres = await fetch(urlFetch, { method: 'GET' });
let adminRes = await nombres.json(); let adminRes = await nombres.json();
@ -47,7 +48,8 @@ const AdministradoresSistema = () => {
} }
useEffect(() => { useEffect(() => {
fetchP(); fetchP();
}, []); }, [])
function registrarAdmin() { function registrarAdmin() {
var data = { var data = {
@ -57,9 +59,10 @@ const AdministradoresSistema = () => {
email: document.getElementById('correo_electronico').value, email: document.getElementById('correo_electronico').value,
phone: document.getElementById('telefono').value, phone: document.getElementById('telefono').value,
password: document.getElementById('correo_electronico').value, password: document.getElementById('correo_electronico').value,
user_type: '1', //1 es admin user_type: "1", //1 es admin
status: '1', status: "1"
}; };
setSysAdmin(data)
// console.log(data); // console.log(data);
fetch('http://localhost:4000/user/createAdminSystem/', { fetch('http://localhost:4000/user/createAdminSystem/', {
@ -67,31 +70,30 @@ const AdministradoresSistema = () => {
method: 'POST', method: 'POST',
body: JSON.stringify(data), body: JSON.stringify(data),
headers: { headers: {
'Content-Type': 'application/json', 'Content-Type': 'application/json'
}, }
}) })
.then(function (response) { .then(
if (response.status != 201) function (response) {
console.log('Ocurrió un error con el servicio: ' + response.status); if (response.status != 201)
else return response.json(); console.log('Ocurrió un error con el servicio: ' + response.status);
}) else
.then(function (response) { return response.json();
let _administrators = [...administrators]; }
let _admin = { ...response.message }; )
_administrators.push(_admin); .then(
setAdministrators(_administrators); function (response) {
}) let _administrators = [...administrators];
.catch((err) => console.log('Ocurrió un error con el fetch', err)); let _admin = { ...sysadmin };
_administrators.push(_admin);
setAdministrators(_administrators)
}
)
.catch(
err => console.log('Ocurrió un error con el fetch', err)
);
} }
const hideDeleteAdminSystemDialog = () => {
setDeleteAdminSystemDialog(false);
};
const hideDeleteAdminsSystemsDialog = () => {
setDeleteAdminsSystemDialog(false);
};
const confirmDeleteAdminSystem = (sysAdmin) => { const confirmDeleteAdminSystem = (sysAdmin) => {
setSysAdmin(sysAdmin); setSysAdmin(sysAdmin);
setDeleteAdminSystemDialog(true); setDeleteAdminSystemDialog(true);
@ -101,6 +103,15 @@ const AdministradoresSistema = () => {
setDeleteAdminsSystemDialog(true); setDeleteAdminsSystemDialog(true);
}; };
const hideDeleteAdminSystemDialog = () => {
setDeleteAdminSystemDialog(false);
};
const hideDeleteAdminsSystemDialog = () => {
setDeleteAdminsSystemDialog(false);
};
const deleteSysAdmin = () => { const deleteSysAdmin = () => {
fetch('http://localhost:4000/user/deleteAdminSystem/' + sysadmin._id, { fetch('http://localhost:4000/user/deleteAdminSystem/' + sysadmin._id, {
cache: 'no-cache', cache: 'no-cache',
@ -206,7 +217,7 @@ const AdministradoresSistema = () => {
const header = ( const header = (
<div className="flex flex-column md:flex-row md:justify-content-between md:align-items-center"> <div className="flex flex-column md:flex-row md:justify-content-between md:align-items-center">
<h5 className="m-0"> <h5 className="m-0">
Administradores del sistema <i class="fal fa-user"></i> Administradores del sistema <i className="fal fa-user"></i>
</h5> </h5>
<span className="block mt-2 md:mt-0 p-input-icon-left"> <span className="block mt-2 md:mt-0 p-input-icon-left">
<i className="pi pi-search" /> <i className="pi pi-search" />
@ -242,7 +253,7 @@ const AdministradoresSistema = () => {
label="No" label="No"
icon="pi pi-times" icon="pi pi-times"
className="p-button-text" className="p-button-text"
onClick={hideDeleteAdminsSystemsDialog} onClick={hideDeleteAdminsSystemDialog}
/> />
<Button <Button
label="Yes" label="Yes"
@ -432,7 +443,7 @@ const AdministradoresSistema = () => {
header="Confirmar" header="Confirmar"
modal modal
footer={deleteAdminsSystemDialogFooter} footer={deleteAdminsSystemDialogFooter}
onHide={hideDeleteAdminsSystemsDialog} onHide={hideDeleteAdminsSystemDialog}
> >
<div className="flex align-items-center justify-content-center"> <div className="flex align-items-center justify-content-center">
<i <i

View File

@ -23,7 +23,7 @@ const Communities = () => {
district: districtId, district: districtId,
phone: '', phone: '',
num_houses: 0, num_houses: 0,
status: 'activo', status: '1',
date_entry: new Date(), date_entry: new Date(),
houses: [], houses: [],
}; };
@ -64,17 +64,6 @@ const Communities = () => {
parent: item.parentCode, parent: item.parentCode,
})); }));
useEffect(() => {
fillProvinces();
}, []);
useEffect(() => {
fillCantons();
}, [provinciaId]);
useEffect(() => {
fillDistricts();
}, [cantonId]);
async function getProvinces() { async function getProvinces() {
const response = await fetch('assets/demo/data/provincias.json', { const response = await fetch('assets/demo/data/provincias.json', {
@ -118,6 +107,20 @@ const Communities = () => {
setDistrictsList(await districts); setDistrictsList(await districts);
} }
useEffect(() => {
fillProvinces();
}, []);
useEffect(() => {
fillCantons();
}, [provinciaId]);
useEffect(() => {
fillDistricts();
}, [cantonId]);
const handleProvinces = (event) => { const handleProvinces = (event) => {
const getprovinciaId = event.target.value; const getprovinciaId = event.target.value;
setProvinciaId(getprovinciaId); setProvinciaId(getprovinciaId);

View File

@ -1,139 +1,321 @@
import React, { useEffect, useState } from 'react'; import React, { useEffect, useState, useRef } from 'react';
import { InputText } from 'primereact/inputtext'; import { InputText } from 'primereact/inputtext';
import { Button } from 'primereact/button'; import { Button } from 'primereact/button';
import { DataTable } from 'primereact/datatable'; import { DataTable } from 'primereact/datatable';
import { Column } from 'primereact/column'; 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 { faEllipsis } from '@fortawesome/free-solid-svg-icons';
const GuardasSeguridad = () => { const GuardasSeguridad = () => {
const [pokemones, setPokemones] = useState([]); const [listaGuardas,setListaGuardas]=useState([]);
const [urlFetch, setUrlFetch] = useState( const [urlFetch,setUrlFetch]=useState('http://localhost:4000/user/findGuards/62be68215692582bbfd77134');
'http://localhost:4000/user/findGuards/62be68215692582bbfd77134', const [guarda, setGuarda] = useState(emptyGuarda);
); const [selectedGuardas, setSelectedGuardas] = useState(null);
async function fetchP() { const [globalFilter, setGlobalFilter] = useState(null);
let nombres = await fetch(urlFetch, { method: 'GET' }); const [deleteGuardaDialog, setDeleteGuardaDialog] = useState(false);
let pokemonesRes = await nombres.json(); const [deleteGuardasDialog, setDeleteGuardasDialog] = useState(false);
setPokemones(pokemonesRes.message); const toast = useRef(null);
console.log(pokemones); const dt = useRef(null);
} let emptyGuarda = {
useEffect(() => { _id: null,
fetchP(); dni: '',
}, []); name: '',
last_name: '',
function registrarGuarda() { email: '',
var data = { phone: '',
dni: document.getElementById('identificacion').value, password: '',
name: document.getElementById('nombre').value, user_type: '1',
last_name: document.getElementById('apellidos').value, status: ''
email: document.getElementById('correo_electronico').value,
phone: document.getElementById('telefono').value,
password: document.getElementById('correo_electronico').value,
user_type: '4', //4 es guarda
status: '1',
community_id: '62be68215692582bbfd77134',
}; };
var data2 = {
dni: '98765',
name: 'Danielito',
last_name: 'Rodriguez',
email: 'danirodriguez@gmail.com',
phone: 84664515,
password: '1203',
user_type: '2',
status: '4',
community_id: '62be68215692582bbfd77134',
};
console.log(data2);
fetch('http://localhost:4000/user/createGuard', {
cache: 'no-cache',
method: 'POST',
mode: 'cors',
body: JSON.stringify(data2),
headers: {
'Content-Type': 'application/json',
},
})
.then(function (response) {
if (response.status != 201)
console.log('Ocurrió un error con el servicio: ' + response.status);
else return response.json();
})
.then(function (response) {
fetchP();
})
.catch((err) => console.log('Ocurrió un error con el fetch', err));
}
return (
<div className="grid"> async function listaGuardasF(){
<div className="col-12"> let nombres=await fetch(urlFetch, {method:'GET'});
<div className="card"> let listaGuardasRes= await nombres.json();
<h5>Guardas de seguridad</h5> setListaGuardas(listaGuardasRes.message);
<DataTable }
value={pokemones} useEffect(()=>{
scrollable listaGuardasF();
scrollHeight="400px" },[])
scrollDirection="both"
className="mt-3" function registrarGuarda() {
> var data = {
<Column dni: document.getElementById('identificacion').value,
field="name" name: document.getElementById('nombre').value,
header="Nombre" last_name: document.getElementById('apellidos').value,
style={{ flexGrow: 1, flexBasis: '160px' }} email: document.getElementById('correo_electronico').value,
></Column> phone: document.getElementById('telefono').value,
<Column password: document.getElementById('correo_electronico').value,
field="last_name" user_type: "4", //4 es guarda
header="Apellidos" status: "1",
style={{ flexGrow: 1, flexBasis: '160px' }} community_id:"62be68215692582bbfd77134"
alignFrozen="left" };
></Column> var data2={
<Column dni: "11979037",
field="dni" name: "Jorge",
header="Identificación" last_name: "Soto",
style={{ flexGrow: 1, flexBasis: '160px' }} email: "jorgesoto@gmail.com",
></Column> phone: 84664515,
<Column password: "1203",
field="email" user_type: "2",
header="Correo electrónico" status: "4",
style={{ flexGrow: 1, flexBasis: '160px' }} community_id:"62be68215692582bbfd77134"
></Column> }
<Column console.log('ssss');
field="phone" fetch('http://localhost:4000/user/createGuard', {
header="Telefóno" cache: 'no-cache',
style={{ flexGrow: 1, flexBasis: '160px' }} method: 'POST',
></Column> mode:'cors',
</DataTable> body: JSON.stringify(data2),
headers: {
'Content-Type': 'application/json'
}
})
.then(
function (response) {
if (response.status != 201)
console.log('Ocurrió un error con el servicio: ' + response.status);
else
return response.json();
}
)
.then(
function (response) {
console.log('fff');
listaGuardasF();
}
)
.catch(
err => console.log('Ocurrió un error con el fetch', err)
);
}
const hideDeleteGuardaDialog = () => {
setDeleteGuardaDialog(false);
}
const hideDeleteGuardasDialog = () => {
setDeleteGuardasDialog(false);
}
const confirmDeleteGuarda = (guarda) => {
setGuarda(guarda);
setDeleteGuardaDialog(true);
}
const confirmDeleteSelected = () => {
setDeleteGuardasDialog(true);
}
const deleteGuarda = () => {
fetch('http://localhost:4000/user/deleteAdminSystem/' + guarda._id, {
cache: 'no-cache',
method: 'DELETE',
headers: {
'Content-Type': 'application/json'
}
})
.then(
function (response) {
if (response.status != 201)
console.log('Ocurrió un error con el servicio: ' + response.status);
else
return response.json();
}
)
.then(
function (response) {
let _guarda = listaGuardas.filter(val => val._id !== guarda._id);
setListaGuardas(_guarda);
setDeleteGuardaDialog(false);
setGuarda(emptyGuarda);
toast.current.show({ severity: 'success', summary: 'Éxito', detail: 'Administrador del Sistema Eliminado', life: 3000 });
}
)
.catch(
err => {
console.log('Ocurrió un error con el fetch', err)
toast.current.show({ severity: 'danger', summary: 'Error', detail: 'Administrador del Sistema no se pudo Eliminar', life: 3000 });
}
);
}
const deleteSelectedGuardas = () => {
let _guardas = listaGuardas.filter(val => !selectedGuardas.includes(val));
selectedGuardas.map((item) => {
fetch('http://localhost:4000/user/deleteAdminSystem/' + item._id, {
cache: 'no-cache',
method: 'DELETE',
headers: {
'Content-Type': 'application/json'
}
})
})
setListaGuardas(_guardas);
setDeleteGuardasDialog(false);
setSelectedGuardas(null);
toast.current.show({ severity: 'success', summary: 'Éxito', detail: 'Administradores del Sistema Eliminados', life: 3000 });
}
const actionsAdmin = (rowData) => {
return (
<div className="actions">
<Button icon="pi pi-trash" className="p-button-rounded p-button-danger mt-2" onClick={() => confirmDeleteGuarda(rowData)} />
</div>
);
}
const leftToolbarTemplate = () => {
return (
<React.Fragment>
<div className="my-2">
<Button label="Eliminar" icon="pi pi-trash" className="p-button-danger" onClick={confirmDeleteSelected} disabled={!selectedGuardas || !selectedGuardas.length} />
</div>
</React.Fragment>
)
}
const rightToolbarTemplate = () => {
return (
<React.Fragment>
<Button label="Exportar" icon="pi pi-upload" className="p-button-help" />
</React.Fragment>
)
}
const header = (
<div className="flex flex-column md:flex-row md:justify-content-between md:align-items-center">
<h5 className="m-0">Guardas de seguridad</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> </div>
</div> );
<div className="col-12">
<div className="card"> const deleteAdminSystemDialogFooter = (
<h5>Registro de un guarda de seguridad</h5> <>
<div className="p-fluid formgrid grid"> <Button label="No" icon="pi pi-times" className="p-button-text" onClick={hideDeleteGuardasDialog} />
<div className="field col-12 md:col-6"> <Button label="Yes" icon="pi pi-check" className="p-button-text" onClick={deleteGuarda} />
<label htmlFor="nombre">Nombre</label> </>
<InputText id="nombre" type="text" /> );
const deleteAdminsSystemDialogFooter = (
<>
<Button label="No" icon="pi pi-times" className="p-button-text" onClick={hideDeleteGuardasDialog} />
<Button label="Yes" icon="pi pi-check" className="p-button-text" onClick={deleteSelectedGuardas} />
</>
);
const headerName = (
<>
<p>Nombre</p>
</>
)
const headerLastName = (
<>
<p>Apellidos</p>
</>
)
const headerDNI = (
<>
<p>Identificación</p>
</>
)
const headerEmail = (
<>
<p>Correo Electrónico</p>
</>
)
const headerPhone = (
<>
<p>Teléfono</p>
</>
)
const headerOptions = (
<>
<p>Opciones</p>
</>
)
return (
<div className="grid">
<div className="col-12">
<Toast ref={toast} />
<div className="card">
<Toolbar className="mb-4" left={leftToolbarTemplate} right={rightToolbarTemplate}></Toolbar>
<DataTable ref={dt} value={listaGuardas} dataKey="_id" paginator rows={5} selection={selectedGuardas} onSelectionChange={(e) => setSelectedGuardas(e.value)}
responsiveLayout="scroll" header={header}
rowsPerPageOptions={[5, 10, 25]} className="datatable-responsive mt-3"
paginatorTemplate="FirstPageLink PrevPageLink PageLinks NextPageLink LastPageLink CurrentPageReport RowsPerPageDropdown"
currentPageReportTemplate="Mostrando {first} a {last} de {totalRecords}"
globalFilter={globalFilter} emptyMessage="No hay guardas registrados.">
<Column selectionMode="multiple" headerStyle={{ width: '3rem' }}></Column>
<Column field="name" sortable header={headerName} style={{ flexGrow: 1, flexBasis: '160px', minWidth: '160px', wordBreak: 'break-word' }}></Column>
<Column field="last_name" sortable header={headerLastName} style={{ flexGrow: 1, flexBasis: '160px', minWidth: '160px', wordBreak: 'break-word' }} alignFrozen="left"></Column>
<Column field="dni" sortable header={headerDNI} style={{ flexGrow: 1, flexBasis: '160px', minWidth: '160px', wordBreak: 'break-word' }}>
</Column>
<Column field="email" sortable header={headerEmail} style={{ flexGrow: 1, flexBasis: '160px', minWidth: '160px', wordBreak: 'break-word' }}></Column>
<Column field="phone" sortable header={headerPhone} style={{ flexGrow: 1, flexBasis: '160px', minWidth: '160px', wordBreak: 'break-word' }}></Column>
<Column header={headerOptions} style={{ flexGrow: 1, flexBasis: '130px', minWidth: '130px' }} body={actionsAdmin}></Column>
</DataTable>
<Dialog visible={deleteGuardaDialog} style={{ width: '450px' }} header="Confirmar" modal footer={deleteAdminSystemDialogFooter} onHide={hideDeleteGuardaDialog}>
<div className="flex align-items-center justify-content-center">
<i className="pi pi-exclamation-triangle mr-3" style={{ fontSize: '2rem' }} />
{guarda && <span>¿Estás seguro que desea eliminar a <b>{guarda.name}</b>?</span>}
</div>
</Dialog>
<Dialog visible={deleteGuardasDialog} style={{ width: '450px' }} header="Confirmar" modal footer={deleteAdminsSystemDialogFooter} onHide={hideDeleteGuardasDialog}>
<div className="flex align-items-center justify-content-center">
<i className="pi pi-exclamation-triangle mr-3" style={{ fontSize: '2rem' }} />
{selectedGuardas && <span>¿Está seguro eliminar los adminsitradores del sistema seleccionados?</span>}
</div>
</Dialog>
</div>
</div> </div>
<div className="field col-12 md:col-6"> <div className="col-12">
<label htmlFor="apellidos">Apellidos</label> <div className="card">
<InputText id="apellidos" type="text" /> <h5>Registro de un guarda de seguridad</h5>
<div className="p-fluid formgrid grid">
<div className="field col-12 md:col-6">
<label htmlFor="nombre">Nombre</label>
<InputText id="nombre" type="text" />
</div>
<div className="field col-12 md:col-6">
<label htmlFor="apellidos">Apellidos</label>
<InputText id="apellidos" type="text" />
</div>
<div className="field col-12 md:col-6">
<label htmlFor="correo_electronico">Correo electrónico</label>
<InputText id="correo_electronico" type="text" />
</div>
<div className="field col-12 md:col-6">
<label htmlFor="identificacion">Identificación</label>
<InputText id="identificacion" type="text" />
</div>
<div className="field col-12">
<label htmlFor="telefono">Teléfono</label>
<InputText id="telefono" type="number" rows="4" />
</div>
<Button label="Registrar" onClick={registrarGuarda}></Button>
</div>
</div>
</div> </div>
<div className="field col-12 md:col-6">
<label htmlFor="correo_electronico">Correo electrónico</label>
<InputText id="correo_electronico" type="text" />
</div>
<div className="field col-12 md:col-6">
<label htmlFor="identificacion">Identificación</label>
<InputText id="identificacion" type="text" />
</div>
<div className="field col-12">
<label htmlFor="telefono">Teléfono</label>
<InputText id="telefono" type="number" rows="4" />
</div>
<Button label="Registrar" onClick={registrarGuarda}></Button>
</div>
</div> </div>
</div>
</div>
); );
}; };

View File

@ -20,8 +20,13 @@ const Inquilinos = () => {
}, []); }, []);
function registrarInquilino() { function registrarInquilino() {
let data = { let data = {
dni: document.getElementById('identificacion').value,
name: document.getElementById('nombre').value,
last_name: document.getElementById('apellidos').value,
phone: document.getElementById('telefono').value,
email: document.getElementById('correo_electronico').value, email: document.getElementById('correo_electronico').value,
community_id: document.getElementById('numero_vivienda').value, community_id: document.getElementById('numero_vivienda').value,
password: document.getElementById('password').value,
user_type: '3', user_type: '3',
status: '1', status: '1',
}; };
@ -48,7 +53,23 @@ const Inquilinos = () => {
<div className="card"> <div className="card">
<h5 className="card-header">Registrar Inquilino</h5> <h5 className="card-header">Registrar Inquilino</h5>
<div className="p-fluid formgrid grid"> <div className="p-fluid formgrid grid">
<div className="p-field col-12 md:col-6"> <div className="field col-12 md:col-6">
<label htmlFor="nombre">Nombre</label>
<InputText type="text" className="form-control" id="nombre" />
</div>
<div className="field col-12 md:col-6">
<label htmlFor="apellidos">Apellidos</label>
<InputText type="text" className="form-control" id="apellidos" />
</div>
<div className="field col-12 md:col-6">
<label htmlFor="identificacion">Identificación</label>
<InputText
type="text"
className="form-control"
id="identificacion"
/>
</div>
<div className="field col-12 md:col-6">
<label htmlFor="correo_electronico">Correo electrónico</label> <label htmlFor="correo_electronico">Correo electrónico</label>
<InputText <InputText
type="email" type="email"
@ -56,7 +77,7 @@ const Inquilinos = () => {
id="correo_electronico" id="correo_electronico"
/> />
</div> </div>
<div className="p-field col-12 md:col-6"> <div className="field col-12 md:col-6">
<label htmlFor="numero_vivienda">Número de Vivienda</label> <label htmlFor="numero_vivienda">Número de Vivienda</label>
<Dropdown <Dropdown
id="numero_vivienda" id="numero_vivienda"
@ -64,6 +85,14 @@ const Inquilinos = () => {
options={communitiesList} options={communitiesList}
/> />
</div> </div>
<div className="field col-12 md:col-6">
<label htmlFor="identificacion">Identificación</label>
<InputText
type="password"
className="form-control"
id="identificacion"
/>
</div>
<Button label="Registrar" onClick={registrarInquilino} /> <Button label="Registrar" onClick={registrarInquilino} />
</div> </div>
</div> </div>