FrontEnd Angular - v0.0.1-alpha
This commit is contained in:
67
src/app/header/header-dropdown/header-dropdown.component.css
Normal file
67
src/app/header/header-dropdown/header-dropdown.component.css
Normal file
@@ -0,0 +1,67 @@
|
||||
.dropdown {
|
||||
width: 180px;
|
||||
border-radius: 8px;
|
||||
background-color: #ffffff;
|
||||
border: 1px solid rgba(46, 46, 46, .3);
|
||||
box-sizing: 0 5px 25px rgba(0, 0, 0, 0.1);
|
||||
box-shadow: 1px 1px 4px 1px rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
|
||||
.dropdown:before {
|
||||
content: '';
|
||||
width: 15px;
|
||||
height: 15px;
|
||||
position: absolute;
|
||||
background-color: #ffffff;
|
||||
border-top: 1px solid rgba(46, 46, 46, .3);
|
||||
border-left: 1px solid rgba(46, 46, 46, .3);
|
||||
transform: translateX(120px) translateY(-50%) rotate(45deg);
|
||||
}
|
||||
|
||||
.info h3{
|
||||
height: 50px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
margin: 0;
|
||||
font-size: 20px;
|
||||
font-weight: 400;
|
||||
color: #555555;
|
||||
}
|
||||
|
||||
.user-management {
|
||||
padding: 0;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.dropdown-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 8px 30px;
|
||||
border-top: 1px solid rgba(0, 0, 0, 0.05);
|
||||
}
|
||||
|
||||
.dropdown-item .icon-box {
|
||||
width: 22px;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.dropdown-item .icon-box fa-icon {
|
||||
color: #919294;
|
||||
font-size: 20px;
|
||||
}
|
||||
|
||||
.dropdown-item:hover .icon-box fa-icon {
|
||||
opacity: 1;
|
||||
color: #f44336;
|
||||
transition: .5s;
|
||||
}
|
||||
|
||||
.dropdown-item p {
|
||||
color: #555555;
|
||||
font-family: 'Montserrat', sans-serif;
|
||||
font-weight: 400;
|
||||
text-decoration: none;
|
||||
padding-left: 10px;
|
||||
margin: 0;
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
<div
|
||||
class="dropdown"
|
||||
appClickedOutside
|
||||
(clickOutside)="onClickedOutside()"
|
||||
[includeClickedOutside]="[management]"
|
||||
[ignoreElementList]="ignoreClickOutside"
|
||||
[@dropdownState]="dropDownState"
|
||||
(@dropdownState.start)="$event.element.style.display = 'block'"
|
||||
(@dropdownState.done)="$event.element.style.display = (state ? 'block' : 'none')">
|
||||
<div class="info">
|
||||
<h3>{{ this.user ? this.user.username : 'User Account' }}</h3>
|
||||
</div>
|
||||
<div #management>
|
||||
<ul class="user-management" *ngIf="!this.user">
|
||||
<li class="dropdown-item" (click)="onLoginOptionClicked()">
|
||||
<div class="icon-box">
|
||||
<fa-icon class="fas fa-user" [icon]="userIcon"></fa-icon>
|
||||
</div>
|
||||
<p>Login</p>
|
||||
</li>
|
||||
<li class="dropdown-item" (click)="onSignUpOptionClick()">
|
||||
<div class="icon-box">
|
||||
<fa-icon class="fas fa-edit" [icon]="editIcon"></fa-icon>
|
||||
</div>
|
||||
<p>Sign up</p>
|
||||
</li>
|
||||
</ul>
|
||||
<ul class="user-management" *ngIf="this.user">
|
||||
<li class="dropdown-item">
|
||||
<div class="icon-box">
|
||||
<fa-icon class="fas fa-user" [icon]="userIcon"></fa-icon>
|
||||
</div>
|
||||
<p>My Profile</p>
|
||||
</li>
|
||||
<li class="dropdown-item">
|
||||
<div class="icon-box">
|
||||
<fa-icon class="fas fa-question-circle" [icon]="questionCircleIcon"></fa-icon>
|
||||
</div>
|
||||
<p>Help</p>
|
||||
</li>
|
||||
<li class="dropdown-item" (click)="onLogout()">
|
||||
<div class="icon-box">
|
||||
<fa-icon class="fas fa-sign-out-alt" [icon]="signOutAltIcon"></fa-icon>
|
||||
</div>
|
||||
<p>Logout</p>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
@@ -0,0 +1,23 @@
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { HeaderDropdownComponent } from './header-dropdown.component';
|
||||
|
||||
describe('HeaderDropdownComponent', () => {
|
||||
let component: HeaderDropdownComponent;
|
||||
let fixture: ComponentFixture<HeaderDropdownComponent>;
|
||||
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
declarations: [ HeaderDropdownComponent ]
|
||||
})
|
||||
.compileComponents();
|
||||
|
||||
fixture = TestBed.createComponent(HeaderDropdownComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
||||
93
src/app/header/header-dropdown/header-dropdown.component.ts
Normal file
93
src/app/header/header-dropdown/header-dropdown.component.ts
Normal file
@@ -0,0 +1,93 @@
|
||||
import { animate, state, style, transition, trigger } from '@angular/animations';
|
||||
import { Component, EventEmitter, Input, OnDestroy, OnInit, Output } from '@angular/core';
|
||||
import { faEdit, faQuestionCircle, faSignOutAlt, faUser } from '@fortawesome/free-solid-svg-icons';
|
||||
import { Subscription, timeout } from 'rxjs';
|
||||
import { AuthService } from 'src/app/shared/auth/auth.service';
|
||||
import UserChecker from 'src/app/shared/model/user/user.checker';
|
||||
import { User } from 'src/app/shared/model/user/user.model';
|
||||
|
||||
@Component({
|
||||
selector: 'app-header-dropdown',
|
||||
templateUrl: './header-dropdown.component.html',
|
||||
styleUrls: ['./header-dropdown.component.css'],
|
||||
animations: [
|
||||
trigger('dropdownState', [
|
||||
state('hide', style({
|
||||
'opacity': '0'
|
||||
})),
|
||||
state('show', style({
|
||||
'opacity': '1'
|
||||
})),
|
||||
transition('hide => show', animate('20ms ease-in')),
|
||||
transition('show => hide', animate('5ms ease-out'))
|
||||
])
|
||||
]
|
||||
})
|
||||
export class HeaderDropdownComponent implements OnInit, OnDestroy {
|
||||
|
||||
userIcon = faUser;
|
||||
|
||||
editIcon = faEdit;
|
||||
|
||||
questionCircleIcon = faQuestionCircle;
|
||||
|
||||
signOutAltIcon = faSignOutAlt;
|
||||
|
||||
user!: User | null;
|
||||
|
||||
private userSubscription!: Subscription;
|
||||
|
||||
@Input()
|
||||
state: boolean = false;
|
||||
|
||||
@Input()
|
||||
ignoreClickOutside!: HTMLDivElement[];
|
||||
|
||||
@Output()
|
||||
clickOutside = new EventEmitter();
|
||||
|
||||
@Output()
|
||||
loginPopupState: EventEmitter<boolean> = new EventEmitter();
|
||||
|
||||
@Output()
|
||||
signupPopupState: EventEmitter<boolean> = new EventEmitter();
|
||||
|
||||
constructor(private authService: AuthService) { }
|
||||
|
||||
ngOnInit(): void {
|
||||
this.userSubscription = this.authService.authSubject.subscribe(
|
||||
res => {
|
||||
if (res && UserChecker.test(res)) {
|
||||
this.user = <User>res;
|
||||
} else {
|
||||
this.user = null;
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
ngOnDestroy(): void {
|
||||
this.userSubscription.unsubscribe();
|
||||
}
|
||||
|
||||
get dropDownState() {
|
||||
return this.state ? 'show' : 'hide';
|
||||
}
|
||||
|
||||
onClickedOutside() {
|
||||
this.clickOutside.emit();
|
||||
}
|
||||
|
||||
onLoginOptionClicked() {
|
||||
this.loginPopupState.emit(true);
|
||||
}
|
||||
|
||||
onSignUpOptionClick() {
|
||||
this.signupPopupState.emit(true);
|
||||
}
|
||||
|
||||
onLogout() {
|
||||
this.authService.logout();
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user