refactor: folders and components
This commit is contained in:
@ -0,0 +1 @@
|
||||
<mat-progress-spinner [color]="color" mode="indeterminate" [diameter]="scale" />
|
18
src/components/common/data-spinner/data-spinner.component.ts
Normal file
18
src/components/common/data-spinner/data-spinner.component.ts
Normal file
@ -0,0 +1,18 @@
|
||||
import {Component, Input} from '@angular/core';
|
||||
import {MatProgressSpinner} from "@angular/material/progress-spinner";
|
||||
import {NgStyle} from "@angular/common";
|
||||
|
||||
@Component({
|
||||
selector: 'app-data-spinner',
|
||||
standalone: true,
|
||||
imports: [
|
||||
MatProgressSpinner,
|
||||
NgStyle
|
||||
],
|
||||
templateUrl: './data-spinner.component.html',
|
||||
styleUrl: './data-spinner.component.css'
|
||||
})
|
||||
export class DataSpinnerComponent {
|
||||
@Input() color: string = "accent";
|
||||
@Input() scale: number = 50;
|
||||
}
|
81
src/components/common/footer/footer.component.css
Normal file
81
src/components/common/footer/footer.component.css
Normal file
@ -0,0 +1,81 @@
|
||||
.app-footer {
|
||||
padding: 12px;
|
||||
font-size: 12px;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.app-footer-copyright {
|
||||
display: flex;
|
||||
flex: 1;
|
||||
justify-content: flex-end;
|
||||
flex-direction: column;
|
||||
min-width: 225px;
|
||||
margin-top: 16px;
|
||||
color: #BCBEC0;
|
||||
align-self: center;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
/*noinspection CssInvalidPropertyValue*/
|
||||
a {
|
||||
text-decoration: none;
|
||||
color: inherit;
|
||||
text-wrap: balance;
|
||||
}
|
||||
|
||||
a:hover,
|
||||
a:focus {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.app-footer-list {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(3, 1fr);
|
||||
grid-template-rows: 1fr;
|
||||
grid-column-gap: 15px;
|
||||
align-items: center;
|
||||
justify-items: center;
|
||||
}
|
||||
|
||||
.app-footer-list div h1 {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
@media screen and (min-width: 600px) and (max-width: 960px) {
|
||||
.app-footer-list {
|
||||
grid-template-columns: repeat(2, 1fr);
|
||||
grid-template-rows: 1fr 3fr;
|
||||
}
|
||||
|
||||
.app-footer-list > div:nth-child(1) {
|
||||
grid-area: 1 / 1 / 2 / 4;
|
||||
}
|
||||
|
||||
.app-footer-list > div:nth-child(2) {
|
||||
grid-area: 2 / 1 / 3 / 2;
|
||||
}
|
||||
|
||||
.app-footer-list > div:nth-child(3) {
|
||||
grid-area: 2 / 2 / 3 / 3;
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (max-width: 600px) {
|
||||
.app-footer-list {
|
||||
grid-template-columns: 1fr;
|
||||
grid-template-rows: 1fr repeat(2, 3fr);
|
||||
justify-items: start;
|
||||
}
|
||||
|
||||
.app-footer-list > div:nth-child(1) {
|
||||
grid-area: 1 / 1 / 2 / 4;
|
||||
}
|
||||
|
||||
.app-footer-list > div:nth-child(2) {
|
||||
grid-area: 2 / 1 / 3 / 2;
|
||||
}
|
||||
|
||||
.app-footer-list > div:nth-child(3) {
|
||||
grid-area: 3 / 1 / 4 / 2;
|
||||
}
|
||||
}
|
29
src/components/common/footer/footer.component.html
Normal file
29
src/components/common/footer/footer.component.html
Normal file
@ -0,0 +1,29 @@
|
||||
<footer style="background-color: #1A2026;">
|
||||
<div class="app-footer">
|
||||
<div class="app-footer-list">
|
||||
<div>
|
||||
<h1>Winsomnia</h1>
|
||||
</div>
|
||||
<div>
|
||||
<mat-list role="list">
|
||||
<mat-list-item role="listitem"><a href="policy/">Политика Конфиденциальности</a></mat-list-item>
|
||||
<mat-list-item role="listitem"><a href="#">Политика по Отношению к Cookie</a></mat-list-item>
|
||||
<mat-list-item role="listitem"><a href="#">Правила и Условия Использования</a></mat-list-item>
|
||||
</mat-list>
|
||||
</div>
|
||||
<div>
|
||||
<mat-list role="list">
|
||||
<mat-list-item role="listitem"><a href="#">Документация</a></mat-list-item>
|
||||
<mat-list-item role="listitem"><a href="#">Лицензия</a></mat-list-item>
|
||||
<mat-list-item role="listitem"><a href="#">О Нас</a></mat-list-item>
|
||||
</mat-list>
|
||||
</div>
|
||||
</div>
|
||||
<hr/>
|
||||
<div class="app-footer-copyright">
|
||||
<span>Powered by Winsomnia ©{{ currentYear }}.</span>
|
||||
<a href="https://opensource.org/license/mit/">Code licensed under an MIT-style License.</a>
|
||||
<span>Current Version: {{ version }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
23
src/components/common/footer/footer.component.ts
Normal file
23
src/components/common/footer/footer.component.ts
Normal file
@ -0,0 +1,23 @@
|
||||
import {Component} from "@angular/core";
|
||||
import {MatList, MatListItem} from "@angular/material/list";
|
||||
import {version} from "../../../../package.json";
|
||||
|
||||
@Component({
|
||||
selector: 'app-footer',
|
||||
standalone: true,
|
||||
imports: [
|
||||
MatList,
|
||||
MatListItem
|
||||
],
|
||||
templateUrl: './footer.component.html',
|
||||
styleUrl: './footer.component.css'
|
||||
})
|
||||
export class FooterComponent {
|
||||
currentYear: number;
|
||||
version: string;
|
||||
|
||||
constructor() {
|
||||
this.currentYear = new Date().getFullYear();
|
||||
this.version = version;
|
||||
}
|
||||
}
|
@ -0,0 +1,7 @@
|
||||
@if (loading) {
|
||||
<app-data-spinner/>
|
||||
} @else {
|
||||
<button mat-fab color="primary" (click)="retryFunction.emit()">
|
||||
<mat-icon>refresh</mat-icon>
|
||||
</button>
|
||||
}
|
@ -0,0 +1,20 @@
|
||||
import {Component, EventEmitter, Input, Output} from '@angular/core';
|
||||
import {DataSpinnerComponent} from "@component/common/data-spinner/data-spinner.component";
|
||||
import {MatIcon} from "@angular/material/icon";
|
||||
import {MatButton, MatFabButton} from "@angular/material/button";
|
||||
|
||||
@Component({
|
||||
selector: 'app-loading-indicator',
|
||||
standalone: true,
|
||||
imports: [
|
||||
DataSpinnerComponent,
|
||||
MatButton,
|
||||
MatIcon,
|
||||
MatFabButton
|
||||
],
|
||||
templateUrl: './loading-indicator.component.html'
|
||||
})
|
||||
export class LoadingIndicatorComponent {
|
||||
@Input() loading: boolean = true;
|
||||
@Output() retryFunction: EventEmitter<void> = new EventEmitter<void>();
|
||||
}
|
@ -0,0 +1,10 @@
|
||||
.notification-content {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
.close-button {
|
||||
margin-left: 8px;
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
<div class="notification-content" [class]="data.className">
|
||||
<span>
|
||||
{{ data.message }}
|
||||
</span>
|
||||
<button mat-icon-button class="close-button" (click)="dismiss()">
|
||||
<mat-icon>close</mat-icon>
|
||||
</button>
|
||||
</div>
|
||||
@if (showProgressBar) {
|
||||
<mat-progress-bar mode="determinate" [value]="progress" [color]="color"/>
|
||||
}
|
50
src/components/common/notification/notification.component.ts
Normal file
50
src/components/common/notification/notification.component.ts
Normal file
@ -0,0 +1,50 @@
|
||||
import {Component, Inject} from '@angular/core';
|
||||
import {MatIcon} from "@angular/material/icon";
|
||||
import {MatProgressBar} from "@angular/material/progress-bar";
|
||||
import {MAT_SNACK_BAR_DATA, MatSnackBarRef} from "@angular/material/snack-bar";
|
||||
import {MatIconButton} from "@angular/material/button";
|
||||
|
||||
@Component({
|
||||
selector: 'app-notification',
|
||||
standalone: true,
|
||||
imports: [
|
||||
MatIconButton,
|
||||
MatIcon,
|
||||
MatProgressBar
|
||||
],
|
||||
templateUrl: './notification.component.html',
|
||||
styleUrl: './notification.component.css'
|
||||
})
|
||||
|
||||
export class NotificationComponent {
|
||||
showProgressBar: boolean = false;
|
||||
progress: number = 100;
|
||||
color: string = "primary";
|
||||
|
||||
constructor(@Inject(MAT_SNACK_BAR_DATA) public data: any, private snackBarRef: MatSnackBarRef<NotificationComponent>) {
|
||||
if (data.duration) {
|
||||
this.startProgress(data.duration);
|
||||
this.showProgressBar = true;
|
||||
}
|
||||
if (data.color) {
|
||||
this.color = data.color;
|
||||
}
|
||||
}
|
||||
|
||||
dismiss(): void {
|
||||
this.snackBarRef.dismiss();
|
||||
}
|
||||
|
||||
private startProgress(duration: number): void {
|
||||
const interval: number = duration / 100;
|
||||
const progressInterval = setInterval(async () => {
|
||||
this.progress--;
|
||||
if (this.progress === 0) {
|
||||
clearInterval(progressInterval);
|
||||
setTimeout(() => {
|
||||
this.dismiss();
|
||||
}, 1000);
|
||||
}
|
||||
}, interval);
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user