Skip to content

Commit

Permalink
refactor: communities listing
Browse files Browse the repository at this point in the history
  • Loading branch information
geromegrignon committed Nov 3, 2024
1 parent 9b9cfff commit 7324613
Show file tree
Hide file tree
Showing 19 changed files with 1,004 additions and 493 deletions.
281 changes: 254 additions & 27 deletions angular-hub/src/app/components/cards/community-card.component.ts
Original file line number Diff line number Diff line change
@@ -1,60 +1,287 @@
import { ChangeDetectionStrategy, Component, input } from '@angular/core';
import { NgOptimizedImage, TitleCasePipe } from '@angular/common';
import {
ChangeDetectionStrategy,
Component,
computed,
input,
} from '@angular/core';
import { DatePipe, NgOptimizedImage, TitleCasePipe } from '@angular/common';
import { Community } from '../../../models/community.model';
import community from '../../../server/routes/v1/community';

@Component({
selector: 'app-community-card',
standalone: true,
changeDetection: ChangeDetectionStrategy.OnPush,
imports: [NgOptimizedImage, TitleCasePipe],
imports: [NgOptimizedImage, TitleCasePipe, DatePipe],
template: `
<article>
<a
[href]="community().url ?? '#'"
target="_blank"
class="flex flex-col max-w-36 items-start gap-1"
>
<article class="bg-[#20212C] px-6 pt-8 pb-4 rounded-xl relative">
<div class="absolute type">
<span
class="font-medium text-sm text-black bg-slate-400 rounded p-1 mr-4"
itemprop="type"
>{{ community().type | titlecase }}</span
>
@if (upcomingEventLength() > 0) {
<span
class="font-medium text-sm text-black bg-green-100 rounded p-1"
itemprop="type"
>
{{ upcomingEventLength() }} upcoming event(s)
</span>
}
@if (inactive()) {
<span
class="font-medium text-sm text-black bg-orange-200 rounded p-1"
itemprop="type"
>
inactive since {{ inactiveSince() | date: 'MMMM y' }}
</span>
}
</div>
<div class="flex items-start md:items-center gap-6">
<img
class="rounded-xl"
[src]="community().logo"
height="200"
width="200"
height="60"
width="60"
alt=""
/>
<div class="text-start">
<span class="font-bold text-primary" itemprop="type">{{
community().type | titlecase
}}</span>
<h3
[attr.aria-labelledby]="community().name"
class="text-xl font-bold"
itemprop="title"
>
<div class="flex-1">
<h3 class="text-xl font-bold" itemprop="title">
{{ community().name }}
</h3>
<span class="text-gray-500 dark:text-gray-400" itemprop="location">{{
community().location
}}</span>
</div>
</a>
<div class="hidden md:flex gap-4 ml-6">
@if (community().eventsUrl) {
<a
class="rounded-xl bg-[#344255] hover:bg-[#4C5765] p-2"
[attr.href]="community().eventsUrl"
target="_blank"
title="events URL"
>
<img
ngSrc="/assets/icons/event-icon.svg"
alt=""
height="30"
width="30"
/>
</a>
}
@if (community().websiteUrl) {
<a
class="rounded-xl bg-[#344255] hover:bg-[#4C5765] p-2"
[attr.href]="community().websiteUrl"
target="_blank"
title="website URL"
>
<img
ngSrc="/assets/icons/website_link-icon.svg"
alt=""
height="30"
width="30"
/>
</a>
}
@if (community().organizersUrl) {
<a
class="rounded-xl bg-[#344255] hover:bg-[#4C5765] p-2"
[attr.href]="community().organizersUrl"
target="_blank"
title="organizers URL"
>
<img
ngSrc="/assets/icons/group-icon.svg"
alt=""
height="30"
width="30"
/>
</a>
}
@if (community().youtubeUrl) {
<a
class="rounded-xl bg-[#344255] hover:bg-[#4C5765] p-2"
[attr.href]="community().youtubeUrl"
target="_blank"
title="YouTube URL"
>
<img
ngSrc="/assets/icons/youtube-icon.svg"
alt=""
height="30"
width="30"
/>
</a>
}
@if (community().twitterUrl) {
<a
class="rounded-xl bg-[#344255] hover:bg-[#4C5765] p-2"
[attr.href]="community().twitterUrl"
target="_blank"
title="Twitter URL"
>
<img
ngSrc="/assets/icons/twitter-icon.svg"
alt=""
height="30"
width="30"
/>
</a>
}
@if (community().linkedinUrl) {
<a
class="rounded-xl bg-[#344255] hover:bg-[#4C5765] p-2"
[attr.href]="community().linkedinUrl"
target="_blank"
title="LinkedIn URL"
>
<img
ngSrc="/assets/icons/linkedin-icon.svg"
alt=""
height="30"
width="30"
/>
</a>
}
</div>
</div>
<div class="flex justify-end md:hidden gap-4 mt-4">
@if (community().eventsUrl) {
<a
class="rounded-xl bg-[#344255] p-2"
[attr.href]="community().eventsUrl"
target="_blank"
title="events URL"
>
<img
ngSrc="/assets/icons/event-icon.svg"
alt=""
height="20"
width="20"
/>
</a>
}
@if (community().websiteUrl) {
<a
class="rounded-xl bg-[#344255] p-2"
[attr.href]="community().websiteUrl"
target="_blank"
title="website URL"
>
<img
ngSrc="/assets/icons/website_link-icon.svg"
alt=""
height="20"
width="20"
/>
</a>
}
@if (community().organizersUrl) {
<a
class="rounded-xl bg-[#344255] p-2"
[attr.href]="community().organizersUrl"
target="_blank"
title="organizers URL"
>
<img
ngSrc="/assets/icons/group-icon.svg"
alt=""
height="20"
width="20"
/>
</a>
}
@if (community().youtubeUrl) {
<a
class="rounded-xl bg-[#344255] p-2"
[attr.href]="community().youtubeUrl"
target="_blank"
title="YouTube URL"
>
<img
ngSrc="/assets/icons/youtube-icon.svg"
alt=""
height="20"
width="20"
/>
</a>
}
@if (community().twitterUrl) {
<a
class="rounded-xl bg-[#344255] p-2"
[attr.href]="community().twitterUrl"
target="_blank"
title="events URL"
>
<img
ngSrc="/assets/icons/twitter-icon.svg"
alt=""
height="20"
width="20"
/>
</a>
}
@if (community().linkedinUrl) {
<a
class="rounded-xl bg-[#344255] p-2"
[attr.href]="community().linkedinUrl"
target="_blank"
>
<img
ngSrc="/assets/icons/linkedin-icon.svg"
alt=""
height="20"
width="20"
/>
</a>
}
</div>
</article>
`,
styles: [
`
:host {
display: block;
padding-block: 0.5rem;
cursor: pointer;
}
&:hover {
h3 {
@apply text-secondary underline;
}
}
.type {
top: -0.7rem;
left: 1.2rem;
}
`,
],
})
export class CommunityCardComponent {
community = input.required<Community>();

upcomingEventLength = computed(() => {
return this.community().events?.filter(
(event) => new Date(event.date).getTime() > new Date().getTime(),
).length;
});

inactive = computed(() => {
const inactivityLimit = new Date();
inactivityLimit.setMonth(inactivityLimit.getMonth() - 6);

const newestEvent = this.community().events?.sort(
(a, b) => new Date(b.date).getTime() - new Date(a.date).getTime(),
)[0];

return newestEvent
? new Date(newestEvent.date).getTime() < inactivityLimit.getTime() &&
this.community().type === 'meetup'
: false;
});

inactiveSince = computed(() => {
const event = this.community().events?.sort(
(a, b) => new Date(b.date).getTime() - new Date(a.date).getTime(),
)[0];

return event ? new Date(event.date) : null;
});
}
4 changes: 1 addition & 3 deletions angular-hub/src/app/components/event-section.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,7 @@ import { EventCardComponent } from './cards/event-card.component';
<h3 class="mb-4">{{ title() }}</h3>
<ul class="flex flex-col gap-4 justify-start items-stretch w-full">
@for (event of events(); track event.url) {
<li
class="flex flex-col gap-2 bg-[#20212C] px-2 rounded-xl md:min-w-[400px]"
>
<li class="bg-[#20212C] p-6 rounded-xl md:min-w-[400px]">
<a [attr.href]="event.url" target="_blank">
<app-event-card [event]="event" />
</a>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
<nav
class="hidden min-w-72 px-8 pt-4 lg:flex flex-col items-center bg-[#20212C] drop-shadow-r-2xl"
>
<a class="flex items-center gap-2" routerLink="/">
<a class="flex items-center gap-4" routerLink="/">
<img class="h-12" src="/assets/images/logo.webp" alt="" />
<span class="title text-3xl">HUB</span>
<span class="title text-5xl">HUB</span>
</a>

<ul class="flex flex-col gap-2 mt-12">
Expand Down
Loading

0 comments on commit 7324613

Please sign in to comment.