transactions
This commit is contained in:
@@ -22,11 +22,7 @@ export class CryptoService {
|
||||
|
||||
private async fetchPublicKey(): Promise<CryptoKey> {
|
||||
try {
|
||||
const response = await axios.get(`${this.cryptoUrl}`, {
|
||||
headers: {
|
||||
'X-Thumbprint': this.thumbprintService.getThumbprint(),
|
||||
},
|
||||
});
|
||||
const response = await axios.get(`${this.cryptoUrl}`);
|
||||
|
||||
if (response.status !== 200) {
|
||||
throw new Error('Failed to fetch public key');
|
||||
@@ -39,7 +35,7 @@ export class CryptoService {
|
||||
binaryDer,
|
||||
{
|
||||
name: 'RSA-OAEP',
|
||||
hash: { name: 'SHA-256' },
|
||||
hash: 'SHA-256',
|
||||
},
|
||||
false,
|
||||
['encrypt']
|
||||
|
@@ -22,6 +22,28 @@ export class userService {
|
||||
return this.userSubject.asObservable();
|
||||
}
|
||||
|
||||
async systemLogin(
|
||||
email: string | null | undefined,
|
||||
password: string | null | undefined,
|
||||
systemKey: string | null | undefined
|
||||
) {
|
||||
if (email == null || password == null || systemKey == null) {
|
||||
return;
|
||||
}
|
||||
const encryptedPassword = this.cryptoService.encryptData(password);
|
||||
const encryptedSystemKey = this.cryptoService.encryptData(systemKey);
|
||||
const response = await axios.post('/users/login', {
|
||||
email,
|
||||
password: await encryptedPassword,
|
||||
systemKey: await encryptedSystemKey,
|
||||
});
|
||||
const { jwt, refresh, usermodel } = response.data;
|
||||
localStorage.setItem('jwt', jwt);
|
||||
localStorage.setItem('refresh', refresh);
|
||||
this.setUser(usermodel);
|
||||
return usermodel;
|
||||
}
|
||||
|
||||
async login(
|
||||
email: string | null | undefined,
|
||||
password: string | null | undefined
|
||||
@@ -40,4 +62,25 @@ export class userService {
|
||||
this.setUser(usermodel);
|
||||
return usermodel;
|
||||
}
|
||||
|
||||
async register(
|
||||
name: string | null | undefined,
|
||||
email: string | null | undefined,
|
||||
password: string | null | undefined
|
||||
): Promise<userModel> {
|
||||
if (email == null || password == null) {
|
||||
throw new Error('Email and password must not be null');
|
||||
}
|
||||
const encrypted = this.cryptoService.encryptData(password);
|
||||
const response = await axios.post('/users/register', {
|
||||
name,
|
||||
email,
|
||||
password: await encrypted,
|
||||
});
|
||||
const { jwt, refresh, usermodel } = response.data;
|
||||
localStorage.setItem('jwt', jwt);
|
||||
localStorage.setItem('refresh', refresh);
|
||||
this.setUser(usermodel);
|
||||
return usermodel;
|
||||
}
|
||||
}
|
||||
|
@@ -1 +1,29 @@
|
||||
<p>forgot-password-view works!</p>
|
||||
<div class="forgot-password-form-container">
|
||||
<h2>Recuperar contraseña</h2>
|
||||
@if(showingForm()) {
|
||||
<form class="forgot-password-form" [formGroup]="form" (ngSubmit)="onSubmit()">
|
||||
<div class="text-input effect-20" [class.has-content]="hasEmailContent()">
|
||||
<input id="email" type="email" formControlName="email" />
|
||||
<label for="email">Email</label>
|
||||
<span class="focus-border">
|
||||
<i></i>
|
||||
</span>
|
||||
</div>
|
||||
<div class="form-buttons">
|
||||
<svg-button
|
||||
label="send-reset-link"
|
||||
type="submit"
|
||||
text="Enviar enlace de restablecimiento"
|
||||
[disabled]="!form.valid"
|
||||
></svg-button>
|
||||
</div>
|
||||
</form>
|
||||
} @else{
|
||||
<div class="success-message">
|
||||
<p>
|
||||
Si existe un usuario con ese correo electrónico, se enviará un enlace para
|
||||
iniciar sesión y restablecer la contraseña.
|
||||
</p>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
|
@@ -0,0 +1,18 @@
|
||||
.forgot-password-form-container {
|
||||
max-width: 400px;
|
||||
margin: 0 auto;
|
||||
padding: 20px;
|
||||
border: 1px solid #ccc;
|
||||
border-radius: 5px;
|
||||
background-color: #fff;
|
||||
}
|
||||
|
||||
.forgot-password-form {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.form-buttons {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
|
@@ -1,11 +1,37 @@
|
||||
import { Component } from '@angular/core';
|
||||
import { Component, inject, signal } from '@angular/core';
|
||||
import { SvgButton } from '../../../utils/svg-button/svg-button';
|
||||
import { FormBuilder, ReactiveFormsModule, Validators } from '@angular/forms';
|
||||
import { emailValidator } from '../../../utils/validators/emailValidator';
|
||||
import axios from 'axios';
|
||||
|
||||
@Component({
|
||||
selector: 'forgot-password-view',
|
||||
imports: [],
|
||||
imports: [SvgButton, ReactiveFormsModule],
|
||||
templateUrl: './forgot-password-view.html',
|
||||
styleUrl: './forgot-password-view.scss'
|
||||
styleUrl: './forgot-password-view.scss',
|
||||
})
|
||||
export class ForgotPasswordView {
|
||||
private formBuilder = inject(FormBuilder);
|
||||
form = this.formBuilder.group({
|
||||
email: ['', [Validators.required, emailValidator]],
|
||||
});
|
||||
showingForm = signal(true);
|
||||
|
||||
get email() {
|
||||
return this.form.get('email');
|
||||
}
|
||||
|
||||
hasEmailContent(): boolean {
|
||||
const emailValue = this.email?.value;
|
||||
return emailValue ? emailValue.trim().length > 0 : false;
|
||||
}
|
||||
|
||||
async onSubmit() {
|
||||
if (this.form.valid) {
|
||||
this.showingForm.set(false);
|
||||
await axios.post('/users/forgot-password', {
|
||||
email: this.email?.value,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -6,7 +6,11 @@
|
||||
<h2>Acceder</h2>
|
||||
@if(submitError()) {
|
||||
<div class="error-message">{{ submitError() }}</div>
|
||||
}
|
||||
@if(showRegisterLink()) {
|
||||
<div class="register-link">
|
||||
<a href="/register">Pincha aquí para registrarte</a>
|
||||
</div>
|
||||
} }
|
||||
<form class="login-form" [formGroup]="loginForm" (ngSubmit)="onSubmit()">
|
||||
<div
|
||||
id="login-view-email-input"
|
||||
@@ -53,22 +57,36 @@
|
||||
</span>
|
||||
} }
|
||||
</div>
|
||||
} @if(isLoginSystem()) {
|
||||
<div
|
||||
id="login-view-system-key-input"
|
||||
class="text-input effect-20"
|
||||
[class.has-content]="hasSystemKeyContent()"
|
||||
>
|
||||
<input id="system-key" type="password" formControlName="systemKey" />
|
||||
<label for="system-key">System Key</label>
|
||||
<span class="focus-border">
|
||||
<i></i>
|
||||
</span>
|
||||
</div>
|
||||
}
|
||||
<svg-button
|
||||
label="login"
|
||||
type="submit"
|
||||
text="Entrar"
|
||||
ngClass="login-button"
|
||||
[disabled]="!loginForm.valid || disableLogin()"
|
||||
></svg-button>
|
||||
<svg-button
|
||||
label="forgot-password"
|
||||
type="button"
|
||||
text="¿Contraseña olvidada?"
|
||||
ngClass="forgot-password-button"
|
||||
[disabled]="!loginForm.valid"
|
||||
(click)="onForgotPassword()"
|
||||
></svg-button>
|
||||
<div class="login-buttons">
|
||||
<svg-button
|
||||
label="login"
|
||||
type="submit"
|
||||
text="Entrar"
|
||||
ngClass="login-button"
|
||||
[disabled]="!loginForm.valid || disableLogin()"
|
||||
></svg-button>
|
||||
<svg-button
|
||||
label="forgot-password"
|
||||
type="button"
|
||||
text="¿Contraseña olvidada?"
|
||||
ngClass="forgot-password-button"
|
||||
[disabled]="!loginForm.valid"
|
||||
(click)="onForgotPassword()"
|
||||
></svg-button>
|
||||
</div>
|
||||
</form>
|
||||
<div class="provider-separator">
|
||||
<span class="line"></span>
|
||||
@@ -108,6 +126,7 @@
|
||||
text="Más opciones de inicio de sesión"
|
||||
(click)="onMoreLoginOptions()"
|
||||
></svg-button>
|
||||
@if(!showRegisterLink()) {
|
||||
<svg-button
|
||||
label="register-link"
|
||||
type="button"
|
||||
@@ -115,6 +134,7 @@
|
||||
ngClass="register-link-button"
|
||||
(click)="onRegister()"
|
||||
></svg-button>
|
||||
}
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
|
@@ -7,14 +7,14 @@
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 20%;
|
||||
padding-top: 5rem;
|
||||
padding-top: 2rem;
|
||||
margin: 0 auto;
|
||||
gap: 1.5rem;
|
||||
|
||||
.login-form {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 1rem;
|
||||
gap: 1.5rem;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
@@ -46,6 +46,13 @@
|
||||
}
|
||||
}
|
||||
|
||||
.login-buttons {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 1rem;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.provider-buttons {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
|
@@ -6,7 +6,7 @@ import { Router } from '@angular/router';
|
||||
import { emailValidator } from '../../../utils/validators/emailValidator';
|
||||
import { PasswordValidator } from '../../../utils/validators/passwordValidator';
|
||||
import { emailPasswordDistinctValidator } from '../../../utils/validators/distinctEmailPasswordValidator';
|
||||
import { from, single } from 'rxjs';
|
||||
import { from } from 'rxjs';
|
||||
|
||||
@Component({
|
||||
selector: 'login-view',
|
||||
@@ -19,18 +19,20 @@ export class LoginView {
|
||||
private formBuilder = inject(FormBuilder);
|
||||
private router = inject(Router);
|
||||
private timer: any;
|
||||
private cuentaAtras: number = 30;
|
||||
private disableLogin = signal(false);
|
||||
private entrando = signal(false);
|
||||
private submitError = signal<string | null>(null);
|
||||
cuentaAtras: number = 30;
|
||||
disableLogin = signal(false);
|
||||
entrando = signal(false);
|
||||
submitError = signal<string | null>(null);
|
||||
showRegisterLink = signal(false);
|
||||
|
||||
private loginForm = this.formBuilder.group(
|
||||
loginForm = this.formBuilder.group(
|
||||
{
|
||||
email: ['', [Validators.required, emailValidator]],
|
||||
password: [
|
||||
'',
|
||||
[Validators.required, Validators.minLength(8), PasswordValidator],
|
||||
],
|
||||
systemKey: [''],
|
||||
},
|
||||
{ validators: emailPasswordDistinctValidator }
|
||||
);
|
||||
@@ -43,6 +45,10 @@ export class LoginView {
|
||||
return this.loginForm.get('password');
|
||||
}
|
||||
|
||||
get systemKey() {
|
||||
return this.loginForm.get('systemKey');
|
||||
}
|
||||
|
||||
// Métodos para verificar si los campos tienen contenido
|
||||
hasEmailContent(): boolean {
|
||||
const emailValue = this.email?.value;
|
||||
@@ -72,6 +78,19 @@ export class LoginView {
|
||||
: false;
|
||||
}
|
||||
|
||||
isLoginSystem(): boolean {
|
||||
const emailValue = this.email?.value;
|
||||
if (emailValue && emailValue == '@system') {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
hasSystemKeyContent(): boolean {
|
||||
const systemKeyValue = this.systemKey?.value;
|
||||
return systemKeyValue ? systemKeyValue.trim().length > 0 : false;
|
||||
}
|
||||
|
||||
ngOnDestroy() {
|
||||
this.submitError.set(null);
|
||||
this.limpiarTimer();
|
||||
@@ -101,10 +120,20 @@ export class LoginView {
|
||||
}
|
||||
|
||||
onSubmit() {
|
||||
if (this.loginForm.valid) {
|
||||
const email = this.loginForm.value.email;
|
||||
const password = this.loginForm.value.password;
|
||||
if (this.isLoginSystem()) {
|
||||
const systemKey = this.systemKey?.value;
|
||||
from(this.userService.systemLogin(email, password, systemKey)).subscribe({
|
||||
next: (user) => {
|
||||
this.router.navigate(['/']);
|
||||
},
|
||||
error: (error) => {
|
||||
this.router.navigate(['/']);
|
||||
},
|
||||
});
|
||||
} else if (this.loginForm.valid) {
|
||||
this.entrando.set(true);
|
||||
const email = this.loginForm.value.email;
|
||||
const password = this.loginForm.value.password;
|
||||
from(this.userService.login(email, password)).subscribe({
|
||||
next: (user) => {
|
||||
this.router.navigate(['/']);
|
||||
@@ -131,9 +160,8 @@ export class LoginView {
|
||||
'No se ha podido conectar con el servidor. Vuelva a intentarlo más tarde. Reconectando...'
|
||||
);
|
||||
} else if (error.status === 404) {
|
||||
this.submitError.set(
|
||||
'El usuario nunca ha existido. ¿Quieres registrarte?'
|
||||
);
|
||||
this.submitError.set('El usuario nunca ha existido.');
|
||||
this.showRegisterLink.set(true);
|
||||
}
|
||||
},
|
||||
});
|
||||
|
@@ -1 +1,83 @@
|
||||
<p>register-view works!</p>
|
||||
<div class="register-view">
|
||||
<form (ngSubmit)="onSubmit()" [formGroup]="form">
|
||||
<div
|
||||
id="login-view-email-input"
|
||||
class="text-input effect-20"
|
||||
[class.has-content]="hasNameContent()"
|
||||
>
|
||||
<input id="name" type="text" formControlName="name" />
|
||||
<label for="name">Name</label>
|
||||
<span class="focus-border">
|
||||
<i></i>
|
||||
</span>
|
||||
</div>
|
||||
<div
|
||||
id="login-view-email-input"
|
||||
class="text-input effect-20"
|
||||
[class.has-content]="hasEmailContent()"
|
||||
>
|
||||
<input id="email" type="email" formControlName="email" />
|
||||
<label for="email">Email</label>
|
||||
<span class="focus-border">
|
||||
<i></i>
|
||||
</span>
|
||||
</div>
|
||||
@if(emailHasErrors()) {
|
||||
<div>
|
||||
<span>* El email no es válido. </span>
|
||||
@if(this.email?.hasError('email')) {
|
||||
<span>El email no tiene un formato válido.</span>
|
||||
}
|
||||
</div>
|
||||
}
|
||||
<div
|
||||
id="login-view-password-input"
|
||||
class="text-input effect-20"
|
||||
[class.has-content]="hasPasswordContent()"
|
||||
>
|
||||
<input id="password" type="password" formControlName="password" />
|
||||
<label for="password">Password</label>
|
||||
<span class="focus-border">
|
||||
<i></i>
|
||||
</span>
|
||||
</div>
|
||||
@if(passwordHasErrors()) {
|
||||
<div>
|
||||
<span>* La contraseña no es válida. <br /></span>
|
||||
@if(this.password?.hasError('minlength')) {
|
||||
<span> Debe tener al menos 8 caracteres. </span>
|
||||
} @else { @if(this.password?.hasError('passwordContainsEmailOrLeet')) {
|
||||
<span> No puede contener trazas del email. </span>
|
||||
} @if(this.password?.hasError('invalidPassword')) {
|
||||
<span>
|
||||
No tiene un formato válido. <br />
|
||||
Tiene que contener al menos una letra mayúscula, una letra minúscula, un
|
||||
número y un carácter especial.
|
||||
</span>
|
||||
} }
|
||||
</div>
|
||||
}
|
||||
<div
|
||||
id="login-view-password-input"
|
||||
class="text-input effect-20"
|
||||
[class.has-content]="hasConfirmPasswordContent()"
|
||||
>
|
||||
<input
|
||||
id="confirm-password"
|
||||
type="password"
|
||||
formControlName="confirmPassword"
|
||||
/>
|
||||
<label for="confirm-password">Confirm Password</label>
|
||||
<span class="focus-border">
|
||||
<i></i>
|
||||
</span>
|
||||
</div>
|
||||
@if(confirmPasswordHasErrors()) {
|
||||
<div>
|
||||
<span>* Las dos contraseñas tienen que coincidir.</span>
|
||||
</div>
|
||||
}
|
||||
|
||||
<button type="submit">Submit</button>
|
||||
</form>
|
||||
</div>
|
||||
|
@@ -0,0 +1,67 @@
|
||||
.register-view {
|
||||
form {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 1rem;
|
||||
}
|
||||
|
||||
.text-input {
|
||||
position: relative;
|
||||
|
||||
input {
|
||||
width: 100%;
|
||||
padding: 0.5rem;
|
||||
border: 1px solid #ccc;
|
||||
border-radius: 4px;
|
||||
|
||||
&:focus {
|
||||
border-color: #007bff;
|
||||
outline: none;
|
||||
}
|
||||
}
|
||||
|
||||
label {
|
||||
position: absolute;
|
||||
top: 0.5rem;
|
||||
left: 0.5rem;
|
||||
transition: 0.2s;
|
||||
}
|
||||
|
||||
&.has-content {
|
||||
label {
|
||||
top: -1rem;
|
||||
left: 0.5rem;
|
||||
font-size: 0.8rem;
|
||||
color: #007bff;
|
||||
}
|
||||
}
|
||||
|
||||
.focus-border {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
height: 2px;
|
||||
background: #007bff;
|
||||
transform: scaleX(0);
|
||||
transition: transform 0.2s;
|
||||
}
|
||||
|
||||
&:focus-within .focus-border {
|
||||
transform: scaleX(1);
|
||||
}
|
||||
}
|
||||
|
||||
button[type="submit"] {
|
||||
padding: 0.5rem 1rem;
|
||||
border: none;
|
||||
border-radius: 4px;
|
||||
background: #007bff;
|
||||
color: white;
|
||||
cursor: pointer;
|
||||
|
||||
&:hover {
|
||||
background: darken(#007bff, 10%);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -1,11 +1,139 @@
|
||||
import { Component } from '@angular/core';
|
||||
import { Component, inject } from '@angular/core';
|
||||
import { FormBuilder, ReactiveFormsModule, Validators } from '@angular/forms';
|
||||
import { emailValidator } from '../../../utils/validators/emailValidator';
|
||||
import { SigningMethods, userModel } from '../../../models/userModel';
|
||||
import { emailPasswordDistinctValidator } from '../../../utils/validators/distinctEmailPasswordValidator';
|
||||
import { from } from 'rxjs';
|
||||
import { Router } from '@angular/router';
|
||||
import { userService } from '../../services/userService/userService';
|
||||
|
||||
@Component({
|
||||
selector: 'register-view',
|
||||
imports: [],
|
||||
imports: [ReactiveFormsModule],
|
||||
templateUrl: './register-view.html',
|
||||
styleUrl: './register-view.scss'
|
||||
styleUrl: './register-view.scss',
|
||||
})
|
||||
export class RegisterView {
|
||||
private userService = inject(userService);
|
||||
private formBuilder = inject(FormBuilder);
|
||||
private router = inject(Router);
|
||||
form = this.formBuilder.group(
|
||||
{
|
||||
name: ['', [Validators.required]],
|
||||
email: ['', [Validators.required, emailValidator]],
|
||||
password: ['', [Validators.required, Validators.minLength(6)]],
|
||||
confirmPassword: [''],
|
||||
// preferredSigninMethod: [SigningMethods.Password],
|
||||
// profilePicture: [null],
|
||||
// bio: ['', [Validators.maxLength(500)]],
|
||||
// socialMedia: this.formBuilder.group({
|
||||
// facebook: [''],
|
||||
// twitter: [''],
|
||||
// instagram: [''],
|
||||
// }),
|
||||
// termsAccepted: [false, [Validators.requiredTrue]],
|
||||
},
|
||||
{ validators: emailPasswordDistinctValidator }
|
||||
);
|
||||
|
||||
get name() {
|
||||
return this.form.get('name');
|
||||
}
|
||||
|
||||
get email() {
|
||||
return this.form.get('email');
|
||||
}
|
||||
|
||||
get password() {
|
||||
return this.form.get('password');
|
||||
}
|
||||
|
||||
get confirmPassword() {
|
||||
return this.form.get('confirmPassword');
|
||||
}
|
||||
|
||||
get bio() {
|
||||
return this.form.get('bio');
|
||||
}
|
||||
|
||||
get socialMedia() {
|
||||
return this.form.get('socialMedia');
|
||||
}
|
||||
|
||||
get profilePicture() {
|
||||
return this.form.get('profilePicture');
|
||||
}
|
||||
|
||||
get preferredSigninMethod() {
|
||||
return this.form.get('preferredSigninMethod');
|
||||
}
|
||||
|
||||
// getTermsAccepted() {
|
||||
// return this.form.value.termsAccepted;
|
||||
// }
|
||||
|
||||
onSubmit() {
|
||||
if (this.form.valid) {
|
||||
const email = this.form.value.email;
|
||||
const password = this.form.value.password;
|
||||
const name = this.form.value.name;
|
||||
from(this.userService.register(name, email, password)).subscribe({
|
||||
next: (user) => {
|
||||
this.router.navigate(['/']);
|
||||
},
|
||||
error: (error) => {
|
||||
console.error('Register error:', error);
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
hasNameContent(): boolean {
|
||||
const nameValue = this.name?.value;
|
||||
return nameValue ? nameValue.trim().length > 0 : false;
|
||||
}
|
||||
|
||||
hasEmailContent(): boolean {
|
||||
const emailValue = this.email?.value;
|
||||
return emailValue ? emailValue.trim().length > 0 : false;
|
||||
}
|
||||
|
||||
hasPasswordContent(): boolean {
|
||||
const passwordValue = this.password?.value;
|
||||
return passwordValue ? passwordValue.trim().length > 0 : false;
|
||||
}
|
||||
|
||||
hasConfirmPasswordContent(): boolean {
|
||||
const confirmPasswordValue = this.confirmPassword?.value;
|
||||
return confirmPasswordValue
|
||||
? confirmPasswordValue.trim().length > 0
|
||||
: false;
|
||||
}
|
||||
|
||||
emailHasErrors(): boolean {
|
||||
const emailControl = this.email;
|
||||
return emailControl
|
||||
? this.hasEmailContent() &&
|
||||
emailControl.invalid &&
|
||||
(emailControl.dirty || emailControl.touched)
|
||||
: false;
|
||||
}
|
||||
|
||||
passwordHasErrors(): boolean {
|
||||
const passwordControl = this.password;
|
||||
return passwordControl
|
||||
? this.hasPasswordContent() &&
|
||||
passwordControl.invalid &&
|
||||
(passwordControl.dirty || passwordControl.touched)
|
||||
: false;
|
||||
}
|
||||
|
||||
confirmPasswordHasErrors(): boolean {
|
||||
const confirmPasswordControl = this.confirmPassword;
|
||||
return confirmPasswordControl
|
||||
? this.hasConfirmPasswordContent() &&
|
||||
confirmPasswordControl.invalid &&
|
||||
(confirmPasswordControl.dirty || confirmPasswordControl.touched)
|
||||
: false;
|
||||
}
|
||||
}
|
||||
|
@@ -17,6 +17,7 @@ type personModelType = {
|
||||
profilePicture?: string | null;
|
||||
avatar?: string | null;
|
||||
socialMedia?: socialMediaType | null;
|
||||
bio?: string | null;
|
||||
};
|
||||
|
||||
export class personModel {
|
||||
@@ -26,18 +27,21 @@ export class personModel {
|
||||
profilePicture,
|
||||
avatar,
|
||||
socialMedia,
|
||||
bio,
|
||||
}: personModelType) {
|
||||
this.id = id;
|
||||
this.name = name;
|
||||
this.profilePicture = profilePicture || null;
|
||||
this.avatar = avatar || null;
|
||||
this.socialMedia = socialMedia || null;
|
||||
this.bio = bio || null;
|
||||
}
|
||||
|
||||
public id: string;
|
||||
public name: string;
|
||||
public profilePicture: string | null = null;
|
||||
public avatar: string | null = null;
|
||||
public bio: string | null = null;
|
||||
public socialMedia: {
|
||||
facebook: string | null;
|
||||
instagram: string | null;
|
||||
|
@@ -1,7 +1,7 @@
|
||||
import { personModel } from './personModel';
|
||||
import { roleModel } from './roleModel';
|
||||
|
||||
export enum SigningMethods {
|
||||
enum SigningMethods {
|
||||
Password = 'password',
|
||||
MagicLink = 'magic-link',
|
||||
Passkeys = 'passkeys',
|
||||
@@ -11,7 +11,7 @@ export enum SigningMethods {
|
||||
Microsoft = 'microsoft',
|
||||
}
|
||||
|
||||
export class userModel extends personModel {
|
||||
class userModel extends personModel {
|
||||
constructor(
|
||||
public override id: string,
|
||||
public email: string,
|
||||
@@ -66,3 +66,5 @@ export class userModel extends personModel {
|
||||
true
|
||||
);
|
||||
}
|
||||
|
||||
export { SigningMethods, userModel };
|
||||
|
@@ -18,10 +18,6 @@
|
||||
color: $primary-white !important;
|
||||
background-color: $disabled-color !important;
|
||||
border-color: $disabled-color !important;
|
||||
&:hover {
|
||||
transform: scale(1);
|
||||
box-shadow: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -37,13 +33,13 @@
|
||||
}
|
||||
|
||||
.register-link-button {
|
||||
color: #1565c0;
|
||||
background-color: rgba(#1565c0, 0.08);
|
||||
border-color: #1565c0;
|
||||
color: #607d8b;
|
||||
background-color: rgba(#607d8b, 0.08);
|
||||
border-color: #607d8b;
|
||||
&:hover {
|
||||
color: $primary-white;
|
||||
background-color: #1565c0;
|
||||
border-color: #1565c0;
|
||||
background-color: #607d8b;
|
||||
border-color: #607d8b;
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -6,6 +6,7 @@ $no-validated: #0603a1; // Example color for effect 20 border
|
||||
|
||||
.text-input {
|
||||
width: 100%;
|
||||
font-size: larger;
|
||||
}
|
||||
|
||||
// Contenedor para el efecto
|
||||
@@ -19,7 +20,7 @@ $no-validated: #0603a1; // Example color for effect 20 border
|
||||
background: transparent;
|
||||
color: $text-dark;
|
||||
width: 100%;
|
||||
height: 2.5rem;
|
||||
height: 2.8rem;
|
||||
padding-left: 1rem;
|
||||
box-sizing: border-box;
|
||||
font-size: 1rem;
|
||||
|
0
front/v2/src/styles/themes/dark.scss
Normal file
0
front/v2/src/styles/themes/dark.scss
Normal file
0
front/v2/src/styles/themes/light.scss
Normal file
0
front/v2/src/styles/themes/light.scss
Normal file
@@ -2,6 +2,7 @@
|
||||
@use "../../styles/variables" as *;
|
||||
|
||||
button {
|
||||
font-size: larger;
|
||||
background: $primary-white;
|
||||
border: 2px solid $standard-button-border;
|
||||
color: $standard-button-icon;
|
||||
@@ -20,6 +21,19 @@ button {
|
||||
align-items: center;
|
||||
align-content: center;
|
||||
justify-content: space-evenly;
|
||||
&:disabled {
|
||||
$disabled-color: rgba(
|
||||
$color: #999999,
|
||||
$alpha: 0.45,
|
||||
);
|
||||
color: $primary-white !important;
|
||||
background-color: $disabled-color !important;
|
||||
border-color: $disabled-color !important;
|
||||
&:hover {
|
||||
transform: scale(1);
|
||||
box-shadow: none;
|
||||
}
|
||||
}
|
||||
|
||||
label {
|
||||
text-align: center;
|
||||
|
Reference in New Issue
Block a user