Browse Source

Feature/add feature page (#694)

* Add feature page

* Update changelog
pull/695/head
Thomas Kaul 3 years ago
committed by GitHub
parent
commit
23da1bd293
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 1
      CHANGELOG.md
  2. 7
      apps/client/src/app/app-routing.module.ts
  3. 11
      apps/client/src/app/components/header/header.component.html
  4. 2
      apps/client/src/app/components/home-holdings/home-holdings.html
  5. 2
      apps/client/src/app/components/positions-table/positions-table.component.html
  6. 1
      apps/client/src/app/core/auth.guard.ts
  7. 3
      apps/client/src/app/pages/about/about-page.html
  8. 15
      apps/client/src/app/pages/features/features-page-routing.module.ts
  9. 44
      apps/client/src/app/pages/features/features-page.component.ts
  10. 220
      apps/client/src/app/pages/features/features-page.html
  11. 19
      apps/client/src/app/pages/features/features-page.module.ts
  12. 17
      apps/client/src/app/pages/features/features-page.scss
  13. 24
      apps/client/src/assets/sitemap.xml

1
CHANGELOG.md

@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Added ### Added
- Added a feature overview page
- Added the asset and asset sub class to the position detail dialog - Added the asset and asset sub class to the position detail dialog
- Added the countries and sectors to the position detail dialog - Added the countries and sectors to the position detail dialog

7
apps/client/src/app/app-routing.module.ts

@ -66,6 +66,13 @@ const routes: Routes = [
'./pages/blog/2022/01/first-months-in-open-source/first-months-in-open-source-page.module' './pages/blog/2022/01/first-months-in-open-source/first-months-in-open-source-page.module'
).then((m) => m.FirstMonthsInOpenSourcePageModule) ).then((m) => m.FirstMonthsInOpenSourcePageModule)
}, },
{
path: 'features',
loadChildren: () =>
import('./pages/features/features-page.module').then(
(m) => m.FeaturesPageModule
)
},
{ {
path: 'home', path: 'home',
loadChildren: () => loadChildren: () =>

11
apps/client/src/app/components/header/header.component.html

@ -238,6 +238,17 @@
></gf-logo> ></gf-logo>
</a> </a>
<span class="spacer"></span> <span class="spacer"></span>
<a
class="d-none d-sm-block mx-1"
i18n
mat-flat-button
[ngClass]="{
'font-weight-bold': currentRoute === 'features',
'text-decoration-underline': currentRoute === 'features'
}"
[routerLink]="['/features']"
>Features</a
>
<a <a
class="d-none d-sm-block mx-1" class="d-none d-sm-block mx-1"
i18n i18n

2
apps/client/src/app/components/home-holdings/home-holdings.html

@ -27,7 +27,7 @@
i18n i18n
mat-button mat-button
[routerLink]="['/portfolio', 'activities']" [routerLink]="['/portfolio', 'activities']"
>Manage Activities...</a >Manage Activities</a
> >
</div> </div>
</div> </div>

2
apps/client/src/app/components/positions-table/positions-table.component.html

@ -139,7 +139,7 @@
class="my-3 text-center" class="my-3 text-center"
> >
<button i18n mat-stroked-button (click)="onShowAllPositions()"> <button i18n mat-stroked-button (click)="onShowAllPositions()">
Show all... Show all
</button> </button>
</div> </div>

1
apps/client/src/app/core/auth.guard.ts

@ -20,6 +20,7 @@ export class AuthGuard implements CanActivate {
'/blog', '/blog',
'/de/blog', '/de/blog',
'/en/blog', '/en/blog',
'/features',
'/p', '/p',
'/pricing', '/pricing',
'/register', '/register',

3
apps/client/src/app/pages/about/about-page.html

@ -32,7 +32,8 @@
</p> </p>
<p> <p>
If you encounter a bug or would like to suggest an improvement or a If you encounter a bug or would like to suggest an improvement or a
new feature, please join the Ghostfolio new <a [routerLink]="['/features']">feature</a>, please join the
Ghostfolio
<a <a
href="https://join.slack.com/t/ghostfolio/shared_invite/zt-vsaan64h-F_I0fEo5M0P88lP9ibCxFg" href="https://join.slack.com/t/ghostfolio/shared_invite/zt-vsaan64h-F_I0fEo5M0P88lP9ibCxFg"
title="Join the Ghostfolio Slack community" title="Join the Ghostfolio Slack community"

15
apps/client/src/app/pages/features/features-page-routing.module.ts

@ -0,0 +1,15 @@
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { AuthGuard } from '@ghostfolio/client/core/auth.guard';
import { FeaturesPageComponent } from './features-page.component';
const routes: Routes = [
{ path: '', component: FeaturesPageComponent, canActivate: [AuthGuard] }
];
@NgModule({
imports: [RouterModule.forChild(routes)],
exports: [RouterModule]
})
export class FeaturesPageRoutingModule {}

44
apps/client/src/app/pages/features/features-page.component.ts

@ -0,0 +1,44 @@
import { ChangeDetectorRef, Component, OnDestroy } from '@angular/core';
import { UserService } from '@ghostfolio/client/services/user/user.service';
import { User } from '@ghostfolio/common/interfaces';
import { Subject, takeUntil } from 'rxjs';
@Component({
host: { class: 'page' },
selector: 'gf-features-page',
styleUrls: ['./features-page.scss'],
templateUrl: './features-page.html'
})
export class FeaturesPageComponent implements OnDestroy {
public user: User;
private unsubscribeSubject = new Subject<void>();
/**
* @constructor
*/
public constructor(
private changeDetectorRef: ChangeDetectorRef,
private userService: UserService
) {}
/**
* Initializes the controller
*/
public ngOnInit() {
this.userService.stateChanged
.pipe(takeUntil(this.unsubscribeSubject))
.subscribe((state) => {
if (state?.user) {
this.user = state.user;
this.changeDetectorRef.markForCheck();
}
});
}
public ngOnDestroy() {
this.unsubscribeSubject.next();
this.unsubscribeSubject.complete();
}
}

220
apps/client/src/app/pages/features/features-page.html

@ -0,0 +1,220 @@
<div class="container">
<div class="row">
<div class="col">
<h3 class="d-flex justify-content-center mb-3 text-center" i18n>
Features
</h3>
<mat-card class="mb-4">
<mat-card-content>
<p>
Check out the numerous features of <strong>Ghostfolio</strong> to
manage your wealth.
</p>
</mat-card-content>
</mat-card>
<div class="row">
<div class="col-xs-12 col-md-4 mb-3">
<mat-card class="d-flex flex-column h-100">
<div class="flex-grow-1">
<h4 i18n>Stocks</h4>
<p class="m-0">Keep track of your stock purchases and sales.</p>
</div>
</mat-card>
</div>
<div class="col-xs-12 col-md-4 mb-3">
<mat-card class="d-flex flex-column h-100">
<div class="flex-grow-1">
<h4 i18n>ETFs</h4>
<p class="m-0">
Are you into ETFs (Exchange Traded Funds)? Track your ETF
investments.
</p>
</div>
</mat-card>
</div>
<div class="col-xs-12 col-md-4 mb-3">
<mat-card class="d-flex flex-column h-100">
<div class="flex-grow-1">
<h4 i18n>Cryptocurrencies</h4>
<p class="m-0">
Keep track of your Bitcoin and Altcoin holdings.
</p>
</div>
</mat-card>
</div>
<div class="col-xs-12 col-md-4 mb-3">
<mat-card class="d-flex flex-column h-100">
<div class="flex-grow-1">
<h4 i18n>Dividend</h4>
<p class="m-0">
Are you building a dividend portfolio? Track your dividend in
Ghostfolio.
</p>
</div>
</mat-card>
</div>
<div class="col-xs-12 col-md-4 mb-3">
<mat-card class="d-flex flex-column h-100">
<div class="flex-grow-1">
<h4 class="align-items-center d-flex" i18n>Wealth Items</h4>
<p class="m-0">
Track all your treasuries, be it your luxury watch or rare
trading cards.
</p>
</div>
</mat-card>
</div>
<div class="col-xs-12 col-md-4 mb-3">
<mat-card class="d-flex flex-column h-100">
<div class="flex-grow-1">
<h4 class="align-items-center d-flex" i18n>Import and Export</h4>
<p class="m-0">Import and export your investment activities.</p>
</div>
</mat-card>
</div>
<div class="col-xs-12 col-md-4 mb-3">
<mat-card class="d-flex flex-column h-100">
<div class="flex-grow-1">
<h4 i18n>Multi-Accounts</h4>
<p class="m-0">
Keep an eye on all your accounts across multiple platforms
(multi-banking).
</p>
</div>
</mat-card>
</div>
<div class="col-xs-12 col-md-4 mb-3">
<mat-card class="d-flex flex-column h-100">
<div class="flex-grow-1">
<h4 class="align-items-center d-flex">
<span i18n>Portfolio Calculations</span>
<ion-icon
class="ml-1 text-muted"
name="diamond-outline"
></ion-icon>
</h4>
<p class="m-0">
Check the rate of return of your portfolio for
<code>Today</code>, <code>YTD</code>, <code>1Y</code>,
<code>5Y</code>, and <code>Max</code>.
</p>
</div>
</mat-card>
</div>
<div class="col-xs-12 col-md-4 mb-3">
<mat-card class="d-flex flex-column h-100">
<div class="flex-grow-1">
<h4 class="align-items-center d-flex">
<span i18n>Portfolio Allocations</span>
<ion-icon
class="ml-1 text-muted"
name="diamond-outline"
></ion-icon>
</h4>
<p class="m-0">
Check the allocations of your portfolio by account, asset class,
currency, region, and sector.
</p>
</div>
</mat-card>
</div>
<div class="col-xs-12 col-md-4 mb-3">
<mat-card class="d-flex flex-column h-100">
<div class="flex-grow-1">
<h4 class="align-items-center d-flex" i18n>Dark Mode</h4>
<p class="m-0">
Ghostfolio automatically switches to a dark color theme based on
your operating system's preferences.
</p>
</div>
</mat-card>
</div>
<div class="col-xs-12 col-md-4 mb-3">
<mat-card class="d-flex flex-column h-100">
<div class="flex-grow-1">
<h4 class="align-items-center d-flex" i18n>Zen Mode</h4>
<p class="m-0">
Keep calm and activate Zen Mode if the markets are going crazy.
</p>
</div>
</mat-card>
</div>
<div class="col-xs-12 col-md-4 mb-3">
<mat-card class="d-flex flex-column h-100">
<div class="flex-grow-1">
<h4 class="align-items-center d-flex">
<span i18n>Market Mood</span>
<ion-icon
class="ml-1 text-muted"
name="diamond-outline"
></ion-icon>
</h4>
<p class="m-0">
Check the current market mood (<a [routerLink]="['/resources']"
>Fear & Greed Index</a
>) within the app.
</p>
</div>
</mat-card>
</div>
<div class="col-xs-12 col-md-4 mb-3">
<mat-card class="d-flex flex-column h-100">
<div class="flex-grow-1">
<h4 class="align-items-center d-flex">
<span i18n>Static Analysis</span>
<ion-icon
class="ml-1 text-muted"
name="diamond-outline"
></ion-icon>
</h4>
<p class="m-0">
Identify potential risks in your portfolio with Ghostfolio
X-ray, the static portfolio analysis.
</p>
</div>
</mat-card>
</div>
<div class="col-xs-12 col-md-4 mb-3">
<mat-card class="d-flex flex-column h-100">
<div class="flex-grow-1">
<h4 i18n>Community</h4>
<p class="m-0">
Join the Ghostfolio
<a
href="https://join.slack.com/t/ghostfolio/shared_invite/zt-vsaan64h-F_I0fEo5M0P88lP9ibCxFg"
title="Join the Ghostfolio Slack community"
>Slack channel</a
>
full of enthusiastic investors and discuss the latest market
trends.
</p>
</div>
</mat-card>
</div>
<div class="col-xs-12 col-md-4 mb-3">
<mat-card class="d-flex flex-column h-100">
<div class="flex-grow-1">
<h4 i18n>Open Source Software</h4>
<p class="m-0">
The source code is fully available as
<a
href="https://github.com/ghostfolio/ghostfolio"
title="Find Ghostfolio on GitHub"
>open source software</a
>
(OSS) and licensed under the <i>AGPLv3 License</i>.
</p>
</div>
</mat-card>
</div>
</div>
</div>
</div>
<div *ngIf="!user" class="row">
<div class="col mt-3 text-center">
<a color="primary" i18n mat-flat-button [routerLink]="['/register']">
Get Started
</a>
</div>
</div>
</div>

19
apps/client/src/app/pages/features/features-page.module.ts

@ -0,0 +1,19 @@
import { CommonModule } from '@angular/common';
import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core';
import { MatButtonModule } from '@angular/material/button';
import { MatCardModule } from '@angular/material/card';
import { FeaturesPageRoutingModule } from './features-page-routing.module';
import { FeaturesPageComponent } from './features-page.component';
@NgModule({
declarations: [FeaturesPageComponent],
imports: [
FeaturesPageRoutingModule,
CommonModule,
MatButtonModule,
MatCardModule
],
schemas: [CUSTOM_ELEMENTS_SCHEMA]
})
export class FeaturesPageModule {}

17
apps/client/src/app/pages/features/features-page.scss

@ -0,0 +1,17 @@
:host {
color: rgb(var(--dark-primary-text));
display: block;
a {
color: rgba(var(--palette-primary-500), 1);
font-weight: 500;
&:hover {
color: rgba(var(--palette-primary-300), 1);
}
}
}
:host-context(.is-dark-theme) {
color: rgb(var(--light-primary-text));
}

24
apps/client/src/assets/sitemap.xml

@ -6,42 +6,46 @@
http://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd"> http://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd">
<url> <url>
<loc>https://ghostfol.io</loc> <loc>https://ghostfol.io</loc>
<lastmod>2022-01-01T00:00:00+00:00</lastmod> <lastmod>2022-02-13T00:00:00+00:00</lastmod>
</url> </url>
<url> <url>
<loc>https://ghostfol.io/about</loc> <loc>https://ghostfol.io/about</loc>
<lastmod>2022-01-01T00:00:00+00:00</lastmod> <lastmod>2022-02-13T00:00:00+00:00</lastmod>
</url> </url>
<url> <url>
<loc>https://ghostfol.io/about/changelog</loc> <loc>https://ghostfol.io/about/changelog</loc>
<lastmod>2022-01-01T00:00:00+00:00</lastmod> <lastmod>2022-02-13T00:00:00+00:00</lastmod>
</url> </url>
<url> <url>
<loc>https://ghostfol.io/blog</loc> <loc>https://ghostfol.io/blog</loc>
<lastmod>2022-01-01T00:00:00+00:00</lastmod> <lastmod>2022-02-13T00:00:00+00:00</lastmod>
</url> </url>
<url> <url>
<loc>https://ghostfol.io/de/blog/2021/07/hallo-ghostfolio</loc> <loc>https://ghostfol.io/de/blog/2021/07/hallo-ghostfolio</loc>
<lastmod>2022-01-01T00:00:00+00:00</lastmod> <lastmod>2022-02-13T00:00:00+00:00</lastmod>
</url> </url>
<url> <url>
<loc>https://ghostfol.io/en/blog/2021/07/hello-ghostfolio</loc> <loc>https://ghostfol.io/en/blog/2021/07/hello-ghostfolio</loc>
<lastmod>2022-01-01T00:00:00+00:00</lastmod> <lastmod>2022-02-13T00:00:00+00:00</lastmod>
</url> </url>
<url> <url>
<loc>https://ghostfol.io/en/blog/2022/01/ghostfolio-first-months-in-open-source</loc> <loc>https://ghostfol.io/en/blog/2022/01/ghostfolio-first-months-in-open-source</loc>
<lastmod>2022-01-05T00:00:00+00:00</lastmod> <lastmod>2022-02-13T00:00:00+00:00</lastmod>
</url>
<url>
<loc>https://ghostfol.io/features</loc>
<lastmod>2022-02-13T00:00:00+00:00</lastmod>
</url> </url>
<url> <url>
<loc>https://ghostfol.io/pricing</loc> <loc>https://ghostfol.io/pricing</loc>
<lastmod>2022-01-01T00:00:00+00:00</lastmod> <lastmod>2022-02-13T00:00:00+00:00</lastmod>
</url> </url>
<url> <url>
<loc>https://ghostfol.io/register</loc> <loc>https://ghostfol.io/register</loc>
<lastmod>2022-01-01T00:00:00+00:00</lastmod> <lastmod>2022-02-13T00:00:00+00:00</lastmod>
</url> </url>
<url> <url>
<loc>https://ghostfol.io/resources</loc> <loc>https://ghostfol.io/resources</loc>
<lastmod>2022-01-01T00:00:00+00:00</lastmod> <lastmod>2022-02-13T00:00:00+00:00</lastmod>
</url> </url>
</urlset> </urlset>

Loading…
Cancel
Save