From d957ce6a1dc7c20de0508e077db7fd4c3c0dbe0d Mon Sep 17 00:00:00 2001 From: Leon Hoppe Date: Fri, 8 Nov 2024 15:20:01 +0100 Subject: [PATCH] created settings page --- package.json | 2 +- src/app/analysis/analysis.page.html | 17 ++++-- src/app/analysis/analysis.page.ts | 33 ++++++----- .../explore-container.component.html | 12 ---- .../explore-container.component.scss | 27 --------- .../explore-container.component.spec.ts | 18 ------ .../explore-container.component.ts | 11 ---- src/app/settings/settings.page.html | 58 ++++++++++++++++++- src/app/settings/settings.page.scss | 8 +++ src/app/settings/settings.page.ts | 55 ++++++++++++++++-- src/app/tabs/tabs.page.html | 2 +- src/app/time/time.page.ts | 3 +- src/global.scss | 6 ++ src/models/settings.ts | 9 +++ src/services/settings.service.ts | 34 +++++++++++ tsconfig.json | 2 +- 16 files changed, 195 insertions(+), 102 deletions(-) delete mode 100644 src/app/explore-container/explore-container.component.html delete mode 100644 src/app/explore-container/explore-container.component.scss delete mode 100644 src/app/explore-container/explore-container.component.spec.ts delete mode 100644 src/app/explore-container/explore-container.component.ts create mode 100644 src/models/settings.ts create mode 100644 src/services/settings.service.ts diff --git a/package.json b/package.json index 6efd5e4..a0da017 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "WorkTime", - "version": "0.2.3", + "version": "0.3.0", "author": "Ionic Framework", "homepage": "https://ionicframework.com/", "scripts": { diff --git a/src/app/analysis/analysis.page.html b/src/app/analysis/analysis.page.html index f843e7b..f8fa282 100644 --- a/src/app/analysis/analysis.page.html +++ b/src/app/analysis/analysis.page.html @@ -27,7 +27,7 @@ Noch zu arbeiten - Tagessoll erreicht! + Tagessoll erreicht! @@ -45,8 +45,8 @@ - {{formatTime(workTime)}} von {{formatTime(maxWorkTime)}} (+{{formatTime(driveTime)}} Reisezeit) - + {{formatTime(workTime)}} von {{formatTime(settings.maxWorkTime)}} (+{{formatTime(driveTime)}} Reisezeit) + @@ -60,9 +60,14 @@ - {{formatTime(Math.max(combinedWorkTime - maxWorkTime, 0))}} von {{formatTime(desOverTime)}} ({{formatTime(maxOverTime)}} maximal) - - + {{formatTime(Math.max(combinedWorkTime - settings.maxWorkTime, 0))}} von {{formatTime(settings.desiredOverTime)}} ({{formatTime(settings.maxOverTime)}} maximal) + + diff --git a/src/app/analysis/analysis.page.ts b/src/app/analysis/analysis.page.ts index 2ea46e3..b864f38 100644 --- a/src/app/analysis/analysis.page.ts +++ b/src/app/analysis/analysis.page.ts @@ -15,7 +15,6 @@ import { IonCardContent, IonCardSubtitle, IonList, IonIcon, IonProgressBar } from '@ionic/angular/standalone'; -import { ExploreContainerComponent } from '../explore-container/explore-container.component'; import {FormsModule} from "@angular/forms"; import {TimeEntry} from "../../models/timeEntry"; import {TimeService} from "../../services/time.service"; @@ -23,13 +22,15 @@ import {Chart} from "chart.js/auto"; import {addIcons} from "ionicons"; import {briefcase, card, pizza} from "ionicons/icons"; import {NgIf} from "@angular/common"; +import {SettingsService} from "../../services/settings.service"; +import {Settings} from "../../models/settings"; @Component({ selector: 'app-tab2', templateUrl: 'analysis.page.html', styleUrls: ['analysis.page.scss'], standalone: true, - imports: [IonHeader, IonToolbar, IonTitle, IonContent, ExploreContainerComponent, IonItem, IonLabel, IonDatetimeButton, IonModal, IonDatetime, FormsModule, IonCard, IonCardHeader, IonCardTitle, IonCardContent, IonCardSubtitle, IonList, IonIcon, IonProgressBar, NgIf] + imports: [IonHeader, IonToolbar, IonTitle, IonContent, IonItem, IonLabel, IonDatetimeButton, IonModal, IonDatetime, FormsModule, IonCard, IonCardHeader, IonCardTitle, IonCardContent, IonCardSubtitle, IonList, IonIcon, IonProgressBar, NgIf] }) export class AnalysisPage { public currentDate: any; @@ -39,17 +40,16 @@ export class AnalysisPage { public pauseTime: number = 0; public driveTime: number = 0; public combinedWorkTime: number = 0; + public maxPauseTime: number = 0; - public maxWorkTime: number = 420; - public maxPauseTime: number = 30; - public maxOverTime: number = 60; - public desOverTime: number = 30; + public settings: Settings; // @ts-ignore @ViewChild('chart') chartRef: ElementRef; private chart: any; - constructor(private time: TimeService) { + constructor(private time: TimeService, private settingsProvider: SettingsService) { + this.settings = this.settingsProvider.loadSettings(); addIcons({briefcase, pizza, card}) } @@ -58,6 +58,7 @@ export class AnalysisPage { } public updateCurrentData() { + this.settings = this.settingsProvider.loadSettings(); this.timeData = this.time.getEntries(this.currentDate); this.workTime = 0; this.pauseTime = 0; @@ -87,13 +88,13 @@ export class AnalysisPage { this.combinedWorkTime = this.workTime + this.driveTime; if (this.combinedWorkTime < 360) { - this.maxPauseTime = 0; + this.maxPauseTime = this.settings.defaultPauseTime; } if (this.combinedWorkTime >= 360) { // 6h - this.maxPauseTime = 30; + this.maxPauseTime = this.settings.pauseAfter6; } if (this.combinedWorkTime >= 540) { // 9h - this.maxPauseTime = 45; + this.maxPauseTime = this.settings.pauseAfter9; } this.updateChart(); @@ -112,9 +113,9 @@ export class AnalysisPage { let overLabels: string[] = []; let overColors: string[] = []; - if (this.combinedWorkTime > this.maxWorkTime) { - const overTime = this.combinedWorkTime - this.maxWorkTime; - const overPercentage = overTime / this.desOverTime; + if (this.combinedWorkTime > this.settings.maxWorkTime) { + const overTime = this.combinedWorkTime - this.settings.maxWorkTime; + const overPercentage = overTime / this.settings.desiredOverTime; overData.push(this.combinedWorkTime * overPercentage); overLabels.push('Überstunden'); @@ -133,7 +134,7 @@ export class AnalysisPage { ], datasets: [{ label: 'Zeit', - data: [...overData, this.workTime, this.driveTime, Math.max(this.maxWorkTime - this.combinedWorkTime, 0)], + data: [...overData, this.workTime, this.driveTime, Math.max(this.settings.maxWorkTime - this.combinedWorkTime, 0)], backgroundColor: [ ...overColors, workColor, @@ -146,7 +147,7 @@ export class AnalysisPage { events: [], plugins: { legend: { - display: this.driveTime > 0 || this.combinedWorkTime > this.maxWorkTime + display: this.driveTime > 0 || this.combinedWorkTime > this.settings.maxWorkTime } } } @@ -174,7 +175,7 @@ export class AnalysisPage { events: [], plugins: { legend: { - display: this.driveTime > 0 || this.combinedWorkTime > this.maxWorkTime + display: this.driveTime > 0 || this.combinedWorkTime > this.settings.maxWorkTime } } } diff --git a/src/app/explore-container/explore-container.component.html b/src/app/explore-container/explore-container.component.html deleted file mode 100644 index a3fcb60..0000000 --- a/src/app/explore-container/explore-container.component.html +++ /dev/null @@ -1,12 +0,0 @@ -
- {{ name }} -

- Explore - UI Components -

-
diff --git a/src/app/explore-container/explore-container.component.scss b/src/app/explore-container/explore-container.component.scss deleted file mode 100644 index 8993e7c..0000000 --- a/src/app/explore-container/explore-container.component.scss +++ /dev/null @@ -1,27 +0,0 @@ -#container { - text-align: center; - - position: absolute; - left: 0; - right: 0; - top: 50%; - transform: translateY(-50%); -} - -#container strong { - font-size: 20px; - line-height: 26px; -} - -#container p { - font-size: 16px; - line-height: 22px; - - color: #8c8c8c; - - margin: 0; -} - -#container a { - text-decoration: none; -} \ No newline at end of file diff --git a/src/app/explore-container/explore-container.component.spec.ts b/src/app/explore-container/explore-container.component.spec.ts deleted file mode 100644 index aa956d9..0000000 --- a/src/app/explore-container/explore-container.component.spec.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { ComponentFixture, TestBed } from '@angular/core/testing'; - -import { ExploreContainerComponent } from './explore-container.component'; - -describe('ExploreContainerComponent', () => { - let component: ExploreContainerComponent; - let fixture: ComponentFixture; - - beforeEach(async () => { - fixture = TestBed.createComponent(ExploreContainerComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); - - it('should create', () => { - expect(component).toBeTruthy(); - }); -}); diff --git a/src/app/explore-container/explore-container.component.ts b/src/app/explore-container/explore-container.component.ts deleted file mode 100644 index d2073a6..0000000 --- a/src/app/explore-container/explore-container.component.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { Component, Input } from '@angular/core'; - -@Component({ - selector: 'app-explore-container', - templateUrl: './explore-container.component.html', - styleUrls: ['./explore-container.component.scss'], - standalone: true, -}) -export class ExploreContainerComponent { - @Input() name?: string; -} diff --git a/src/app/settings/settings.page.html b/src/app/settings/settings.page.html index 222333d..af7d0e2 100644 --- a/src/app/settings/settings.page.html +++ b/src/app/settings/settings.page.html @@ -1,7 +1,7 @@ - Tab 3 + Einstellungen @@ -9,9 +9,61 @@ - Tab 3 + Einstellungen - + + + +

Zeiten

+
+ + Arbeitszeit + + Stunden + + + +

Pause

+
+ + Nach 0 Stunden + + Minuten + + + Nach 6 Stunden + + Minuten + + + Nach 9 Stunden + + Minuten + + + +

Überstunden

+
+ + Optimal + + Minuten + + + Maximal + + Minuten + + + + + Speichern + + +
diff --git a/src/app/settings/settings.page.scss b/src/app/settings/settings.page.scss index e69de29..60a165a 100644 --- a/src/app/settings/settings.page.scss +++ b/src/app/settings/settings.page.scss @@ -0,0 +1,8 @@ +ion-item-divider { + --background: transparent; + border-bottom: none; +} + +ion-item { + --border-style: none; +} diff --git a/src/app/settings/settings.page.ts b/src/app/settings/settings.page.ts index 0cca1d1..b53bbe4 100644 --- a/src/app/settings/settings.page.ts +++ b/src/app/settings/settings.page.ts @@ -1,14 +1,61 @@ import { Component } from '@angular/core'; -import { IonHeader, IonToolbar, IonTitle, IonContent } from '@ionic/angular/standalone'; -import { ExploreContainerComponent } from '../explore-container/explore-container.component'; +import { + IonHeader, + IonToolbar, + IonTitle, + IonContent, + IonList, + IonItem, + IonInput, + IonToggle, IonButton, IonLabel, IonItemDivider, IonCol, ToastController +} from '@ionic/angular/standalone'; +import {Settings} from "../../models/settings"; +import {SettingsService} from "../../services/settings.service"; +import {FormsModule} from "@angular/forms"; +import {addIcons} from "ionicons"; +import { save } from 'ionicons/icons'; @Component({ selector: 'app-tab3', templateUrl: 'settings.page.html', styleUrls: ['settings.page.scss'], standalone: true, - imports: [IonHeader, IonToolbar, IonTitle, IonContent, ExploreContainerComponent], + imports: [IonHeader, IonToolbar, IonTitle, IonContent, IonList, IonItem, IonInput, FormsModule, IonToggle, IonButton, IonLabel, IonItemDivider, IonCol], }) export class SettingsPage { - constructor() {} + public settings: Settings; + public input: Settings = {}; + + constructor(private settingsProvider: SettingsService, private toasts: ToastController) { + this.settings = settingsProvider.loadSettings(); + this.input.notifications = this.settings.notifications; + + addIcons({save}); + } + + public async save() { + if (this.input.maxWorkTime != undefined) + this.input.maxWorkTime = this.input.maxWorkTime * 60; + + this.input.maxWorkTime ??= this.settings.maxWorkTime; + this.input.defaultPauseTime ??= this.settings.defaultPauseTime; + this.input.pauseAfter6 ??= this.settings.pauseAfter6; + this.input.pauseAfter9 ??= this.settings.pauseAfter9; + this.input.maxOverTime ??= this.settings.maxOverTime; + this.input.desiredOverTime ??= this.settings.desiredOverTime; + + this.settingsProvider.saveSettings(this.input); + + this.settings = this.settingsProvider.loadSettings(); + this.input = {}; + this.input.notifications = this.settings.notifications; + + const toast = await this.toasts.create({ + message: "Einstellungen gespeichert!", + icon: "save", + duration: 2000, + cssClass: 'toast' + }); + await toast.present(); + } } diff --git a/src/app/tabs/tabs.page.html b/src/app/tabs/tabs.page.html index 4fa7ca3..02f7742 100644 --- a/src/app/tabs/tabs.page.html +++ b/src/app/tabs/tabs.page.html @@ -10,7 +10,7 @@ Analyse - + Einstellungen diff --git a/src/app/time/time.page.ts b/src/app/time/time.page.ts index 75ffdf0..2efdff1 100644 --- a/src/app/time/time.page.ts +++ b/src/app/time/time.page.ts @@ -9,7 +9,6 @@ import { IonItem, IonLabel, IonIcon, IonModal, IonButtons, IonInput, IonDatetime, IonDatetimeButton, IonSelect, IonSelectOption } from '@ionic/angular/standalone'; -import { ExploreContainerComponent } from '../explore-container/explore-container.component'; import {TimeEntry, TimeType} from "../../models/timeEntry"; import {NgClass, NgForOf, NgIf} from "@angular/common"; import {addIcons} from "ionicons"; @@ -22,7 +21,7 @@ import {TimeService} from "../../services/time.service"; templateUrl: 'time.page.html', styleUrls: ['time.page.scss'], standalone: true, - imports: [IonHeader, IonToolbar, IonTitle, IonContent, ExploreContainerComponent, NgForOf, IonButton, IonList, IonItem, IonLabel, NgIf, NgClass, IonIcon, IonModal, IonButtons, IonInput, IonDatetime, IonDatetimeButton, IonSelect, IonSelectOption, FormsModule], + imports: [IonHeader, IonToolbar, IonTitle, IonContent, NgForOf, IonButton, IonList, IonItem, IonLabel, NgIf, NgClass, IonIcon, IonModal, IonButtons, IonInput, IonDatetime, IonDatetimeButton, IonSelect, IonSelectOption, FormsModule], }) export class TimePage { public data: TimeEntry[] = []; diff --git a/src/global.scss b/src/global.scss index 6b2884b..3b42094 100644 --- a/src/global.scss +++ b/src/global.scss @@ -39,3 +39,9 @@ .ios .icon-button { width: 50px; } + +.toast { + --background: var(--ion-item-background); + --color: var(--ion-text-color); + --ion-safe-area-bottom: 60px; +} diff --git a/src/models/settings.ts b/src/models/settings.ts new file mode 100644 index 0000000..40e727a --- /dev/null +++ b/src/models/settings.ts @@ -0,0 +1,9 @@ +export interface Settings { + notifications?: boolean; + maxWorkTime?: number; + defaultPauseTime?: number; + pauseAfter6?: number; + pauseAfter9?: number; + maxOverTime?: number; + desiredOverTime?: number; +} diff --git a/src/services/settings.service.ts b/src/services/settings.service.ts new file mode 100644 index 0000000..944f21e --- /dev/null +++ b/src/services/settings.service.ts @@ -0,0 +1,34 @@ +import { Injectable } from '@angular/core'; +import {Settings} from "../models/settings"; + +@Injectable({ + providedIn: 'root' +}) +export class SettingsService { + + constructor() { } + + public loadSettings(): Settings { + const raw = localStorage.getItem("settings"); + + if (raw == undefined) return this.defaultSettings(); + + return JSON.parse(raw) as Settings; + } + + public saveSettings(settings: Settings): void { + localStorage.setItem("settings", JSON.stringify(settings)); + } + + public defaultSettings(): Settings { + return { + notifications: false, + maxWorkTime: 420, // 7h + defaultPauseTime: 0, + pauseAfter6: 30, + pauseAfter9: 45, + maxOverTime: 60, + desiredOverTime: 30 + }; + } +} diff --git a/tsconfig.json b/tsconfig.json index 6d869b4..1168f6e 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -5,7 +5,7 @@ "baseUrl": "./", "outDir": "./dist/out-tsc", "forceConsistentCasingInFileNames": true, - "strict": true, + "strict": false, "noImplicitOverride": true, "noPropertyAccessFromIndexSignature": true, "noImplicitReturns": true,