Move from old git to gittea
This commit is contained in:
20
src/app/app.component.html
Normal file
20
src/app/app.component.html
Normal file
@@ -0,0 +1,20 @@
|
||||
<ion-app>
|
||||
<ion-split-pane contentId="main-content">
|
||||
<ion-menu contentId="main-content" type="overlay">
|
||||
<ion-content>
|
||||
<ion-list id="inbox-list">
|
||||
<ion-list-header>Inbox</ion-list-header>
|
||||
<ion-note>hi@ionicframework.com</ion-note>
|
||||
|
||||
<ion-menu-toggle auto-hide="false" *ngFor="let p of appPages; let i = index">
|
||||
<ion-item routerDirection="root" [routerLink]="[p.url]" lines="none" detail="false" routerLinkActive="selected">
|
||||
<ion-icon aria-hidden="true" slot="start" [ios]="p.icon + '-outline'" [md]="p.icon + '-sharp'"></ion-icon>
|
||||
<ion-label>{{ p.title }}</ion-label>
|
||||
</ion-item>
|
||||
</ion-menu-toggle>
|
||||
</ion-list>
|
||||
</ion-content>
|
||||
</ion-menu>
|
||||
<ion-router-outlet id="main-content"></ion-router-outlet>
|
||||
</ion-split-pane>
|
||||
</ion-app>
|
||||
119
src/app/app.component.scss
Normal file
119
src/app/app.component.scss
Normal file
@@ -0,0 +1,119 @@
|
||||
ion-menu ion-content {
|
||||
--background: var(--ion-item-background, var(--ion-background-color, #fff));
|
||||
}
|
||||
|
||||
ion-menu.md ion-content {
|
||||
--padding-start: 8px;
|
||||
--padding-end: 8px;
|
||||
--padding-top: 20px;
|
||||
--padding-bottom: 20px;
|
||||
}
|
||||
|
||||
ion-menu.md ion-list {
|
||||
padding: 20px 0;
|
||||
}
|
||||
|
||||
ion-menu.md ion-note {
|
||||
margin-bottom: 30px;
|
||||
}
|
||||
|
||||
ion-menu.md ion-list-header,
|
||||
ion-menu.md ion-note {
|
||||
padding-left: 10px;
|
||||
}
|
||||
|
||||
ion-menu.md ion-list#inbox-list {
|
||||
border-bottom: 1px solid var(--ion-color-step-150, #d7d8da);
|
||||
}
|
||||
|
||||
ion-menu.md ion-list#inbox-list ion-list-header {
|
||||
font-size: 22px;
|
||||
font-weight: 600;
|
||||
|
||||
min-height: 20px;
|
||||
}
|
||||
|
||||
ion-menu.md ion-list#labels-list ion-list-header {
|
||||
font-size: 16px;
|
||||
|
||||
margin-bottom: 18px;
|
||||
|
||||
color: #757575;
|
||||
|
||||
min-height: 26px;
|
||||
}
|
||||
|
||||
ion-menu.md ion-item {
|
||||
--padding-start: 10px;
|
||||
--padding-end: 10px;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
ion-menu.md ion-item.selected {
|
||||
--background: rgba(var(--ion-color-primary-rgb), 0.14);
|
||||
}
|
||||
|
||||
ion-menu.md ion-item.selected ion-icon {
|
||||
color: var(--ion-color-primary);
|
||||
}
|
||||
|
||||
ion-menu.md ion-item ion-icon {
|
||||
color: #616e7e;
|
||||
}
|
||||
|
||||
ion-menu.md ion-item ion-label {
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
ion-menu.ios ion-content {
|
||||
--padding-bottom: 20px;
|
||||
}
|
||||
|
||||
ion-menu.ios ion-list {
|
||||
padding: 20px 0 0 0;
|
||||
}
|
||||
|
||||
ion-menu.ios ion-note {
|
||||
line-height: 24px;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
ion-menu.ios ion-item {
|
||||
--padding-start: 16px;
|
||||
--padding-end: 16px;
|
||||
--min-height: 50px;
|
||||
}
|
||||
|
||||
ion-menu.ios ion-item.selected ion-icon {
|
||||
color: var(--ion-color-primary);
|
||||
}
|
||||
|
||||
ion-menu.ios ion-item ion-icon {
|
||||
font-size: 24px;
|
||||
color: #73849a;
|
||||
}
|
||||
|
||||
ion-menu.ios ion-list#labels-list ion-list-header {
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
ion-menu.ios ion-list-header,
|
||||
ion-menu.ios ion-note {
|
||||
padding-left: 16px;
|
||||
padding-right: 16px;
|
||||
}
|
||||
|
||||
ion-menu.ios ion-note {
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
ion-note {
|
||||
display: inline-block;
|
||||
font-size: 16px;
|
||||
|
||||
color: var(--ion-color-medium-shade);
|
||||
}
|
||||
|
||||
ion-item.selected {
|
||||
--color: var(--ion-color-primary);
|
||||
}
|
||||
44
src/app/app.component.spec.ts
Normal file
44
src/app/app.component.spec.ts
Normal file
@@ -0,0 +1,44 @@
|
||||
import { TestBed } from '@angular/core/testing';
|
||||
import { RouterTestingModule } from '@angular/router/testing';
|
||||
|
||||
import { AppComponent } from './app.component';
|
||||
|
||||
describe('AppComponent', () => {
|
||||
beforeEach(async () => {
|
||||
TestBed.overrideComponent(AppComponent, {
|
||||
add: {
|
||||
imports: [RouterTestingModule]
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
it('should create the app', () => {
|
||||
const fixture = TestBed.createComponent(AppComponent);
|
||||
const app = fixture.componentInstance;
|
||||
expect(app).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should have menu labels', () => {
|
||||
const fixture = TestBed.createComponent(AppComponent);
|
||||
fixture.detectChanges();
|
||||
const app = fixture.nativeElement;
|
||||
const menuItems = app.querySelectorAll('ion-label');
|
||||
expect(menuItems.length).toEqual(12);
|
||||
expect(menuItems[0].textContent).toContain('Inbox');
|
||||
expect(menuItems[1].textContent).toContain('Outbox');
|
||||
});
|
||||
|
||||
it('should have urls', () => {
|
||||
const fixture = TestBed.createComponent(AppComponent);
|
||||
fixture.detectChanges();
|
||||
const app = fixture.nativeElement;
|
||||
const menuItems = app.querySelectorAll('ion-item');
|
||||
expect(menuItems.length).toEqual(12);
|
||||
expect(menuItems[0].getAttribute('ng-reflect-router-link')).toEqual(
|
||||
'/folder/inbox'
|
||||
);
|
||||
expect(menuItems[1].getAttribute('ng-reflect-router-link')).toEqual(
|
||||
'/folder/outbox'
|
||||
);
|
||||
});
|
||||
});
|
||||
32
src/app/app.component.ts
Normal file
32
src/app/app.component.ts
Normal file
@@ -0,0 +1,32 @@
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { Component } from '@angular/core';
|
||||
import { RouterLink, RouterLinkActive } from '@angular/router';
|
||||
import { IonApp, IonSplitPane, IonMenu, IonContent, IonList, IonListHeader, IonNote, IonMenuToggle, IonItem, IonIcon, IonLabel, IonRouterOutlet } from '@ionic/angular/standalone';
|
||||
import { addIcons } from 'ionicons';
|
||||
import { mailOutline, mailSharp, paperPlaneOutline, paperPlaneSharp, heartOutline, heartSharp, archiveOutline, archiveSharp, trashOutline, trashSharp, warningOutline, warningSharp, bookmarkOutline, bookmarkSharp } from 'ionicons/icons';
|
||||
import { HomePage} from "./pages/home/home.component";
|
||||
|
||||
@Component({
|
||||
selector: 'app-root',
|
||||
templateUrl: 'app.component.html',
|
||||
styleUrls: ['app.component.scss'],
|
||||
standalone: true,
|
||||
imports: [HomePage, RouterLink, RouterLinkActive, CommonModule, IonApp, IonSplitPane, IonMenu, IonContent, IonList, IonListHeader, IonNote, IonMenuToggle, IonItem, IonIcon, IonLabel, IonRouterOutlet],
|
||||
})
|
||||
export class AppComponent {
|
||||
public appPages = [
|
||||
{ title: 'Home', url: '/tusha/home', icon: 'home' },
|
||||
{ title: 'Daily goals', url: '/folder/daily', icon: 'today' },
|
||||
{ title: 'Weekly goals', url: '/folder/weekly', icon: 'calendar' },
|
||||
{ title: 'Quarterly goals', url: '/folder/quaterly', icon: 'book' },
|
||||
{ title: 'Modus', url: '/tusha/modus', icon: 'aperture' },
|
||||
{ title: 'Settings', url: '/folder/settings', icon: 'settings' },
|
||||
];
|
||||
public labels = ['Family', 'Friends', 'Notes', 'Work', 'Travel', 'Reminders'];
|
||||
|
||||
constructor() {
|
||||
type Test = 'a' | 'b';
|
||||
// ^?
|
||||
addIcons({ mailOutline, mailSharp, paperPlaneOutline, paperPlaneSharp, heartOutline, heartSharp, archiveOutline, archiveSharp, trashOutline, trashSharp, warningOutline, warningSharp, bookmarkOutline, bookmarkSharp });
|
||||
}
|
||||
}
|
||||
26
src/app/app.routes.ts
Normal file
26
src/app/app.routes.ts
Normal file
@@ -0,0 +1,26 @@
|
||||
import { Routes } from '@angular/router';
|
||||
|
||||
export const routes: Routes = [
|
||||
{
|
||||
path: '',
|
||||
redirectTo: 'tusha/home',
|
||||
pathMatch: 'full',
|
||||
},
|
||||
{
|
||||
path: 'tusha/home',
|
||||
loadComponent: () => import('./pages/home/home.component').then(m => m.HomePage)
|
||||
},
|
||||
{
|
||||
path: 'tusha/modus',
|
||||
loadComponent: () => import('./pages/modus/modus-overview.component').then(m => m.ModusOverviewPage)
|
||||
},
|
||||
{
|
||||
path: 'tusha/modus/focus',
|
||||
loadComponent: () => import('./pages/modus/focus/focus.component').then(m => m.FocusPage)
|
||||
},
|
||||
{
|
||||
path: 'folder/:id',
|
||||
loadComponent: () =>
|
||||
import('./folder/folder.page').then((m) => m.FolderPage),
|
||||
},
|
||||
];
|
||||
21
src/app/folder/folder.page.html
Normal file
21
src/app/folder/folder.page.html
Normal file
@@ -0,0 +1,21 @@
|
||||
<ion-header [translucent]="true">
|
||||
<ion-toolbar>
|
||||
<ion-buttons slot="start">
|
||||
<ion-menu-button></ion-menu-button>
|
||||
</ion-buttons>
|
||||
<ion-title>{{ folder }}</ion-title>
|
||||
</ion-toolbar>
|
||||
</ion-header>
|
||||
|
||||
<ion-content [fullscreen]="true">
|
||||
<ion-header collapse="condense">
|
||||
<ion-toolbar>
|
||||
<ion-title size="large">{{ folder }}</ion-title>
|
||||
</ion-toolbar>
|
||||
</ion-header>
|
||||
|
||||
<div id="container">
|
||||
<strong class="capitalize">{{ folder }}</strong>
|
||||
<p>Explore <a target="_blank" rel="noopener noreferrer" href="https://ionicframework.com/docs/components">UI Components</a></p>
|
||||
</div>
|
||||
</ion-content>
|
||||
28
src/app/folder/folder.page.scss
Normal file
28
src/app/folder/folder.page.scss
Normal file
@@ -0,0 +1,28 @@
|
||||
ion-menu-button {
|
||||
color: var(--ion-color-primary);
|
||||
}
|
||||
|
||||
#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;
|
||||
}
|
||||
25
src/app/folder/folder.page.spec.ts
Normal file
25
src/app/folder/folder.page.spec.ts
Normal file
@@ -0,0 +1,25 @@
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
import { RouterTestingModule } from '@angular/router/testing';
|
||||
|
||||
import { FolderPage } from './folder.page';
|
||||
|
||||
describe('FolderPage', () => {
|
||||
let component: FolderPage;
|
||||
let fixture: ComponentFixture<FolderPage>;
|
||||
|
||||
beforeEach(async () => {
|
||||
TestBed.overrideComponent(FolderPage, {
|
||||
add: {
|
||||
imports: [RouterTestingModule]
|
||||
}
|
||||
});
|
||||
|
||||
fixture = TestBed.createComponent(FolderPage);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
||||
20
src/app/folder/folder.page.ts
Normal file
20
src/app/folder/folder.page.ts
Normal file
@@ -0,0 +1,20 @@
|
||||
import { Component, inject, OnInit } from '@angular/core';
|
||||
import { ActivatedRoute } from '@angular/router';
|
||||
import { IonHeader, IonToolbar, IonButtons, IonMenuButton, IonTitle, IonContent } from '@ionic/angular/standalone';
|
||||
|
||||
@Component({
|
||||
selector: 'app-folder',
|
||||
templateUrl: './folder.page.html',
|
||||
styleUrls: ['./folder.page.scss'],
|
||||
standalone: true,
|
||||
imports: [IonHeader, IonToolbar, IonButtons, IonMenuButton, IonTitle, IonContent],
|
||||
})
|
||||
export class FolderPage implements OnInit {
|
||||
public folder!: string;
|
||||
private activatedRoute = inject(ActivatedRoute);
|
||||
constructor() {}
|
||||
|
||||
ngOnInit() {
|
||||
this.folder = this.activatedRoute.snapshot.paramMap.get('id') as string;
|
||||
}
|
||||
}
|
||||
0
src/app/pages/daily/dialy.component.css
Normal file
0
src/app/pages/daily/dialy.component.css
Normal file
11
src/app/pages/home/home.component.css
Normal file
11
src/app/pages/home/home.component.css
Normal file
@@ -0,0 +1,11 @@
|
||||
|
||||
ion-footer ion-title {
|
||||
position: absolute;
|
||||
right: 0px;
|
||||
color: darkgray;
|
||||
font-size: 0.75rem;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
13
src/app/pages/home/home.component.html
Normal file
13
src/app/pages/home/home.component.html
Normal file
@@ -0,0 +1,13 @@
|
||||
<app-tusha-page>
|
||||
<ion-breadcrumbs slot="breadcrumb">
|
||||
<ion-breadcrumb >
|
||||
<ion-icon slot="start" name="home"/>
|
||||
Home
|
||||
</ion-breadcrumb>
|
||||
</ion-breadcrumbs>
|
||||
|
||||
<tusha-status-cards [card1]="card1" [card2]="card2" />
|
||||
|
||||
<tusha-nav-rows [navcards]="navcards" />
|
||||
|
||||
</app-tusha-page>
|
||||
54
src/app/pages/home/home.component.ts
Normal file
54
src/app/pages/home/home.component.ts
Normal file
@@ -0,0 +1,54 @@
|
||||
import { Component } from "@angular/core";
|
||||
import {Router} from "@angular/router";
|
||||
import {
|
||||
IonBreadcrumbs, IonCard, IonCardContent, IonCol, IonRow, IonBreadcrumb, IonIcon
|
||||
} from "@ionic/angular/standalone";
|
||||
import {TushaNavRowsComponent} from "../../tusha/tusha-nav-rows/tusha-nav-rows.component";
|
||||
import {NavCardData} from "../../tusha/tusha-nav-rows/nav-card-data";
|
||||
import {TushaPageComponent} from "../../tusha/tusha-page/tusha-page.component";
|
||||
import {TushaStatusCardsComponent} from "../../tusha/tusha-status-cards/tusha-status-cards.component";
|
||||
import {StatusCardsData} from "../../tusha/tusha-status-cards/status-cards-data";
|
||||
|
||||
@Component({
|
||||
templateUrl: 'home.component.html',
|
||||
styleUrls: ['home.component.css'],
|
||||
standalone: true,
|
||||
imports: [IonRow, IonCol, IonCard, IonCardContent, TushaNavRowsComponent, TushaPageComponent, IonBreadcrumbs, IonBreadcrumb, IonIcon, TushaStatusCardsComponent]
|
||||
})
|
||||
export class HomePage {
|
||||
navcards: NavCardData[];
|
||||
card1: StatusCardsData;
|
||||
card2: StatusCardsData;
|
||||
|
||||
constructor(public router: Router) {
|
||||
this.navcards = [
|
||||
{id: 1, title: 'Daily Goals', color: {color: 'blue'}, onclick: this.goToDailyGoals.bind(this), icon: 'today-outline'},
|
||||
{id: 2, title: 'Weekly Goals', color: {color: 'green'}, onclick: this.goToDailyGoals.bind(this), icon: 'calendar-outline'},
|
||||
{id: 3, title: 'Quaterly Goals', color: {color: 'orange'}, onclick: this.goToDailyGoals.bind(this), icon: 'book-outline'},
|
||||
{id: 4, title: 'Go Into Modus', color: {color: 'black'}, onclick: this.goToModus.bind(this), icon: 'aperture-outline'},
|
||||
];
|
||||
this.card1 = {
|
||||
id: 1,
|
||||
color: {color: 'orange'},
|
||||
type: 'number',
|
||||
amount: 15,
|
||||
description: 'Tasks Done'
|
||||
};
|
||||
this.card2 = {
|
||||
id: 2,
|
||||
color: {color: 'green'},
|
||||
type: 'percentage',
|
||||
amount: 58,
|
||||
description: 'Week Progress'
|
||||
};
|
||||
}
|
||||
|
||||
goToDailyGoals() {
|
||||
this.router.navigate(['folder/daily']);
|
||||
}
|
||||
|
||||
goToModus() {
|
||||
this.router.navigate(['tusha/modus']);
|
||||
}
|
||||
|
||||
}
|
||||
9
src/app/pages/modus/focus/focus-configuration.ts
Normal file
9
src/app/pages/modus/focus/focus-configuration.ts
Normal file
@@ -0,0 +1,9 @@
|
||||
export class FocusConfiguration {
|
||||
focusMinutes: number = 25;
|
||||
shortBreak: number = 5;
|
||||
longBreak: number = 15;
|
||||
|
||||
cyclesBeforeLongBreak: number = 4;
|
||||
|
||||
behaviorOnFocusEnd: 'nothing' | 'startBreak' | 'overtime' = 'overtime';
|
||||
}
|
||||
40
src/app/pages/modus/focus/focus-service.ts
Normal file
40
src/app/pages/modus/focus/focus-service.ts
Normal file
@@ -0,0 +1,40 @@
|
||||
import {FocusStats} from "./focus-stats";
|
||||
|
||||
export class FocusService {
|
||||
stats: FocusStats = new FocusStats();
|
||||
|
||||
registerFocus(minutes: number) {
|
||||
this.stats.focusCycles++;
|
||||
this.stats.focusMinutes += minutes;
|
||||
}
|
||||
|
||||
registerShortBreak(minutes: number) {
|
||||
this.stats.shortBreakCycles++;
|
||||
this.stats.breakMinutes += minutes;
|
||||
}
|
||||
|
||||
registerLongBreak(minutes: number) {
|
||||
this.stats.longBreakCycles++;
|
||||
this.stats.breakMinutes += minutes;
|
||||
}
|
||||
|
||||
getFocusCycles(): number {
|
||||
return this.stats.focusCycles;
|
||||
}
|
||||
|
||||
getFocusMinutes(): number {
|
||||
return this.stats.focusMinutes;
|
||||
}
|
||||
|
||||
getShortBreakCycles(): number {
|
||||
return this.stats.shortBreakCycles;
|
||||
}
|
||||
|
||||
getLongBreakCycles(): number {
|
||||
return this.stats.longBreakCycles;
|
||||
}
|
||||
|
||||
getBreakMinutes(): number {
|
||||
return this.stats.breakMinutes;
|
||||
}
|
||||
}
|
||||
3
src/app/pages/modus/focus/focus-state.ts
Normal file
3
src/app/pages/modus/focus/focus-state.ts
Normal file
@@ -0,0 +1,3 @@
|
||||
export enum FocusState {
|
||||
FOCUS = 'in_focus', SHORT_BREAK = 'short_break', LONG_BREAK = 'long_break', STOPPED = 'stopped'
|
||||
}
|
||||
7
src/app/pages/modus/focus/focus-stats.ts
Normal file
7
src/app/pages/modus/focus/focus-stats.ts
Normal file
@@ -0,0 +1,7 @@
|
||||
export class FocusStats {
|
||||
focusCycles: number = 0;
|
||||
focusMinutes: number = 0;
|
||||
shortBreakCycles: number = 0;
|
||||
longBreakCycles: number = 0;
|
||||
breakMinutes: number = 0;
|
||||
}
|
||||
165
src/app/pages/modus/focus/focus.component.css
Normal file
165
src/app/pages/modus/focus/focus.component.css
Normal file
@@ -0,0 +1,165 @@
|
||||
|
||||
/* focus-timer.component.scss */
|
||||
app-tusha-page {
|
||||
height: 500px;
|
||||
}
|
||||
|
||||
.leftright-line {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.countdown-box {
|
||||
width: 320px;
|
||||
height: 320px;
|
||||
border: 2px solid;
|
||||
padding: 0.5em 0.5em 0.5em 0.5em;
|
||||
}
|
||||
|
||||
.countdown-state-text {
|
||||
font-family: Monaco, "Lucida Console", monospace;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
.countdown-state-stopped-box {
|
||||
background-color: lightcoral;
|
||||
border-color: darkred;
|
||||
}
|
||||
|
||||
.countdown-state-stopped-text{
|
||||
color: darkred;
|
||||
}
|
||||
|
||||
.countdown-state-short-break-box {
|
||||
background-color: lightgreen;
|
||||
border-color: darkgreen;
|
||||
}
|
||||
|
||||
.countdown-state-short-break-text {
|
||||
color: darkgreen;
|
||||
}
|
||||
|
||||
.countdown-state-long-break-box {
|
||||
background-color: peachpuff;
|
||||
border-color: orangered;
|
||||
}
|
||||
|
||||
.countdown-state-long-break-text {
|
||||
color: orangered;
|
||||
|
||||
}
|
||||
|
||||
.countdown-state-in-focus-box {
|
||||
background-color: lightblue;
|
||||
border-color: darkblue;
|
||||
}
|
||||
|
||||
.countdown-state-in-focus-text {
|
||||
color: darkblue;
|
||||
}
|
||||
|
||||
.focustimer {
|
||||
position: relative;
|
||||
width: 270px;
|
||||
height: 270px;
|
||||
border-radius: 50%;
|
||||
overflow: hidden;
|
||||
margin: 0 auto;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
border: 2px solid;
|
||||
background-color: lavender;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
.countdown {
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
width: 300px;
|
||||
height: 300px;
|
||||
align-content: center;
|
||||
z-index: 3;
|
||||
}
|
||||
|
||||
.focusmode {
|
||||
border-width: 10px;
|
||||
border-color: lightblue;
|
||||
border-style: outset;
|
||||
background-color: aliceblue;
|
||||
}
|
||||
|
||||
.breakmode {
|
||||
border-width: 10px;
|
||||
border-color: antiquewhite;
|
||||
border-style: outset;
|
||||
background-color: beige;
|
||||
}
|
||||
|
||||
ion-button {
|
||||
position: relative;
|
||||
left: 50%;
|
||||
margin-top: 20px;
|
||||
transform: translate(-50%, 0%);
|
||||
}
|
||||
|
||||
.countdown-text {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
font-size: 4em;
|
||||
color: var(--ion-color-primary);
|
||||
}
|
||||
|
||||
.timer {
|
||||
width: 350px;
|
||||
height: 350px;
|
||||
}
|
||||
|
||||
.state {
|
||||
font-weight: bold;
|
||||
font-size: 1.5em;
|
||||
border: 2px solid;
|
||||
width: 350px;
|
||||
height: 350px;
|
||||
text-align: center;
|
||||
margin: 0 auto;
|
||||
padding: 10px;
|
||||
display: block;
|
||||
position: relative;
|
||||
top: -350px;
|
||||
left: -50px;
|
||||
}
|
||||
|
||||
.state-stopped {
|
||||
color: darkred;
|
||||
background-color: lightcoral;
|
||||
border-color: darkred;
|
||||
}
|
||||
|
||||
.state-short_break {
|
||||
color: darkgreen;
|
||||
background-color: lightgreen;
|
||||
border-color: darkgreen;
|
||||
}
|
||||
|
||||
.state-long_break {
|
||||
color: orangered;
|
||||
background-color: peachpuff;
|
||||
border-color: orangered;
|
||||
}
|
||||
|
||||
.state_in_focus {
|
||||
color: darkblue;
|
||||
background-color: lightblue;
|
||||
border-color: darkblue;
|
||||
}
|
||||
|
||||
.button-bar {
|
||||
width: 350px;
|
||||
display: block;
|
||||
}
|
||||
|
||||
89
src/app/pages/modus/focus/focus.component.html
Normal file
89
src/app/pages/modus/focus/focus.component.html
Normal file
@@ -0,0 +1,89 @@
|
||||
<app-tusha-page>
|
||||
<ion-breadcrumbs slot="breadcrumb">
|
||||
<ion-breadcrumb href="tusha/home">
|
||||
<ion-icon slot="start" name="home"/>
|
||||
Home
|
||||
</ion-breadcrumb>
|
||||
<ion-breadcrumb href="tusha/modus">
|
||||
<ion-icon slot="start" name="aperture"/>
|
||||
Modus
|
||||
</ion-breadcrumb>
|
||||
<ion-breadcrumb>
|
||||
<ion-icon slot="start" name="time"/>
|
||||
Focus
|
||||
</ion-breadcrumb>
|
||||
</ion-breadcrumbs>
|
||||
|
||||
|
||||
<!-- TODO add settings cogwheel -->
|
||||
|
||||
<!-- TODO add default action to div -->
|
||||
<!-- TODO add are you sure pop-ups -->
|
||||
|
||||
<div class="countdown-box countdown-state-{{state}}-box">
|
||||
<div class="leftright-line">
|
||||
<span class="countdown-state-text countdown-state-{{state}}-text">{{state}}</span>
|
||||
<ion-icon name="settings-outline"></ion-icon>
|
||||
</div>
|
||||
<div class="countdown-timer">
|
||||
<svg class="focustimer countdown-state-{{state}}-box" width="100%" height="100%" viewBox="0 0 200 200" (click)="startWhereWeAre()">
|
||||
<!-- Definieer de gradient -->
|
||||
<defs>
|
||||
<!-- have the gradient follow the path is possible but too difficult for now - can be read at https://stackoverflow.com/questions/14633363/can-i-apply-a-gradient-along-an-svg-path -->
|
||||
<linearGradient id="grad1" x1="1" y1="0" x2="0" y2="0">
|
||||
<stop offset="0%" stop-color="blue"></stop>
|
||||
<stop offset="80%" stop-color="green"></stop>
|
||||
<stop offset="100%" stop-color="red"></stop>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
|
||||
<path id="1stPath" [attr.d]="pathD"
|
||||
fill="none" stroke="url(#grad1)" stroke-width="30" stroke-dasharray="0" [attr.stroke-dashoffset]="dashOffset" />
|
||||
</svg>
|
||||
<div class="countdown-text">{{ minutesText }}:{{ secondsText }}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="leftright-line">
|
||||
<ion-button (click)="startTimer(25)">Focus</ion-button>
|
||||
<ion-button (click)="stopTimer()">Give up</ion-button>
|
||||
</div>
|
||||
<div class="leftright-line">
|
||||
<ion-button (click)="startTimer(5)">Reload</ion-button>
|
||||
<ion-button (click)="startTimer(15)">Recharge</ion-button>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<div class="timer">
|
||||
<div class="countdown focusmode">
|
||||
<svg class="focustimer" width="100%" height="100%" viewBox="0 0 200 200" style="background-color: lavender;" (click)="startWhereWeAre()">
|
||||
<!-- Definieer de gradient -->
|
||||
<defs>
|
||||
<!-- have the gradient follow the path is possible but too difficult for now - can be read at https://stackoverflow.com/questions/14633363/can-i-apply-a-gradient-along-an-svg-path -->
|
||||
<linearGradient id="grad1" x1="1" y1="0" x2="0" y2="0">
|
||||
<stop offset="0%" stop-color="blue"></stop>
|
||||
<stop offset="80%" stop-color="green"></stop>
|
||||
<stop offset="100%" stop-color="red"></stop>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
|
||||
<path id="1stPath" [attr.d]="pathD"
|
||||
fill="none" stroke="url(#grad1)" stroke-width="30" stroke-dasharray="0" [attr.stroke-dashoffset]="dashOffset" />
|
||||
</svg>
|
||||
<div class="countdown-text">{{ minutesText }}:{{ secondsText }}</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="state state-{{state}}">{{state}}</div>
|
||||
<!-- TODO decide buttons to show on state -->
|
||||
<div class="buttonBar">
|
||||
<ion-button (click)="startTimer(25)">Focus</ion-button>
|
||||
<ion-button (click)="stopTimer()">Give up</ion-button>
|
||||
</div>
|
||||
<div class="buttonBar">
|
||||
<ion-button (click)="startTimer(5)">Reload</ion-button>
|
||||
<ion-button (click)="startTimer(15)">Recharge</ion-button>
|
||||
</div>
|
||||
|
||||
</app-tusha-page>
|
||||
|
||||
101
src/app/pages/modus/focus/focus.component.ts
Normal file
101
src/app/pages/modus/focus/focus.component.ts
Normal file
@@ -0,0 +1,101 @@
|
||||
import {Component, OnDestroy, OnInit, Renderer2} from "@angular/core";
|
||||
import {IonBreadcrumb, IonBreadcrumbs, IonButton, IonContent, IonIcon, IonProgressBar} from "@ionic/angular/standalone";
|
||||
import {TushaPageComponent} from "../../../tusha/tusha-page/tusha-page.component";
|
||||
import {FocusState} from "./focus-state";
|
||||
|
||||
@Component({
|
||||
templateUrl: 'focus.component.html',
|
||||
styleUrls: ['focus.component.css'],
|
||||
standalone: true,
|
||||
imports: [IonBreadcrumbs, IonBreadcrumb, IonIcon, TushaPageComponent, IonProgressBar, IonContent, IonButton]
|
||||
})
|
||||
export class FocusPage implements OnInit, OnDestroy {
|
||||
duration: number = 0.5; // default duration in minutes
|
||||
minutes: number = 25;
|
||||
minutesText: string = '';
|
||||
seconds: number = 0;
|
||||
secondsText: string = '';
|
||||
private interval: any;
|
||||
private startTime: number | null = null;
|
||||
state: FocusState = FocusState.STOPPED;
|
||||
|
||||
|
||||
pathD: string = 'M100 10 A90 90 0 1 1 0 0';
|
||||
|
||||
dashOffset = 0;
|
||||
|
||||
constructor(private renderer: Renderer2) {}
|
||||
|
||||
ngOnInit() {
|
||||
this.updateTimeDisplay(this.duration * 60, 0, 1);
|
||||
}
|
||||
|
||||
ngOnDestroy() {
|
||||
if (this.interval) {
|
||||
clearInterval(this.interval);
|
||||
}
|
||||
}
|
||||
|
||||
startTimer(duration: number) {
|
||||
this.duration = duration;
|
||||
if (this.interval) {
|
||||
clearInterval(this.interval);
|
||||
}
|
||||
|
||||
this.startTime = Date.now();
|
||||
this.interval = setInterval(() => this.update(), 1000);
|
||||
}
|
||||
|
||||
private update() {
|
||||
const elapsed = Math.round((Date.now() - (this.startTime as number)) / 1000); // in seconden
|
||||
let progress = elapsed / (this.duration * 60);
|
||||
|
||||
if (progress >= 1) {
|
||||
console.log('timer reader');
|
||||
progress = 1;
|
||||
clearInterval(this.interval);
|
||||
}
|
||||
|
||||
const path1 = document.getElementById('1stPath') as unknown as SVGPathElement;
|
||||
|
||||
const totalLength1 = path1.getTotalLength();
|
||||
|
||||
// path1.style.strokeDasharray = `${totalLength1}`;
|
||||
// path1.style.strokeDashoffset = `${totalLength1 - totalLength1 * this.progress}`;
|
||||
//
|
||||
// path2.style.strokeDasharray = `${totalLength2}`;
|
||||
// path2.style.strokeDashoffset = `${totalLength2 - totalLength2 * this.progress}`;
|
||||
|
||||
this.renderer.setStyle(
|
||||
document.documentElement,
|
||||
'--progress',
|
||||
progress.toString()
|
||||
);
|
||||
|
||||
this.updateTimeDisplay(this.duration * 60 - elapsed, elapsed, 1 - progress);
|
||||
}
|
||||
|
||||
private updateTimeDisplay(timeLeft: number, elapsed: number, percentage: number) {
|
||||
const theta = 2 * Math.PI * (percentage - 0.25);
|
||||
const circleEndX = 100 + 90 * Math.cos(theta);
|
||||
const circleEndY = 100 + 90 * Math.sin(theta);
|
||||
this.pathD = 'M100 10 A90 90 0 ' + (percentage > 0.5 ? '1' : '0') + ' 1 ' + circleEndX + ' ' + circleEndY;
|
||||
|
||||
const twoNumbers = (n: number) => n < 10 && n >= 0 ? '0' + n.toString() : n.toString();
|
||||
this.minutes = Math.max(Math.floor(timeLeft / 60), 0);
|
||||
this.seconds = Math.max(Math.floor(timeLeft % 60), 0);
|
||||
this.minutesText = twoNumbers(this.minutes);
|
||||
this.secondsText = twoNumbers(this.seconds);
|
||||
|
||||
const progress = -1 * (elapsed / (this.duration * 60));
|
||||
this.dashOffset = elapsed;
|
||||
}
|
||||
|
||||
startWhereWeAre() {
|
||||
this.startTimer(25);
|
||||
}
|
||||
|
||||
stopTimer() {
|
||||
clearInterval(this.interval);
|
||||
}
|
||||
}
|
||||
0
src/app/pages/modus/modus-overview.component.css
Normal file
0
src/app/pages/modus/modus-overview.component.css
Normal file
16
src/app/pages/modus/modus-overview.component.html
Normal file
16
src/app/pages/modus/modus-overview.component.html
Normal file
@@ -0,0 +1,16 @@
|
||||
<app-tusha-page>
|
||||
<ion-breadcrumbs slot="breadcrumb">
|
||||
<ion-breadcrumb href="tusha/home">
|
||||
<ion-icon slot="start" name="home"/>
|
||||
Home
|
||||
</ion-breadcrumb>
|
||||
<ion-breadcrumb >
|
||||
<ion-icon slot="start" name="aperture"/>
|
||||
Modus
|
||||
</ion-breadcrumb>
|
||||
</ion-breadcrumbs>
|
||||
|
||||
<tusha-status-cards [card1]="card1" [card2]="card2" />
|
||||
|
||||
<tusha-nav-rows [navcards]="navcards" />
|
||||
</app-tusha-page>
|
||||
61
src/app/pages/modus/modus-overview.component.ts
Normal file
61
src/app/pages/modus/modus-overview.component.ts
Normal file
@@ -0,0 +1,61 @@
|
||||
import {Component} from "@angular/core";
|
||||
import {
|
||||
IonBreadcrumb,
|
||||
IonBreadcrumbs,
|
||||
IonCard,
|
||||
IonCardContent,
|
||||
IonCol,
|
||||
IonIcon,
|
||||
IonRow
|
||||
} from "@ionic/angular/standalone";
|
||||
import {TushaNavRowsComponent} from "../../tusha/tusha-nav-rows/tusha-nav-rows.component";
|
||||
import {TushaPageComponent} from "../../tusha/tusha-page/tusha-page.component";
|
||||
import {NavCardData} from "../../tusha/tusha-nav-rows/nav-card-data";
|
||||
import {Router} from "@angular/router";
|
||||
import {StatusCardsData} from "../../tusha/tusha-status-cards/status-cards-data";
|
||||
import {TushaStatusCardsComponent} from "../../tusha/tusha-status-cards/tusha-status-cards.component";
|
||||
|
||||
|
||||
@Component({
|
||||
templateUrl: 'modus-overview.component.html',
|
||||
styleUrls: ['modus-overview.component.css'],
|
||||
standalone: true,
|
||||
imports: [IonRow, IonCol, IonCard, IonCardContent, TushaNavRowsComponent, TushaPageComponent, IonBreadcrumb, IonBreadcrumbs, IonIcon, TushaStatusCardsComponent]
|
||||
})
|
||||
export class ModusOverviewPage {
|
||||
navcards: NavCardData[];
|
||||
card1: StatusCardsData;
|
||||
card2: StatusCardsData;
|
||||
|
||||
constructor(public router: Router) {
|
||||
this.navcards = [
|
||||
{id: 1, title: 'Focus', color: {color: 'blue'}, onclick: this.goToFocus.bind(this), icon: 'time-outline'},
|
||||
{id: 2, title: 'Perceive', color: {color: 'purple'}, onclick: this.goToDailyGoals.bind(this), icon: 'leaf-outline'},
|
||||
{id: 3, title: 'Grow', color: {color: 'green'}, onclick: this.goToDailyGoals.bind(this), icon: 'rocket-outline'},
|
||||
{id: 4, title: 'Reflect', color: {color: 'beige'}, onclick: this.goToDailyGoals.bind(this), icon: 'speedometer-outline'},
|
||||
{id: 5, title: 'Love', color: {color: 'red'}, onclick: this.goToDailyGoals.bind(this), icon: 'heart-outline'},
|
||||
];
|
||||
this.card1 = {
|
||||
id: 1,
|
||||
color: {color: 'blue'},
|
||||
type: 'number',
|
||||
amount: 3,
|
||||
description: 'Focus sessions'
|
||||
};
|
||||
this.card2 = {
|
||||
id: 2,
|
||||
color: {color: 'orange'},
|
||||
type: 'number',
|
||||
amount: 4,
|
||||
description: 'Modus types'
|
||||
};
|
||||
}
|
||||
|
||||
goToDailyGoals() {
|
||||
this.router.navigate(['folder/daily']);
|
||||
}
|
||||
|
||||
goToFocus() {
|
||||
this.router.navigate(['tusha/modus/focus']);
|
||||
}
|
||||
}
|
||||
3
src/app/tusha/tusha-nav-card/card-color.ts
Normal file
3
src/app/tusha/tusha-nav-card/card-color.ts
Normal file
@@ -0,0 +1,3 @@
|
||||
export interface CardColor {
|
||||
color: '' | 'blue' | 'green' | 'orange' | 'black' | 'purple' | 'beige' | 'red';
|
||||
}
|
||||
115
src/app/tusha/tusha-nav-card/tusha-nav-card.component.css
Normal file
115
src/app/tusha/tusha-nav-card/tusha-nav-card.component.css
Normal file
@@ -0,0 +1,115 @@
|
||||
ion-card {
|
||||
margin: 0 0 0 0;
|
||||
}
|
||||
|
||||
ion-grid.innergrid {
|
||||
margin: 0 0 0 0;
|
||||
padding: 0 0 0 0;
|
||||
}
|
||||
|
||||
ion-grid.innergrid ion-row {
|
||||
margin: 0 0 0 0;
|
||||
padding: 0 0 0 0;
|
||||
}
|
||||
|
||||
ion-grid.innergrid ion-row ion-col {
|
||||
margin: 0 0 0 0;
|
||||
padding: 0 0 0 0;
|
||||
}
|
||||
.navcard {
|
||||
margin-bottom: 0;
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
.navcard.daily {
|
||||
background-color: lightcyan;
|
||||
}
|
||||
|
||||
.navcard.daily :active {
|
||||
background-color: cyan;
|
||||
}
|
||||
|
||||
.navcard.weekly {
|
||||
background-color: mistyrose;
|
||||
}
|
||||
|
||||
.navcard.weekly :active {
|
||||
background-color: rosybrown;
|
||||
}
|
||||
|
||||
.navcard.quarterly {
|
||||
background-color: bisque;
|
||||
}
|
||||
|
||||
.navcard.quarterly :active {
|
||||
background-color: burlywood;
|
||||
}
|
||||
|
||||
.navcard.modus {
|
||||
background-color: lightgoldenrodyellow;
|
||||
}
|
||||
|
||||
.navcard.modus :active {
|
||||
background-color: gold;
|
||||
}
|
||||
|
||||
|
||||
.navcard.blue {
|
||||
background-color: #dbeeff;
|
||||
}
|
||||
.navcard.blue :active {
|
||||
background-color: #2898ff;
|
||||
color: white;
|
||||
}
|
||||
.navcard.green {
|
||||
background-color: #cafae7;
|
||||
}
|
||||
.navcard.green :active {
|
||||
background-color: #33a86a;
|
||||
color: white;
|
||||
}
|
||||
.navcard.orange {
|
||||
background-color: #ffbaa0;
|
||||
}
|
||||
.navcard.orange :active {
|
||||
background-color: #ff5b1a;
|
||||
color: white;
|
||||
}
|
||||
.navcard.black {
|
||||
background-color: #2f2f2f;
|
||||
color: white;
|
||||
}
|
||||
.navcard.black :active {
|
||||
background-color: #e1e1e1;
|
||||
color: black;
|
||||
}
|
||||
|
||||
.navcard.purple {
|
||||
background-color: #794279;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.navcard.purple :active {
|
||||
background-color: #f3adf3;
|
||||
color: black;
|
||||
}
|
||||
|
||||
.navcard.beige {
|
||||
background-color: #ecbb9e;
|
||||
color: black;
|
||||
}
|
||||
|
||||
.navcard.beige :active {
|
||||
background-color: #735b4c;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.navcard.red {
|
||||
background-color: #770101;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.navcard.red :active {
|
||||
background-color: #d5b2b2;
|
||||
color: black;
|
||||
}
|
||||
18
src/app/tusha/tusha-nav-card/tusha-nav-card.component.html
Normal file
18
src/app/tusha/tusha-nav-card/tusha-nav-card.component.html
Normal file
@@ -0,0 +1,18 @@
|
||||
|
||||
<ion-card (click)="onClick()" class="navcard {{ color().color }}">
|
||||
<ion-card-content>
|
||||
<ion-grid class="innergrid">
|
||||
<ion-row>
|
||||
<ion-col size="1.5">
|
||||
<ng-content />
|
||||
</ion-col>
|
||||
<ion-col size="9.5">
|
||||
<p>{{ title() }}</p>
|
||||
</ion-col>
|
||||
<ion-col size="1">
|
||||
<ion-icon name="caret-forward"></ion-icon>
|
||||
</ion-col>
|
||||
</ion-row>
|
||||
</ion-grid>
|
||||
</ion-card-content>
|
||||
</ion-card>
|
||||
28
src/app/tusha/tusha-nav-card/tusha-nav-card.component.ts
Normal file
28
src/app/tusha/tusha-nav-card/tusha-nav-card.component.ts
Normal file
@@ -0,0 +1,28 @@
|
||||
import {Component, input, InputSignal, output} from "@angular/core";
|
||||
import {Router} from "@angular/router";
|
||||
import {
|
||||
IonCard, IonCardContent, IonCol,IonGrid, IonIcon, IonRow,
|
||||
} from "@ionic/angular/standalone";
|
||||
import {CardColor} from "./card-color";
|
||||
|
||||
@Component({
|
||||
selector: 'tusha-nav-card',
|
||||
templateUrl: 'tusha-nav-card.component.html',
|
||||
styleUrls: ['tusha-nav-card.component.css'],
|
||||
standalone: true,
|
||||
imports: [ IonIcon, IonCard, IonCardContent, IonGrid, IonRow, IonCol],
|
||||
styles: []
|
||||
})
|
||||
export class TushaNavCardComponent {
|
||||
title = input.required<String>();
|
||||
color: InputSignal<CardColor> = input<CardColor>({color: ''});
|
||||
|
||||
click = output<void>();
|
||||
|
||||
constructor(public router: Router) {
|
||||
}
|
||||
|
||||
onClick() {
|
||||
this.click.emit();
|
||||
}
|
||||
}
|
||||
9
src/app/tusha/tusha-nav-rows/nav-card-data.ts
Normal file
9
src/app/tusha/tusha-nav-rows/nav-card-data.ts
Normal file
@@ -0,0 +1,9 @@
|
||||
import {CardColor} from "../tusha-nav-card/card-color";
|
||||
|
||||
export interface NavCardData {
|
||||
id: number;
|
||||
title: string;
|
||||
color: CardColor;
|
||||
icon: string;
|
||||
onclick: () => void;
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
@for (navcard of navcards(); track navcard.id) {
|
||||
<ion-row>
|
||||
<ion-col size="12">
|
||||
<tusha-nav-card [title]="navcard.title" [color]="navcard.color" (click)="navcard.onclick()">
|
||||
<ion-icon [name]="navcard.icon"></ion-icon>
|
||||
</tusha-nav-card>
|
||||
</ion-col>
|
||||
</ion-row>
|
||||
}
|
||||
22
src/app/tusha/tusha-nav-rows/tusha-nav-rows.component.ts
Normal file
22
src/app/tusha/tusha-nav-rows/tusha-nav-rows.component.ts
Normal file
@@ -0,0 +1,22 @@
|
||||
import {Component, input, Input} from "@angular/core";
|
||||
import {IonCol, IonGrid, IonIcon, IonRow,
|
||||
} from "@ionic/angular/standalone";
|
||||
import {NavCardData} from "./nav-card-data";
|
||||
import {TushaNavCardComponent} from "../tusha-nav-card/tusha-nav-card.component";
|
||||
import {Route, Router} from "@angular/router";
|
||||
|
||||
@Component({
|
||||
selector: 'tusha-nav-rows',
|
||||
templateUrl: 'tusha-nav-rows.component.html',
|
||||
styleUrls: ['tusha-nav-rows.component.css'],
|
||||
standalone: true,
|
||||
imports: [IonIcon, IonGrid, IonRow, IonCol, TushaNavCardComponent],
|
||||
styles: []
|
||||
})
|
||||
export class TushaNavRowsComponent {
|
||||
navcards = input<NavCardData[]>([]);
|
||||
|
||||
constructor() {
|
||||
|
||||
}
|
||||
}
|
||||
23
src/app/tusha/tusha-page/tusha-page.component.css
Normal file
23
src/app/tusha/tusha-page/tusha-page.component.css
Normal file
@@ -0,0 +1,23 @@
|
||||
ion-grid {
|
||||
max-width: 280px;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
ion-grid .backpane {
|
||||
background-color: rgb(249, 239, 214);
|
||||
}
|
||||
|
||||
ion-grid.innergrid {
|
||||
margin: 0 0 0 0;
|
||||
padding: 0 0 0 0;
|
||||
}
|
||||
|
||||
ion-grid.innergrid ion-row {
|
||||
margin: 0 0 0 0;
|
||||
padding: 0 0 0 0;
|
||||
}
|
||||
|
||||
ion-grid.innergrid ion-row ion-col {
|
||||
margin: 0 0 0 0;
|
||||
padding: 0 0 0 0;
|
||||
}
|
||||
19
src/app/tusha/tusha-page/tusha-page.component.html
Normal file
19
src/app/tusha/tusha-page/tusha-page.component.html
Normal file
@@ -0,0 +1,19 @@
|
||||
<ion-header [translucent]="true">
|
||||
<ion-toolbar>
|
||||
<ion-buttons slot="start">
|
||||
<ion-menu-button></ion-menu-button>
|
||||
</ion-buttons>
|
||||
<ion-title>{{ 'Tusha - Home' }}</ion-title>
|
||||
</ion-toolbar>
|
||||
</ion-header>
|
||||
|
||||
<ng-content select="[slot=breadcrumb]"></ng-content>
|
||||
<ion-grid class="backpane">
|
||||
<ng-content />
|
||||
|
||||
</ion-grid>
|
||||
<ion-footer>
|
||||
<ion-toolbar>
|
||||
<ion-title>{{ 'Tusha - The Ultimate SelfHelp App - By AgileCC' }}</ion-title>
|
||||
</ion-toolbar>
|
||||
</ion-footer>
|
||||
18
src/app/tusha/tusha-page/tusha-page.component.ts
Normal file
18
src/app/tusha/tusha-page/tusha-page.component.ts
Normal file
@@ -0,0 +1,18 @@
|
||||
import {Component} from "@angular/core";
|
||||
import {
|
||||
IonBreadcrumb, IonBreadcrumbs,
|
||||
IonButtons, IonFooter, IonGrid, IonHeader, IonIcon, IonMenuButton, IonTitle, IonToolbar
|
||||
} from "@ionic/angular/standalone";
|
||||
|
||||
|
||||
@Component({
|
||||
selector: 'app-tusha-page',
|
||||
templateUrl: 'tusha-page.component.html',
|
||||
styleUrls: ['tusha-page.component.css'],
|
||||
standalone: true,
|
||||
imports: [IonGrid, IonTitle, IonToolbar, IonFooter, IonMenuButton, IonButtons, IonHeader, IonBreadcrumb, IonBreadcrumbs, IonIcon],
|
||||
styles: []
|
||||
})
|
||||
export class TushaPageComponent {
|
||||
|
||||
}
|
||||
9
src/app/tusha/tusha-status-cards/status-cards-data.ts
Normal file
9
src/app/tusha/tusha-status-cards/status-cards-data.ts
Normal file
@@ -0,0 +1,9 @@
|
||||
import {CardColor} from "../tusha-nav-card/card-color";
|
||||
|
||||
export interface StatusCardsData {
|
||||
id: number,
|
||||
color: CardColor,
|
||||
type: "number" | "percentage",
|
||||
amount: number,
|
||||
description: string
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
ion-card {
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
.scorecard {
|
||||
width: 7rem;
|
||||
height: 7rem;
|
||||
}
|
||||
|
||||
.scorecard .content {
|
||||
display: flex;
|
||||
height: 100%;
|
||||
justify-content: center;
|
||||
flex-wrap: wrap;
|
||||
padding: 1rem 0.2rem 1rem 0.2rem;
|
||||
}
|
||||
|
||||
.scorecard .number {
|
||||
color: black;
|
||||
height: 4rem;
|
||||
}
|
||||
|
||||
.scoreboard .number, .large {
|
||||
font-size: 3rem;
|
||||
}
|
||||
|
||||
.scoreboard .number, .medium {
|
||||
font-size: 2.75rem;
|
||||
}
|
||||
|
||||
.scorecard.orange {
|
||||
background-color: lightsalmon;
|
||||
}
|
||||
|
||||
.scorecard.green {
|
||||
background-color: lightgreen;
|
||||
}
|
||||
|
||||
.scorecard.blue {
|
||||
background-color: #2898ff;
|
||||
}
|
||||
|
||||
.scorecard .description {
|
||||
color: black;
|
||||
font-size: 0.8rem;
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
<ion-row>
|
||||
<ion-col size="6">
|
||||
<ion-card class={{card1_container_css}} id=`tusha-card-${card1().id}`>
|
||||
<ion-card-content class="content">
|
||||
<p class={{card1_number_css}}>{{ card1_number }}</p>
|
||||
<p class="description">{{ card1().description }}</p>
|
||||
</ion-card-content>
|
||||
</ion-card>
|
||||
</ion-col>
|
||||
<ion-col size="6">
|
||||
<ion-card class={{card2_container_css}} id=`tusha-card-${card2().id}`>
|
||||
<ion-card-content class="content">
|
||||
<p class={{card2_number_css}}>{{ card2_number }}</p>
|
||||
<p class="description">{{ card2().description }}</p>
|
||||
</ion-card-content>
|
||||
</ion-card>
|
||||
</ion-col>
|
||||
</ion-row>
|
||||
@@ -0,0 +1,67 @@
|
||||
import {Component, input, InputSignal, OnInit} from "@angular/core";
|
||||
import {StatusCardsData} from "./status-cards-data";
|
||||
import {IonCard, IonCardContent, IonCol, IonRow} from "@ionic/angular/standalone";
|
||||
|
||||
|
||||
@Component({
|
||||
selector: "tusha-status-cards",
|
||||
templateUrl: "tusha-status-cards.component.html",
|
||||
styleUrls: ["tusha-status-cards.component.css"],
|
||||
standalone: true,
|
||||
imports: [IonRow, IonCol, IonCard, IonCardContent]
|
||||
})
|
||||
export class TushaStatusCardsComponent implements OnInit {
|
||||
card1: InputSignal<StatusCardsData> = input.required<StatusCardsData>();
|
||||
card2: InputSignal<StatusCardsData> = input.required<StatusCardsData>();
|
||||
card1_number_css: string = '';
|
||||
card2_number_css: string = '';
|
||||
card1_container_css: string = '';
|
||||
card2_container_css: string = '';
|
||||
card1_number: string = '';
|
||||
card2_number: string = '';
|
||||
|
||||
getSuffix(statusCard: StatusCardsData): string {
|
||||
console.log(statusCard);
|
||||
if (statusCard.type === 'percentage') {
|
||||
return '%';
|
||||
} else {
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
getSizeClass(statusCard: StatusCardsData): string {
|
||||
if (statusCard.type === 'percentage') {
|
||||
return 'medium';
|
||||
} else {
|
||||
return 'large';
|
||||
}
|
||||
}
|
||||
|
||||
ngOnInit(): void {
|
||||
function initCard(statusCardsData: StatusCardsData): { css_number: string, css_container: string, number: string } {
|
||||
if (statusCardsData.type === 'percentage') {
|
||||
return {
|
||||
css_container: 'scorecard ' + statusCardsData.color.color,
|
||||
css_number: 'number medium',
|
||||
number: statusCardsData.amount + ' %'
|
||||
}
|
||||
} else {
|
||||
return {
|
||||
css_container: 'scorecard ' + statusCardsData.color.color,
|
||||
css_number: 'number large',
|
||||
number: statusCardsData.amount + ''
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const values1 = initCard(this.card1());
|
||||
this.card1_container_css = values1.css_container;
|
||||
this.card1_number_css = values1.css_number;
|
||||
this.card1_number = values1.number;
|
||||
|
||||
const values2 = initCard(this.card2());
|
||||
this.card2_container_css = values2.css_container;
|
||||
this.card2_number_css = values2.css_number;
|
||||
this.card2_number = values2.number;
|
||||
}
|
||||
}
|
||||
BIN
src/assets/icon/favicon.png
Normal file
BIN
src/assets/icon/favicon.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 930 B |
1
src/assets/shapes.svg
Normal file
1
src/assets/shapes.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg width="350" height="140" xmlns="http://www.w3.org/2000/svg" style="background:#f6f7f9"><g fill="none" fill-rule="evenodd"><path fill="#F04141" style="mix-blend-mode:multiply" d="M61.905-34.23l96.194 54.51-66.982 54.512L22 34.887z"/><circle fill="#10DC60" style="mix-blend-mode:multiply" cx="155.5" cy="135.5" r="57.5"/><path fill="#3880FF" style="mix-blend-mode:multiply" d="M208.538 9.513l84.417 15.392L223.93 93.93z"/><path fill="#FFCE00" style="mix-blend-mode:multiply" d="M268.625 106.557l46.332-26.75 46.332 26.75v53.5l-46.332 26.75-46.332-26.75z"/><circle fill="#7044FF" style="mix-blend-mode:multiply" cx="299.5" cy="9.5" r="38.5"/><rect fill="#11D3EA" style="mix-blend-mode:multiply" transform="rotate(-60 148.47 37.886)" x="143.372" y="-7.056" width="10.196" height="89.884" rx="5.098"/><path d="M-25.389 74.253l84.86 8.107c5.498.525 9.53 5.407 9.004 10.905a10 10 0 0 1-.057.477l-12.36 85.671a10.002 10.002 0 0 1-11.634 8.42l-86.351-15.226c-5.44-.959-9.07-6.145-8.112-11.584l13.851-78.551a10 10 0 0 1 10.799-8.219z" fill="#7044FF" style="mix-blend-mode:multiply"/><circle fill="#0CD1E8" style="mix-blend-mode:multiply" cx="273.5" cy="106.5" r="20.5"/></g></svg>
|
||||
|
After Width: | Height: | Size: 1.1 KiB |
3
src/environments/environment.prod.ts
Normal file
3
src/environments/environment.prod.ts
Normal file
@@ -0,0 +1,3 @@
|
||||
export const environment = {
|
||||
production: true
|
||||
};
|
||||
16
src/environments/environment.ts
Normal file
16
src/environments/environment.ts
Normal file
@@ -0,0 +1,16 @@
|
||||
// This file can be replaced during build by using the `fileReplacements` array.
|
||||
// `ng build` replaces `environment.ts` with `environment.prod.ts`.
|
||||
// The list of file replacements can be found in `angular.json`.
|
||||
|
||||
export const environment = {
|
||||
production: false
|
||||
};
|
||||
|
||||
/*
|
||||
* For easier debugging in development mode, you can import the following file
|
||||
* to ignore zone related error stack frames such as `zone.run`, `zoneDelegate.invokeTask`.
|
||||
*
|
||||
* This import should be commented out in production mode because it will have a negative impact
|
||||
* on performance if an error is thrown.
|
||||
*/
|
||||
// import 'zone.js/plugins/zone-error'; // Included with Angular CLI.
|
||||
26
src/global.scss
Normal file
26
src/global.scss
Normal file
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
* App Global CSS
|
||||
* ----------------------------------------------------------------------------
|
||||
* Put style rules here that you want to apply globally. These styles are for
|
||||
* the entire app and not just one component. Additionally, this file can be
|
||||
* used as an entry point to import other CSS/Sass files to be included in the
|
||||
* output CSS.
|
||||
* For more information on global stylesheets, visit the documentation:
|
||||
* https://ionicframework.com/docs/layout/global-stylesheets
|
||||
*/
|
||||
|
||||
/* Core CSS required for Ionic components to work properly */
|
||||
@import "@ionic/angular/css/core.css";
|
||||
|
||||
/* Basic CSS for apps built with Ionic */
|
||||
@import "@ionic/angular/css/normalize.css";
|
||||
@import "@ionic/angular/css/structure.css";
|
||||
@import "@ionic/angular/css/typography.css";
|
||||
@import "@ionic/angular/css/display.css";
|
||||
|
||||
/* Optional CSS utils that can be commented out */
|
||||
@import "@ionic/angular/css/padding.css";
|
||||
@import "@ionic/angular/css/float-elements.css";
|
||||
@import "@ionic/angular/css/text-alignment.css";
|
||||
@import "@ionic/angular/css/text-transformation.css";
|
||||
@import "@ionic/angular/css/flex-utils.css";
|
||||
29
src/index.html
Normal file
29
src/index.html
Normal file
@@ -0,0 +1,29 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<title>Ionic App</title>
|
||||
|
||||
<base href="/" />
|
||||
|
||||
<meta name="color-scheme" content="light dark" />
|
||||
<meta name="viewport" content="viewport-fit=cover, width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no" />
|
||||
<meta name="format-detection" content="telephone=no" />
|
||||
<meta name="msapplication-tap-highlight" content="no" />
|
||||
|
||||
<link rel="icon" type="image/png" href="assets/icon/favicon.png" />
|
||||
|
||||
<!-- add to homescreen for ios -->
|
||||
<meta name="apple-mobile-web-app-capable" content="yes" />
|
||||
<meta name="apple-mobile-web-app-status-bar-style" content="black" />
|
||||
|
||||
<script type="module" src="https://unpkg.com/ionicons@5.0.0/dist/ionicons/ionicons.esm.js"></script>
|
||||
<script nomodule="" src="https://unpkg.com/ionicons@5.0.0/dist/ionicons/ionicons.js"></script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<app-root></app-root>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
20
src/main.ts
Normal file
20
src/main.ts
Normal file
@@ -0,0 +1,20 @@
|
||||
import { enableProdMode } from '@angular/core';
|
||||
import { bootstrapApplication } from '@angular/platform-browser';
|
||||
import { RouteReuseStrategy, provideRouter } from '@angular/router';
|
||||
import { IonicRouteStrategy, provideIonicAngular } from '@ionic/angular/standalone';
|
||||
|
||||
import { routes } from './app/app.routes';
|
||||
import { AppComponent } from './app/app.component';
|
||||
import { environment } from './environments/environment';
|
||||
|
||||
if (environment.production) {
|
||||
enableProdMode();
|
||||
}
|
||||
|
||||
bootstrapApplication(AppComponent, {
|
||||
providers: [
|
||||
{ provide: RouteReuseStrategy, useClass: IonicRouteStrategy },
|
||||
provideIonicAngular(),
|
||||
provideRouter(routes),
|
||||
],
|
||||
});
|
||||
55
src/polyfills.ts
Normal file
55
src/polyfills.ts
Normal file
@@ -0,0 +1,55 @@
|
||||
/**
|
||||
* This file includes polyfills needed by Angular and is loaded before the app.
|
||||
* You can add your own extra polyfills to this file.
|
||||
*
|
||||
* This file is divided into 2 sections:
|
||||
* 1. Browser polyfills. These are applied before loading ZoneJS and are sorted by browsers.
|
||||
* 2. Application imports. Files imported after ZoneJS that should be loaded before your main
|
||||
* file.
|
||||
*
|
||||
* The current setup is for so-called "evergreen" browsers; the last versions of browsers that
|
||||
* automatically update themselves. This includes recent versions of Safari, Chrome (including
|
||||
* Opera), Edge on the desktop, and iOS and Chrome on mobile.
|
||||
*
|
||||
* Learn more in https://angular.io/guide/browser-support
|
||||
*/
|
||||
|
||||
/***************************************************************************************************
|
||||
* BROWSER POLYFILLS
|
||||
*/
|
||||
|
||||
/**
|
||||
* By default, zone.js will patch all possible macroTask and DomEvents
|
||||
* user can disable parts of macroTask/DomEvents patch by setting following flags
|
||||
* because those flags need to be set before `zone.js` being loaded, and webpack
|
||||
* will put import in the top of bundle, so user need to create a separate file
|
||||
* in this directory (for example: zone-flags.ts), and put the following flags
|
||||
* into that file, and then add the following code before importing zone.js.
|
||||
* import './zone-flags';
|
||||
*
|
||||
* The flags allowed in zone-flags.ts are listed here.
|
||||
*
|
||||
* The following flags will work for all browsers.
|
||||
*
|
||||
* (window as any).__Zone_disable_requestAnimationFrame = true; // disable patch requestAnimationFrame
|
||||
* (window as any).__Zone_disable_on_property = true; // disable patch onProperty such as onclick
|
||||
* (window as any).__zone_symbol__UNPATCHED_EVENTS = ['scroll', 'mousemove']; // disable patch specified eventNames
|
||||
*
|
||||
* in IE/Edge developer tools, the addEventListener will also be wrapped by zone.js
|
||||
* with the following flag, it will bypass `zone.js` patch for IE/Edge
|
||||
*
|
||||
* (window as any).__Zone_enable_cross_context_check = true;
|
||||
*
|
||||
*/
|
||||
|
||||
import './zone-flags';
|
||||
|
||||
/***************************************************************************************************
|
||||
* Zone JS is required by default for Angular itself.
|
||||
*/
|
||||
import 'zone.js'; // Included with Angular CLI.
|
||||
|
||||
|
||||
/***************************************************************************************************
|
||||
* APPLICATION IMPORTS
|
||||
*/
|
||||
14
src/test.ts
Normal file
14
src/test.ts
Normal file
@@ -0,0 +1,14 @@
|
||||
// This file is required by karma.conf.js and loads recursively all the .spec and framework files
|
||||
|
||||
import 'zone.js/testing';
|
||||
import { getTestBed } from '@angular/core/testing';
|
||||
import {
|
||||
BrowserDynamicTestingModule,
|
||||
platformBrowserDynamicTesting
|
||||
} from '@angular/platform-browser-dynamic/testing';
|
||||
|
||||
// First, initialize the Angular testing environment.
|
||||
getTestBed().initTestEnvironment(
|
||||
BrowserDynamicTestingModule,
|
||||
platformBrowserDynamicTesting(),
|
||||
);
|
||||
244
src/theme/variables.scss
Normal file
244
src/theme/variables.scss
Normal file
@@ -0,0 +1,244 @@
|
||||
// Ionic Variables and Theming. For more info, please see:
|
||||
// http://ionicframework.com/docs/theming/
|
||||
|
||||
/** Ionic CSS Variables **/
|
||||
:root {
|
||||
/** primary **/
|
||||
--ion-color-primary: #3880ff;
|
||||
--ion-color-primary-rgb: 56, 128, 255;
|
||||
--ion-color-primary-contrast: #ffffff;
|
||||
--ion-color-primary-contrast-rgb: 255, 255, 255;
|
||||
--ion-color-primary-shade: #3171e0;
|
||||
--ion-color-primary-tint: #4c8dff;
|
||||
|
||||
/** secondary **/
|
||||
--ion-color-secondary: #3dc2ff;
|
||||
--ion-color-secondary-rgb: 61, 194, 255;
|
||||
--ion-color-secondary-contrast: #ffffff;
|
||||
--ion-color-secondary-contrast-rgb: 255, 255, 255;
|
||||
--ion-color-secondary-shade: #36abe0;
|
||||
--ion-color-secondary-tint: #50c8ff;
|
||||
|
||||
/** tertiary **/
|
||||
--ion-color-tertiary: #5260ff;
|
||||
--ion-color-tertiary-rgb: 82, 96, 255;
|
||||
--ion-color-tertiary-contrast: #ffffff;
|
||||
--ion-color-tertiary-contrast-rgb: 255, 255, 255;
|
||||
--ion-color-tertiary-shade: #4854e0;
|
||||
--ion-color-tertiary-tint: #6370ff;
|
||||
|
||||
/** success **/
|
||||
--ion-color-success: #2dd36f;
|
||||
--ion-color-success-rgb: 45, 211, 111;
|
||||
--ion-color-success-contrast: #ffffff;
|
||||
--ion-color-success-contrast-rgb: 255, 255, 255;
|
||||
--ion-color-success-shade: #28ba62;
|
||||
--ion-color-success-tint: #42d77d;
|
||||
|
||||
/** warning **/
|
||||
--ion-color-warning: #ffc409;
|
||||
--ion-color-warning-rgb: 255, 196, 9;
|
||||
--ion-color-warning-contrast: #000000;
|
||||
--ion-color-warning-contrast-rgb: 0, 0, 0;
|
||||
--ion-color-warning-shade: #e0ac08;
|
||||
--ion-color-warning-tint: #ffca22;
|
||||
|
||||
/** danger **/
|
||||
--ion-color-danger: #eb445a;
|
||||
--ion-color-danger-rgb: 235, 68, 90;
|
||||
--ion-color-danger-contrast: #ffffff;
|
||||
--ion-color-danger-contrast-rgb: 255, 255, 255;
|
||||
--ion-color-danger-shade: #cf3c4f;
|
||||
--ion-color-danger-tint: #ed576b;
|
||||
|
||||
/** dark **/
|
||||
--ion-color-dark: #222428;
|
||||
--ion-color-dark-rgb: 34, 36, 40;
|
||||
--ion-color-dark-contrast: #ffffff;
|
||||
--ion-color-dark-contrast-rgb: 255, 255, 255;
|
||||
--ion-color-dark-shade: #1e2023;
|
||||
--ion-color-dark-tint: #383a3e;
|
||||
|
||||
/** medium **/
|
||||
--ion-color-medium: #92949c;
|
||||
--ion-color-medium-rgb: 146, 148, 156;
|
||||
--ion-color-medium-contrast: #ffffff;
|
||||
--ion-color-medium-contrast-rgb: 255, 255, 255;
|
||||
--ion-color-medium-shade: #808289;
|
||||
--ion-color-medium-tint: #9d9fa6;
|
||||
|
||||
/** light **/
|
||||
--ion-color-light: #f4f5f8;
|
||||
--ion-color-light-rgb: 244, 245, 248;
|
||||
--ion-color-light-contrast: #000000;
|
||||
--ion-color-light-contrast-rgb: 0, 0, 0;
|
||||
--ion-color-light-shade: #d7d8da;
|
||||
--ion-color-light-tint: #f5f6f9;
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
/*
|
||||
* Dark Colors
|
||||
* -------------------------------------------
|
||||
*/
|
||||
|
||||
body {
|
||||
--ion-color-primary: #428cff;
|
||||
--ion-color-primary-rgb: 66,140,255;
|
||||
--ion-color-primary-contrast: #ffffff;
|
||||
--ion-color-primary-contrast-rgb: 255,255,255;
|
||||
--ion-color-primary-shade: #3a7be0;
|
||||
--ion-color-primary-tint: #5598ff;
|
||||
|
||||
--ion-color-secondary: #50c8ff;
|
||||
--ion-color-secondary-rgb: 80,200,255;
|
||||
--ion-color-secondary-contrast: #ffffff;
|
||||
--ion-color-secondary-contrast-rgb: 255,255,255;
|
||||
--ion-color-secondary-shade: #46b0e0;
|
||||
--ion-color-secondary-tint: #62ceff;
|
||||
|
||||
--ion-color-tertiary: #6a64ff;
|
||||
--ion-color-tertiary-rgb: 106,100,255;
|
||||
--ion-color-tertiary-contrast: #ffffff;
|
||||
--ion-color-tertiary-contrast-rgb: 255,255,255;
|
||||
--ion-color-tertiary-shade: #5d58e0;
|
||||
--ion-color-tertiary-tint: #7974ff;
|
||||
|
||||
--ion-color-success: #2fdf75;
|
||||
--ion-color-success-rgb: 47,223,117;
|
||||
--ion-color-success-contrast: #000000;
|
||||
--ion-color-success-contrast-rgb: 0,0,0;
|
||||
--ion-color-success-shade: #29c467;
|
||||
--ion-color-success-tint: #44e283;
|
||||
|
||||
--ion-color-warning: #ffd534;
|
||||
--ion-color-warning-rgb: 255,213,52;
|
||||
--ion-color-warning-contrast: #000000;
|
||||
--ion-color-warning-contrast-rgb: 0,0,0;
|
||||
--ion-color-warning-shade: #e0bb2e;
|
||||
--ion-color-warning-tint: #ffd948;
|
||||
|
||||
--ion-color-danger: #ff4961;
|
||||
--ion-color-danger-rgb: 255,73,97;
|
||||
--ion-color-danger-contrast: #ffffff;
|
||||
--ion-color-danger-contrast-rgb: 255,255,255;
|
||||
--ion-color-danger-shade: #e04055;
|
||||
--ion-color-danger-tint: #ff5b71;
|
||||
|
||||
--ion-color-dark: #f4f5f8;
|
||||
--ion-color-dark-rgb: 244,245,248;
|
||||
--ion-color-dark-contrast: #000000;
|
||||
--ion-color-dark-contrast-rgb: 0,0,0;
|
||||
--ion-color-dark-shade: #d7d8da;
|
||||
--ion-color-dark-tint: #f5f6f9;
|
||||
|
||||
--ion-color-medium: #989aa2;
|
||||
--ion-color-medium-rgb: 152,154,162;
|
||||
--ion-color-medium-contrast: #000000;
|
||||
--ion-color-medium-contrast-rgb: 0,0,0;
|
||||
--ion-color-medium-shade: #86888f;
|
||||
--ion-color-medium-tint: #a2a4ab;
|
||||
|
||||
--ion-color-light: #222428;
|
||||
--ion-color-light-rgb: 34,36,40;
|
||||
--ion-color-light-contrast: #ffffff;
|
||||
--ion-color-light-contrast-rgb: 255,255,255;
|
||||
--ion-color-light-shade: #1e2023;
|
||||
--ion-color-light-tint: #383a3e;
|
||||
}
|
||||
|
||||
/*
|
||||
* iOS Dark Theme
|
||||
* -------------------------------------------
|
||||
*/
|
||||
|
||||
.ios body {
|
||||
--ion-background-color: #000000;
|
||||
--ion-background-color-rgb: 0,0,0;
|
||||
|
||||
--ion-text-color: #ffffff;
|
||||
--ion-text-color-rgb: 255,255,255;
|
||||
|
||||
--ion-color-step-50: #0d0d0d;
|
||||
--ion-color-step-100: #1a1a1a;
|
||||
--ion-color-step-150: #262626;
|
||||
--ion-color-step-200: #333333;
|
||||
--ion-color-step-250: #404040;
|
||||
--ion-color-step-300: #4d4d4d;
|
||||
--ion-color-step-350: #595959;
|
||||
--ion-color-step-400: #666666;
|
||||
--ion-color-step-450: #737373;
|
||||
--ion-color-step-500: #808080;
|
||||
--ion-color-step-550: #8c8c8c;
|
||||
--ion-color-step-600: #999999;
|
||||
--ion-color-step-650: #a6a6a6;
|
||||
--ion-color-step-700: #b3b3b3;
|
||||
--ion-color-step-750: #bfbfbf;
|
||||
--ion-color-step-800: #cccccc;
|
||||
--ion-color-step-850: #d9d9d9;
|
||||
--ion-color-step-900: #e6e6e6;
|
||||
--ion-color-step-950: #f2f2f2;
|
||||
|
||||
--ion-item-background: #000000;
|
||||
|
||||
--ion-card-background: #1c1c1d;
|
||||
}
|
||||
|
||||
.ios ion-modal {
|
||||
--ion-background-color: var(--ion-color-step-100);
|
||||
--ion-toolbar-background: var(--ion-color-step-150);
|
||||
--ion-toolbar-border-color: var(--ion-color-step-250);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Material Design Dark Theme
|
||||
* -------------------------------------------
|
||||
*/
|
||||
|
||||
.md body {
|
||||
--ion-background-color: #121212;
|
||||
--ion-background-color-rgb: 18,18,18;
|
||||
|
||||
--ion-text-color: #ffffff;
|
||||
--ion-text-color-rgb: 255,255,255;
|
||||
|
||||
--ion-border-color: #222222;
|
||||
|
||||
--ion-color-step-50: #1e1e1e;
|
||||
--ion-color-step-100: #2a2a2a;
|
||||
--ion-color-step-150: #363636;
|
||||
--ion-color-step-200: #414141;
|
||||
--ion-color-step-250: #4d4d4d;
|
||||
--ion-color-step-300: #595959;
|
||||
--ion-color-step-350: #656565;
|
||||
--ion-color-step-400: #717171;
|
||||
--ion-color-step-450: #7d7d7d;
|
||||
--ion-color-step-500: #898989;
|
||||
--ion-color-step-550: #949494;
|
||||
--ion-color-step-600: #a0a0a0;
|
||||
--ion-color-step-650: #acacac;
|
||||
--ion-color-step-700: #b8b8b8;
|
||||
--ion-color-step-750: #c4c4c4;
|
||||
--ion-color-step-800: #d0d0d0;
|
||||
--ion-color-step-850: #dbdbdb;
|
||||
--ion-color-step-900: #e7e7e7;
|
||||
--ion-color-step-950: #f3f3f3;
|
||||
|
||||
--ion-item-background: #1e1e1e;
|
||||
|
||||
--ion-toolbar-background: #1f1f1f;
|
||||
|
||||
--ion-tab-bar-background: #1f1f1f;
|
||||
|
||||
--ion-card-background: #1e1e1e;
|
||||
}
|
||||
}
|
||||
|
||||
html {
|
||||
/*
|
||||
* For more information on dynamic font scaling, visit the documentation:
|
||||
* https://ionicframework.com/docs/layout/dynamic-font-scaling
|
||||
*/
|
||||
--ion-dynamic-font: var(--ion-default-dynamic-font);
|
||||
}
|
||||
6
src/zone-flags.ts
Normal file
6
src/zone-flags.ts
Normal file
@@ -0,0 +1,6 @@
|
||||
/**
|
||||
* Prevents Angular change detection from
|
||||
* running with certain Web Component callbacks
|
||||
*/
|
||||
// eslint-disable-next-line no-underscore-dangle
|
||||
(window as any).__Zone_disable_customElements = true;
|
||||
Reference in New Issue
Block a user