-
-
Notifications
You must be signed in to change notification settings - Fork 30
/
Copy pathindex.page.ts
117 lines (111 loc) · 3.27 KB
/
index.page.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
import { Component, computed, signal } from '@angular/core';
import { CommunityCardComponent } from '../../components/cards/community-card.component';
import { toSignal } from '@angular/core/rxjs-interop';
import { injectLoad, RouteMeta } from '@analogjs/router';
import { load } from './index.server';
import { Title } from '@angular/platform-browser';
import { JsonLdService } from '../../services/json-ld.service';
import { DropdownModule } from 'primeng/dropdown';
import { FormsModule } from '@angular/forms';
import { BannerComponent } from '../../components/banner.component';
export const routeMeta: RouteMeta = {
meta: [
{
name: 'description',
content: 'Curated list of Angular communities',
},
],
};
@Component({
selector: 'app-communities',
standalone: true,
imports: [
CommunityCardComponent,
DropdownModule,
FormsModule,
BannerComponent,
],
template: `
<app-banner description="Curated list of Angular Communities" />
<form
class="w-full flex flex-col sm:flex-row justify-center items-center gap-2 mb-8"
>
<p-dropdown
ariaLabel="Select a country"
name="language"
[options]="countries()"
[style]="{ width: '230px' }"
[showClear]="true"
placeholder="Select a country"
[(ngModel)]="selectedCountry"
/>
</form>
<ul class="flex flex-wrap justify-center gap-x-8 gap-y-4 px-8">
@for (community of filteredCommunities(); track community) {
<li>
<app-community-card [community]="community"></app-community-card>
</li>
}
</ul>
`,
})
export default class CommunitiesComponent {
communities = toSignal(injectLoad<typeof load>(), { requireSync: true });
selectedCountry = signal(null);
countries = computed(() =>
this.communities()
.map((community) => community.location)
.reduce<string[]>((acc, curr) => {
const location = curr
? curr.includes(',')
? curr.split(',').at(-1)
: curr
: '';
if (location && !acc.includes(location.trim())) {
acc.push(location.trim());
}
return acc;
}, [])
.sort((a, b) =>
a.toLocaleUpperCase().localeCompare(b.toLocaleUpperCase()),
),
);
filteredCommunities = computed(() =>
this.communities().filter((community) =>
this.selectedCountry()
? community.location?.includes(this.selectedCountry() ?? '')
: true,
),
);
constructor(
private title: Title,
private jsonldService: JsonLdService,
) {
this.title.setTitle('Angular HUB - Communities');
this.jsonldService.updateJsonLd(this.setJsonLd());
}
setJsonLd() {
return {
'@context': 'https://schema.org',
'@type': 'ItemList',
itemListElement: this.communities().map((community, index) => ({
'@type': 'ListItem',
position: index + 1,
item: {
'@type': 'Organization',
name: community.name,
url: community.url,
...(community.location
? {
address: {
'@type': 'PostalAddress',
addressLocality: community.location,
},
}
: {}),
knowsAbout: 'Angular',
},
})),
};
}
}