Skip to content

Commit 2748afb

Browse files
authored
Merge pull request #692 from Hochfrequenz/align-colors-in-global-search
style: Align Colors and Add Feature Dropdown
2 parents 74932be + eb83ae1 commit 2748afb

File tree

9 files changed

+401
-69
lines changed

9 files changed

+401
-69
lines changed
Lines changed: 75 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -1,55 +1,77 @@
1-
<div class="search-page">
2-
<mat-toolbar class="search-header">
3-
<h1>AHB Globale Suche</h1>
4-
<span class="spacer"></span>
5-
</mat-toolbar>
6-
7-
<div class="search-content">
8-
<!-- Search Filters -->
9-
<mat-card class="filters-card">
10-
<mat-card-header>
11-
<mat-card-title>Suche & Filter</mat-card-title>
12-
</mat-card-header>
13-
<mat-card-content>
14-
<app-search-filters
15-
(queryChange)="onQueryChange($event)"
16-
(filtersChange)="onFiltersChange($event)">
17-
</app-search-filters>
18-
</mat-card-content>
19-
</mat-card>
20-
21-
<!-- Search Results -->
22-
<mat-card class="results-card">
23-
<mat-card-header>
24-
<mat-card-title>
25-
Ergebnisse
26-
<span *ngIf="searchResults" class="result-count">
27-
({{ searchResults.total }} items)
28-
</span>
29-
</mat-card-title>
30-
</mat-card-header>
31-
<mat-card-content>
32-
<div *ngIf="loading" class="loading-container">
33-
<mat-spinner diameter="40"></mat-spinner>
34-
<p>Searching...</p>
35-
</div>
36-
37-
<div *ngIf="error" class="error-container">
38-
<mat-icon color="warn" fontSet="mdi" fontIcon="mdi-alert"></mat-icon>
39-
<p>{{ error }}</p>
40-
</div>
41-
42-
<app-search-table
43-
*ngIf="searchResults && !loading && !error"
44-
[data]="searchResults.items || []"
45-
[totalItems]="searchResults.total || 0"
46-
[page]="searchResults.page || 1"
47-
[pageSize]="searchResults.pageSize || 25"
48-
(pageChange)="onPageChange($event)"
49-
(pageSizeChange)="onPageSizeChange($event)"
50-
(sortChange)="onSortChange($event)">
51-
</app-search-table>
52-
</mat-card-content>
53-
</mat-card>
1+
<div class="h-screen flex flex-col">
2+
<!-- Fixed Main Header -->
3+
<app-header class="flex-none">
4+
<!-- Desktop projection -->
5+
<div slot="search" class="inline-block w-full md:w-96">
6+
<!-- Search functionality can be added here if needed -->
7+
</div>
8+
9+
<!-- Mobile projection -->
10+
<div slot="search-mobile" class="w-full">
11+
<!-- Search functionality can be added here if needed -->
12+
</div>
13+
</app-header>
14+
15+
<!-- Scrollable Content -->
16+
<div class="flex-1 overflow-auto bg-hf-pastell-rot">
17+
<div class="search-page">
18+
<div class="search-content">
19+
<!-- Search Filters -->
20+
<mat-card class="filters-card">
21+
<mat-card-header>
22+
<mat-card-title>Suche & Filter</mat-card-title>
23+
</mat-card-header>
24+
<mat-card-content>
25+
<app-search-filters
26+
(queryChange)="onQueryChange($event)"
27+
(filtersChange)="onFiltersChange($event)">
28+
</app-search-filters>
29+
</mat-card-content>
30+
</mat-card>
31+
32+
<!-- Search Results -->
33+
<mat-card class="results-card">
34+
<mat-card-header>
35+
<mat-card-title>
36+
Ergebnisse
37+
<span *ngIf="searchResults" class="result-count">
38+
({{ searchResults.total }} items)
39+
</span>
40+
</mat-card-title>
41+
</mat-card-header>
42+
<mat-card-content>
43+
<div *ngIf="loading" class="loading-container">
44+
<mat-spinner diameter="40"></mat-spinner>
45+
<p>Searching...</p>
46+
</div>
47+
48+
<div *ngIf="error" class="error-container">
49+
<mat-icon color="warn" fontSet="mdi" fontIcon="mdi-alert"></mat-icon>
50+
<p>{{ error }}</p>
51+
</div>
52+
53+
<app-search-table
54+
*ngIf="searchResults && !loading && !error"
55+
[data]="searchResults.items || []"
56+
[totalItems]="searchResults.total || 0"
57+
[page]="searchResults.page || 1"
58+
[pageSize]="searchResults.pageSize || 25"
59+
(pageChange)="onPageChange($event)"
60+
(pageSizeChange)="onPageSizeChange($event)"
61+
(sortChange)="onSortChange($event)">
62+
</app-search-table>
63+
</mat-card-content>
64+
</mat-card>
65+
</div>
66+
67+
<!-- Solutions footer inside scroll: visible only on small screens -->
68+
<app-solutions-footer class="block md:hidden"></app-solutions-footer>
69+
</div>
5470
</div>
71+
72+
<!-- Solutions footer for desktop/tablet: visible on md+ screens at bottom -->
73+
<app-solutions-footer class="flex-none hidden md:block"></app-solutions-footer>
74+
75+
<!-- Fixed Footer -->
76+
<app-footer class="flex-none" />
5577
</div>

src/app/features/search/views/search-page/search-page.component.scss

Lines changed: 1 addition & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -4,19 +4,7 @@
44
margin: 0 auto;
55
}
66

7-
.search-header {
8-
margin-bottom: 16px;
9-
10-
h1 {
11-
margin: 0;
12-
font-size: 24px;
13-
font-weight: 500;
14-
}
15-
16-
.spacer {
17-
flex: 1 1 auto;
18-
}
19-
}
7+
// Header and footer now using inline styles for better visibility
208

219
.search-content {
2210
display: flex;

src/app/features/search/views/search-page/search-page.component.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,9 @@ import { SearchService } from '../../services/search.service';
1313
import { SearchQueryResponse } from '../../../../core/api/models';
1414
import { SearchTableComponent } from '../../components/search-table/search-table.component';
1515
import { SearchFiltersComponent } from '../../components/search-filters/search-filters.component';
16+
import { HeaderComponent } from '../../../../shared/components/header/header.component';
17+
import { FooterComponent } from '../../../../shared/components/footer/footer.component';
18+
import { SolutionsFooterComponent } from '../../../../shared/components/solutions-footer/solutions-footer.component';
1619

1720
@Component({
1821
selector: 'app-search-page',
@@ -27,6 +30,9 @@ import { SearchFiltersComponent } from '../../components/search-filters/search-f
2730
MatProgressSpinnerModule,
2831
SearchTableComponent,
2932
SearchFiltersComponent,
33+
HeaderComponent,
34+
FooterComponent,
35+
SolutionsFooterComponent,
3036
],
3137
standalone: true,
3238
})
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
<div
2+
class="feature-switcher"
3+
(click)="toggleDropdown()"
4+
(keydown.enter)="toggleDropdown($event)"
5+
(keydown.space)="toggleDropdown($event)"
6+
tabindex="0"
7+
role="button"
8+
[attr.aria-expanded]="isDropdownOpen"
9+
[attr.aria-haspopup]="true"
10+
aria-label="Feature switcher">
11+
<span class="feature-text">{{ getCurrentFeatureLabel() }}</span>
12+
<span class="dropdown-arrow" [class.open]="isDropdownOpen"></span>
13+
14+
<div class="dropdown-menu" [class.open]="isDropdownOpen" role="menu">
15+
<div
16+
*ngFor="let feature of features"
17+
class="dropdown-option"
18+
(click)="selectFeature(feature, $event)"
19+
(keydown.enter)="selectFeature(feature, $event)"
20+
(keydown.space)="selectFeature(feature, $event)"
21+
tabindex="0"
22+
role="menuitem"
23+
[class.selected]="isFeatureSelected(feature)">
24+
{{ feature.label }}
25+
</div>
26+
</div>
27+
</div>
Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
.feature-switcher {
2+
position: relative;
3+
display: inline-block;
4+
cursor: pointer;
5+
user-select: none;
6+
7+
.feature-text {
8+
color: var(--hf-weiches-schwarz, #333);
9+
font-size: 1.25rem; // text-xl
10+
font-weight: 500;
11+
line-height: normal;
12+
}
13+
14+
.dropdown-arrow {
15+
color: var(--hf-weiches-schwarz, #333);
16+
margin-left: 4px;
17+
font-size: 0.75rem;
18+
transition: all 0.2s ease;
19+
opacity: 0;
20+
21+
&.open {
22+
transform: rotate(180deg);
23+
}
24+
}
25+
26+
&:hover .dropdown-arrow {
27+
opacity: 0.7;
28+
}
29+
30+
.dropdown-menu {
31+
position: absolute;
32+
top: 100%;
33+
left: 0;
34+
background-color: white;
35+
border: none;
36+
border-radius: 8px;
37+
box-shadow:
38+
0 4px 6px -1px rgba(0, 0, 0, 0.1),
39+
0 2px 4px -1px rgba(0, 0, 0, 0.06);
40+
min-width: 160px;
41+
z-index: 1000;
42+
opacity: 0;
43+
visibility: hidden;
44+
transform: translateY(-4px);
45+
transition: all 0.2s ease;
46+
47+
&.open {
48+
opacity: 1;
49+
visibility: visible;
50+
transform: translateY(0);
51+
}
52+
53+
.dropdown-option {
54+
padding: 12px 16px;
55+
color: var(--hf-weiches-schwarz, #333);
56+
font-size: 1rem;
57+
transition: all 0.2s ease;
58+
cursor: pointer;
59+
60+
&:first-child {
61+
border-radius: 8px 8px 0 0;
62+
}
63+
64+
&:last-child {
65+
border-radius: 0 0 8px 8px;
66+
}
67+
68+
&.selected {
69+
background-color: var(--hf-pastell-rose, #fce7f3);
70+
color: var(--hf-dunkel-rose, #be185d);
71+
font-weight: 500;
72+
}
73+
74+
&:hover:not(.selected) {
75+
background-color: var(--hf-pastell-rose, #fce7f3);
76+
opacity: 0.8;
77+
}
78+
}
79+
}
80+
}
81+
82+
// Mobile specific styles
83+
@media (max-width: 1023px) {
84+
.feature-switcher {
85+
width: 100%;
86+
margin-bottom: 8px;
87+
text-align: center;
88+
89+
.dropdown-menu {
90+
left: 50%;
91+
transform: translateX(-50%) translateY(-4px);
92+
93+
&.open {
94+
transform: translateX(-50%) translateY(0);
95+
}
96+
}
97+
}
98+
}

0 commit comments

Comments
 (0)