1
- import { Component } from '@angular/core' ;
1
+ import { Component , computed , signal } from '@angular/core' ;
2
2
import { CommunityCardComponent } from '../../components/cards/community-card.component' ;
3
3
import { toSignal } from '@angular/core/rxjs-interop' ;
4
4
import { injectLoad , RouteMeta } from '@analogjs/router' ;
5
5
import { load } from './index.server' ;
6
6
import { Title } from '@angular/platform-browser' ;
7
7
import { JsonLdService } from '../../services/json-ld.service' ;
8
+ import { DropdownModule } from 'primeng/dropdown' ;
9
+ import { FormsModule } from '@angular/forms' ;
8
10
9
11
export const routeMeta : RouteMeta = {
10
12
meta : [
@@ -18,7 +20,7 @@ export const routeMeta: RouteMeta = {
18
20
@Component ( {
19
21
selector : 'app-communities' ,
20
22
standalone : true ,
21
- imports : [ CommunityCardComponent ] ,
23
+ imports : [ CommunityCardComponent , DropdownModule , FormsModule ] ,
22
24
template : `
23
25
<aside
24
26
class="h-36 w-full flex flex-col justify-center items-center mb-8 bg-no-repeat bg-auto md:bg-cover px-4"
@@ -28,8 +30,22 @@ export const routeMeta: RouteMeta = {
28
30
<h2 class="text-2xl text-center">Curated list of Angular Communities</h2>
29
31
</aside>
30
32
33
+ <form
34
+ class="w-full flex flex-col sm:flex-row justify-center items-center gap-2 mb-8"
35
+ >
36
+ <p-dropdown
37
+ name="language"
38
+ [options]="countries()"
39
+ [style]="{ width: '230px' }"
40
+ [showClear]="true"
41
+ placeholder="Select a country"
42
+ [ngModel]="selectedCountry()"
43
+ (ngModelChange)="selectedCountry.set($event)"
44
+ />
45
+ </form>
46
+
31
47
<ul class="flex flex-wrap justify-center gap-x-8 gap-y-4 px-8">
32
- @for (community of communities (); track community.name) {
48
+ @for (community of filteredCommunities (); track community.name) {
33
49
<li>
34
50
<app-community-card [community]="community"></app-community-card>
35
51
</li>
@@ -39,6 +55,33 @@ export const routeMeta: RouteMeta = {
39
55
} )
40
56
export default class CommunitiesComponent {
41
57
communities = toSignal ( injectLoad < typeof load > ( ) , { requireSync : true } ) ;
58
+ selectedCountry = signal ( null ) ;
59
+ countries = computed ( ( ) =>
60
+ this . communities ( )
61
+ . map ( ( community ) => community . location )
62
+ . reduce < string [ ] > ( ( acc , curr ) => {
63
+ const location = curr
64
+ ? curr . includes ( ',' )
65
+ ? curr . split ( ',' ) . at ( - 1 )
66
+ : curr
67
+ : '' ;
68
+ if ( location && ! acc . includes ( location . trim ( ) ) ) {
69
+ acc . push ( location . trim ( ) ) ;
70
+ }
71
+ return acc ;
72
+ } , [ ] )
73
+ . sort ( ( a , b ) =>
74
+ a . toLocaleUpperCase ( ) . localeCompare ( b . toLocaleUpperCase ( ) ) ,
75
+ ) ,
76
+ ) ;
77
+
78
+ filteredCommunities = computed ( ( ) =>
79
+ this . communities ( ) . filter ( ( community ) =>
80
+ this . selectedCountry ( )
81
+ ? community . location ?. includes ( this . selectedCountry ( ) ?? '' )
82
+ : true ,
83
+ ) ,
84
+ ) ;
42
85
43
86
constructor (
44
87
private title : Title ,
0 commit comments