Skip to content

Commit 7324613

Browse files
committed
refactor: communities listing
1 parent 9b9cfff commit 7324613

19 files changed

+1004
-493
lines changed
Original file line numberDiff line numberDiff line change
@@ -1,60 +1,287 @@
1-
import { ChangeDetectionStrategy, Component, input } from '@angular/core';
2-
import { NgOptimizedImage, TitleCasePipe } from '@angular/common';
1+
import {
2+
ChangeDetectionStrategy,
3+
Component,
4+
computed,
5+
input,
6+
} from '@angular/core';
7+
import { DatePipe, NgOptimizedImage, TitleCasePipe } from '@angular/common';
38
import { Community } from '../../../models/community.model';
9+
import community from '../../../server/routes/v1/community';
410

511
@Component({
612
selector: 'app-community-card',
713
standalone: true,
814
changeDetection: ChangeDetectionStrategy.OnPush,
9-
imports: [NgOptimizedImage, TitleCasePipe],
15+
imports: [NgOptimizedImage, TitleCasePipe, DatePipe],
1016
template: `
11-
<article>
12-
<a
13-
[href]="community().url ?? '#'"
14-
target="_blank"
15-
class="flex flex-col max-w-36 items-start gap-1"
16-
>
17+
<article class="bg-[#20212C] px-6 pt-8 pb-4 rounded-xl relative">
18+
<div class="absolute type">
19+
<span
20+
class="font-medium text-sm text-black bg-slate-400 rounded p-1 mr-4"
21+
itemprop="type"
22+
>{{ community().type | titlecase }}</span
23+
>
24+
@if (upcomingEventLength() > 0) {
25+
<span
26+
class="font-medium text-sm text-black bg-green-100 rounded p-1"
27+
itemprop="type"
28+
>
29+
{{ upcomingEventLength() }} upcoming event(s)
30+
</span>
31+
}
32+
@if (inactive()) {
33+
<span
34+
class="font-medium text-sm text-black bg-orange-200 rounded p-1"
35+
itemprop="type"
36+
>
37+
inactive since {{ inactiveSince() | date: 'MMMM y' }}
38+
</span>
39+
}
40+
</div>
41+
<div class="flex items-start md:items-center gap-6">
1742
<img
1843
class="rounded-xl"
1944
[src]="community().logo"
20-
height="200"
21-
width="200"
45+
height="60"
46+
width="60"
2247
alt=""
2348
/>
24-
<div class="text-start">
25-
<span class="font-bold text-primary" itemprop="type">{{
26-
community().type | titlecase
27-
}}</span>
28-
<h3
29-
[attr.aria-labelledby]="community().name"
30-
class="text-xl font-bold"
31-
itemprop="title"
32-
>
49+
<div class="flex-1">
50+
<h3 class="text-xl font-bold" itemprop="title">
3351
{{ community().name }}
3452
</h3>
3553
<span class="text-gray-500 dark:text-gray-400" itemprop="location">{{
3654
community().location
3755
}}</span>
3856
</div>
39-
</a>
57+
<div class="hidden md:flex gap-4 ml-6">
58+
@if (community().eventsUrl) {
59+
<a
60+
class="rounded-xl bg-[#344255] hover:bg-[#4C5765] p-2"
61+
[attr.href]="community().eventsUrl"
62+
target="_blank"
63+
title="events URL"
64+
>
65+
<img
66+
ngSrc="/assets/icons/event-icon.svg"
67+
alt=""
68+
height="30"
69+
width="30"
70+
/>
71+
</a>
72+
}
73+
@if (community().websiteUrl) {
74+
<a
75+
class="rounded-xl bg-[#344255] hover:bg-[#4C5765] p-2"
76+
[attr.href]="community().websiteUrl"
77+
target="_blank"
78+
title="website URL"
79+
>
80+
<img
81+
ngSrc="/assets/icons/website_link-icon.svg"
82+
alt=""
83+
height="30"
84+
width="30"
85+
/>
86+
</a>
87+
}
88+
@if (community().organizersUrl) {
89+
<a
90+
class="rounded-xl bg-[#344255] hover:bg-[#4C5765] p-2"
91+
[attr.href]="community().organizersUrl"
92+
target="_blank"
93+
title="organizers URL"
94+
>
95+
<img
96+
ngSrc="/assets/icons/group-icon.svg"
97+
alt=""
98+
height="30"
99+
width="30"
100+
/>
101+
</a>
102+
}
103+
@if (community().youtubeUrl) {
104+
<a
105+
class="rounded-xl bg-[#344255] hover:bg-[#4C5765] p-2"
106+
[attr.href]="community().youtubeUrl"
107+
target="_blank"
108+
title="YouTube URL"
109+
>
110+
<img
111+
ngSrc="/assets/icons/youtube-icon.svg"
112+
alt=""
113+
height="30"
114+
width="30"
115+
/>
116+
</a>
117+
}
118+
@if (community().twitterUrl) {
119+
<a
120+
class="rounded-xl bg-[#344255] hover:bg-[#4C5765] p-2"
121+
[attr.href]="community().twitterUrl"
122+
target="_blank"
123+
title="Twitter URL"
124+
>
125+
<img
126+
ngSrc="/assets/icons/twitter-icon.svg"
127+
alt=""
128+
height="30"
129+
width="30"
130+
/>
131+
</a>
132+
}
133+
@if (community().linkedinUrl) {
134+
<a
135+
class="rounded-xl bg-[#344255] hover:bg-[#4C5765] p-2"
136+
[attr.href]="community().linkedinUrl"
137+
target="_blank"
138+
title="LinkedIn URL"
139+
>
140+
<img
141+
ngSrc="/assets/icons/linkedin-icon.svg"
142+
alt=""
143+
height="30"
144+
width="30"
145+
/>
146+
</a>
147+
}
148+
</div>
149+
</div>
150+
<div class="flex justify-end md:hidden gap-4 mt-4">
151+
@if (community().eventsUrl) {
152+
<a
153+
class="rounded-xl bg-[#344255] p-2"
154+
[attr.href]="community().eventsUrl"
155+
target="_blank"
156+
title="events URL"
157+
>
158+
<img
159+
ngSrc="/assets/icons/event-icon.svg"
160+
alt=""
161+
height="20"
162+
width="20"
163+
/>
164+
</a>
165+
}
166+
@if (community().websiteUrl) {
167+
<a
168+
class="rounded-xl bg-[#344255] p-2"
169+
[attr.href]="community().websiteUrl"
170+
target="_blank"
171+
title="website URL"
172+
>
173+
<img
174+
ngSrc="/assets/icons/website_link-icon.svg"
175+
alt=""
176+
height="20"
177+
width="20"
178+
/>
179+
</a>
180+
}
181+
@if (community().organizersUrl) {
182+
<a
183+
class="rounded-xl bg-[#344255] p-2"
184+
[attr.href]="community().organizersUrl"
185+
target="_blank"
186+
title="organizers URL"
187+
>
188+
<img
189+
ngSrc="/assets/icons/group-icon.svg"
190+
alt=""
191+
height="20"
192+
width="20"
193+
/>
194+
</a>
195+
}
196+
@if (community().youtubeUrl) {
197+
<a
198+
class="rounded-xl bg-[#344255] p-2"
199+
[attr.href]="community().youtubeUrl"
200+
target="_blank"
201+
title="YouTube URL"
202+
>
203+
<img
204+
ngSrc="/assets/icons/youtube-icon.svg"
205+
alt=""
206+
height="20"
207+
width="20"
208+
/>
209+
</a>
210+
}
211+
@if (community().twitterUrl) {
212+
<a
213+
class="rounded-xl bg-[#344255] p-2"
214+
[attr.href]="community().twitterUrl"
215+
target="_blank"
216+
title="events URL"
217+
>
218+
<img
219+
ngSrc="/assets/icons/twitter-icon.svg"
220+
alt=""
221+
height="20"
222+
width="20"
223+
/>
224+
</a>
225+
}
226+
@if (community().linkedinUrl) {
227+
<a
228+
class="rounded-xl bg-[#344255] p-2"
229+
[attr.href]="community().linkedinUrl"
230+
target="_blank"
231+
>
232+
<img
233+
ngSrc="/assets/icons/linkedin-icon.svg"
234+
alt=""
235+
height="20"
236+
width="20"
237+
/>
238+
</a>
239+
}
240+
</div>
40241
</article>
41242
`,
42243
styles: [
43244
`
44245
:host {
45246
display: block;
46247
padding-block: 0.5rem;
47-
cursor: pointer;
248+
}
48249
49-
&:hover {
50-
h3 {
51-
@apply text-secondary underline;
52-
}
53-
}
250+
.type {
251+
top: -0.7rem;
252+
left: 1.2rem;
54253
}
55254
`,
56255
],
57256
})
58257
export class CommunityCardComponent {
59258
community = input.required<Community>();
259+
260+
upcomingEventLength = computed(() => {
261+
return this.community().events?.filter(
262+
(event) => new Date(event.date).getTime() > new Date().getTime(),
263+
).length;
264+
});
265+
266+
inactive = computed(() => {
267+
const inactivityLimit = new Date();
268+
inactivityLimit.setMonth(inactivityLimit.getMonth() - 6);
269+
270+
const newestEvent = this.community().events?.sort(
271+
(a, b) => new Date(b.date).getTime() - new Date(a.date).getTime(),
272+
)[0];
273+
274+
return newestEvent
275+
? new Date(newestEvent.date).getTime() < inactivityLimit.getTime() &&
276+
this.community().type === 'meetup'
277+
: false;
278+
});
279+
280+
inactiveSince = computed(() => {
281+
const event = this.community().events?.sort(
282+
(a, b) => new Date(b.date).getTime() - new Date(a.date).getTime(),
283+
)[0];
284+
285+
return event ? new Date(event.date) : null;
286+
});
60287
}

angular-hub/src/app/components/event-section.component.ts

+1-3
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,7 @@ import { EventCardComponent } from './cards/event-card.component';
88
<h3 class="mb-4">{{ title() }}</h3>
99
<ul class="flex flex-col gap-4 justify-start items-stretch w-full">
1010
@for (event of events(); track event.url) {
11-
<li
12-
class="flex flex-col gap-2 bg-[#20212C] px-2 rounded-xl md:min-w-[400px]"
13-
>
11+
<li class="bg-[#20212C] p-6 rounded-xl md:min-w-[400px]">
1412
<a [attr.href]="event.url" target="_blank">
1513
<app-event-card [event]="event" />
1614
</a>

angular-hub/src/app/components/navigation/navigation.component.html

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
<nav
22
class="hidden min-w-72 px-8 pt-4 lg:flex flex-col items-center bg-[#20212C] drop-shadow-r-2xl"
33
>
4-
<a class="flex items-center gap-2" routerLink="/">
4+
<a class="flex items-center gap-4" routerLink="/">
55
<img class="h-12" src="/assets/images/logo.webp" alt="" />
6-
<span class="title text-3xl">HUB</span>
6+
<span class="title text-5xl">HUB</span>
77
</a>
88

99
<ul class="flex flex-col gap-2 mt-12">

0 commit comments

Comments
 (0)