all done, need to fix routing to Dashboard
This commit is contained in:
parent
11a4b0fc86
commit
ea41ebf364
|
@ -28,6 +28,7 @@
|
|||
"src/assets"
|
||||
],
|
||||
"styles": [
|
||||
"node_modules/bootstrap/dist/css/bootstrap.min.css",
|
||||
"src/styles.scss"
|
||||
],
|
||||
"scripts": []
|
||||
|
|
|
@ -0,0 +1,19 @@
|
|||
<div class="displayTable">
|
||||
<div class="displayTableCell">
|
||||
<div class="authBlock">
|
||||
<h3>Reset Password</h3>
|
||||
<p class="text-center">Please enter your email address to request a password reset.</p>
|
||||
<div class="formGroup">
|
||||
<input type="email" class="formControl" placeholder="Email Address" #passwordResetEmail required>
|
||||
</div>
|
||||
<!-- Calling ForgotPassword from AuthService Api -->
|
||||
<div class="formGroup">
|
||||
<input type="submit" class="btn btnPrimary" value="Reset Password"
|
||||
(click)="authService.ForgotPassword(passwordResetEmail.value)">
|
||||
</div>
|
||||
</div>
|
||||
<div class="redirectToLogin">
|
||||
<span>Go back to ? <span class="redirect" routerLink="/sign-in">Log In</span></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
|
@ -0,0 +1,23 @@
|
|||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { ForgotPasswordComponent } from './forgot-password.component';
|
||||
|
||||
describe('ForgotPasswordComponent', () => {
|
||||
let component: ForgotPasswordComponent;
|
||||
let fixture: ComponentFixture<ForgotPasswordComponent>;
|
||||
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
declarations: [ ForgotPasswordComponent ]
|
||||
})
|
||||
.compileComponents();
|
||||
|
||||
fixture = TestBed.createComponent(ForgotPasswordComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
16
src/app/account/forgot-password/forgot-password.component.ts
Normal file
16
src/app/account/forgot-password/forgot-password.component.ts
Normal file
|
@ -0,0 +1,16 @@
|
|||
import { Component, OnInit } from '@angular/core';
|
||||
import { AuthService } from 'src/app/services/auth.service';
|
||||
|
||||
@Component({
|
||||
selector: 'app-forgot-password',
|
||||
templateUrl: './forgot-password.component.html',
|
||||
styleUrls: ['./forgot-password.component.scss']
|
||||
})
|
||||
export class ForgotPasswordComponent implements OnInit {
|
||||
|
||||
constructor(public authService: AuthService) { }
|
||||
|
||||
ngOnInit(): void {
|
||||
}
|
||||
|
||||
}
|
34
src/app/account/sign-in/sign-in.component.html
Normal file
34
src/app/account/sign-in/sign-in.component.html
Normal file
|
@ -0,0 +1,34 @@
|
|||
<div class="displayTable">
|
||||
<div class="displayTableCell">
|
||||
<div class="authBlock">
|
||||
<h3>Sign In</h3>
|
||||
<div class="formGroup">
|
||||
<input type="text" class="formControl" placeholder="Username" #userName required>
|
||||
</div>
|
||||
<div class="formGroup">
|
||||
<input type="password" class="formControl" placeholder="Password" #userPassword required>
|
||||
</div>
|
||||
<!-- Calling SignIn Api from AuthService -->
|
||||
<div class="formGroup">
|
||||
<input type="button" class="btn btnPrimary" value="Log in"
|
||||
(click)="authService.SignIn(userName.value, userPassword.value)">
|
||||
</div>
|
||||
<div class="formGroup">
|
||||
<span class="or"><span class="orInner">Or</span></span>
|
||||
</div>
|
||||
<!-- Calling GoogleAuth Api from AuthService -->
|
||||
<div class="formGroup">
|
||||
<button type="button" class="btn googleBtn" (click)="authService.GoogleAuth()">
|
||||
<i class="fab fa-google-plus-g"></i>
|
||||
Log in with Google
|
||||
</button>
|
||||
</div>
|
||||
<div class="forgotPassword">
|
||||
<span routerLink="/forgot-password">Forgot Password?</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="redirectToLogin">
|
||||
<span>Don't have an account?<span class="redirect" routerLink="/register-user"> Sign Up</span></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
0
src/app/account/sign-in/sign-in.component.scss
Normal file
0
src/app/account/sign-in/sign-in.component.scss
Normal file
|
@ -1,18 +1,18 @@
|
|||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { HeaderComponent } from './header.component';
|
||||
import { SignInComponent } from './sign-in.component';
|
||||
|
||||
describe('HeaderComponent', () => {
|
||||
let component: HeaderComponent;
|
||||
let fixture: ComponentFixture<HeaderComponent>;
|
||||
describe('SignInComponent', () => {
|
||||
let component: SignInComponent;
|
||||
let fixture: ComponentFixture<SignInComponent>;
|
||||
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
declarations: [ HeaderComponent ]
|
||||
declarations: [ SignInComponent ]
|
||||
})
|
||||
.compileComponents();
|
||||
|
||||
fixture = TestBed.createComponent(HeaderComponent);
|
||||
fixture = TestBed.createComponent(SignInComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
16
src/app/account/sign-in/sign-in.component.ts
Normal file
16
src/app/account/sign-in/sign-in.component.ts
Normal file
|
@ -0,0 +1,16 @@
|
|||
import { Component, OnInit } from '@angular/core';
|
||||
import { AuthService } from 'src/app/services/auth.service';
|
||||
|
||||
@Component({
|
||||
selector: 'app-sign-in',
|
||||
templateUrl: './sign-in.component.html',
|
||||
styleUrls: ['./sign-in.component.scss']
|
||||
})
|
||||
export class SignInComponent implements OnInit {
|
||||
|
||||
constructor(public authService: AuthService) { }
|
||||
|
||||
ngOnInit(): void {
|
||||
}
|
||||
|
||||
}
|
31
src/app/account/sign-up/sign-up.component.html
Normal file
31
src/app/account/sign-up/sign-up.component.html
Normal file
|
@ -0,0 +1,31 @@
|
|||
<div class="displayTable">
|
||||
<div class="displayTableCell">
|
||||
<div class="authBlock">
|
||||
<h3>Sign Up</h3>
|
||||
<div class="formGroup">
|
||||
<input type="email" class="formControl" placeholder="Email Address" #userEmail required />
|
||||
</div>
|
||||
<div class="formGroup">
|
||||
<input type="password" class="formControl" placeholder="Password" #userPwd required />
|
||||
</div>
|
||||
<div class="formGroup">
|
||||
<input type="button" class="btn btnPrimary" value="Sign Up"
|
||||
(click)="authService.SignUp(userEmail.value, userPwd.value)" />
|
||||
</div>
|
||||
<div class="formGroup">
|
||||
<span class="or"><span class="orInner">Or</span></span>
|
||||
</div>
|
||||
<!-- Continue with Google -->
|
||||
<div class="formGroup">
|
||||
<button type="button" class="btn googleBtn" (click)="authService.GoogleAuth()">
|
||||
<i class="fab fa-google-plus-g"></i>
|
||||
Continue with Google
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="redirectToLogin">
|
||||
<span>Already have an account?
|
||||
<span class="redirect" routerLink="/sign-in">Log In</span></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
0
src/app/account/sign-up/sign-up.component.scss
Normal file
0
src/app/account/sign-up/sign-up.component.scss
Normal file
|
@ -1,18 +1,18 @@
|
|||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { FirebaseAuthComponent } from './firebase-auth.component';
|
||||
import { SignUpComponent } from './sign-up.component';
|
||||
|
||||
describe('FirebaseAuthComponent', () => {
|
||||
let component: FirebaseAuthComponent;
|
||||
let fixture: ComponentFixture<FirebaseAuthComponent>;
|
||||
describe('SignUpComponent', () => {
|
||||
let component: SignUpComponent;
|
||||
let fixture: ComponentFixture<SignUpComponent>;
|
||||
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
declarations: [ FirebaseAuthComponent ]
|
||||
declarations: [ SignUpComponent ]
|
||||
})
|
||||
.compileComponents();
|
||||
|
||||
fixture = TestBed.createComponent(FirebaseAuthComponent);
|
||||
fixture = TestBed.createComponent(SignUpComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
16
src/app/account/sign-up/sign-up.component.ts
Normal file
16
src/app/account/sign-up/sign-up.component.ts
Normal file
|
@ -0,0 +1,16 @@
|
|||
import { Component, OnInit } from '@angular/core';
|
||||
import { AuthService } from 'src/app/services/auth.service';
|
||||
|
||||
@Component({
|
||||
selector: 'app-sign-up',
|
||||
templateUrl: './sign-up.component.html',
|
||||
styleUrls: ['./sign-up.component.scss']
|
||||
})
|
||||
export class SignUpComponent implements OnInit {
|
||||
|
||||
constructor(public authService: AuthService) { }
|
||||
|
||||
ngOnInit(): void {
|
||||
}
|
||||
|
||||
}
|
22
src/app/account/verify-email/verify-email.component.html
Normal file
22
src/app/account/verify-email/verify-email.component.html
Normal file
|
@ -0,0 +1,22 @@
|
|||
<div class="displayTable">
|
||||
<div class="displayTableCell">
|
||||
<div class="authBlock">
|
||||
<h3>Thank You for Registering</h3>
|
||||
<div class="formGroup" *ngIf="authService.userData as user">
|
||||
<p class="text-center">We have sent a confirmation email to <strong>{{user.email}}</strong>.</p>
|
||||
<p class="text-center">Please check your email and click on the link to verfiy your email address.</p>
|
||||
</div>
|
||||
|
||||
<!-- Calling SendVerificationMail() method using authService Api -->
|
||||
<div class="formGroup">
|
||||
<button type="button" class="btn btnPrimary" (click)="authService.SendVerificationMail()">
|
||||
<i class="fas fa-redo-alt"></i>
|
||||
Resend Verification Email
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="redirectToLogin">
|
||||
<span>Go back to?<span class="redirect" routerLink="/sign-in"> Sign in</span></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
23
src/app/account/verify-email/verify-email.component.spec.ts
Normal file
23
src/app/account/verify-email/verify-email.component.spec.ts
Normal file
|
@ -0,0 +1,23 @@
|
|||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { VerifyEmailComponent } from './verify-email.component';
|
||||
|
||||
describe('VerifyEmailComponent', () => {
|
||||
let component: VerifyEmailComponent;
|
||||
let fixture: ComponentFixture<VerifyEmailComponent>;
|
||||
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
declarations: [ VerifyEmailComponent ]
|
||||
})
|
||||
.compileComponents();
|
||||
|
||||
fixture = TestBed.createComponent(VerifyEmailComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
16
src/app/account/verify-email/verify-email.component.ts
Normal file
16
src/app/account/verify-email/verify-email.component.ts
Normal file
|
@ -0,0 +1,16 @@
|
|||
import { Component, OnInit } from '@angular/core';
|
||||
import { AuthService } from 'src/app/services/auth.service';
|
||||
|
||||
@Component({
|
||||
selector: 'app-verify-email',
|
||||
templateUrl: './verify-email.component.html',
|
||||
styleUrls: ['./verify-email.component.scss']
|
||||
})
|
||||
export class VerifyEmailComponent implements OnInit {
|
||||
|
||||
constructor(public authService: AuthService) { }
|
||||
|
||||
ngOnInit(): void {
|
||||
}
|
||||
|
||||
}
|
|
@ -1,7 +1,26 @@
|
|||
import { NgModule } from '@angular/core';
|
||||
import { RouterModule, Routes } from '@angular/router';
|
||||
|
||||
const routes: Routes = [];
|
||||
//Accounting
|
||||
import { SignInComponent } from './account/sign-in/sign-in.component';
|
||||
import { SignUpComponent } from './account/sign-up/sign-up.component';
|
||||
import { ForgotPasswordComponent } from './account/forgot-password/forgot-password.component';
|
||||
import { VerifyEmailComponent } from './account/verify-email/verify-email.component';
|
||||
|
||||
//Guard
|
||||
import { AuthGuard } from './guard/auth.guard';
|
||||
|
||||
// Page
|
||||
import { DashboardComponent } from './dashboard/dashboard.component';
|
||||
|
||||
const routes: Routes = [
|
||||
{ path: '', redirectTo: '/sign-in', pathMatch: 'full' },
|
||||
{ path: 'sign-in', component: SignInComponent },
|
||||
{ path: 'register-user', component: SignUpComponent },
|
||||
{ path: 'dashboard', component: DashboardComponent, canActivate: [AuthGuard] },
|
||||
{ path: 'forgot-password', component: ForgotPasswordComponent },
|
||||
{ path: 'verify-email-address', component: VerifyEmailComponent },
|
||||
];
|
||||
|
||||
@NgModule({
|
||||
imports: [RouterModule.forRoot(routes)],
|
||||
|
|
|
@ -1,5 +1 @@
|
|||
|
||||
<app-header>dfsfs</app-header>
|
||||
|
||||
|
||||
<app-firebase-auth></app-firebase-auth>
|
||||
<router-outlet></router-outlet>
|
|
@ -8,21 +8,32 @@ import { MatButtonModule } from '@angular/material/button';
|
|||
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
|
||||
|
||||
// Firebase service
|
||||
import { FirebaseAuthComponent } from './firebase-auth/firebase-auth.component';
|
||||
import { AngularFireModule } from '@angular/fire/compat';
|
||||
import { AngularFireAuthModule } from '@angular/fire/compat/auth';
|
||||
import { AngularFireStorageModule } from '@angular/fire/compat/storage';
|
||||
import { AngularFirestoreModule } from '@angular/fire/compat/firestore';
|
||||
import { AngularFireDatabaseModule } from '@angular/fire/compat/database';
|
||||
import { environment } from '../environments/environment';
|
||||
import { AuthService } from './services/auth.service';
|
||||
|
||||
|
||||
import { SignInComponent } from './account/sign-in/sign-in.component';
|
||||
import { SignUpComponent } from './account/sign-up/sign-up.component';
|
||||
import { ForgotPasswordComponent } from './account/forgot-password/forgot-password.component';
|
||||
import { VerifyEmailComponent } from './account/verify-email/verify-email.component';
|
||||
import { DashboardComponent } from './dashboard/dashboard.component';
|
||||
|
||||
|
||||
import { HeaderComponent } from './header/header.component';
|
||||
|
||||
@NgModule({
|
||||
declarations: [
|
||||
AppComponent,
|
||||
FirebaseAuthComponent,
|
||||
HeaderComponent
|
||||
SignInComponent,
|
||||
SignUpComponent,
|
||||
ForgotPasswordComponent,
|
||||
VerifyEmailComponent,
|
||||
DashboardComponent,
|
||||
|
||||
],
|
||||
imports: [
|
||||
BrowserModule,
|
||||
|
@ -36,7 +47,7 @@ import { HeaderComponent } from './header/header.component';
|
|||
AngularFireStorageModule,
|
||||
AngularFireDatabaseModule,
|
||||
],
|
||||
providers: [],
|
||||
providers: [AuthService],
|
||||
bootstrap: [AppComponent]
|
||||
})
|
||||
export class AppModule { }
|
||||
|
|
52
src/app/dashboard/dashboard.component.html
Normal file
52
src/app/dashboard/dashboard.component.html
Normal file
|
@ -0,0 +1,52 @@
|
|||
<!-- Top navigation -->
|
||||
<nav class="navbar navbar-dark fixed-top bg-dark flex-md-nowrap p-0 shadow">
|
||||
<a class="navbar-brand col-sm-3 col-md-2 mr-0">
|
||||
<img class="brand-logo" src="assets/logo-positronx-white.svg" alt="positronX.io Logo">
|
||||
</a>
|
||||
</nav>
|
||||
<!-- Sidebar navigation -->
|
||||
<div class="container-fluid">
|
||||
<div class="row">
|
||||
<nav class="col-md-2 d-md-block bg-light sidebar">
|
||||
<div class="sidebar-sticky">
|
||||
<ul class="nav flex-column">
|
||||
<li class="nav-item">
|
||||
<a class="nav-link active">
|
||||
<i class="fas fa-user"></i>User Profile
|
||||
</a>
|
||||
</li>
|
||||
<!-- Calling SignOut() Api from AuthService -->
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" (click)="authService.SignOut()">
|
||||
<i class="fas fa-sign-out-alt"></i>Log out
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</nav>
|
||||
<!-- Main content -->
|
||||
<main role="main" class="col-md-9 ml-sm-auto col-lg-10 px-4">
|
||||
<div class="inner-adjust">
|
||||
<div class="pt-3 pb-2 mb-3 border-bottom">
|
||||
<h1 class="h2">User Profile</h1>
|
||||
</div>
|
||||
<!-- Show user data when logged in -->
|
||||
<div class="row" *ngIf="authService.userData as user">
|
||||
<div class="col-md-12">
|
||||
<div class="media">
|
||||
<img class="align-self-start mr-5 img-thumbnail rounded-circle"
|
||||
src="{{(user.photoURL) ? user.photoURL : '/assets/dummy-user.png'}}"
|
||||
alt="{{user.displayName}}">
|
||||
<div class="media-body">
|
||||
<h1>Hello: <strong>{{(user.displayName) ? user.displayName : 'User'}}</strong></h1>
|
||||
<p>User ID: <strong>{{user.uid}}</strong></p>
|
||||
<p>Email: <strong>{{user.email}}</strong></p>
|
||||
<p>Email Verified: <strong>{{user.emailVerified}}</strong></p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
</div>
|
||||
</div>
|
0
src/app/dashboard/dashboard.component.scss
Normal file
0
src/app/dashboard/dashboard.component.scss
Normal file
23
src/app/dashboard/dashboard.component.spec.ts
Normal file
23
src/app/dashboard/dashboard.component.spec.ts
Normal file
|
@ -0,0 +1,23 @@
|
|||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { DashboardComponent } from './dashboard.component';
|
||||
|
||||
describe('DashboardComponent', () => {
|
||||
let component: DashboardComponent;
|
||||
let fixture: ComponentFixture<DashboardComponent>;
|
||||
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
declarations: [ DashboardComponent ]
|
||||
})
|
||||
.compileComponents();
|
||||
|
||||
fixture = TestBed.createComponent(DashboardComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
16
src/app/dashboard/dashboard.component.ts
Normal file
16
src/app/dashboard/dashboard.component.ts
Normal file
|
@ -0,0 +1,16 @@
|
|||
import { Component, OnInit } from '@angular/core';
|
||||
import { AuthService } from '../services/auth.service';
|
||||
|
||||
@Component({
|
||||
selector: 'app-dashboard',
|
||||
templateUrl: './dashboard.component.html',
|
||||
styleUrls: ['./dashboard.component.scss']
|
||||
})
|
||||
export class DashboardComponent implements OnInit {
|
||||
|
||||
constructor(public authService: AuthService) { }
|
||||
|
||||
ngOnInit(): void {
|
||||
}
|
||||
|
||||
}
|
|
@ -1,14 +0,0 @@
|
|||
<div class="main">
|
||||
<div class="loginContainer">
|
||||
<mat-form-field class="inputField" appearance="fill">
|
||||
<mat-label>Username</mat-label>
|
||||
<input matInput>
|
||||
</mat-form-field>
|
||||
<mat-form-field class="inputField" appearance="fill">
|
||||
<mat-label>Password</mat-label>
|
||||
<input matInput>
|
||||
</mat-form-field>
|
||||
<button mat-button color="primary">Login</button>
|
||||
<button mat-button color="primary">Sign up</button>
|
||||
</div>
|
||||
</div>
|
|
@ -1,29 +0,0 @@
|
|||
.main{
|
||||
background-color: rgb(58, 104, 191);
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.loginContainer{
|
||||
background-color: cornflowerblue;
|
||||
border: 2px solid rgb(121, 120, 120);
|
||||
border-radius: 15px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
width: 50%;
|
||||
height: 50%;
|
||||
padding:20px;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.inputField{
|
||||
background-color: transparent;
|
||||
width: 80%;
|
||||
margin-bottom: 25px;
|
||||
|
||||
}
|
|
@ -1,20 +0,0 @@
|
|||
import { Component, OnInit } from '@angular/core';
|
||||
|
||||
import { getAuth, createUserWithEmailAndPassword } from "firebase/auth";
|
||||
import { initializeApp } from "firebase/app";
|
||||
import { getAnalytics } from "firebase/analytics";
|
||||
@Component({
|
||||
selector: 'app-firebase-auth',
|
||||
templateUrl: './firebase-auth.component.html',
|
||||
styleUrls: ['./firebase-auth.component.scss']
|
||||
})
|
||||
export class FirebaseAuthComponent implements OnInit {
|
||||
|
||||
constructor() {
|
||||
}
|
||||
|
||||
ngOnInit(): void {
|
||||
|
||||
}
|
||||
|
||||
}
|
16
src/app/guard/auth.guard.spec.ts
Normal file
16
src/app/guard/auth.guard.spec.ts
Normal file
|
@ -0,0 +1,16 @@
|
|||
import { TestBed } from '@angular/core/testing';
|
||||
|
||||
import { AuthGuard } from './auth.guard';
|
||||
|
||||
describe('AuthGuard', () => {
|
||||
let guard: AuthGuard;
|
||||
|
||||
beforeEach(() => {
|
||||
TestBed.configureTestingModule({});
|
||||
guard = TestBed.inject(AuthGuard);
|
||||
});
|
||||
|
||||
it('should be created', () => {
|
||||
expect(guard).toBeTruthy();
|
||||
});
|
||||
});
|
22
src/app/guard/auth.guard.ts
Normal file
22
src/app/guard/auth.guard.ts
Normal file
|
@ -0,0 +1,22 @@
|
|||
import { Injectable } from '@angular/core';
|
||||
import { ActivatedRouteSnapshot, CanActivate, RouterStateSnapshot, UrlTree, Router } from '@angular/router';
|
||||
import { Observable } from 'rxjs';
|
||||
import { AuthService } from '../services/auth.service';
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
})
|
||||
export class AuthGuard implements CanActivate {
|
||||
|
||||
constructor(public authService: AuthService, public router: Router) { }
|
||||
|
||||
canActivate(
|
||||
next: ActivatedRouteSnapshot,
|
||||
state: RouterStateSnapshot): Observable<boolean> | Promise<boolean> | boolean {
|
||||
if (this.authService.isLoggetIn !== true) {
|
||||
this.router.navigate(['sign-in'])
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
@ -1 +0,0 @@
|
|||
<p>header works!</p>
|
|
@ -1,15 +0,0 @@
|
|||
import { Component, OnInit } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'app-header',
|
||||
templateUrl: './header.component.html',
|
||||
styleUrls: ['./header.component.scss']
|
||||
})
|
||||
export class HeaderComponent implements OnInit {
|
||||
|
||||
constructor() { }
|
||||
|
||||
ngOnInit(): void {
|
||||
}
|
||||
|
||||
}
|
16
src/app/services/auth.service.spec.ts
Normal file
16
src/app/services/auth.service.spec.ts
Normal file
|
@ -0,0 +1,16 @@
|
|||
import { TestBed } from '@angular/core/testing';
|
||||
|
||||
import { AuthService } from './auth.service';
|
||||
|
||||
describe('AuthService', () => {
|
||||
let service: AuthService;
|
||||
|
||||
beforeEach(() => {
|
||||
TestBed.configureTestingModule({});
|
||||
service = TestBed.inject(AuthService);
|
||||
});
|
||||
|
||||
it('should be created', () => {
|
||||
expect(service).toBeTruthy();
|
||||
});
|
||||
});
|
129
src/app/services/auth.service.ts
Normal file
129
src/app/services/auth.service.ts
Normal file
|
@ -0,0 +1,129 @@
|
|||
import { Injectable, NgZone } from '@angular/core';
|
||||
import { AngularFireAuth } from '@angular/fire/compat/auth';
|
||||
import { AngularFirestore, AngularFirestoreDocument } from '@angular/fire/compat/firestore';
|
||||
import * as auth from 'firebase/auth';
|
||||
import { Router } from '@angular/router';
|
||||
import { User } from './user';
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
})
|
||||
export class AuthService {
|
||||
userData: any;
|
||||
|
||||
|
||||
// Inject Firestore service, Firebase auth service, NgZone service to remove outside scope warning
|
||||
constructor(public firestore: AngularFirestore, public authentication: AngularFireAuth, public router: Router, public ngZone: NgZone) {
|
||||
/* Saving user data in localstorage when
|
||||
logged in and setting up null when logged out */
|
||||
|
||||
this.authentication.authState.subscribe((user) => {
|
||||
if (user) {
|
||||
this.userData = user;
|
||||
localStorage.setItem('user', JSON.stringify(this.userData));
|
||||
JSON.parse(localStorage.getItem('user')!);
|
||||
} else {
|
||||
localStorage.setItem('user', 'null');
|
||||
JSON.parse(localStorage.getItem('user')!);
|
||||
}
|
||||
});
|
||||
}
|
||||
// Sign in with email/password
|
||||
SignIn(email: string, password: string) {
|
||||
return this.authentication
|
||||
.signInWithEmailAndPassword(email, password)
|
||||
.then((result) => {
|
||||
this.SetUserData(result.user);
|
||||
this.authentication.authState.subscribe((user) => {
|
||||
if (user) {
|
||||
this.router.navigate(['dashboard']);
|
||||
}
|
||||
});
|
||||
})
|
||||
.catch((error) => {
|
||||
window.alert(error.message);
|
||||
});
|
||||
}
|
||||
// Sign up with email/password
|
||||
SignUp(email: string, password: string) {
|
||||
return this.authentication
|
||||
.createUserWithEmailAndPassword(email, password)
|
||||
.then((result) => {
|
||||
/* Call the SendVerificaitonMail() function when new user sign
|
||||
up and returns promise */
|
||||
this.SendVerificationMail();
|
||||
this.SetUserData(result.user);
|
||||
})
|
||||
.catch((error) => {
|
||||
window.alert(error.message)
|
||||
});
|
||||
}
|
||||
|
||||
// Send email verfificaiton when new user sign up
|
||||
SendVerificationMail() {
|
||||
return this.authentication.currentUser
|
||||
.then((u: any) => u.sendEmailVerification())
|
||||
.then(() => {
|
||||
this.router.navigate(['verify-email-address']);
|
||||
});
|
||||
}
|
||||
// Reset Forggot password
|
||||
ForgotPassword(passwordResetEmail: string) {
|
||||
return this.authentication
|
||||
.sendPasswordResetEmail(passwordResetEmail)
|
||||
.then(() => {
|
||||
window.alert('Password reset mail sent, check your inbox.');
|
||||
})
|
||||
.catch((error) => {
|
||||
window.alert(error)
|
||||
});
|
||||
}
|
||||
// Returns true when user is looged in and email is verified
|
||||
get isLoggetIn(): boolean {
|
||||
const user = JSON.parse(localStorage.getItem('user')!);
|
||||
return (user !== null && user.emailVerified !== false) ? true : false;
|
||||
}
|
||||
// Sign in with Google
|
||||
GoogleAuth() {
|
||||
return this.AuthLogin(new auth.GoogleAuthProvider()).then((res: any) => {
|
||||
this.router.navigate(['dashboard']);
|
||||
});
|
||||
}
|
||||
// Auth logic to run auth providers
|
||||
AuthLogin(provider: any) {
|
||||
return this.authentication
|
||||
.signInWithPopup(provider)
|
||||
.then((result) => {
|
||||
this.router.navigate(['dashboard']);
|
||||
this.SetUserData(result.user);
|
||||
})
|
||||
.catch((error) => {
|
||||
window.alert(error);
|
||||
});
|
||||
}
|
||||
/* Setting up user data when sign in with username/password,
|
||||
sign up with username/password and sign in with social auth
|
||||
provider in Firestore database using AngularFirestore + AngularFirestoreDocument service */
|
||||
SetUserData(user: any) {
|
||||
const userRef: AngularFirestoreDocument<any> = this.firestore.doc(
|
||||
`users/${user.uid}`
|
||||
);
|
||||
const userData: User = {
|
||||
uid: user.uid,
|
||||
email: user.email,
|
||||
displayName: user.displayName,
|
||||
photoURL: user.photoURL,
|
||||
emailVerified: user.emailVerified,
|
||||
};
|
||||
return userRef.set(userData, {
|
||||
merge: true,
|
||||
});
|
||||
}
|
||||
SignOut() {
|
||||
return this.authentication.signOut().then(() => {
|
||||
localStorage.removeItem('user');
|
||||
this.router.navigate(['sign-in'])
|
||||
})
|
||||
}
|
||||
}
|
||||
|
7
src/app/services/user.ts
Normal file
7
src/app/services/user.ts
Normal file
|
@ -0,0 +1,7 @@
|
|||
export interface User {
|
||||
uid: string;
|
||||
email: string;
|
||||
displayName: string;
|
||||
photoURL: string;
|
||||
emailVerified: boolean;
|
||||
}
|
686
src/styles.scss
686
src/styles.scss
|
@ -1,39 +1,663 @@
|
|||
@import "https://use.fontawesome.com/releases/v5.5.0/css/all.css";
|
||||
|
||||
// Custom Theming for Angular Material
|
||||
// For more information: https://material.angular.io/guide/theming
|
||||
@use '@angular/material' as mat;
|
||||
// Plus imports for other components in your app.
|
||||
* {
|
||||
-webkit-box-sizing: border-box;
|
||||
-moz-box-sizing: border-box;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
// Include the common styles for Angular Material. We include this here so that you only
|
||||
// have to load a single css file for Angular Material in your app.
|
||||
// Be sure that you only ever include this mixin once!
|
||||
@include mat.core();
|
||||
html,
|
||||
body {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
font-weight: 400;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
font-family: "Poppins", sans-serif;
|
||||
}
|
||||
|
||||
// Define the palettes for your theme using the Material Design palettes available in palette.scss
|
||||
// (imported above). For each palette, you can optionally specify a default, lighter, and darker
|
||||
// hue. Available color palettes: https://material.io/design/color/
|
||||
$Angular_Firebase_Login-primary: mat.define-palette(mat.$indigo-palette);
|
||||
$Angular_Firebase_Login-accent: mat.define-palette(mat.$pink-palette, A200, A100, A400);
|
||||
.feather {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
vertical-align: text-bottom;
|
||||
}
|
||||
|
||||
// The warn palette is optional (defaults to red).
|
||||
$Angular_Firebase_Login-warn: mat.define-palette(mat.$red-palette);
|
||||
h1,
|
||||
h2,
|
||||
h3,
|
||||
h4,
|
||||
h5,
|
||||
h6 {
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
// Create the theme object. A theme consists of configurations for individual
|
||||
// theming systems such as "color" or "typography".
|
||||
$Angular_Firebase_Login-theme: mat.define-light-theme((
|
||||
color: (
|
||||
primary: $Angular_Firebase_Login-primary,
|
||||
accent: $Angular_Firebase_Login-accent,
|
||||
warn: $Angular_Firebase_Login-warn,
|
||||
)
|
||||
));
|
||||
.media-body h1 {
|
||||
font-weight: 300;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
// Include theme styles for core and each component used in your app.
|
||||
// Alternatively, you can import and @include the theme mixins for each component
|
||||
// that you are using.
|
||||
@include mat.all-component-themes($Angular_Firebase_Login-theme);
|
||||
.media-body h1 strong {
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
/* You can add global styles to this file, and also import other style files */
|
||||
.media-body p {
|
||||
margin-bottom: 10px;
|
||||
font-weight: 300;
|
||||
}
|
||||
|
||||
html, body { height: 100%; }
|
||||
body { margin: 0; font-family: Roboto, "Helvetica Neue", sans-serif; }
|
||||
.media-body p strong {
|
||||
margin-bottom: 10px;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.px-logo {
|
||||
display: block;
|
||||
clear: both;
|
||||
margin: 0 auto 20px;
|
||||
width: 220px;
|
||||
}
|
||||
|
||||
.px-logo a img {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.displayTable {
|
||||
display: table;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: #12056d;
|
||||
}
|
||||
|
||||
.displayTableCell {
|
||||
display: table-cell;
|
||||
vertical-align: middle;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
h3 {
|
||||
text-align: center;
|
||||
font-size: 22px;
|
||||
margin: 0 0 20px;
|
||||
}
|
||||
|
||||
.authBlock {
|
||||
margin: 0 auto;
|
||||
max-width: 400px;
|
||||
background: white;
|
||||
padding: 30px 40px 10px;
|
||||
overflow: hidden;
|
||||
-webkit-box-shadow: 0 0 4px 0 rgba(0, 0, 0, 0.04);
|
||||
box-shadow: 0 0 4px 0 rgba(0, 0, 0, 0.04);
|
||||
}
|
||||
|
||||
label {
|
||||
display: block;
|
||||
font-size: 13px;
|
||||
padding-bottom: 5px;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.formGroup {
|
||||
margin-bottom: 20px;
|
||||
float: left;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.formControl {
|
||||
width: 100%;
|
||||
display: block;
|
||||
padding: 15px 15px 14px;
|
||||
border: 2px solid #e7e7e7;
|
||||
outline: none;
|
||||
font-size: 15px;
|
||||
color: #444444;
|
||||
background: #fcfcfc;
|
||||
}
|
||||
|
||||
.formControl:focus {
|
||||
border: 2px solid #d3d3d6;
|
||||
}
|
||||
|
||||
input::-webkit-input-placeholder {
|
||||
color: #bbbbbb;
|
||||
}
|
||||
|
||||
input::-moz-placeholder {
|
||||
color: #bbbbbb;
|
||||
}
|
||||
|
||||
input:-ms-input-placeholder {
|
||||
color: #bbbbbb;
|
||||
}
|
||||
|
||||
input:-moz-placeholder {
|
||||
color: #bbbbbb;
|
||||
}
|
||||
|
||||
.displayTable .btn {
|
||||
width: 100%;
|
||||
border: none;
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
padding: 15px 0;
|
||||
background: #f96ea8;
|
||||
color: #ffffff;
|
||||
cursor: pointer;
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.displayTable .btn:hover {
|
||||
opacity: 0.88;
|
||||
}
|
||||
|
||||
.displayTable .btnSecondary {
|
||||
background: #eeeeee;
|
||||
color: #404040;
|
||||
}
|
||||
|
||||
.displayTable .googleBtn {
|
||||
background: #4dd5fe;
|
||||
}
|
||||
|
||||
.displayTable .facebookBtn {
|
||||
background: #4dd5fe;
|
||||
}
|
||||
|
||||
.or {
|
||||
text-align: center;
|
||||
display: block;
|
||||
color: #a0a0a0;
|
||||
background: white;
|
||||
position: relative;
|
||||
margin: 5px 0 0px;
|
||||
}
|
||||
|
||||
.orInner {
|
||||
background: white;
|
||||
display: inline-block;
|
||||
z-index: 4;
|
||||
position: relative;
|
||||
padding: 0 12px;
|
||||
}
|
||||
|
||||
.or:before {
|
||||
position: absolute;
|
||||
content: "";
|
||||
left: 0;
|
||||
top: 11px;
|
||||
width: 100%;
|
||||
height: 1px;
|
||||
background: #e2e2e2;
|
||||
}
|
||||
|
||||
.halfWidth {
|
||||
width: 48.5%;
|
||||
}
|
||||
|
||||
.left {
|
||||
float: left;
|
||||
}
|
||||
|
||||
.right {
|
||||
float: right;
|
||||
}
|
||||
|
||||
.forgotPassword {
|
||||
text-align: center;
|
||||
margin: -12px 0 15px 0;
|
||||
float: left;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.forgotPassword span {
|
||||
color: #4dd5fe;
|
||||
font-size: 14px;
|
||||
font-weight: 400;
|
||||
cursor: pointer;
|
||||
display: inline-block;
|
||||
padding-top: 20px;
|
||||
}
|
||||
|
||||
.redirectToLogin {
|
||||
padding: 15px 0 0;
|
||||
text-align: center;
|
||||
font-size: 14px;
|
||||
font-weight: 400;
|
||||
display: block;
|
||||
color: rgba(255, 255, 255, 0.6);
|
||||
}
|
||||
|
||||
.redirectToLogin .redirect {
|
||||
cursor: pointer;
|
||||
color: #ffffff;
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
/* * Sidebar */
|
||||
.sidebar {
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
z-index: 100;
|
||||
padding: 48px 0 0;
|
||||
box-shadow: inset -1px 0 0 rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.sidebar-sticky {
|
||||
position: relative;
|
||||
top: 0;
|
||||
height: calc(100vh - 48px);
|
||||
padding-top: 0.5rem;
|
||||
overflow-x: hidden;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
@supports ((position: -webkit-sticky) or (position: sticky)) {
|
||||
.sidebar-sticky {
|
||||
position: -webkit-sticky;
|
||||
position: sticky;
|
||||
}
|
||||
}
|
||||
|
||||
.sidebar .nav-link {
|
||||
font-weight: 500;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.sidebar .nav-link .feather {
|
||||
margin-right: 4px;
|
||||
color: #999;
|
||||
}
|
||||
|
||||
.sidebar-heading {
|
||||
font-size: 0.75rem;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
.nav-link {
|
||||
padding: 1.5rem 1rem;
|
||||
border-bottom: 1px solid #dde0e2;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.sidebar .nav-link.active,
|
||||
.sidebar a:hover,
|
||||
a:not([href]):not([tabindex]):focus,
|
||||
a:not([href]):not([tabindex]):hover {
|
||||
color: #e91e63;
|
||||
background: #efefef;
|
||||
}
|
||||
|
||||
/* * Content */
|
||||
[role="main"] {
|
||||
padding-top: 48px;
|
||||
}
|
||||
|
||||
.dasboard-text {
|
||||
border-left: 1px solid rgb(255, 255, 255, 0.3);
|
||||
color: rgb(255, 255, 255, 0.5);
|
||||
display: inline-block;
|
||||
padding: 0 0 0 14px;
|
||||
font-size: 15px;
|
||||
margin-left: 15px;
|
||||
position: relative;
|
||||
top: -1px;
|
||||
}
|
||||
|
||||
/* * Navbar */
|
||||
.navbar-brand {
|
||||
padding-top: 0.75rem;
|
||||
padding-bottom: 0.75rem;
|
||||
}
|
||||
|
||||
.navbar .form-control {
|
||||
padding: 0.75rem 1rem;
|
||||
border-width: 0;
|
||||
border-radius: 0;
|
||||
}
|
||||
|
||||
.form-control-dark {
|
||||
color: #fff;
|
||||
background-color: rgba(255, 255, 255, 0.1);
|
||||
border-color: rgba(255, 255, 255, 0.1);
|
||||
}
|
||||
|
||||
.form-control-dark:focus {
|
||||
border-color: transparent;
|
||||
box-shadow: 0 0 0 3px rgba(255, 255, 255, 0.25);
|
||||
}
|
||||
|
||||
.form-control:focus {
|
||||
border-color: #00bcd4;
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
.form-control {
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.bg-dark {
|
||||
background-color: #3f51b5 !important;
|
||||
}
|
||||
|
||||
.gap-right {
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
i {
|
||||
width: 22px;
|
||||
text-align: center;
|
||||
margin-right: 5px;
|
||||
}
|
||||
|
||||
.inner-adjust {
|
||||
padding: 0 20px;
|
||||
}
|
||||
|
||||
.action-block {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.action-block .fa-edit:hover {
|
||||
color: #009688;
|
||||
}
|
||||
|
||||
.action-block .fa-trash-alt:hover {
|
||||
color: #e91e63;
|
||||
}
|
||||
|
||||
.btn-primary.focus,
|
||||
.btn-primary:focus {
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
/* Pagination */
|
||||
body pagination-template {
|
||||
padding: 0;
|
||||
margin: 8px 0 0;
|
||||
float: left;
|
||||
width: 100%;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
body .ngx-pagination li:last-child {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
body .ngx-pagination .current {
|
||||
background: #055af9;
|
||||
}
|
||||
|
||||
.ngx-pagination a:hover,
|
||||
.ngx-pagination button:hover {
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
/* Error */
|
||||
.error {
|
||||
color: red;
|
||||
margin-top: 5px;
|
||||
}
|
||||
|
||||
input.ng-invalid.ng-touched {
|
||||
border: 1px solid red;
|
||||
}
|
||||
|
||||
.btn-success.disabled,
|
||||
.btn-success:disabled {
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
/* Nav */
|
||||
body .navbar {
|
||||
padding: 6px 0 !important;
|
||||
}
|
||||
|
||||
body .navbar-brand {
|
||||
background: none;
|
||||
}
|
||||
|
||||
.brand-logo {
|
||||
max-width: 85%;
|
||||
}
|
||||
|
||||
.pt-3,
|
||||
.py-3 {
|
||||
padding-top: 2.4rem !important;
|
||||
}
|
||||
|
||||
.sidebar-sticky {
|
||||
padding-top: 1.2rem !important;
|
||||
}
|
||||
|
||||
/* Form */
|
||||
label {
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.form-control {
|
||||
padding: 1.375rem 0.75rem;
|
||||
}
|
||||
|
||||
/* Misc */
|
||||
.no-data img {
|
||||
max-width: 420px;
|
||||
margin: 20px auto 0;
|
||||
}
|
||||
|
||||
.nodata-msg {
|
||||
margin: 25px 0 15px;
|
||||
font-size: 28px;
|
||||
color: #a9a6c5;
|
||||
font-weight: 300;
|
||||
letter-spacing: 0.2px;
|
||||
}
|
||||
|
||||
[role="main"] {
|
||||
padding-top: 65px;
|
||||
}
|
||||
|
||||
.preloader {
|
||||
min-height: 400px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
margin-top: -15px;
|
||||
}
|
||||
|
||||
.custom-text {
|
||||
font-size: 15px;
|
||||
color: #5f5f5f;
|
||||
letter-spacing: 0.2px;
|
||||
}
|
||||
|
||||
.navbar-dark .navbar-brand {
|
||||
margin-left: 6px;
|
||||
}
|
||||
|
||||
.custom-text strong {
|
||||
color: #3a3a3a;
|
||||
}
|
||||
|
||||
.mb-3,
|
||||
.my-3 {
|
||||
margin-bottom: 1.4rem !important;
|
||||
}
|
||||
|
||||
.custom-fa-plus {
|
||||
margin: 0;
|
||||
width: auto;
|
||||
}
|
||||
|
||||
.user-image {
|
||||
width: 42px;
|
||||
height: 42px;
|
||||
display: inline-block;
|
||||
border-radius: 50%;
|
||||
vertical-align: middle;
|
||||
margin-right: 7px;
|
||||
background-size: cover;
|
||||
background-repeat: no-repeat;
|
||||
background-position: 0 0;
|
||||
}
|
||||
|
||||
body .table thead th {
|
||||
background: #f3f5ff;
|
||||
}
|
||||
|
||||
.pricing-header {
|
||||
padding-bottom: 50px;
|
||||
}
|
||||
|
||||
.userImage {
|
||||
max-width: 125px;
|
||||
}
|
||||
|
||||
.navbar-dark .navbar-nav .nav-link {
|
||||
color: rgba(255, 255, 255, 1);
|
||||
}
|
||||
|
||||
.card {
|
||||
border: none;
|
||||
}
|
||||
|
||||
.list-group-item {
|
||||
padding: 0 1.25rem 15px;
|
||||
border: none;
|
||||
}
|
||||
|
||||
.fa-sign-out-alt {
|
||||
position: relative;
|
||||
top: 1px;
|
||||
}
|
||||
|
||||
.logOutBtn {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.no-access {
|
||||
text-align: center;
|
||||
font-size: 26px;
|
||||
padding: 70px 0;
|
||||
}
|
||||
|
||||
.rounded-circle {
|
||||
max-width: 150px;
|
||||
}
|
||||
|
||||
/* Responsive */
|
||||
@media (max-width: 767px) {
|
||||
.sidebar {
|
||||
position: static;
|
||||
padding: 40px 0 10px;
|
||||
height: auto;
|
||||
}
|
||||
|
||||
[role="main"] {
|
||||
padding-top: 0;
|
||||
}
|
||||
|
||||
.inner-adjust {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
ul.nav.flex-column {
|
||||
flex-direction: inherit !important;
|
||||
}
|
||||
|
||||
.pt-3,
|
||||
.py-3 {
|
||||
padding-top: 1.5rem !important;
|
||||
}
|
||||
|
||||
.brand-logo {
|
||||
max-width: 175px;
|
||||
margin: 0 auto;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.dasboard-text {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
.sidebar-sticky {
|
||||
padding-top: 1.9rem !important;
|
||||
height: auto;
|
||||
}
|
||||
|
||||
.sidebar-sticky .nav li {
|
||||
width: 50%;
|
||||
text-align: center;
|
||||
border-right: 1px solid #c7ceff;
|
||||
}
|
||||
|
||||
.sidebar-sticky .nav li:last-child {
|
||||
border: none;
|
||||
}
|
||||
|
||||
.no-data img {
|
||||
max-width: 100%;
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
.nodata-msg,
|
||||
.h2,
|
||||
h2 {
|
||||
font-size: 1.4rem;
|
||||
}
|
||||
|
||||
.custom-text {
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.navbar-nav {
|
||||
float: right;
|
||||
width: 50%;
|
||||
text-align: right;
|
||||
display: inherit;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.navbar-dark .navbar-brand {
|
||||
margin: 0;
|
||||
width: 50%;
|
||||
float: left;
|
||||
display: inherit;
|
||||
}
|
||||
|
||||
.sidebar {
|
||||
padding: 40px 0 0;
|
||||
}
|
||||
|
||||
footer br {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.media {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.rounded-circle {
|
||||
max-width: 150px;
|
||||
margin: 0 auto 20px !important;
|
||||
display: block;
|
||||
}
|
||||
|
||||
b,
|
||||
strong {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.displayTable {
|
||||
background: white;
|
||||
}
|
||||
|
||||
.authBlock {
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
.px-logo {
|
||||
display: none;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user