Feature/add global heat map to landing page (#1584)

* Add global heat map

* Update changelog
pull/1588/head
Thomas Kaul 1 year ago committed by GitHub
parent fc8e23a9c8
commit 90a7a84ac5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## Unreleased
### Added
- Extended the landing page by a global heat map of subscribers
### Changed
- Improved the form of the import dividends dialog (disable while loading)

@ -7,6 +7,7 @@ import { PropertyService } from '@ghostfolio/api/services/property/property.serv
import { TagService } from '@ghostfolio/api/services/tag/tag.service';
import {
DEMO_USER_ID,
PROPERTY_COUNTRIES_OF_SUBSCRIBERS,
PROPERTY_IS_READ_ONLY_MODE,
PROPERTY_SLACK_COMMUNITY_USERS,
PROPERTY_STRIPE_CONFIG,
@ -92,6 +93,10 @@ export class InfoService {
if (this.configurationService.get('ENABLE_FEATURE_SUBSCRIPTION')) {
globalPermissions.push(permissions.enableSubscription);
info.countriesOfSubscribers =
((await this.propertyService.getByKey(
PROPERTY_COUNTRIES_OF_SUBSCRIBERS
)) as string[]) ?? [];
info.stripePublicKey = this.configurationService.get('STRIPE_PUBLIC_KEY');
}

@ -16,8 +16,8 @@ import svgMap from 'svgmap';
styleUrls: ['./world-map-chart.component.scss']
})
export class WorldMapChartComponent implements OnChanges, OnDestroy, OnInit {
@Input() baseCurrency: string;
@Input() countries: { [code: string]: { name: string; value: number } };
@Input() countries: { [code: string]: { name?: string; value: number } };
@Input() format: string;
@Input() isInPercent = false;
public isLoading = true;
@ -71,7 +71,7 @@ export class WorldMapChartComponent implements OnChanges, OnDestroy, OnInit {
applyData: 'value',
data: {
value: {
format: this.isInPercent ? `{0}%` : `{0} ${this.baseCurrency}`
format: this.format
}
},
values: this.countries

@ -13,10 +13,14 @@ import { Subject } from 'rxjs';
templateUrl: './landing-page.html'
})
export class LandingPageComponent implements OnDestroy, OnInit {
public countriesOfSubscribersMap: {
[code: string]: { value: number };
} = {};
public currentYear = format(new Date(), 'yyyy');
public demoAuthToken: string;
public deviceType: string;
public hasPermissionForStatistics: boolean;
public hasPermissionForSubscription: boolean;
public hasPermissionToCreateUser: boolean;
public statistics: Statistics;
public testimonials = [
@ -48,13 +52,25 @@ export class LandingPageComponent implements OnDestroy, OnInit {
private dataService: DataService,
private deviceService: DeviceDetectorService
) {
const { globalPermissions, statistics } = this.dataService.fetchInfo();
const { countriesOfSubscribers, globalPermissions, statistics } =
this.dataService.fetchInfo();
for (const country of countriesOfSubscribers) {
this.countriesOfSubscribersMap[country] = {
value: 1
};
}
this.hasPermissionForStatistics = hasPermission(
globalPermissions,
permissions.enableStatistics
);
this.hasPermissionForSubscription = hasPermission(
globalPermissions,
permissions.enableSubscription
);
this.hasPermissionToCreateUser = hasPermission(
globalPermissions,
permissions.createUserAccount

@ -269,6 +269,21 @@
</div>
</div>
<div *ngIf="hasPermissionForSubscription" class="row my-5">
<div class="col-12">
<h2 class="h4 text-center">
Members from around the globe are using
<a href="pricing"><strong>Ghostfolio Premium</strong></a>
</h2>
</div>
<div class="col-md-8 customer-map-container offset-md-2">
<gf-world-map-chart
format="👻"
[countries]="countriesOfSubscribersMap"
></gf-world-map-chart>
</div>
</div>
<div class="row my-3">
<div class="col-12">
<h2 class="h4 mb-1 text-center">

@ -3,7 +3,9 @@ import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core';
import { MatButtonModule } from '@angular/material/button';
import { MatCardModule } from '@angular/material/card';
import { RouterModule } from '@angular/router';
import { GfWorldMapChartModule } from '@ghostfolio/client/components/world-map-chart/world-map-chart.module';
import { GfLogoModule } from '@ghostfolio/ui/logo';
import { GfPremiumIndicatorModule } from '@ghostfolio/ui/premium-indicator';
import { GfValueModule } from '@ghostfolio/ui/value';
import { LandingPageRoutingModule } from './landing-page-routing.module';
@ -14,7 +16,9 @@ import { LandingPageComponent } from './landing-page.component';
imports: [
CommonModule,
GfLogoModule,
GfPremiumIndicatorModule,
GfValueModule,
GfWorldMapChartModule,
LandingPageRoutingModule,
MatButtonModule,
MatCardModule,

@ -9,6 +9,10 @@
}
}
.customer-map-container {
aspect-ratio: 16 / 9;
}
.downloads {
img {
height: 2.5rem;

@ -84,6 +84,7 @@ export class AllocationsPageComponent implements OnDestroy, OnInit {
};
public user: User;
public worldMapChartFormat: string;
private unsubscribeSubject = new Subject<void>();
@ -193,6 +194,11 @@ export class AllocationsPageComponent implements OnDestroy, OnInit {
...tagFilters
];
this.worldMapChartFormat =
this.hasImpersonationId || this.user.settings.isRestrictedView
? `{0}%`
: `{0} ${this.user?.settings?.baseCurrency}`;
this.changeDetectorRef.markForCheck();
}
});

@ -257,8 +257,8 @@
</mat-card-header>
<mat-card-content>
<gf-world-map-chart
[baseCurrency]="user?.settings?.baseCurrency"
[countries]="countries"
[format]="worldMapChartFormat"
[isInPercent]="hasImpersonationId || user.settings.isRestrictedView"
></gf-world-map-chart>
<div class="row">

@ -72,6 +72,7 @@ export const GATHER_HISTORICAL_MARKET_DATA_PROCESS_OPTIONS: JobOptions = {
export const MAX_CHART_ITEMS = 365;
export const PROPERTY_BENCHMARKS = 'BENCHMARKS';
export const PROPERTY_COUNTRIES_OF_SUBSCRIBERS = 'COUNTRIES_OF_SUBSCRIBERS';
export const PROPERTY_COUPONS = 'COUPONS';
export const PROPERTY_CURRENCIES = 'CURRENCIES';
export const PROPERTY_IS_READ_ONLY_MODE = 'IS_READ_ONLY_MODE';

@ -6,12 +6,12 @@ import { Subscription } from './subscription.interface';
export interface InfoItem {
baseCurrency: string;
benchmarks: Partial<SymbolProfile>[];
countriesOfSubscribers?: string[];
currencies: string[];
demoAuthToken: string;
fearAndGreedDataSource?: string;
globalPermissions: string[];
isReadOnlyMode?: boolean;
lastDataGathering?: Date;
platforms: { id: string; name: string }[];
statistics: Statistics;
stripePublicKey?: string;

Loading…
Cancel
Save