initial
This commit is contained in:
2
idp_client/src/app/app.component.html
Normal file
2
idp_client/src/app/app.component.html
Normal file
@@ -0,0 +1,2 @@
|
||||
<router-outlet></router-outlet>
|
||||
iodsuj
|
||||
0
idp_client/src/app/app.component.scss
Normal file
0
idp_client/src/app/app.component.scss
Normal file
29
idp_client/src/app/app.component.spec.ts
Normal file
29
idp_client/src/app/app.component.spec.ts
Normal file
@@ -0,0 +1,29 @@
|
||||
import { TestBed } from '@angular/core/testing';
|
||||
import { AppComponent } from './app.component';
|
||||
|
||||
describe('AppComponent', () => {
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
imports: [AppComponent],
|
||||
}).compileComponents();
|
||||
});
|
||||
|
||||
it('should create the app', () => {
|
||||
const fixture = TestBed.createComponent(AppComponent);
|
||||
const app = fixture.componentInstance;
|
||||
expect(app).toBeTruthy();
|
||||
});
|
||||
|
||||
it(`should have the 'idp_client' title`, () => {
|
||||
const fixture = TestBed.createComponent(AppComponent);
|
||||
const app = fixture.componentInstance;
|
||||
expect(app.title).toEqual('idp_client');
|
||||
});
|
||||
|
||||
it('should render title', () => {
|
||||
const fixture = TestBed.createComponent(AppComponent);
|
||||
fixture.detectChanges();
|
||||
const compiled = fixture.nativeElement as HTMLElement;
|
||||
expect(compiled.querySelector('h1')?.textContent).toContain('Hello, idp_client');
|
||||
});
|
||||
});
|
||||
13
idp_client/src/app/app.component.ts
Normal file
13
idp_client/src/app/app.component.ts
Normal file
@@ -0,0 +1,13 @@
|
||||
import { Component } from '@angular/core';
|
||||
import { RouterOutlet } from '@angular/router';
|
||||
|
||||
@Component({
|
||||
selector: 'app-root',
|
||||
standalone: true,
|
||||
imports: [RouterOutlet],
|
||||
templateUrl: './app.component.html',
|
||||
styleUrl: './app.component.scss'
|
||||
})
|
||||
export class AppComponent {
|
||||
title = 'idp_client';
|
||||
}
|
||||
10
idp_client/src/app/app.config.ts
Normal file
10
idp_client/src/app/app.config.ts
Normal file
@@ -0,0 +1,10 @@
|
||||
import { ApplicationConfig, provideZoneChangeDetection } from '@angular/core';
|
||||
import { provideRouter } from '@angular/router';
|
||||
|
||||
import { routes } from './app.routes';
|
||||
import { provideHttpClient } from '@angular/common/http';
|
||||
import { provideHotToastConfig } from '@ngxpert/hot-toast';
|
||||
|
||||
export const appConfig: ApplicationConfig = {
|
||||
providers: [provideZoneChangeDetection({ eventCoalescing: true }), provideRouter(routes), provideHttpClient(), provideHotToastConfig(),]
|
||||
};
|
||||
6
idp_client/src/app/app.routes.ts
Normal file
6
idp_client/src/app/app.routes.ts
Normal file
@@ -0,0 +1,6 @@
|
||||
import { Routes } from '@angular/router';
|
||||
import { LoginComponent } from './login/login.component';
|
||||
|
||||
export const routes: Routes = [
|
||||
{ path: 'login', component: LoginComponent },
|
||||
];
|
||||
27
idp_client/src/app/login/login.component.html
Normal file
27
idp_client/src/app/login/login.component.html
Normal file
@@ -0,0 +1,27 @@
|
||||
<div class="container">
|
||||
<div class="screen">
|
||||
<div class="screen__content">
|
||||
<h1>{{ client }}</h1>
|
||||
<form class="login" [formGroup]="loginForm" >
|
||||
<div class="login__field">
|
||||
<i class="login__icon fas fa-user user"></i>
|
||||
<input formControlName="username" type="text" class="login__input" placeholder="User name / Email">
|
||||
</div>
|
||||
<div class="login__field">
|
||||
<i class="login__icon fas fa-lock safe"></i>
|
||||
<input type="password" formControlName="password" class="login__input" placeholder="Password">
|
||||
</div>
|
||||
<button class="button login__submit" (click)="login()">
|
||||
<span class="button__text">Log In Now</span>
|
||||
<i class="button__icon fas fa-chevron-right"></i>
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
<div class="screen__background">
|
||||
<span class="screen__background__shape screen__background__shape4"></span>
|
||||
<span class="screen__background__shape screen__background__shape3"></span>
|
||||
<span class="screen__background__shape screen__background__shape2"></span>
|
||||
<span class="screen__background__shape screen__background__shape1"></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
187
idp_client/src/app/login/login.component.scss
Normal file
187
idp_client/src/app/login/login.component.scss
Normal file
@@ -0,0 +1,187 @@
|
||||
// @import url('https://fonts.googleapis.com/css?family=Raleway:400,700');
|
||||
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
font-family: Raleway, sans-serif;
|
||||
}
|
||||
h1 {
|
||||
margin-top: 24px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
body {
|
||||
background: linear-gradient(90deg, #C7C5F4, #5a5a5c);
|
||||
// background: linear-gradient(90deg, #C7C5F4, #776BCC);
|
||||
}
|
||||
|
||||
.container {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: 100vh;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.screen {
|
||||
background: linear-gradient(90deg, #303033, #9c9ca3);
|
||||
position: relative;
|
||||
height: 600px;
|
||||
width: 360px;
|
||||
box-shadow: 0px 0px 24px #8b8b8f;
|
||||
}
|
||||
|
||||
.screen__content {
|
||||
z-index: 1;
|
||||
position: relative;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.screen__background {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
z-index: 0;
|
||||
-webkit-clip-path: inset(0 0 0 0);
|
||||
clip-path: inset(0 0 0 0);
|
||||
}
|
||||
|
||||
.screen__background__shape {
|
||||
transform: rotate(45deg);
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
.screen__background__shape1 {
|
||||
height: 520px;
|
||||
width: 520px;
|
||||
background: #FFF;
|
||||
top: -50px;
|
||||
right: 120px;
|
||||
border-radius: 0 72px 0 0;
|
||||
}
|
||||
|
||||
.screen__background__shape2 {
|
||||
height: 220px;
|
||||
width: 220px;
|
||||
background: #6C63AC;
|
||||
top: -172px;
|
||||
right: 0;
|
||||
border-radius: 32px;
|
||||
}
|
||||
|
||||
.screen__background__shape3 {
|
||||
height: 540px;
|
||||
width: 190px;
|
||||
background: linear-gradient(270deg, #5D54A4, #6A679E);
|
||||
top: -24px;
|
||||
right: 0;
|
||||
border-radius: 32px;
|
||||
}
|
||||
|
||||
.screen__background__shape4 {
|
||||
height: 400px;
|
||||
width: 200px;
|
||||
background: #7E7BB9;
|
||||
top: 420px;
|
||||
right: 50px;
|
||||
border-radius: 60px;
|
||||
}
|
||||
|
||||
.login {
|
||||
width: 320px;
|
||||
padding: 30px;
|
||||
padding-top: 100px;
|
||||
}
|
||||
|
||||
.login__field {
|
||||
padding: 20px 0px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.login__icon {
|
||||
position: absolute;
|
||||
top: 22px;
|
||||
color: #7875B5;
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
left: 4px;
|
||||
}
|
||||
|
||||
.login__input {
|
||||
border: none;
|
||||
border-bottom: 2px solid #D1D1D4;
|
||||
background: none;
|
||||
padding: 10px;
|
||||
padding-left: 36px;
|
||||
font-weight: 700;
|
||||
width: 85%;
|
||||
transition: .2s;
|
||||
}
|
||||
|
||||
.login__input:active,
|
||||
.login__input:focus,
|
||||
.login__input:hover {
|
||||
outline: none;
|
||||
border-bottom-color: #6A679E;
|
||||
}
|
||||
|
||||
.login__submit {
|
||||
background: #fff;
|
||||
font-size: 14px;
|
||||
margin-top: 30px;
|
||||
padding: 16px 20px;
|
||||
border-radius: 26px;
|
||||
border: 1px solid #D4D3E8;
|
||||
text-transform: uppercase;
|
||||
font-weight: 700;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
width: 100%;
|
||||
color: #4C489D;
|
||||
box-shadow: 0px 2px 2px #5C5696;
|
||||
cursor: pointer;
|
||||
transition: .2s;
|
||||
}
|
||||
|
||||
.login__submit:active,
|
||||
.login__submit:focus,
|
||||
.login__submit:hover {
|
||||
border-color: #6A679E;
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.button__icon {
|
||||
font-size: 24px;
|
||||
margin-left: auto;
|
||||
color: #7875B5;
|
||||
}
|
||||
|
||||
.social-login {
|
||||
position: absolute;
|
||||
height: 140px;
|
||||
width: 160px;
|
||||
text-align: center;
|
||||
bottom: 0px;
|
||||
right: 0px;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.social-icons {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.social-login__icon {
|
||||
padding: 20px 10px;
|
||||
color: #fff;
|
||||
text-decoration: none;
|
||||
text-shadow: 0px 0px 8px #7875B5;
|
||||
}
|
||||
|
||||
.social-login__icon:hover {
|
||||
transform: scale(1.5);
|
||||
}
|
||||
23
idp_client/src/app/login/login.component.spec.ts
Normal file
23
idp_client/src/app/login/login.component.spec.ts
Normal file
@@ -0,0 +1,23 @@
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { LoginComponent } from './login.component';
|
||||
|
||||
describe('LoginComponent', () => {
|
||||
let component: LoginComponent;
|
||||
let fixture: ComponentFixture<LoginComponent>;
|
||||
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
imports: [LoginComponent]
|
||||
})
|
||||
.compileComponents();
|
||||
|
||||
fixture = TestBed.createComponent(LoginComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
||||
70
idp_client/src/app/login/login.component.ts
Normal file
70
idp_client/src/app/login/login.component.ts
Normal file
@@ -0,0 +1,70 @@
|
||||
import { HttpClient } from '@angular/common/http';
|
||||
import { Component, inject } from '@angular/core';
|
||||
import { ActivatedRoute } from '@angular/router';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { FormControl, FormGroup, FormsModule, ReactiveFormsModule } from '@angular/forms';
|
||||
import { environment } from '../../environments/environment';
|
||||
import { HotToastService } from '@ngxpert/hot-toast';
|
||||
|
||||
@Component({
|
||||
selector: 'app-login',
|
||||
standalone: true,
|
||||
imports: [CommonModule, FormsModule, ReactiveFormsModule],
|
||||
templateUrl: './login.component.html',
|
||||
styleUrl: './login.component.scss'
|
||||
})
|
||||
export class LoginComponent {
|
||||
private http: HttpClient = inject(HttpClient);
|
||||
private route: ActivatedRoute = inject(ActivatedRoute);
|
||||
private toast: HotToastService = inject(HotToastService);
|
||||
|
||||
redirectUri = null;
|
||||
client: string = "";
|
||||
client_id = null;
|
||||
|
||||
loginForm = new FormGroup({
|
||||
username: new FormControl(''),
|
||||
password: new FormControl(''),
|
||||
})
|
||||
|
||||
constructor() {
|
||||
this.getclient();
|
||||
}
|
||||
|
||||
|
||||
getclient() {
|
||||
const params = (this.route.snapshot.queryParamMap as any)["params"];
|
||||
this.redirectUri = params.redirect_uri;
|
||||
this.client_id = params.client_id;
|
||||
this.route.snapshot.queryParamMap.keys.forEach((key) => {
|
||||
console.log(key, this.route.snapshot.queryParamMap.get(key));
|
||||
});
|
||||
|
||||
this.http.get<any>(environment.api_url + 'auth/', {
|
||||
params
|
||||
}).subscribe({
|
||||
next: (client) => {
|
||||
console.log(client)
|
||||
this.client = client.clientName;
|
||||
},
|
||||
error: (error) => {
|
||||
console.error(error);
|
||||
this.toast.error('Invalid client');
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
login() {
|
||||
this.http.post(environment.api_url + 'auth/login?'+ 'client_id=' + this.client_id, this.loginForm.value).subscribe({
|
||||
next: (data) => {
|
||||
if (data["code"] != null) {
|
||||
location.href = this.redirectUri + "?code=" + data["code"];
|
||||
}
|
||||
},
|
||||
error: (error) => {
|
||||
console.error(error);
|
||||
this.toast.error('Invalid login');
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user