Skip to content

Commit a919390

Browse files
Creating the substance-selector component and applying to every appliable page
1 parent b28f747 commit a919390

File tree

9 files changed

+115
-135
lines changed

9 files changed

+115
-135
lines changed
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
<!-- Substance Selector -->
2+
<div class="bg-white/80 dark:bg-gray-900/80 backdrop-blur-sm rounded-2xl shadow-md p-6 mb-8 border border-gray-100 dark:border-gray-800">
3+
<h3 class="text-lg font-semibold text-gray-700 dark:text-gray-200 mb-4">
4+
{{ 'Filter by Substance' | transloco }}
5+
</h3>
6+
<div class="flex flex-wrap gap-2">
7+
<button
8+
(click)="currentSubstance.set(0)"
9+
[ngClass]="currentSubstance() === 0
10+
? 'bg-gradient-to-r from-purple-500 to-orange-500 text-white shadow-sm'
11+
: 'bg-gray-100 dark:bg-gray-800 text-gray-700 dark:text-gray-200 hover:bg-gray-200 dark:hover:bg-gray-700'"
12+
class="px-4 py-2 rounded-full text-sm transition-all"
13+
>
14+
{{ 'All Substances' | transloco }}
15+
</button>
16+
<button
17+
*ngFor="let substance of substances()"
18+
(click)="currentSubstance.set(substance.id)"
19+
[ngClass]="currentSubstance() === substance.id
20+
? 'bg-gradient-to-r from-purple-500 to-orange-500 text-white shadow-sm'
21+
: 'bg-gray-100 dark:bg-gray-800 text-gray-700 dark:text-gray-200 hover:bg-gray-200 dark:hover:bg-gray-700'"
22+
class="px-4 py-2 rounded-full text-sm transition-all"
23+
>
24+
{{ substance.name }}
25+
</button>
26+
</div>
27+
</div>
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import { ComponentFixture, TestBed } from '@angular/core/testing';
2+
3+
import { SubstanceSelectorComponent } from './substance-selector.component';
4+
5+
describe('SubstanceSelector', () => {
6+
let component: SubstanceSelectorComponent;
7+
let fixture: ComponentFixture<SubstanceSelectorComponent>;
8+
9+
beforeEach(async () => {
10+
await TestBed.configureTestingModule({
11+
imports: [SubstanceSelectorComponent]
12+
})
13+
.compileComponents();
14+
15+
fixture = TestBed.createComponent(SubstanceSelectorComponent);
16+
component = fixture.componentInstance;
17+
fixture.detectChanges();
18+
});
19+
20+
it('should create', () => {
21+
expect(component).toBeTruthy();
22+
});
23+
});
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import { Component, input, model } from '@angular/core';
2+
import { SubstanceDto } from '../../dto/substance.dto';
3+
import { TranslocoModule } from '@jsverse/transloco';
4+
import { FormsModule } from '@angular/forms';
5+
import { CommonModule } from '@angular/common';
6+
7+
@Component({
8+
selector: 'app-substance-selector',
9+
imports: [
10+
TranslocoModule,
11+
FormsModule,
12+
CommonModule
13+
],
14+
templateUrl: './substance-selector.component.html'
15+
})
16+
export class SubstanceSelectorComponent {
17+
18+
19+
currentSubstance = model<number>();
20+
21+
substances = input<MapIterator<SubstanceDto>>();
22+
23+
}

src/app/pages/recovery-dashboard/recovery-dashboard.component.html

Lines changed: 5 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -23,50 +23,11 @@
2323
</div>
2424
</div>
2525

26-
<!-- Filters and Controls -->
27-
<div class="bg-white/80 dark:bg-gray-900/80 backdrop-blur-sm rounded-2xl shadow-md p-5 mb-6 border border-gray-100 dark:border-gray-800">
28-
<div class="flex flex-wrap items-center justify-between gap-4">
29-
<div class="flex items-center">
30-
<span class="text-gray-700 dark:text-gray-200 font-medium mr-3">{{ 'Filter by:' | transloco }}</span>
31-
<form>
32-
@let options = [{ id: 0, name: ('All Substances' | transloco) }].concat(Array.from(substances().values()));
33-
<p-select
34-
[options]="options"
35-
optionLabel="name"
36-
optionValue="id"
37-
[(ngModel)]="selectedAnalysisSubstance"
38-
name="substance"
39-
[style]="{ minWidth: '200px' }"
40-
placeholder="{{ 'All Substances' | transloco }}"
41-
(onChange)="onSelectedAnalysisSubstanceChange()"
42-
></p-select>
43-
</form>
44-
</div>
45-
<div class="flex items-center gap-2">
46-
@if (substanceMap().length === -1) {
47-
<button
48-
class="bg-purple-50 dark:bg-purple-900/40 hover:bg-purple-100 dark:hover:bg-purple-800 text-purple-700 dark:text-purple-200 px-4 py-2 rounded-lg border border-purple-200 dark:border-purple-800 transition-colors flex items-center">
49-
<svg xmlns="http://www.w3.org/2000/svg" class="h-4 w-4 mr-1.5" fill="none" viewBox="0 0 24 24"
50-
stroke="currentColor">
51-
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
52-
d="M3 4a1 1 0 011-1h16a1 1 0 011 1v2.586a1 1 0 01-.293.707l-6.414 6.414a1 1 0 00-.293.707V17l-4 4v-6.586a1 1 0 00-.293-.707L3.293 7.293A1 1 0 013 6.586V4z" />
53-
</svg>
54-
{{ 'Filter' | transloco }}
55-
</button>
56-
<button
57-
class="bg-orange-50 dark:bg-orange-900/40 hover:bg-orange-100 dark:hover:bg-orange-800 text-orange-700 dark:text-orange-200 px-4 py-2 rounded-lg border border-orange-200 dark:border-orange-800 transition-colors flex items-center">
58-
<svg xmlns="http://www.w3.org/2000/svg" class="h-4 w-4 mr-1.5" fill="none" viewBox="0 0 24 24"
59-
stroke="currentColor">
60-
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
61-
d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2" />
62-
</svg>
63-
{{ 'Export' | transloco }}
64-
</button>
65-
}
66-
</div>
67-
</div>
68-
</div>
69-
26+
<app-substance-selector
27+
[currentSubstance]="selectedAnalysisSubstance()"
28+
(currentSubstanceChange)="selectedAnalysisSubstance.set($event?.valueOf() || 0); onSelectedAnalysisSubstanceChange()"
29+
[substances]="substances().values()"
30+
/>
7031

7132
<!-- Substance Analysis Section -->
7233
<app-substance-analysis-card [usageHistory]="usageHistory()"

src/app/pages/recovery-dashboard/recovery-dashboard.component.ts

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -19,20 +19,22 @@ import { RouterLink } from "@angular/router";
1919
import { TranslocoAvailableLangs } from "../../app.config";
2020
import { getDateForChart } from "../../util/date.utils";
2121
import { SelectModule } from "primeng/select";
22+
import { SubstanceSelectorComponent } from "../../components/substance/substance-selector.component";
2223

2324
@Component({
2425
selector: "app-recovery-dashboard",
2526
standalone: true,
2627
imports: [
27-
CommonModule,
28-
FormsModule,
29-
FinancialImpactCardComponent,
30-
SubstanceAnalysisCardComponent,
31-
SobrietyCardComponent,
32-
TranslocoModule,
33-
RouterLink,
34-
SelectModule,
35-
],
28+
CommonModule,
29+
FormsModule,
30+
FinancialImpactCardComponent,
31+
SubstanceAnalysisCardComponent,
32+
SobrietyCardComponent,
33+
TranslocoModule,
34+
RouterLink,
35+
SelectModule,
36+
SubstanceSelectorComponent
37+
],
3638
templateUrl: "./recovery-dashboard.component.html",
3739
})
3840
export class RecoveryDashboardComponent implements OnInit {

src/app/pages/triggers/triggers.component.html

Lines changed: 5 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -10,33 +10,11 @@ <h2 class="text-2xl font-semibold bg-gradient-to-r from-purple-600 to-orange-500
1010
</p>
1111
</div>
1212

13-
<!-- Substance Selector -->
14-
<div class="bg-white/80 dark:bg-gray-900/80 backdrop-blur-sm rounded-2xl shadow-md p-6 mb-8 border border-gray-100 dark:border-gray-800">
15-
<h3 class="text-lg font-semibold text-gray-700 dark:text-gray-200 mb-4">
16-
{{ 'Filter by Substance' | transloco }}
17-
</h3>
18-
<div class="flex flex-wrap gap-2">
19-
<button
20-
(click)="setSelectedSubstance('all')"
21-
[ngClass]="selectedSubstance === 'all'
22-
? 'bg-gradient-to-r from-purple-500 to-orange-500 text-white shadow-sm'
23-
: 'bg-gray-100 dark:bg-gray-800 text-gray-700 dark:text-gray-200 hover:bg-gray-200 dark:hover:bg-gray-700'"
24-
class="px-4 py-2 rounded-full text-sm transition-all"
25-
>
26-
{{ 'All Substances' | transloco }}
27-
</button>
28-
<button
29-
*ngFor="let substance of substances"
30-
(click)="setSelectedSubstance(substance.name)"
31-
[ngClass]="selectedSubstance === substance.name
32-
? 'bg-gradient-to-r from-purple-500 to-orange-500 text-white shadow-sm'
33-
: 'bg-gray-100 dark:bg-gray-800 text-gray-700 dark:text-gray-200 hover:bg-gray-200 dark:hover:bg-gray-700'"
34-
class="px-4 py-2 rounded-full text-sm transition-all"
35-
>
36-
{{ substance.name }}
37-
</button>
38-
</div>
39-
</div>
13+
<app-substance-selector
14+
[currentSubstance]="selectedSubstanceId()"
15+
(currentSubstanceChange)="setSelectedSubstanceId($event || 0)"
16+
[substances]="substancesMap.values()"
17+
/>
4018

4119
<!-- Trigger Distribution -->
4220
<div class="bg-white/80 dark:bg-gray-900/80 backdrop-blur-sm rounded-2xl shadow-md p-6 mb-8 border border-gray-100 dark:border-gray-800">

src/app/pages/triggers/triggers.component.ts

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { CommonModule } from "@angular/common";
2-
import { Component, OnInit } from "@angular/core";
2+
import { Component, model, OnInit } from "@angular/core";
33
import { UsageService } from "../../services/usage.service";
44
import { SubstanceService } from "../../services/substance.service";
55
import { UsageDto } from "../../dto/usage.dto";
@@ -8,17 +8,20 @@ import { TriggerDto } from "../../dto/trigger.dto";
88
import { ChartModule } from "primeng/chart";
99
import { TriggerService } from "../../services/trigger.service";
1010
import { TranslocoModule } from "@jsverse/transloco";
11+
import { SubstanceSelectorComponent } from "../../components/substance/substance-selector.component";
1112

1213
@Component({
1314
selector: "app-triggers-page",
1415
standalone: true,
15-
imports: [CommonModule, ChartModule, TranslocoModule],
16+
imports: [CommonModule, ChartModule, TranslocoModule, SubstanceSelectorComponent],
1617
templateUrl: "./triggers.component.html",
1718
})
1819
export class TriggersComponent implements OnInit {
1920
usageHistory: UsageDto[] = [];
2021
substances: SubstanceDto[] = [];
22+
substancesMap = new Map<number, SubstanceDto>();
2123
selectedSubstance = "all";
24+
selectedSubstanceId = model<number>(0);
2225
triggers: TriggerDto[] = [];
2326
COLORS = ["#8B5CF6", "#F97316", "#6366F1", "#FB923C", "#A855F7", "#FDBA74"];
2427

@@ -43,6 +46,9 @@ export class TriggersComponent implements OnInit {
4346
});
4447
this.substanceService.list().then((subs) => {
4548
this.substances = subs as SubstanceDto[];
49+
this.substancesMap = this.substances.reduce(
50+
(prev, curr, currIdx) => prev.set(currIdx, curr), new Map<number, SubstanceDto>
51+
);
4652
this.updateCharts();
4753
});
4854
this.triggerService.list().then((triggers) => {
@@ -252,6 +258,13 @@ export class TriggersComponent implements OnInit {
252258

253259
setSelectedSubstance(substance: string) {
254260
this.selectedSubstance = substance;
261+
this.selectedSubstanceId.set(this.substances.find((sub => sub.name == substance))?.id || 0);
262+
this.updateCharts();
263+
}
264+
265+
setSelectedSubstanceId(substanceId: number) {
266+
this.selectedSubstanceId.set(substanceId);
267+
this.selectedSubstance = this.substancesMap.get(substanceId - 1)?.name || 'all';
255268
this.updateCharts();
256269
}
257270

src/app/pages/usage-entries/usage-entries.component.html

Lines changed: 4 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -12,58 +12,10 @@
1212
</p>
1313
</div>
1414

15-
<!-- Filters and Controls -->
16-
<div class="bg-white/80 dark:bg-gray-900/80 backdrop-blur-sm rounded-2xl shadow-md p-5 mb-6 border border-gray-100 dark:border-gray-800">
17-
<div class="flex flex-wrap items-center justify-between gap-4">
18-
<div class="flex items-center">
19-
<span class="text-gray-700 dark:text-gray-200 font-medium mr-3">{{ 'Filter by:' | transloco }}</span>
20-
<form>
21-
@let options = [{ id: 0, name: ('All Substances' | transloco) }].concat(Array.from(substances.values()));
22-
<p-select
23-
[options]="options"
24-
optionLabel="name"
25-
optionValue="id"
26-
[(ngModel)]="currentSubstance"
27-
name="substance"
28-
[style]="{ minWidth: '200px' }"
29-
placeholder="{{ 'All Substances' | transloco }}"
30-
></p-select>
31-
<!-- <select
32-
class="bg-gray-50 dark:bg-gray-800 border border-gray-200 dark:border-gray-700 text-gray-700 dark:text-gray-200 rounded-lg px-3 py-2 focus:outline-none focus:ring-2 focus:ring-purple-500 focus:border-transparent"
33-
name="substance"
34-
[(ngModel)]="currentSubstance"
35-
>
36-
<option value="0">{{ 'All Substances' | transloco }}</option>
37-
<option *ngFor="let substance of substances.values()" [value]="substance.id">
38-
{{ substance.name }}
39-
</option>
40-
</select> -->
41-
</form>
42-
</div>
43-
<div class="flex items-center gap-2">
44-
@if (substances.size === -1) {
45-
<button
46-
class="bg-purple-50 dark:bg-purple-900/40 hover:bg-purple-100 dark:hover:bg-purple-800 text-purple-700 dark:text-purple-200 px-4 py-2 rounded-lg border border-purple-200 dark:border-purple-800 transition-colors flex items-center">
47-
<svg xmlns="http://www.w3.org/2000/svg" class="h-4 w-4 mr-1.5" fill="none" viewBox="0 0 24 24"
48-
stroke="currentColor">
49-
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
50-
d="M3 4a1 1 0 011-1h16a1 1 0 011 1v2.586a1 1 0 01-.293.707l-6.414 6.414a1 1 0 00-.293.707V17l-4 4v-6.586a1 1 0 00-.293-.707L3.293 7.293A1 1 0 013 6.586V4z" />
51-
</svg>
52-
{{ 'Filter' | transloco }}
53-
</button>
54-
<button
55-
class="bg-orange-50 dark:bg-orange-900/40 hover:bg-orange-100 dark:hover:bg-orange-800 text-orange-700 dark:text-orange-200 px-4 py-2 rounded-lg border border-orange-200 dark:border-orange-800 transition-colors flex items-center">
56-
<svg xmlns="http://www.w3.org/2000/svg" class="h-4 w-4 mr-1.5" fill="none" viewBox="0 0 24 24"
57-
stroke="currentColor">
58-
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
59-
d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2" />
60-
</svg>
61-
{{ 'Export' | transloco }}
62-
</button>
63-
}
64-
</div>
65-
</div>
66-
</div>
15+
<app-substance-selector
16+
[(currentSubstance)]="currentSubstance"
17+
[substances]="substances.values()"
18+
/>
6719

6820
<!-- Entries List + Stats -->
6921
<div class="bg-white/80 dark:bg-gray-900/80 backdrop-blur-sm rounded-2xl shadow-md p-6 mb-8 border border-gray-100 dark:border-gray-800">

src/app/pages/usage-entries/usage-entries.component.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,12 @@ import { FormsModule } from "@angular/forms";
1010
import { SelectModule } from "primeng/select";
1111
import { MessageService } from "primeng/api";
1212
import { TranslocoModule } from "@jsverse/transloco";
13+
import { SubstanceSelectorComponent } from "../../components/substance/substance-selector.component";
1314

1415
@Component({
1516
selector: "app-usage-entries",
1617
standalone: true,
17-
imports: [CommonModule, FormsModule, SelectModule, TranslocoModule],
18+
imports: [CommonModule, FormsModule, SelectModule, TranslocoModule, SubstanceSelectorComponent],
1819
templateUrl: "./usage-entries.component.html",
1920
})
2021
export class UsageEntriesComponent implements OnInit {

0 commit comments

Comments
 (0)