From 8d3954304ef2396df0b75a194dfb6586ee9afec8 Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Sat, 1 Oct 2022 11:16:43 +0200 Subject: [PATCH] Feature/add statistics section to landing page (#1306) * Add pulls on Docker Hub to statistics * Add statistics to landing page * Update changelog --- CHANGELOG.md | 2 + apps/api/src/app/info/info.service.ts | 24 ++++ .../pages/landing/landing-page.component.ts | 16 ++- .../src/app/pages/landing/landing-page.html | 53 +++++++- .../app/pages/landing/landing-page.module.ts | 2 + apps/client/src/styles.scss | 5 + .../lib/interfaces/statistics.interface.ts | 1 + libs/ui/src/lib/value/value.component.html | 128 +++++++++--------- libs/ui/src/lib/value/value.component.scss | 2 +- libs/ui/src/lib/value/value.component.ts | 1 + libs/ui/src/lib/value/value.module.ts | 4 +- 11 files changed, 169 insertions(+), 69 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3a7d19a45..4d08790e8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,7 +9,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added +- Added a mini statistics section to the landing page including pulls on _Docker Hub_ - Added an _As seen in_ section to the landing page +- Added support for an icon in the value component ### Changed diff --git a/apps/api/src/app/info/info.service.ts b/apps/api/src/app/info/info.service.ts index e4f906b9a..8ed589cb5 100644 --- a/apps/api/src/app/info/info.service.ts +++ b/apps/api/src/app/info/info.service.ts @@ -145,6 +145,27 @@ export class InfoService { }); } + private async countDockerHubPulls(): Promise { + try { + const get = bent( + `https://hub.docker.com/v2/repositories/ghostfolio/ghostfolio`, + 'GET', + 'json', + 200, + { + 'User-Agent': 'request' + } + ); + + const { pull_count } = await get(); + return pull_count; + } catch (error) { + Logger.error(error, 'InfoService'); + + return undefined; + } + } + private async countGitHubContributors(): Promise { try { const get = bent( @@ -245,6 +266,8 @@ export class InfoService { const activeUsers1d = await this.countActiveUsers(1); const activeUsers30d = await this.countActiveUsers(30); const newUsers30d = await this.countNewUsers(30); + + const dockerHubPulls = await this.countDockerHubPulls(); const gitHubContributors = await this.countGitHubContributors(); const gitHubStargazers = await this.countGitHubStargazers(); const slackCommunityUsers = await this.countSlackCommunityUsers(); @@ -252,6 +275,7 @@ export class InfoService { statistics = { activeUsers1d, activeUsers30d, + dockerHubPulls, gitHubContributors, gitHubStargazers, newUsers30d, diff --git a/apps/client/src/app/pages/landing/landing-page.component.ts b/apps/client/src/app/pages/landing/landing-page.component.ts index 26f27d991..7fef8b092 100644 --- a/apps/client/src/app/pages/landing/landing-page.component.ts +++ b/apps/client/src/app/pages/landing/landing-page.component.ts @@ -1,4 +1,7 @@ import { Component, OnDestroy, OnInit } from '@angular/core'; +import { DataService } from '@ghostfolio/client/services/data.service'; +import { Statistics } from '@ghostfolio/common/interfaces/statistics.interface'; +import { hasPermission, permissions } from '@ghostfolio/common/permissions'; import { format } from 'date-fns'; import { Subject } from 'rxjs'; @@ -11,6 +14,8 @@ import { Subject } from 'rxjs'; export class LandingPageComponent implements OnDestroy, OnInit { public currentYear = format(new Date(), 'yyyy'); public demoAuthToken: string; + public hasPermissionForStatistics: boolean; + public statistics: Statistics; public testimonials = [ { author: 'Philipp', @@ -36,7 +41,16 @@ export class LandingPageComponent implements OnDestroy, OnInit { private unsubscribeSubject = new Subject(); - public constructor() {} + public constructor(private dataService: DataService) { + const { globalPermissions, statistics } = this.dataService.fetchInfo(); + + this.hasPermissionForStatistics = hasPermission( + globalPermissions, + permissions.enableStatistics + ); + + this.statistics = statistics; + } public ngOnInit() {} diff --git a/apps/client/src/app/pages/landing/landing-page.html b/apps/client/src/app/pages/landing/landing-page.html index a10e64671..9ddd83106 100644 --- a/apps/client/src/app/pages/landing/landing-page.html +++ b/apps/client/src/app/pages/landing/landing-page.html @@ -42,7 +42,52 @@ -
+ + +
As seen in
- 360° View + 360° View Get the full picture of your personal finances across multiple platforms.
- Web3 Ready + Web3 Ready Use Ghostfolio anonymously and own your financial data.
- Open Source + Open Source Benefit from continuous improvements through a strong community.
diff --git a/apps/client/src/app/pages/landing/landing-page.module.ts b/apps/client/src/app/pages/landing/landing-page.module.ts index 2116d972d..37c67f270 100644 --- a/apps/client/src/app/pages/landing/landing-page.module.ts +++ b/apps/client/src/app/pages/landing/landing-page.module.ts @@ -4,6 +4,7 @@ import { MatButtonModule } from '@angular/material/button'; import { MatCardModule } from '@angular/material/card'; import { RouterModule } from '@angular/router'; import { GfLogoModule } from '@ghostfolio/ui/logo'; +import { GfValueModule } from '@ghostfolio/ui/value'; import { LandingPageRoutingModule } from './landing-page-routing.module'; import { LandingPageComponent } from './landing-page.component'; @@ -13,6 +14,7 @@ import { LandingPageComponent } from './landing-page.component'; imports: [ CommonModule, GfLogoModule, + GfValueModule, LandingPageRoutingModule, MatButtonModule, MatCardModule, diff --git a/apps/client/src/styles.scss b/apps/client/src/styles.scss index 932c548f5..ae0ef8c40 100644 --- a/apps/client/src/styles.scss +++ b/apps/client/src/styles.scss @@ -18,6 +18,7 @@ $mat-css-light-theme-selector: '.is-light-theme'; :root { --dark-background: rgb(39, 39, 39); + --font-family-sans-serif: Roboto, 'Helvetica Neue', sans-serif; --light-background: rgb(255, 255, 255); } @@ -146,6 +147,10 @@ ngx-skeleton-loader { @include gf-table; } +.lead { + font-weight: unset; +} + .mat-card { &:not([class*='mat-elevation-z']) { border: 1px solid rgba(var(--dark-dividers)); diff --git a/libs/common/src/lib/interfaces/statistics.interface.ts b/libs/common/src/lib/interfaces/statistics.interface.ts index ba3f0a1d9..f39529426 100644 --- a/libs/common/src/lib/interfaces/statistics.interface.ts +++ b/libs/common/src/lib/interfaces/statistics.interface.ts @@ -1,6 +1,7 @@ export interface Statistics { activeUsers1d: number; activeUsers30d: number; + dockerHubPulls: number; gitHubContributors: number; gitHubStargazers: number; newUsers30d: number; diff --git a/libs/ui/src/lib/value/value.component.html b/libs/ui/src/lib/value/value.component.html index 9a08ad813..80b6a09fa 100644 --- a/libs/ui/src/lib/value/value.component.html +++ b/libs/ui/src/lib/value/value.component.html @@ -1,67 +1,73 @@ - - -
- - -
+
-
-
-
-
- {{ formattedValue }}% -
-
- - *** - - - {{ formattedValue }} +
+ +
+
+ + +
+ + +
+
+
-
+
+ {{ formattedValue }}% +
+
+ + *** + + + {{ formattedValue }} + +
+ + {{ currency }} + +
+ {{ currency }} +
+
+ +
+ {{ formattedValue | titlecase }} +
+
+
+ +
+ + {{ subLabel }}
- - {{ currency }} + + -
- {{ currency }} -
- -
- {{ formattedValue | titlecase }} -
-
-
- -
- - {{ subLabel }} -
- - -
-
- + +
diff --git a/libs/ui/src/lib/value/value.component.scss b/libs/ui/src/lib/value/value.component.scss index 04c8fe3ff..f690dc46c 100644 --- a/libs/ui/src/lib/value/value.component.scss +++ b/libs/ui/src/lib/value/value.component.scss @@ -1,6 +1,6 @@ :host { display: flex; - flex-direction: column; + flex-direction: row; font-variant-numeric: tabular-nums; .h2 { diff --git a/libs/ui/src/lib/value/value.component.ts b/libs/ui/src/lib/value/value.component.ts index f05e53551..d92d87cb1 100644 --- a/libs/ui/src/lib/value/value.component.ts +++ b/libs/ui/src/lib/value/value.component.ts @@ -16,6 +16,7 @@ import { isNumber } from 'lodash'; export class ValueComponent implements OnChanges { @Input() colorizeSign = false; @Input() currency = ''; + @Input() icon = ''; @Input() isAbsolute = false; @Input() isCurrency = false; @Input() isDate = false; diff --git a/libs/ui/src/lib/value/value.module.ts b/libs/ui/src/lib/value/value.module.ts index 9d3c9aedb..1cb91050e 100644 --- a/libs/ui/src/lib/value/value.module.ts +++ b/libs/ui/src/lib/value/value.module.ts @@ -1,5 +1,5 @@ import { CommonModule } from '@angular/common'; -import { NgModule } from '@angular/core'; +import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core'; import { NgxSkeletonLoaderModule } from 'ngx-skeleton-loader'; import { ValueComponent } from './value.component'; @@ -8,6 +8,6 @@ import { ValueComponent } from './value.component'; declarations: [ValueComponent], exports: [ValueComponent], imports: [CommonModule, NgxSkeletonLoaderModule], - providers: [] + schemas: [CUSTOM_ELEMENTS_SCHEMA] }) export class GfValueModule {}