chore: updates angular to v20
This commit is contained in:
@@ -9,6 +9,7 @@ import {CookieConsertService} from './shared/cookie-consent/cookie-consert.servi
|
||||
selector: 'app-root',
|
||||
templateUrl: './app.component.html',
|
||||
styleUrls: ['./app.component.css'],
|
||||
standalone: false
|
||||
})
|
||||
export class AppComponent implements OnInit {
|
||||
title = 'frontend-hideyoshi.com';
|
||||
|
||||
@@ -5,6 +5,7 @@ import {faGithub, faLinkedinIn, faTwitter,} from '@fortawesome/free-brands-svg-i
|
||||
selector: 'app-footer',
|
||||
templateUrl: './footer.component.html',
|
||||
styleUrls: ['./footer.component.css'],
|
||||
standalone: false
|
||||
})
|
||||
export class FooterComponent {
|
||||
_githubIcon = faGithub;
|
||||
|
||||
@@ -1,36 +1,44 @@
|
||||
<div
|
||||
class="dropdown"
|
||||
appClickedOutside
|
||||
(clickOutside)="onClickedOutside()"
|
||||
[includeClickedOutside]="[management]"
|
||||
[ignoreElementList]="ignoreClickOutside"
|
||||
[@dropdownState]="dropDownState"
|
||||
(@dropdownState.start)="$event.element.style.display = 'block'"
|
||||
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 *ngFor="let option of mainOptions"
|
||||
class="dropdown-item" (click)=option.callback()>
|
||||
<div class="icon-box">
|
||||
<fa-icon [icon]="option.icon"></fa-icon>
|
||||
</div>
|
||||
<p>{{option.text}}</p>
|
||||
</li>
|
||||
</ul>
|
||||
<ul class="user-management" *ngIf="this.user">
|
||||
<li *ngFor="let option of userOptions"
|
||||
class="dropdown-item" (click)=option.callback()>
|
||||
<div class="icon-box">
|
||||
<fa-icon [icon]="option.icon"></fa-icon>
|
||||
</div>
|
||||
<p>{{option.text}}</p>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
>
|
||||
<div class="info">
|
||||
<h3>{{ this.user ? this.user.username : "User Account" }}</h3>
|
||||
</div>
|
||||
<div #management>
|
||||
@if (!this.user) {
|
||||
<ul class="user-management">
|
||||
@for (option of mainOptions; track option) {
|
||||
<li
|
||||
class="dropdown-item" (click)=option.callback()>
|
||||
<div class="icon-box">
|
||||
<fa-icon [icon]="option.icon"></fa-icon>
|
||||
</div>
|
||||
<p>{{option.text}}</p>
|
||||
</li>
|
||||
}
|
||||
</ul>
|
||||
}
|
||||
@if (this.user) {
|
||||
<ul class="user-management">
|
||||
@for (option of userOptions; track option) {
|
||||
<li
|
||||
class="dropdown-item" (click)=option.callback()>
|
||||
<div class="icon-box">
|
||||
<fa-icon [icon]="option.icon"></fa-icon>
|
||||
</div>
|
||||
<p>{{option.text}}</p>
|
||||
</li>
|
||||
}
|
||||
</ul>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -13,22 +13,17 @@ import {Value} from "@sinclair/typebox/value";
|
||||
styleUrls: ['./header-dropdown.component.css'],
|
||||
animations: [
|
||||
trigger('dropdownState', [
|
||||
state(
|
||||
'hide',
|
||||
style({
|
||||
opacity: '0',
|
||||
}),
|
||||
),
|
||||
state(
|
||||
'show',
|
||||
style({
|
||||
opacity: '1',
|
||||
}),
|
||||
),
|
||||
state('hide', style({
|
||||
opacity: '0',
|
||||
})),
|
||||
state('show', style({
|
||||
opacity: '1',
|
||||
})),
|
||||
transition('hide => show', animate('20ms ease-in')),
|
||||
transition('show => hide', animate('5ms ease-out')),
|
||||
]),
|
||||
],
|
||||
standalone: false
|
||||
})
|
||||
export class HeaderDropdownComponent implements OnInit, OnDestroy {
|
||||
mainOptions: { text: string, icon: IconDefinition, callback: () => void }[] = [
|
||||
|
||||
@@ -6,6 +6,7 @@ import {AuthService} from 'src/app/shared/service/auth.service';
|
||||
selector: 'app-callback',
|
||||
templateUrl: './callback.component.html',
|
||||
styleUrls: ['./callback.component.css'],
|
||||
standalone: false
|
||||
})
|
||||
export class CallbackComponent implements OnInit {
|
||||
constructor(
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
<div class="error-box" *ngIf="errorMessage">
|
||||
@if (errorMessage) {
|
||||
<div class="error-box">
|
||||
{{ errorMessage }}
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ import {Component, Input} from '@angular/core';
|
||||
selector: 'app-error-box',
|
||||
templateUrl: './error-box.component.html',
|
||||
styleUrls: ['./error-box.component.css'],
|
||||
standalone: false
|
||||
})
|
||||
export class ErrorBoxComponent {
|
||||
@Input()
|
||||
|
||||
@@ -4,6 +4,7 @@ import {Component, EventEmitter, Input, Output} from '@angular/core';
|
||||
selector: 'app-help',
|
||||
templateUrl: './help.component.html',
|
||||
styleUrls: ['./help.component.css'],
|
||||
standalone: false
|
||||
})
|
||||
export class HelpComponent {
|
||||
@Input()
|
||||
|
||||
@@ -1,96 +1,98 @@
|
||||
<app-popup
|
||||
[state]="state"
|
||||
(stateChange)="onStateChange($event)"
|
||||
[ignoreClickOutside]="ignoreClickOutside"
|
||||
>
|
||||
<div
|
||||
class="container m-0 overflow-hidden"
|
||||
[@resizeContainerForErrorMessage]="hideErrorMessage()"
|
||||
[state]="state"
|
||||
(stateChange)="onStateChange($event)"
|
||||
[ignoreClickOutside]="ignoreClickOutside"
|
||||
>
|
||||
<div
|
||||
class="container m-0 overflow-hidden"
|
||||
[@resizeContainerForErrorMessage]="hideErrorMessage()"
|
||||
>
|
||||
<app-error-box
|
||||
[errorMessage]="errorMessage"
|
||||
[@showErrorMessage]="showErrorMessage()"
|
||||
>
|
||||
</app-error-box>
|
||||
<app-error-box
|
||||
[errorMessage]="errorMessage"
|
||||
[@showErrorMessage]="showErrorMessage()"
|
||||
>
|
||||
</app-error-box>
|
||||
|
||||
<div
|
||||
class="container authentication-container"
|
||||
[@hideAuthContainer]="hideErrorMessage()"
|
||||
(@hideAuthContainer.done)="hideAuthContainer($event)"
|
||||
>
|
||||
<div class="row">
|
||||
<div class="col-lg-6 authentication-body">
|
||||
<form [formGroup]="loginForm" (ngSubmit)="onLogin()">
|
||||
<div class="input-div">
|
||||
<fa-icon class="input-div-icon" [icon]="_userIcon">
|
||||
</fa-icon>
|
||||
<input
|
||||
type="text"
|
||||
id="username"
|
||||
formControlName="username"
|
||||
class="form-control"
|
||||
placeholder="Username"
|
||||
/>
|
||||
</div>
|
||||
<div class="input-div">
|
||||
<fa-icon
|
||||
class="input-div-icon"
|
||||
[icon]="_passwordIcon"
|
||||
>
|
||||
</fa-icon>
|
||||
<input
|
||||
type="password"
|
||||
id="password"
|
||||
formControlName="password"
|
||||
class="form-control"
|
||||
placeholder="Password"
|
||||
/>
|
||||
</div>
|
||||
<button
|
||||
class="btn"
|
||||
[disabled]="loginForm.invalid"
|
||||
type="submit"
|
||||
>
|
||||
Login
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
<div class="separator-line">
|
||||
<div class="line"></div>
|
||||
</div>
|
||||
<div class="col-lg-6 authentication-body">
|
||||
<button
|
||||
mat-button
|
||||
class="oauth-button d-flex justify-content-center align-items-center"
|
||||
[disabled]="isCookieBlocked"
|
||||
(click)="onGoogleLogin()"
|
||||
>
|
||||
<mat-icon
|
||||
*ngIf="!isCookieBlocked"
|
||||
style="width: 50px; height: 30px"
|
||||
svgIcon="google-logo"
|
||||
></mat-icon>
|
||||
<mat-icon
|
||||
*ngIf="isCookieBlocked"
|
||||
style="width: 50px; height: 30px"
|
||||
svgIcon="google-disabled-logo"
|
||||
></mat-icon>
|
||||
Login With Google
|
||||
</button>
|
||||
<button
|
||||
mat-button
|
||||
class="oauth-button d-flex justify-content-center align-items-center"
|
||||
[disabled]="isCookieBlocked"
|
||||
(click)="onGithubLogin()"
|
||||
>
|
||||
<mat-icon
|
||||
style="width: 50px; height: 30px"
|
||||
svgIcon="github-logo"
|
||||
></mat-icon>
|
||||
Login With Github
|
||||
</button>
|
||||
</div>
|
||||
<div
|
||||
class="container authentication-container"
|
||||
[@hideAuthContainer]="hideErrorMessage()"
|
||||
(@hideAuthContainer.done)="hideAuthContainer($event)"
|
||||
>
|
||||
<div class="row">
|
||||
<div class="col-lg-6 authentication-body">
|
||||
<form [formGroup]="loginForm" (ngSubmit)="onLogin()">
|
||||
<div class="input-div">
|
||||
<fa-icon class="input-div-icon" [icon]="_userIcon">
|
||||
</fa-icon>
|
||||
<input
|
||||
type="text"
|
||||
id="username"
|
||||
formControlName="username"
|
||||
class="form-control"
|
||||
placeholder="Username"
|
||||
/>
|
||||
</div>
|
||||
<div class="input-div">
|
||||
<fa-icon
|
||||
class="input-div-icon"
|
||||
[icon]="_passwordIcon"
|
||||
>
|
||||
</fa-icon>
|
||||
<input
|
||||
type="password"
|
||||
id="password"
|
||||
formControlName="password"
|
||||
class="form-control"
|
||||
placeholder="Password"
|
||||
/>
|
||||
</div>
|
||||
<button
|
||||
class="btn"
|
||||
[disabled]="loginForm.invalid"
|
||||
type="submit"
|
||||
>
|
||||
Login
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
<div class="separator-line">
|
||||
<div class="line"></div>
|
||||
</div>
|
||||
<div class="col-lg-6 authentication-body">
|
||||
<button
|
||||
mat-button
|
||||
class="oauth-button d-flex justify-content-center align-items-center"
|
||||
[disabled]="isCookieBlocked"
|
||||
(click)="onGoogleLogin()"
|
||||
>
|
||||
@if (!isCookieBlocked) {
|
||||
<mat-icon
|
||||
style="width: 50px; height: 30px"
|
||||
svgIcon="google-logo"
|
||||
></mat-icon>
|
||||
}
|
||||
@if (isCookieBlocked) {
|
||||
<mat-icon
|
||||
style="width: 50px; height: 30px"
|
||||
svgIcon="google-disabled-logo"
|
||||
></mat-icon>
|
||||
}
|
||||
Login With Google
|
||||
</button>
|
||||
<button
|
||||
mat-button
|
||||
class="oauth-button d-flex justify-content-center align-items-center"
|
||||
[disabled]="isCookieBlocked"
|
||||
(click)="onGithubLogin()"
|
||||
>
|
||||
<mat-icon
|
||||
style="width: 50px; height: 30px"
|
||||
svgIcon="github-logo"
|
||||
></mat-icon>
|
||||
Login With Github
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</app-popup>
|
||||
|
||||
@@ -33,56 +33,39 @@ const GITHUB_LOGO_SVG = 'assets/img/providers/github.svg';
|
||||
styleUrls: ['./login.component.css'],
|
||||
animations: [
|
||||
trigger('resizeContainerForErrorMessage', [
|
||||
state(
|
||||
'hide',
|
||||
style({
|
||||
height: '100px',
|
||||
width: '320px',
|
||||
}),
|
||||
),
|
||||
transition(
|
||||
'show => hide',
|
||||
group([
|
||||
query('@*', animateChild(), { optional: true }),
|
||||
animate('1s ease'),
|
||||
]),
|
||||
),
|
||||
state('hide', style({
|
||||
height: '100px',
|
||||
width: '320px',
|
||||
})),
|
||||
transition('show => hide', group([
|
||||
query('@*', animateChild(), { optional: true }),
|
||||
animate('1s ease'),
|
||||
])),
|
||||
]),
|
||||
trigger('showErrorMessage', [
|
||||
state(
|
||||
'show',
|
||||
style({
|
||||
opacity: 1,
|
||||
height: '100px',
|
||||
width: '320px',
|
||||
}),
|
||||
),
|
||||
state(
|
||||
'hide',
|
||||
style({
|
||||
opacity: 0,
|
||||
height: '0px',
|
||||
width: '0px',
|
||||
}),
|
||||
),
|
||||
state('show', style({
|
||||
opacity: 1,
|
||||
height: '100px',
|
||||
width: '320px',
|
||||
})),
|
||||
state('hide', style({
|
||||
opacity: 0,
|
||||
height: '0px',
|
||||
width: '0px',
|
||||
})),
|
||||
transition('* => show', animate('500ms ease-in')),
|
||||
]),
|
||||
trigger('hideAuthContainer', [
|
||||
state(
|
||||
'hide',
|
||||
style({
|
||||
opacity: 0,
|
||||
}),
|
||||
),
|
||||
transition(
|
||||
'show => hide',
|
||||
group([
|
||||
query('@*', animateChild(), { optional: true }),
|
||||
animate('250ms ease-out'),
|
||||
]),
|
||||
),
|
||||
state('hide', style({
|
||||
opacity: 0,
|
||||
})),
|
||||
transition('show => hide', group([
|
||||
query('@*', animateChild(), { optional: true }),
|
||||
animate('250ms ease-out'),
|
||||
])),
|
||||
]),
|
||||
],
|
||||
standalone: false
|
||||
})
|
||||
export class LoginComponent implements OnInit, AfterViewInit, OnDestroy {
|
||||
@Input()
|
||||
|
||||
@@ -13,56 +13,39 @@ import {faFileUpload} from '@fortawesome/free-solid-svg-icons';
|
||||
styleUrls: ['./my-profile.component.css'],
|
||||
animations: [
|
||||
trigger('resizeContainerForErrorMessage', [
|
||||
state(
|
||||
'hide',
|
||||
style({
|
||||
height: '100px',
|
||||
width: '320px',
|
||||
}),
|
||||
),
|
||||
transition(
|
||||
'show => hide',
|
||||
group([
|
||||
query('@*', animateChild(), { optional: true }),
|
||||
animate('1s ease'),
|
||||
]),
|
||||
),
|
||||
state('hide', style({
|
||||
height: '100px',
|
||||
width: '320px',
|
||||
})),
|
||||
transition('show => hide', group([
|
||||
query('@*', animateChild(), { optional: true }),
|
||||
animate('1s ease'),
|
||||
])),
|
||||
]),
|
||||
trigger('showErrorMessage', [
|
||||
state(
|
||||
'show',
|
||||
style({
|
||||
opacity: 1,
|
||||
height: '100px',
|
||||
width: '320px',
|
||||
}),
|
||||
),
|
||||
state(
|
||||
'hide',
|
||||
style({
|
||||
opacity: 0,
|
||||
height: '0px',
|
||||
width: '0px',
|
||||
}),
|
||||
),
|
||||
state('show', style({
|
||||
opacity: 1,
|
||||
height: '100px',
|
||||
width: '320px',
|
||||
})),
|
||||
state('hide', style({
|
||||
opacity: 0,
|
||||
height: '0px',
|
||||
width: '0px',
|
||||
})),
|
||||
transition('* => show', animate('500ms ease-in')),
|
||||
]),
|
||||
trigger('hideAuthContainer', [
|
||||
state(
|
||||
'hide',
|
||||
style({
|
||||
opacity: 0,
|
||||
}),
|
||||
),
|
||||
transition(
|
||||
'show => hide',
|
||||
group([
|
||||
query('@*', animateChild(), { optional: true }),
|
||||
animate('250ms ease-out'),
|
||||
]),
|
||||
),
|
||||
state('hide', style({
|
||||
opacity: 0,
|
||||
})),
|
||||
transition('show => hide', group([
|
||||
query('@*', animateChild(), { optional: true }),
|
||||
animate('250ms ease-out'),
|
||||
])),
|
||||
]),
|
||||
],
|
||||
standalone: false
|
||||
})
|
||||
export class MyProfileComponent implements OnInit {
|
||||
@Input()
|
||||
|
||||
@@ -5,6 +5,7 @@ import {AuthService} from '../../../../shared/service/auth.service';
|
||||
selector: 'app-profile-picture-picker',
|
||||
templateUrl: './profile-picture-picker.component.html',
|
||||
styleUrls: ['./profile-picture-picker.component.css'],
|
||||
standalone: false
|
||||
})
|
||||
export class ProfilePicturePickerComponent {
|
||||
@Output()
|
||||
|
||||
@@ -22,56 +22,39 @@ const GITHUB_LOGO_SVG = 'assets/img/providers/github.svg';
|
||||
styleUrls: ['./signup.component.css'],
|
||||
animations: [
|
||||
trigger('resizeContainerForErrorMessage', [
|
||||
state(
|
||||
'hide',
|
||||
style({
|
||||
height: '100px',
|
||||
width: '320px',
|
||||
}),
|
||||
),
|
||||
transition(
|
||||
'show => hide',
|
||||
group([
|
||||
query('@*', animateChild(), { optional: true }),
|
||||
animate('1s ease'),
|
||||
]),
|
||||
),
|
||||
state('hide', style({
|
||||
height: '100px',
|
||||
width: '320px',
|
||||
})),
|
||||
transition('show => hide', group([
|
||||
query('@*', animateChild(), { optional: true }),
|
||||
animate('1s ease'),
|
||||
])),
|
||||
]),
|
||||
trigger('showErrorMessage', [
|
||||
state(
|
||||
'show',
|
||||
style({
|
||||
opacity: 1,
|
||||
height: '100px',
|
||||
width: '320px',
|
||||
}),
|
||||
),
|
||||
state(
|
||||
'hide',
|
||||
style({
|
||||
opacity: 0,
|
||||
height: '0px',
|
||||
width: '0px',
|
||||
}),
|
||||
),
|
||||
state('show', style({
|
||||
opacity: 1,
|
||||
height: '100px',
|
||||
width: '320px',
|
||||
})),
|
||||
state('hide', style({
|
||||
opacity: 0,
|
||||
height: '0px',
|
||||
width: '0px',
|
||||
})),
|
||||
transition('* => show', animate('500ms ease-in')),
|
||||
]),
|
||||
trigger('hideAuthContainer', [
|
||||
state(
|
||||
'hide',
|
||||
style({
|
||||
opacity: 0,
|
||||
}),
|
||||
),
|
||||
transition(
|
||||
'show => hide',
|
||||
group([
|
||||
query('@*', animateChild(), { optional: true }),
|
||||
animate('250ms ease-out'),
|
||||
]),
|
||||
),
|
||||
state('hide', style({
|
||||
opacity: 0,
|
||||
})),
|
||||
transition('show => hide', group([
|
||||
query('@*', animateChild(), { optional: true }),
|
||||
animate('250ms ease-out'),
|
||||
])),
|
||||
]),
|
||||
],
|
||||
standalone: false
|
||||
})
|
||||
export class SignupComponent implements OnInit {
|
||||
@Input()
|
||||
|
||||
@@ -7,18 +7,12 @@ import {Component, EventEmitter, Input, Output} from '@angular/core';
|
||||
styleUrls: ['./header-slider.component.css'],
|
||||
animations: [
|
||||
trigger('slideState', [
|
||||
state(
|
||||
'hide',
|
||||
style({
|
||||
transform: 'translateX(100%)',
|
||||
}),
|
||||
),
|
||||
state(
|
||||
'show',
|
||||
style({
|
||||
transform: 'translateX(0%)',
|
||||
}),
|
||||
),
|
||||
state('hide', style({
|
||||
transform: 'translateX(100%)',
|
||||
})),
|
||||
state('show', style({
|
||||
transform: 'translateX(0%)',
|
||||
})),
|
||||
transition('hide => show', [
|
||||
group([
|
||||
query('@*', animateChild(), { optional: true }),
|
||||
@@ -33,6 +27,7 @@ import {Component, EventEmitter, Input, Output} from '@angular/core';
|
||||
]),
|
||||
]),
|
||||
],
|
||||
standalone: false
|
||||
})
|
||||
export class HeaderSliderComponent {
|
||||
@Input()
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
<div class="links-container">
|
||||
<div class="nav-links">
|
||||
<ul>
|
||||
<li
|
||||
*ngFor="let page of pages; let i = index"
|
||||
<div class="nav-links">
|
||||
<ul>
|
||||
@for (page of pages; track page; let i = $index) {
|
||||
<li
|
||||
[@animateSliderItem]="{
|
||||
value: itemStatus,
|
||||
params: {
|
||||
@@ -10,18 +10,19 @@
|
||||
fadeOutTime: 0.6 - i / 10
|
||||
}
|
||||
}"
|
||||
>
|
||||
<a [routerLink]="page.route">
|
||||
{{ page.name }}
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
>
|
||||
<a [routerLink]="page.route">
|
||||
{{ page.name }}
|
||||
</a>
|
||||
</li>
|
||||
}
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="profile-container">
|
||||
<div
|
||||
class="profile"
|
||||
<div
|
||||
class="profile"
|
||||
[@animateSliderItem]="{
|
||||
value: itemStatus,
|
||||
params: {
|
||||
@@ -29,23 +30,25 @@
|
||||
fadeOutTime: 0.6 - (pages.length + 1) / 10
|
||||
}
|
||||
}"
|
||||
#profile
|
||||
>
|
||||
<div class="profile-btn" (click)="onProfileButtonClicked()">
|
||||
<fa-icon
|
||||
*ngIf="!loggedUser || !loggedUser.profilePictureUrl"
|
||||
class="fas fa-user"
|
||||
[icon]="userIcon"
|
||||
></fa-icon>
|
||||
<img
|
||||
*ngIf="!!loggedUser && !!loggedUser.profilePictureUrl"
|
||||
class="profile-picture"
|
||||
[ngSrc]="loggedUser.profilePictureUrl"
|
||||
width="50"
|
||||
height="50"
|
||||
alt="Profile Picture"
|
||||
priority
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
#profile
|
||||
>
|
||||
<div class="profile-btn" (click)="onProfileButtonClicked()">
|
||||
@if (!loggedUser || !loggedUser.profilePictureUrl) {
|
||||
<fa-icon
|
||||
class="fas fa-user"
|
||||
[icon]="userIcon"
|
||||
></fa-icon>
|
||||
}
|
||||
@if (!!loggedUser && !!loggedUser.profilePictureUrl) {
|
||||
<img
|
||||
class="profile-picture"
|
||||
[ngSrc]="loggedUser.profilePictureUrl"
|
||||
width="50"
|
||||
height="50"
|
||||
alt="Profile Picture"
|
||||
priority
|
||||
/>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -10,6 +10,7 @@ import {Value} from "@sinclair/typebox/value";
|
||||
selector: 'app-nav-slider',
|
||||
templateUrl: './nav-slider.component.html',
|
||||
styleUrls: ['./nav-slider.component.css'],
|
||||
standalone: false
|
||||
})
|
||||
export class NavSliderComponent
|
||||
extends SliderItemComponent
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
<div class="user-container">
|
||||
<div class="user-options">
|
||||
<ul>
|
||||
<li
|
||||
*ngFor="
|
||||
let options of user ? userOptions : userlessOptions;
|
||||
let i = index
|
||||
"
|
||||
<div class="user-options">
|
||||
<ul>
|
||||
@for (
|
||||
options of user ? userOptions : userlessOptions; track
|
||||
options; let i = $index) {
|
||||
<li
|
||||
[@animateSliderItem]="{
|
||||
value: itemStatus,
|
||||
params: {
|
||||
@@ -13,11 +12,12 @@
|
||||
fadeOutTime: 0.6 - i / 10
|
||||
}
|
||||
}"
|
||||
>
|
||||
<a (click)="options.onClick()">
|
||||
{{ options.name }}
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
>
|
||||
<a (click)="options.onClick()">
|
||||
{{ options.name }}
|
||||
</a>
|
||||
</li>
|
||||
}
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -9,6 +9,7 @@ import {Value} from "@sinclair/typebox/value";
|
||||
selector: 'app-user-slider',
|
||||
templateUrl: './user-slider.component.html',
|
||||
styleUrls: ['./user-slider.component.css'],
|
||||
standalone: false
|
||||
})
|
||||
export class UserSliderComponent extends SliderItemComponent implements OnInit {
|
||||
userlessOptions = [
|
||||
|
||||
@@ -1,90 +1,94 @@
|
||||
<div class="header">
|
||||
<div class="main" #header>
|
||||
<div class="logo">
|
||||
<a routerLink="">
|
||||
<img src="assets/img/logohideyoshi-white.png" alt="" />
|
||||
</a>
|
||||
</div>
|
||||
<div class="nav-links">
|
||||
<ul class="link-container">
|
||||
<li *ngFor="let page of pages">
|
||||
<a [routerLink]="page.route">{{ page.name }}</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="profile" #profileDropdown>
|
||||
<div
|
||||
class="profile-btn"
|
||||
(click)="toogleProfileDropdown()"
|
||||
#profileBtn
|
||||
>
|
||||
<fa-icon
|
||||
*ngIf="!loggedUser || !loggedUser.profilePictureUrl"
|
||||
class="fas fa-user"
|
||||
[icon]="userIcon"
|
||||
></fa-icon>
|
||||
<img
|
||||
*ngIf="!!loggedUser && !!loggedUser.profilePictureUrl"
|
||||
class="profile-picture"
|
||||
[ngSrc]="loggedUser.profilePictureUrl"
|
||||
width="50"
|
||||
height="50"
|
||||
alt="Profile Picture"
|
||||
priority
|
||||
/>
|
||||
</div>
|
||||
|
||||
<app-header-dropdown
|
||||
class="dropdown"
|
||||
(clickOutside)="closeDropdown()"
|
||||
[ignoreClickOutside]="[profileBtn]"
|
||||
[state]="profileDropdownState"
|
||||
(loginPopupState)="loginPopupStateChange($event)"
|
||||
(signupPopupState)="signupPopupStateChange($event)"
|
||||
(myProfilePopupState)="myProfilePopupStateChange($event)"
|
||||
(helpPopupState)="helpPopupStateChange($event)"
|
||||
>
|
||||
</app-header-dropdown>
|
||||
</div>
|
||||
<div class="burger-container" (click)="toogleNavSlider()">
|
||||
<div
|
||||
class="burger-menu"
|
||||
[ngClass]="{ open: navSliderStatus }"
|
||||
></div>
|
||||
</div>
|
||||
<div class="main" #header>
|
||||
<div class="logo">
|
||||
<a routerLink="">
|
||||
<img src="assets/img/logohideyoshi-white.png" alt="" />
|
||||
</a>
|
||||
</div>
|
||||
<div class="nav-links">
|
||||
<ul class="link-container">
|
||||
@for (page of pages; track page) {
|
||||
<li>
|
||||
<a [routerLink]="page.route">{{ page.name }}</a>
|
||||
</li>
|
||||
}
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="profile" #profileDropdown>
|
||||
<div
|
||||
class="profile-btn"
|
||||
(click)="toogleProfileDropdown()"
|
||||
#profileBtn
|
||||
>
|
||||
@if (!loggedUser || !loggedUser.profilePictureUrl) {
|
||||
<fa-icon
|
||||
class="fas fa-user"
|
||||
[icon]="userIcon"
|
||||
></fa-icon>
|
||||
}
|
||||
@if (!!loggedUser && !!loggedUser.profilePictureUrl) {
|
||||
<img
|
||||
class="profile-picture"
|
||||
[ngSrc]="loggedUser.profilePictureUrl"
|
||||
width="50"
|
||||
height="50"
|
||||
alt="Profile Picture"
|
||||
priority
|
||||
/>
|
||||
}
|
||||
</div>
|
||||
|
||||
<app-header-dropdown
|
||||
class="dropdown"
|
||||
(clickOutside)="closeDropdown()"
|
||||
[ignoreClickOutside]="[profileBtn]"
|
||||
[state]="profileDropdownState"
|
||||
(loginPopupState)="loginPopupStateChange($event)"
|
||||
(signupPopupState)="signupPopupStateChange($event)"
|
||||
(myProfilePopupState)="myProfilePopupStateChange($event)"
|
||||
(helpPopupState)="helpPopupStateChange($event)"
|
||||
>
|
||||
</app-header-dropdown>
|
||||
</div>
|
||||
<div class="burger-container" (click)="toogleNavSlider()">
|
||||
<div
|
||||
class="burger-menu"
|
||||
[ngClass]="{ open: navSliderStatus }"
|
||||
></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="slider-container" #nav>
|
||||
<app-header-slider
|
||||
[(state)]="navSliderStatus"
|
||||
[clickOutsideStopWatching]="userSliderStatus"
|
||||
[ignoreClickOutside]="[header, user]"
|
||||
<app-header-slider
|
||||
[(state)]="navSliderStatus"
|
||||
[clickOutsideStopWatching]="userSliderStatus"
|
||||
[ignoreClickOutside]="[header, user]"
|
||||
>
|
||||
<app-nav-slider
|
||||
[state]="navSliderStatus"
|
||||
(profileButtonClicked)="profileButtonClicked()"
|
||||
[pages]="pages"
|
||||
>
|
||||
</app-nav-slider>
|
||||
</app-header-slider>
|
||||
<app-nav-slider
|
||||
[state]="navSliderStatus"
|
||||
(profileButtonClicked)="profileButtonClicked()"
|
||||
[pages]="pages"
|
||||
>
|
||||
</app-nav-slider>
|
||||
</app-header-slider>
|
||||
</div>
|
||||
|
||||
<div class="slider-container" #user>
|
||||
<app-header-slider
|
||||
[(state)]="userSliderStatus"
|
||||
[ignoreClickOutside]="[header, nav]"
|
||||
<app-header-slider
|
||||
[(state)]="userSliderStatus"
|
||||
[ignoreClickOutside]="[header, nav]"
|
||||
>
|
||||
<app-user-slider
|
||||
[state]="userSliderStatus"
|
||||
(loginPopupState)="loginPopupStateChange($event)"
|
||||
(signupPopupState)="signupPopupStateChange($event)"
|
||||
(myProfilePopupState)="myProfilePopupStateChange($event)"
|
||||
(helpPopupState)="helpPopupStateChange($event)"
|
||||
>
|
||||
</app-user-slider>
|
||||
</app-header-slider>
|
||||
<app-user-slider
|
||||
[state]="userSliderStatus"
|
||||
(loginPopupState)="loginPopupStateChange($event)"
|
||||
(signupPopupState)="signupPopupStateChange($event)"
|
||||
(myProfilePopupState)="myProfilePopupStateChange($event)"
|
||||
(helpPopupState)="helpPopupStateChange($event)"
|
||||
>
|
||||
</app-user-slider>
|
||||
</app-header-slider>
|
||||
</div>
|
||||
|
||||
<div class="header-spacer"></div>
|
||||
|
||||
@@ -13,6 +13,7 @@ import {Value} from "@sinclair/typebox/value";
|
||||
selector: 'app-header',
|
||||
templateUrl: './header.component.html',
|
||||
styleUrls: ['./header.component.css'],
|
||||
standalone: false
|
||||
})
|
||||
export class HeaderComponent implements OnInit, OnDestroy {
|
||||
pages: { name: string; route: string }[] = [
|
||||
|
||||
@@ -4,6 +4,7 @@ import {Component} from '@angular/core';
|
||||
selector: 'app-home',
|
||||
templateUrl: './home.component.html',
|
||||
styleUrls: ['./home.component.css'],
|
||||
standalone: false
|
||||
})
|
||||
export class HomeComponent {
|
||||
constructor() {}
|
||||
|
||||
@@ -23,6 +23,7 @@ import {animate, state, style, transition, trigger} from "@angular/animations";
|
||||
]),
|
||||
])
|
||||
],
|
||||
standalone: false
|
||||
})
|
||||
export class StackCardComponent {
|
||||
@Input()
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
<ngx-glide #ngxGlide class="container stack-slider" *ngIf="stacks && stacks.length > 0">
|
||||
<app-stack-card *ngFor="let stack of stacks" class="slider-card" [stack]="stack"
|
||||
@if (stacks && stacks.length > 0) {
|
||||
<ngx-glide #ngxGlide class="container stack-slider">
|
||||
@for (stack of stacks; track stack) {
|
||||
<app-stack-card class="slider-card" [stack]="stack"
|
||||
[inFocus]="isInFocus(stack)">
|
||||
</app-stack-card>
|
||||
</ngx-glide>
|
||||
</app-stack-card>
|
||||
}
|
||||
</ngx-glide>
|
||||
}
|
||||
|
||||
@@ -6,7 +6,8 @@ import {Stack} from "../../shared/model/stack/stack.model";
|
||||
@Component({
|
||||
selector: 'app-stack-slider',
|
||||
templateUrl: './stack-slider.component.html',
|
||||
styleUrls: ['./stack-slider.component.css']
|
||||
styleUrls: ['./stack-slider.component.css'],
|
||||
standalone: false
|
||||
})
|
||||
export class StackSliderComponent implements AfterViewInit {
|
||||
@ViewChild('ngxGlide')
|
||||
|
||||
@@ -1,49 +1,55 @@
|
||||
<div class="card container">
|
||||
<div class="card-content">
|
||||
<div class="card-content-h">
|
||||
<h2 class="card-title">
|
||||
<a [href]="project.link">{{project.name}}</a>
|
||||
</h2>
|
||||
<p class="card-text">{{project.description}}</p>
|
||||
</div>
|
||||
<div class="card-content-f row">
|
||||
<div class="card-languages col-md-9" *ngIf="hasLanguage" id="language-chart">
|
||||
<apx-chart *ngIf="chartOptions !== undefined"
|
||||
[series]="chartOptions.series"
|
||||
[colors]="chartOptions.colors"
|
||||
[chart]="chartOptions.chart"
|
||||
[labels]="chartOptions.labels"
|
||||
[responsive]="chartOptions.responsive"
|
||||
[plotOptions]="chartOptions.plotOptions"
|
||||
[dataLabels]="chartOptions.dataLabels">
|
||||
</apx-chart>
|
||||
</div>
|
||||
<div class="card-stats" [ngClass]="hasLanguage ? 'col-md-3' : 'stats-inline'">
|
||||
<div class="stat-item" *ngIf="hasLicense">
|
||||
<div class="stat-icon">
|
||||
<fa-icon [icon]="faLicense"></fa-icon>
|
||||
</div>
|
||||
<span>{{project.license}}</span>
|
||||
</div>
|
||||
<div class="stat-item">
|
||||
<div class="stat-icon">
|
||||
<fa-icon [icon]="faStars"></fa-icon>
|
||||
</div>
|
||||
<span>{{project.stars}}</span>
|
||||
</div>
|
||||
<div class="stat-item">
|
||||
<div class="stat-icon">
|
||||
<fa-icon [icon]="faCodeFork"></fa-icon>
|
||||
</div>
|
||||
<span>{{project.forks}}</span>
|
||||
</div>
|
||||
<div class="stat-item">
|
||||
<div class="stat-icon">
|
||||
<fa-icon [icon]="faEye"></fa-icon>
|
||||
</div>
|
||||
<span>{{project.watchers}}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card container">
|
||||
<div class="card-content">
|
||||
<div class="card-content-h">
|
||||
<h2 class="card-title">
|
||||
<a [href]="project.link">{{project.name}}</a>
|
||||
</h2>
|
||||
<p class="card-text">{{project.description}}</p>
|
||||
</div>
|
||||
<div class="card-content-f row">
|
||||
@if (hasLanguage) {
|
||||
<div class="card-languages col-md-9" id="language-chart">
|
||||
@if (chartOptions !== undefined) {
|
||||
<apx-chart
|
||||
[series]="chartOptions.series"
|
||||
[colors]="chartOptions.colors"
|
||||
[chart]="chartOptions.chart"
|
||||
[labels]="chartOptions.labels"
|
||||
[responsive]="chartOptions.responsive"
|
||||
[plotOptions]="chartOptions.plotOptions"
|
||||
[dataLabels]="chartOptions.dataLabels">
|
||||
</apx-chart>
|
||||
}
|
||||
</div>
|
||||
}
|
||||
<div class="card-stats" [ngClass]="hasLanguage ? 'col-md-3' : 'stats-inline'">
|
||||
@if (hasLicense) {
|
||||
<div class="stat-item">
|
||||
<div class="stat-icon">
|
||||
<fa-icon [icon]="faLicense"></fa-icon>
|
||||
</div>
|
||||
<span>{{project.license}}</span>
|
||||
</div>
|
||||
}
|
||||
<div class="stat-item">
|
||||
<div class="stat-icon">
|
||||
<fa-icon [icon]="faStars"></fa-icon>
|
||||
</div>
|
||||
<span>{{project.stars}}</span>
|
||||
</div>
|
||||
<div class="stat-item">
|
||||
<div class="stat-icon">
|
||||
<fa-icon [icon]="faCodeFork"></fa-icon>
|
||||
</div>
|
||||
<span>{{project.forks}}</span>
|
||||
</div>
|
||||
<div class="stat-item">
|
||||
<div class="stat-icon">
|
||||
<fa-icon [icon]="faEye"></fa-icon>
|
||||
</div>
|
||||
<span>{{project.watchers}}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -24,7 +24,8 @@ export type ChartOptions = {
|
||||
@Component({
|
||||
selector: 'app-project-card',
|
||||
templateUrl: './project-card.component.html',
|
||||
styleUrls: ['./project-card.component.css']
|
||||
styleUrls: ['./project-card.component.css'],
|
||||
standalone: false
|
||||
})
|
||||
export class ProjectCardComponent implements OnInit {
|
||||
@Input() inverted: boolean = false;
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
<div class="container">
|
||||
<div *ngFor="let p of projects; index as i;trackBy: identifyProject">
|
||||
<app-project-card [project]="p" [inverted]="i % 2 !== 0">
|
||||
</app-project-card>
|
||||
@for (p of projects; track identifyProject(i, p); let i = $index) {
|
||||
<div>
|
||||
<app-project-card [project]="p" [inverted]="i % 2 !== 0">
|
||||
</app-project-card>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
|
||||
@@ -5,7 +5,8 @@ import {Project} from "../shared/model/project/project.model";
|
||||
@Component({
|
||||
selector: 'app-projects',
|
||||
templateUrl: './projects.component.html',
|
||||
styleUrls: ['./projects.component.css']
|
||||
styleUrls: ['./projects.component.css'],
|
||||
standalone: false
|
||||
})
|
||||
export class ProjectsComponent implements OnInit {
|
||||
projects!: Project[];
|
||||
|
||||
@@ -7,36 +7,25 @@ import {Component, EventEmitter, Input, Output,} from '@angular/core';
|
||||
styleUrls: ['./popup.component.css'],
|
||||
animations: [
|
||||
trigger('popupState', [
|
||||
state(
|
||||
'hide',
|
||||
style({
|
||||
opacity: '0',
|
||||
zIndex: 2
|
||||
}),
|
||||
),
|
||||
state(
|
||||
'show',
|
||||
style({
|
||||
opacity: '1',
|
||||
zIndex: 2
|
||||
}),
|
||||
),
|
||||
transition(
|
||||
'* => show',
|
||||
group([
|
||||
query('@*', animateChild(), { optional: true }),
|
||||
animate('250ms ease-in'),
|
||||
]),
|
||||
),
|
||||
transition(
|
||||
'show => hide',
|
||||
group([
|
||||
query('@*', animateChild(), { optional: true }),
|
||||
animate('250ms ease-out'),
|
||||
]),
|
||||
),
|
||||
state('hide', style({
|
||||
opacity: '0',
|
||||
zIndex: 2
|
||||
})),
|
||||
state('show', style({
|
||||
opacity: '1',
|
||||
zIndex: 2
|
||||
})),
|
||||
transition('* => show', group([
|
||||
query('@*', animateChild(), { optional: true }),
|
||||
animate('250ms ease-in'),
|
||||
])),
|
||||
transition('show => hide', group([
|
||||
query('@*', animateChild(), { optional: true }),
|
||||
animate('250ms ease-out'),
|
||||
])),
|
||||
]),
|
||||
],
|
||||
standalone: false
|
||||
})
|
||||
export class PopupComponent {
|
||||
@Input()
|
||||
|
||||
@@ -7,36 +7,29 @@ import {Component, Input} from '@angular/core';
|
||||
styleUrls: ['./slider-item.component.css'],
|
||||
animations: [
|
||||
trigger('animateSliderItem', [
|
||||
state(
|
||||
'hide',
|
||||
style({
|
||||
opacity: '0',
|
||||
transform: 'translateX(150px)',
|
||||
}),
|
||||
{
|
||||
params: {
|
||||
fadeInTime: 600,
|
||||
fadeOutTime: 600,
|
||||
},
|
||||
state('hide', style({
|
||||
opacity: '0',
|
||||
transform: 'translateX(150px)',
|
||||
}), {
|
||||
params: {
|
||||
fadeInTime: 600,
|
||||
fadeOutTime: 600,
|
||||
},
|
||||
),
|
||||
state(
|
||||
'show',
|
||||
style({
|
||||
opacity: '1',
|
||||
transform: 'translateX(0px)',
|
||||
}),
|
||||
{
|
||||
params: {
|
||||
fadeOutTime: 600,
|
||||
fadeInTime: 600,
|
||||
},
|
||||
}),
|
||||
state('show', style({
|
||||
opacity: '1',
|
||||
transform: 'translateX(0px)',
|
||||
}), {
|
||||
params: {
|
||||
fadeOutTime: 600,
|
||||
fadeInTime: 600,
|
||||
},
|
||||
),
|
||||
}),
|
||||
transition('hide => show', animate(`{{ fadeInTime }}s ease-in`)),
|
||||
transition('show => hide', animate(`{{ fadeOutTime }}s ease-out`)),
|
||||
]),
|
||||
],
|
||||
standalone: false
|
||||
})
|
||||
export class SliderItemComponent {
|
||||
@Input()
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
import {DOCUMENT} from '@angular/common';
|
||||
import {AfterViewInit, Directive, ElementRef, EventEmitter, Inject, Input, OnDestroy, Output,} from '@angular/core';
|
||||
|
||||
import {AfterViewInit, Directive, ElementRef, EventEmitter, Inject, Input, OnDestroy, Output, DOCUMENT} from '@angular/core';
|
||||
import {filter, fromEvent, Subscription,} from 'rxjs';
|
||||
|
||||
@Directive({
|
||||
selector: '[appClickedOutside]',
|
||||
standalone: false
|
||||
})
|
||||
export class ClickedOutsideDirective implements AfterViewInit, OnDestroy {
|
||||
@Input()
|
||||
|
||||
Reference in New Issue
Block a user