Docker, API proxy, Drone CI, .env

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Rafał Miczek
2026-02-13 19:58:25 +01:00
co-authored by Cursor
commit d5d4883917
76 changed files with 15170 additions and 0 deletions
@@ -0,0 +1,110 @@
import { Component, Input } from '@angular/core';
import { CommonModule } from '@angular/common';
import { NgChartsModule } from 'ng2-charts';
import {
ChartConfiguration,
ChartData,
} from 'chart.js';
import { SportGoal, Activity } from '../../../core/models/sport-goal.model';
import { ProgressCardComponent } from '../../../shared/components/progress-card/progress-card.component';
import { ChartCardComponent } from '../../../shared/components/chart-card/chart-card.component';
@Component({
selector: 'app-sport-section',
standalone: true,
imports: [CommonModule, NgChartsModule, ProgressCardComponent, ChartCardComponent],
template: `
<div
class="backdrop-blur-sm rounded-2xl shadow-xl p-6 md:p-8 border-2 mt-8"
[ngClass]="gradientClass"
>
<div class="flex items-center gap-3 mb-6 pb-4 border-b-2" [ngClass]="borderClass">
<span class="text-5xl">{{ emoji }}</span>
<div>
<h3 class="text-2xl font-bold text-gray-900">{{ title }}</h3>
<p class="text-sm text-gray-600">{{ description }}</p>
</div>
</div>
<div class="space-y-6">
<app-progress-card
[title]="title"
[emoji]="emoji"
[percentage]="goal.percentage"
[currentLabel]="formatDistance(goal.current) + ' km'"
[targetLabel]="goal.target + ' km'"
[description]="
'Progress: ' +
formatDistance(goal.current) +
' / ' +
goal.target +
' km'
"
[estimatedCompletion]="estimatedCompletion"
[dailyKmNeeded]="dailyKmNeeded"
[currentDailyAvg]="currentDailyAvg"
[optimalDailyAvg]="optimalDailyAvg"
[daysAheadOrBehind]="daysAheadOrBehind"
[recentActivities]="recentActivities"
></app-progress-card>
<div class="bg-white/90 backdrop-blur-md rounded-xl shadow-lg p-6 border" [ngClass]="borderColorClass">
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
<div>
<h4 class="text-lg font-semibold text-gray-900 mb-4 text-center">Progress</h4>
<div class="h-64">
<canvas
baseChart
[data]="doughnutData"
[type]="'doughnut'"
[options]="doughnutOptions"
></canvas>
</div>
<div class="mt-4 text-center space-y-2">
<p class="text-sm text-gray-600">
<span class="font-semibold text-gray-900">{{ goal.percentage.toFixed(1) }}%</span> Actual
</p>
<p class="text-xs text-gray-500">
Optimal: <span class="font-semibold">{{ idealProgress.toFixed(1) }}%</span>
</p>
</div>
</div>
<div>
<app-chart-card
[title]="title + ' Progress Over Time'"
[chartData]="chartData"
[chartType]="'line'"
[chartOptions]="chartOptions"
></app-chart-card>
</div>
</div>
</div>
</div>
</div>
`,
})
export class SportSectionComponent {
@Input() title = '';
@Input() emoji = '';
@Input() description = '';
@Input() goal!: SportGoal;
@Input() estimatedCompletion: string | null = null;
@Input() dailyKmNeeded: number | null = null;
@Input() currentDailyAvg: number | null = null;
@Input() optimalDailyAvg: number | null = null;
@Input() daysAheadOrBehind: number | null = null;
@Input() recentActivities: Activity[] | null = null;
@Input() idealProgress = 0;
@Input() doughnutData!: ChartData<'doughnut'>;
@Input() chartData!: ChartData<'line'>;
@Input() doughnutOptions!: ChartConfiguration<'doughnut'>['options'];
@Input() chartOptions!: ChartConfiguration['options'];
@Input() gradientClass = '';
@Input() borderClass = '';
@Input() borderColorClass = '';
readonly Math = Math;
formatDistance(km: number): string {
return km.toFixed(2);
}
}