Commit a1cfea4d authored by Julieta Dubra Raimunde's avatar Julieta Dubra Raimunde
Browse files

Merge commit '511679cc' into master

parents 6d0469b0 511679cc
Pipeline #16239 passed with stage
in 2 minutes and 36 seconds
......@@ -21,13 +21,10 @@
}
},
"rules": {
"linebreak-style": [
"error",
"windows"
],
"import/prefer-default-export":"off",
"@typescript-eslint/camelcase":"off",
"class-methods-use-this":"off",
"prefer-destructuring": ["error", {"object": true, "array": false}]
"prefer-destructuring": ["error", {"object": true, "array": false}],
"linebreak-style": "off"
}
}
......@@ -7,6 +7,8 @@ import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { AuthModule } from './modules/auth/auth.module';
import { SharedModule } from './modules/shared/shared.module';
import { AdminGuard } from './guards/admin.guard';
import { UserGuard } from './guards/user.guard';
@NgModule({
declarations: [
......@@ -21,7 +23,10 @@ import { SharedModule } from './modules/shared/shared.module';
ReactiveFormsModule,
HttpClientModule,
],
providers: [],
providers: [
AdminGuard,
UserGuard
],
bootstrap: [AppComponent],
})
export class AppModule { }
export enum UserTypes {
Admin = 1,
Client = 2
}
\ No newline at end of file
import { Injectable } from "@angular/core";
import { ActivatedRouteSnapshot, CanActivate, Router, RouterStateSnapshot } from "@angular/router";
import { Observable } from "rxjs";
import { map, catchError } from "rxjs/operators";
import { UserTypes } from "../enums/UserTypes";
import { User } from "../models";
import { AuthService } from "../services";
@Injectable()
export class AdminGuard implements CanActivate {
constructor(
private authService: AuthService,
private router: Router
) {}
canActivate(next: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean> {
return this.authService.checkUser()
.pipe(
map((user: {userId: number, userType: number}) => {
if (!user) {
this.router.navigate(['']);
}
return user.userType == UserTypes.Admin;
}),
catchError((err: any, caught: Observable<boolean>): Observable<boolean> => {
this.router.navigate(['']);
return new Observable<boolean>();
})
);
}
}
\ No newline at end of file
import { Injectable } from "@angular/core";
import { ActivatedRouteSnapshot, CanActivate, Router, RouterStateSnapshot } from "@angular/router";
import { Observable } from "rxjs";
import { map, catchError } from "rxjs/operators";
import { AuthService } from "../services";
import { User } from "../models";
@Injectable()
export class UserGuard implements CanActivate {
constructor(
private authService: AuthService,
private router: Router
) {}
canActivate(next: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean> {
return this.authService.checkUser()
.pipe(
map((user: {userId: number, userType: number}) => {
if (!user) {
this.router.navigate(['']);
}
return true;
}),
catchError((err: any, caught: Observable<boolean>): Observable<boolean> => {
this.router.navigate(['']);
return new Observable<boolean>();
})
);
}
}
\ No newline at end of file
export interface CreateFaqDTO {
question: string;
answer: string;
}
export interface IFAQ {
id: number;
question: string;
answer: string;
position: number;
createdAt: Date;
}
......@@ -27,6 +27,7 @@ import { MatStepperModule } from '@angular/material/stepper';
import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
import { MatProgressBarModule } from '@angular/material/progress-bar';
import { MatSlideToggleModule } from '@angular/material/slide-toggle';
import { MatMenuModule } from '@angular/material/menu';
// NgxModules
import {
......@@ -68,6 +69,7 @@ import {
NgxMatNativeDateModule,
NgxMatTimepickerModule,
MatSlideToggleModule,
MatMenuModule,
],
exports: [
MatCardModule,
......@@ -99,6 +101,7 @@ import {
NgxMatNativeDateModule,
NgxMatTimepickerModule,
MatSlideToggleModule,
MatMenuModule,
],
providers: [
MatDatepickerModule,
......
import { AuditorySearch } from './auditory-search.model';
describe('AuditorySearch', () => {
it('should create an instance', () => {
expect(new AuditorySearch()).toBeTruthy();
});
});
export class AuditorySearch {
constructor(
public cant : number,
public page : number,
) {}
}
import { IFAQ } from '../interfaces/faq.interface';
export class FAQ implements IFAQ {
id: number;
question: string;
answer: string;
position: number;
createdAt: Date;
}
import { Log } from './log.model';
describe('Log', () => {
it('should create an instance', () => {
expect(new Log()).toBeTruthy();
});
});
/**
* Modelo con la información de los logs de cambio para auditoría.
*/
export class Log {
constructor(
public id: number,
public email: string,
public user_name: number,
public organization_name: string,
public date: string,
public action: string,
) { }
}
......@@ -25,12 +25,12 @@
<div class="formBx">
<form [formGroup]="loginForm">
<h2>Ingresar</h2>
<input formControlName="email" name="email" type="text" placeholder="Email" >
<input formControlName="email" name="email" type="text" placeholder="Email" tabindex="-1">
<small *ngIf="loginForm.get('email')?.hasError('required') && loginForm.get('email')?.touched">El email es requerido.</small>
<input formControlName="password" name="password" type="password" placeholder="Contraseña">
<input formControlName="password" name="password" type="password" placeholder="Contraseña" tabindex="-1">
<small *ngIf="loginForm.get('password')?.hasError('required') && loginForm.get('password')?.touched">La contraseña es requerida.</small>
<p></p>
<input (click)="login()" [disabled]="loginForm.invalid" type="submit" value="Ingresar">
<input (click)="login()" [disabled]="loginForm.invalid" type="submit" value="Ingresar" tabindex="-1">
<p class="signup">No tienes una cuenta? <a id="registrarse" (click)="toggleForm()">Registrese</a></p>
<p class="signup">IR A LA <a id="inicio" (click)="dashboard()">PÁGINA PRINCIPAL</a></p>
</form>
......@@ -40,29 +40,29 @@
<div class="formBx">
<form [formGroup]="registerForm">
<h2>Crear una cuenta</h2>
<input formControlName="name" name="nombre" type="text" placeholder="Usuario" >
<input formControlName="name" name="nombre" type="text" placeholder="Usuario" tabindex="-1">
<small *ngIf="registerForm.get('name')?.hasError('required') && registerForm.get('name')?.touched">El nombre es requerido.</small>
<small *ngIf="registerForm.get('name')?.hasError('minlength') && registerForm.get('name')?.touched">Como mínimo 3 caracteres.</small>
<small *ngIf="registerForm.get('name')?.hasError('maxlength') && registerForm.get('name')?.touched">Como máximo 40 caracteres.</small>
<input formControlName="email" name="email" type="text" placeholder="Email" >
<input formControlName="email" name="email" type="text" placeholder="Email" tabindex="-1">
<small *ngIf="registerForm.get('email')?.hasError('required') && registerForm.get('email')?.touched">El email es requerido.</small>
<small *ngIf="registerForm.get('email')?.hasError('email') && registerForm.get('email')?.touched">El no tiene in fromato válido.</small>
<small *ngIf="registerForm.get('email')?.hasError('maxlength') && registerForm.get('email')?.touched">Como máximo 60 caracteres.</small>
<input formControlName="organization" name="organization" type="text" placeholder="Organizacion" >
<input formControlName="organization" name="organization" type="text" placeholder="Organizacion" tabindex="-1">
<small *ngIf="registerForm.get('organization')?.hasError('required') && registerForm.get('organization')?.touched">La organizacion es requerida.</small>
<small *ngIf="registerForm.get('organization')?.hasError('maxlength') && registerForm.get('organization')?.touched">Como máximo 50 caracteres.</small>
<input formControlName="password" name="password" type="password" placeholder="Contraseña">
<input formControlName="password" name="password" type="password" placeholder="Contraseña" tabindex="-1">
<small *ngIf="registerForm.get('password')?.hasError('required') && registerForm.get('password')?.touched">La contraseña es requerida.</small>
<small *ngIf="registerForm.get('password')?.hasError('minlength') && registerForm.get('password')?.touched">Como mínimo 6 caracteres.</small>
<small *ngIf="registerForm.get('password')?.hasError('maxlength') && registerForm.get('password')?.touched">Como máximo 50 caracteres.</small>
<input formControlName="passwordConf" name="passwordConf" type="password" placeholder="Repetir Contraseña">
<input formControlName="passwordConf" name="passwordConf" type="password" placeholder="Repetir Contraseña" tabindex="-1">
<small *ngIf="registerForm.get('passwordConf')?.hasError('required') && registerForm.get('passwordConf')?.touched">La confirmacion de constraseña es requerida</small>
<input (click)="register()" [disabled]="registerForm.invalid" type="submit" value="Registrarse">
<input (click)="register()" [disabled]="registerForm.invalid" type="submit" value="Registrarse" tabindex="-1">
<p class="signup">Ya tienes cuenta? <a id="ingresar" (click)="toggleForm()">Ingresar</a></p>
</form>
</div>
......
......@@ -48,7 +48,6 @@ export class LoginRegistroComponent implements OnInit {
register() {
// solo deja llamar a esta funcion en caso de que todos los campos sean validos
const values: Register = this.registerForm.value;
console.log(values);
if (values.password !== values.passwordConf) {
this.message = 'Las contraseñas no coinciden';
this.alertaSuccess = false;
......@@ -79,7 +78,6 @@ export class LoginRegistroComponent implements OnInit {
// limpia los inputs
this.registerForm.reset();
// this.efectuarIngreso(res);
this.authService.loggedUser = result.user;
this.router.navigate(['']);
},
(err) => {
......
button {
margin: 1rem 1rem 0 1rem;
font-family: Roboto;
font-style: normal;
font-weight: 400;
font-size: 3rem;
height: 20rem;
width: 20rem;
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
.router-content {
body {
display: flex;
width: 100%;
justify-content: center;
align-items: center;
background: #ccfdff;
overflow: hidden;
}
.container {
display: flex;
justify-content: center;
align-items: center;
flex-wrap: row;
}
.container .box {
position: relative;
height: 360px;
display: flex;
justify-content: center;
align-items: center;
margin: 15px 40px;
cursor: pointer;
transition: 0.5s;
}
.container .box::before {
content: "";
position: absolute;
top: 0;
left: 70px;
width: 50%;
height: 100%;
background: #fff;
border-radius: 8px;
transform: skewX(15deg);
transition: 0.5s;
}
.container .box::after {
content: "";
position: absolute;
top: 0;
left: 70px;
width: 50%;
height: 100%;
flex-wrap: wrap;
}
\ No newline at end of file
background: #fff;
border-radius: 8px;
transform: skewX(15deg);
transition: 0.5s;
filter: blur(20px);
transition: 0.5s;
}
@keyframes init-diagonal-top-down {
0% {
transform: translateY(-1000px) translateX(-300px) skewX(15deg);
}
100% {
transform: translateY(0) translateX(0) skewX(15deg);
}
}
@keyframes init-diagonal-bottom-up {
0% {
transform: translateY(1000px) translateX(300px) skewX(15deg);
}
100% {
transform: translateY(0) translateX(0) skewX(15deg);
}
}
@keyframes init-bottom-up {
0% {
transform: translateY(100vh);
}
10% {
transform: translateY(60vh);
}
20% {
transform: translateY(30vh);
}
30% {
transform: translateY(15vh);
}
40% {
transform: translateY(5vh);
}
60% {
transform: translateY(0);
}
75% {
transform: skewX(0);
}
100% {
transform: skewX(15deg);
}
}
@keyframes init-top-down {
0% {
transform: translateY(-100vh);
}
10% {
transform: translateY(-60vh);
}
20% {
transform: translateY(-30vh);
}
30% {
transform: translateY(-15vh);
}
40% {
transform: translateY(-5vh);
}
50% {
transform: translateY(0);
}
70% {
transform: skewX(0);
}
100% {
transform: skewX(15deg);
}
}
.container .box:hover:before,
.container .box:hover:after {
transform: skewX(0deg);
left: 45px;
width: calc(100% - 90px);
}
.container .box:nth-child(1):before,
.container .box:nth-child(1):after {
background: linear-gradient(315deg, #65fdd7, #3cd17f);
animation: init-diagonal-top-down 0.2s ease-in;
}
.container .box:nth-child(2):before,
.container .box:nth-child(2):after {
background: linear-gradient(315deg, #2b98ff, #61fff7);
animation: init-diagonal-bottom-up 0.35s ease-in;
}
.container .box:nth-child(3):before,
.container .box:nth-child(3):after {
background: linear-gradient(315deg, #f0e796, #f7a944);
animation: init-diagonal-top-down 0.5s ease-in;
}
.container .box:nth-child(4):before,
.container .box:nth-child(4):after {
background: linear-gradient(315deg, #ee516b, #ee8ab8);
animation: init-diagonal-bottom-up 0.65s ease-in;
}
.container .box:nth-child(5):before,
.container .box:nth-child(5):after {
background: linear-gradient(315deg, #e5bef1, #ad3df8);
animation: init-diagonal-top-down 0.8s ease-in;
}
.container .box span::before {
content: "";
position: absolute;
top: 0px;
left: 0;
width: 100%;
height: 100%;
border-radius: 8px;
background: rgba(255, 255, 255, 0.1);
backdrop-filter: blur(10px);
opacity: 0;
transition: 0.5s;
animation: animate 2s ease-in-out infinite;
box-shadow: 0 5px 15px rgba(0, 0, 0, 0.05);
}
.container .box .content {
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
position: relative;
padding: 20px 20px;
left: 0;
width: 300px;
background: #3f51b5;
box-shadow: 0 5px 15px rgba(0, 0, 0, 0.1);
border-radius: 6px;
z-index: 1;
color: #fff;
overflow-y: hidden;
transition: 0.3s;
}
.container .box:hover .content {
padding: 50px 20px;
left: 0px;
}
.container .box .content h2 {
position: relative;
text-align: center;
font-size: 2.2em;
font-weight: 400;
color: #fff;
letter-spacing: 2px;
margin-bottom: 0px;
transition: 0.35s;
}
.container .box:hover .content h2 {
font-size: 2.6em;
color: #fff;
font-weight: 700;
margin-bottom: 10px;
letter-spacing: 4px;
}
.container .box:nth-child(1):hover .content h2 {
background: linear-gradient(90deg, #3cd17f, #65fdd7, #3cd17f);
-webkit-text-fill-color: transparent;
background-clip: text;
}
.container .box:nth-child(2):hover .content h2 {
background: linear-gradient(90deg, #61fff7, #2b98ff, #61fff7);
-webkit-text-fill-color: transparent;
background-clip: text;
}
.container .box:nth-child(3):hover .content h2 {
background: linear-gradient(90deg, #f7a944, #f0e796, #f7a944);
-webkit-text-fill-color: transparent;
background-clip: text;
}
.container .box:nth-child(4):hover .content h2 {
background: linear-gradient(90deg, #ee8ab8, #ee516b, #ee8ab8);
-webkit-text-fill-color: transparent;
background-clip: text;
}
.container .box:nth-child(5):hover .content h2 {
background: linear-gradient(90deg, #b755f8, #e2b9f0, #b05de7);
-webkit-text-fill-color: transparent;
background-clip: text;
}
.container .box .content p {
font-size: 1.2em;
margin-bottom: 10px;
line-height: 1.4em;
transform: translateY(500%);
height: 0;
overflow: hidden;
transition: height 0.25s 0.1s, transform 0.5s 0s;
}
.container .box:hover .content p {
height: 80px;
transform: translateY(0);
transition: height 0.25s 0s, transform 0.4s 0.05s;
}
.container .box .content a {
display: inline-block;
font-size: 1.1em;
color: #111;
background: #fff;
padding: 10px;
border-radius: 4px;
text-decoration: none;
font-weight: 700;
margin-top: 5px;
}
@media (max-width: 1820px) {
.container .box {
height: 320px;
margin: 8px 25px;
}
.container .box::before {
left: 60px;
}
.container .box::after {
left: 60px;
}
.container .box .content {
padding: 15px 10px;
width: 250px;
}
.container .box:hover .content {
padding: 35px 20px;
left: -7.5px;
}
.container .box:hover .content h2 {
font-size: 2.1em;
letter-spacing: 3px;
}
.container .box:hover .content p {
font-size: 1em;
}
.container .box:hover:before,
.container .box:hover:after {
left: 35px;
}
}
@media (max-width: 1460px) {
.container .box {
height: 280px;
margin: 6px 14px;
}
.container .box::befor