Localize routes (#2250)

* Localize about path

* Localize faq path

* Localize features path

* Localize markets path

* Localize pricing path

* Localize register path

* Localize resources path

* Extend sitemap
pull/2251/head
Thomas Kaul 1 year ago committed by GitHub
parent ff59fd4196
commit 02dc7c52b1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -322,6 +322,10 @@
<loc>https://ghostfol.io/es/sobre/licencia</loc>
<lastmod>${currentDate}T00:00:00+00:00</lastmod>
</url>
<url>
<loc>https://ghostfol.io/es/sobre/oss-friends</loc>
<lastmod>${currentDate}T00:00:00+00:00</lastmod>
</url>
<url>
<loc>https://ghostfol.io/es/sobre/politica-de-privacidad</loc>
<lastmod>${currentDate}T00:00:00+00:00</lastmod>
@ -342,6 +346,10 @@
<loc>https://ghostfol.io/fr/a-propos/licence</loc>
<lastmod>${currentDate}T00:00:00+00:00</lastmod>
</url>
<url>
<loc>https://ghostfol.io/fr/a-propos/oss-friends</loc>
<lastmod>${currentDate}T00:00:00+00:00</lastmod>
</url>
<url>
<loc>https://ghostfol.io/fr/a-propos/politique-de-confidentialite</loc>
<lastmod>${currentDate}T00:00:00+00:00</lastmod>
@ -396,12 +404,16 @@
<loc>https://ghostfol.io/it/informazioni-su/changelog</loc>
<lastmod>${currentDate}T00:00:00+00:00</lastmod>
</url>
<url>
<loc>https://ghostfol.io/it/informazioni-su/informativa-sulla-privacy</loc>
<lastmod>${currentDate}T00:00:00+00:00</lastmod>
</url>
<url>
<loc>https://ghostfol.io/it/informazioni-su/licenza</loc>
<lastmod>${currentDate}T00:00:00+00:00</lastmod>
</url>
<url>
<loc>https://ghostfol.io/it/informazioni-su/informativa-sulla-privacy</loc>
<loc>https://ghostfol.io/it/informazioni-su/oss-friends</loc>
<lastmod>${currentDate}T00:00:00+00:00</lastmod>
</url>
<url>
@ -460,6 +472,10 @@
<loc>https://ghostfol.io/nl/over/licentie</loc>
<lastmod>${currentDate}T00:00:00+00:00</lastmod>
</url>
<url>
<loc>https://ghostfol.io/nl/over/oss-friends</loc>
<lastmod>${currentDate}T00:00:00+00:00</lastmod>
</url>
<url>
<loc>https://ghostfol.io/nl/over/privacybeleid</loc>
<lastmod>${currentDate}T00:00:00+00:00</lastmod>
@ -520,6 +536,10 @@
<loc>https://ghostfol.io/pt/sobre/licenca</loc>
<lastmod>${currentDate}T00:00:00+00:00</lastmod>
</url>
<url>
<loc>https://ghostfol.io/pt/sobre/oss-friends</loc>
<lastmod>${currentDate}T00:00:00+00:00</lastmod>
</url>
<url>
<loc>https://ghostfol.io/pt/sobre/politica-de-privacidade</loc>
<lastmod>${currentDate}T00:00:00+00:00</lastmod>

@ -1,22 +1,27 @@
import { NgModule } from '@angular/core';
import { RouterModule, Routes, TitleStrategy } from '@angular/router';
import { routes as aboutRoutes } from '@ghostfolio/client/pages/about/routes';
import { routes as faqRoutes } from '@ghostfolio/client/pages/faq/routes';
import { routes as featuresRoutes } from '@ghostfolio/client/pages/features/routes';
import { routes as marketsRoutes } from '@ghostfolio/client/pages/markets/routes';
import { routes as pricingRoutes } from '@ghostfolio/client/pages/pricing/routes';
import { routes as registerRoutes } from '@ghostfolio/client/pages/register/routes';
import { routes as resourcesRoutes } from '@ghostfolio/client/pages/resources/routes';
import { PageTitleStrategy } from '@ghostfolio/client/services/page-title.strategy';
import { ModulePreloadService } from './core/module-preload.service';
export const paths = {
about: $localize`about`,
faq: $localize`faq`,
features: $localize`features`,
license: $localize`license`,
markets: $localize`markets`,
pricing: $localize`pricing`,
privacyPolicy: $localize`privacy-policy`,
register: $localize`register`,
resources: $localize`resources`
};
const routes: Routes = [
...aboutRoutes.map((path) => ({
path,
{
path: paths.about,
loadChildren: () =>
import('./pages/about/about-page.module').then((m) => m.AboutPageModule)
})),
},
{
path: 'account',
loadChildren: () =>
@ -51,30 +56,30 @@ const routes: Routes = [
loadChildren: () =>
import('./pages/demo/demo-page.module').then((m) => m.DemoPageModule)
},
...faqRoutes.map((path) => ({
path,
{
path: paths.faq,
loadChildren: () =>
import('./pages/faq/faq-page.module').then((m) => m.FaqPageModule)
})),
...featuresRoutes.map((path) => ({
path,
},
{
path: paths.features,
loadChildren: () =>
import('./pages/features/features-page.module').then(
(m) => m.FeaturesPageModule
)
})),
},
{
path: 'home',
loadChildren: () =>
import('./pages/home/home-page.module').then((m) => m.HomePageModule)
},
...marketsRoutes.map((path) => ({
path,
{
path: paths.markets,
loadChildren: () =>
import('./pages/markets/markets-page.module').then(
(m) => m.MarketsPageModule
)
})),
},
{
path: 'open',
loadChildren: () =>
@ -94,27 +99,27 @@ const routes: Routes = [
(m) => m.PortfolioPageModule
)
},
...pricingRoutes.map((path) => ({
path,
{
path: paths.pricing,
loadChildren: () =>
import('./pages/pricing/pricing-page.module').then(
(m) => m.PricingPageModule
)
})),
...registerRoutes.map((path) => ({
path,
},
{
path: paths.register,
loadChildren: () =>
import('./pages/register/register-page.module').then(
(m) => m.RegisterPageModule
)
})),
...resourcesRoutes.map((path) => ({
path,
},
{
path: paths.resources,
loadChildren: () =>
import('./pages/resources/resources-page.module').then(
(m) => m.ResourcesPageModule
)
})),
},
{
path: 'start',
loadChildren: () =>

@ -19,7 +19,7 @@
<a
*ngIf="canCreateAccount"
class="text-center"
[routerLink]="['/register']"
[routerLink]="routerLinkRegister"
>
<div
class="cursor-pointer d-inline-block info-message px-3 py-2"
@ -43,22 +43,7 @@
<router-outlet></router-outlet>
</main>
<footer
*ngIf="
(currentRoute === 'blog' ||
currentRoute === 'faq' ||
currentRoute === 'features' ||
currentRoute === 'markets' ||
currentRoute === 'open' ||
currentRoute === 'p' ||
currentRoute === 'pricing' ||
currentRoute === 'resources' ||
currentRoute === 'register' ||
currentRoute === 'start') &&
deviceType !== 'mobile'
"
class="d-flex justify-content-center py-4 w-100"
>
<footer *ngIf="showFooter" class="d-flex justify-content-center py-4 w-100">
<div class="container">
<div class="mb-3 row">
<div class="col-sm">
@ -68,36 +53,38 @@
<div class="h6 mt-2" i18n>Personal Finance</div>
<ul class="list-unstyled">
<li *ngIf="hasPermissionToAccessFearAndGreedIndex">
<a i18n [routerLink]="['/markets']">Markets</a>
<a i18n [routerLink]="routerLinkMarkets">Markets</a>
</li>
<li><a i18n [routerLink]="['/resources']">Resources</a></li>
<li><a i18n [routerLink]="routerLinkResources">Resources</a></li>
</ul>
</div>
<div class="col-sm">
<div class="h6 mt-2">Ghostfolio</div>
<ul class="list-unstyled">
<li><a i18n [routerLink]="['/about']">About</a></li>
<li><a i18n [routerLink]="routerLinkAbout">About</a></li>
<li *ngIf="hasPermissionForBlog">
<a i18n [routerLink]="['/blog']">Blog</a>
</li>
<li>
<a i18n [routerLink]="['/about', 'changelog']">Changelog</a>
<a i18n [routerLink]="routerLinkAboutChangelog">Changelog</a>
</li>
<li><a i18n [routerLink]="['/features']">Features</a></li>
<li><a i18n [routerLink]="routerLinkFeatures">Features</a></li>
<li *ngIf="hasPermissionForSubscription">
<a i18n [routerLink]="['/faq']">Frequently Asked Questions (FAQ)</a>
<a i18n [routerLink]="routerLinkFaq"
>Frequently Asked Questions (FAQ)</a
>
</li>
<li>
<a i18n [routerLink]="['/about', 'license']">License</a>
<a i18n [routerLink]="routerLinkAboutLicense">License</a>
</li>
<li *ngIf="hasPermissionForStatistics">
<a [routerLink]="['/open']">Open Startup</a>
</li>
<li *ngIf="hasPermissionForSubscription">
<a i18n [routerLink]="['/pricing']">Pricing</a>
<a i18n [routerLink]="routerLinkPricing">Pricing</a>
</li>
<li *ngIf="hasPermissionForSubscription">
<a i18n [routerLink]="['/about', 'privacy-policy']"
<a i18n [routerLink]="routerLinkAboutPrivacyPolicy"
>Privacy Policy</a
>
</li>

@ -38,6 +38,20 @@ export class AppComponent implements OnDestroy, OnInit {
public hasPermissionToAccessFearAndGreedIndex: boolean;
public info: InfoItem;
public pageTitle: string;
public routerLinkAbout = ['/' + $localize`about`];
public routerLinkAboutChangelog = ['/' + $localize`about`, 'changelog'];
public routerLinkAboutLicense = ['/' + $localize`about`, $localize`license`];
public routerLinkAboutPrivacyPolicy = [
'/' + $localize`about`,
$localize`privacy-policy`
];
public routerLinkFaq = ['/' + $localize`faq`];
public routerLinkFeatures = ['/' + $localize`features`];
public routerLinkMarkets = ['/' + $localize`markets`];
public routerLinkPricing = ['/' + $localize`pricing`];
public routerLinkRegister = ['/' + $localize`register`];
public routerLinkResources = ['/' + $localize`resources`];
public showFooter = false;
public user: User;
public version = environment.version;
@ -89,6 +103,19 @@ export class AppComponent implements OnDestroy, OnInit {
const urlSegments = urlSegmentGroup.segments;
this.currentRoute = urlSegments[0].path;
this.showFooter =
(this.currentRoute === 'blog' ||
this.currentRoute === this.routerLinkFaq[0].slice(1) ||
this.currentRoute === this.routerLinkFeatures[0].slice(1) ||
this.currentRoute === this.routerLinkMarkets[0].slice(1) ||
this.currentRoute === 'open' ||
this.currentRoute === 'p' ||
this.currentRoute === this.routerLinkPricing[0].slice(1) ||
this.currentRoute === this.routerLinkRegister[0].slice(1) ||
this.currentRoute === this.routerLinkResources[0].slice(1) ||
this.currentRoute === 'start') &&
this.deviceType !== 'mobile';
if (this.deviceType === 'mobile') {
setTimeout(() => {
const index = this.title.getTitle().indexOf('');

@ -69,10 +69,10 @@
i18n
mat-flat-button
[ngClass]="{
'font-weight-bold': currentRoute === 'resources',
'text-decoration-underline': currentRoute === 'resources'
'font-weight-bold': currentRoute === routeResources,
'text-decoration-underline': currentRoute === routeResources
}"
[routerLink]="['/resources']"
[routerLink]="routerLinkResources"
>Resources</a
>
</li>
@ -87,10 +87,10 @@
i18n
mat-flat-button
[ngClass]="{
'font-weight-bold': currentRoute === 'pricing',
'text-decoration-underline': currentRoute === 'pricing'
'font-weight-bold': currentRoute === routePricing,
'text-decoration-underline': currentRoute === routePricing
}"
[routerLink]="['/pricing']"
[routerLink]="routerLinkPricing"
>Pricing</a
>
</li>
@ -100,10 +100,10 @@
i18n
mat-flat-button
[ngClass]="{
'font-weight-bold': currentRoute === 'about',
'text-decoration-underline': currentRoute === 'about'
'font-weight-bold': currentRoute === routeAbout,
'text-decoration-underline': currentRoute === routeAbout
}"
[routerLink]="['/about']"
[routerLink]="routerLinkAbout"
>About</a
>
</li>
@ -210,9 +210,9 @@
i18n
mat-menu-item
[ngClass]="{
'font-weight-bold': currentRoute === 'resources'
'font-weight-bold': currentRoute === routeResources
}"
[routerLink]="['/resources']"
[routerLink]="routerLinkResources"
>Resources</a
>
<a
@ -223,16 +223,16 @@
class="d-flex d-sm-none"
i18n
mat-menu-item
[ngClass]="{ 'font-weight-bold': currentRoute === 'pricing' }"
[routerLink]="['/pricing']"
[ngClass]="{ 'font-weight-bold': currentRoute === routePricing }"
[routerLink]="routerLinkPricing"
>Pricing</a
>
<a
class="d-flex d-sm-none"
i18n
mat-menu-item
[ngClass]="{ 'font-weight-bold': currentRoute === 'about' }"
[routerLink]="['/about']"
[ngClass]="{ 'font-weight-bold': currentRoute === routeAbout }"
[routerLink]="routerLinkAbout"
>About Ghostfolio</a
>
<hr class="d-flex d-sm-none m-0" />
@ -260,10 +260,10 @@
i18n
mat-flat-button
[ngClass]="{
'font-weight-bold': currentRoute === 'features',
'text-decoration-underline': currentRoute === 'features'
'font-weight-bold': currentRoute === routeFeatures,
'text-decoration-underline': currentRoute === routeFeatuers
}"
[routerLink]="['/features']"
[routerLink]="routerLinkFeatures"
>Features</a
>
</li>
@ -273,10 +273,10 @@
i18n
mat-flat-button
[ngClass]="{
'font-weight-bold': currentRoute === 'about',
'text-decoration-underline': currentRoute === 'about'
'font-weight-bold': currentRoute === routeAbout,
'text-decoration-underline': currentRoute === routeAbout
}"
[routerLink]="['/about']"
[routerLink]="routerLinkAbout"
>About</a
>
</li>
@ -285,10 +285,10 @@
i18n
mat-flat-button
[ngClass]="{
'font-weight-bold': currentRoute === 'pricing',
'text-decoration-underline': currentRoute === 'pricing'
'font-weight-bold': currentRoute === routePricing,
'text-decoration-underline': currentRoute === routePricing
}"
[routerLink]="['/pricing']"
[routerLink]="routerLinkPricing"
>Pricing</a
>
</li>
@ -301,10 +301,10 @@
i18n
mat-flat-button
[ngClass]="{
'font-weight-bold': currentRoute === 'markets',
'text-decoration-underline': currentRoute === 'markets'
'font-weight-bold': currentRoute === routeMarkets,
'text-decoration-underline': currentRoute === routeMarkets
}"
[routerLink]="['/markets']"
[routerLink]="routerLinkMarkets"
>Markets</a
>
</li>
@ -329,7 +329,7 @@
class="d-none d-sm-block"
color="primary"
mat-flat-button
[routerLink]="['/register']"
[routerLink]="routerLinkRegister"
><ng-container i18n>Get started</ng-container>
</a>
</li>

@ -42,6 +42,17 @@ export class HeaderComponent implements OnChanges {
public hasPermissionToCreateUser: boolean;
public impersonationId: string;
public isMenuOpen: boolean;
public routeAbout = $localize`about`;
public routeFeatures = $localize`features`;
public routeMarkets = $localize`markets`;
public routePricing = $localize`pricing`;
public routeResources = $localize`resources`;
public routerLinkAbout = ['/' + $localize`about`];
public routerLinkFeatures = ['/' + $localize`features`];
public routerLinkMarkets = ['/' + $localize`markets`];
public routerLinkPricing = ['/' + $localize`pricing`];
public routerLinkRegister = ['/' + $localize`register`];
public routerLinkResources = ['/' + $localize`resources`];
private unsubscribeSubject = new Subject<void>();

@ -121,7 +121,7 @@ export class HomeSummaryComponent implements OnDestroy, OnInit {
});
this.snackBarRef.onAction().subscribe(() => {
this.router.navigate(['/pricing']);
this.router.navigate(['/' + $localize`pricing`]);
});
}

@ -11,6 +11,8 @@ import { SubscriptionInterstitialDialogParams } from './interfaces/interfaces';
templateUrl: 'subscription-interstitial-dialog.html'
})
export class SubscriptionInterstitialDialog {
public routerLinkPricing = ['/' + $localize`pricing`];
public constructor(
@Inject(MAT_DIALOG_DATA) public data: SubscriptionInterstitialDialogParams,
public dialogRef: MatDialogRef<SubscriptionInterstitialDialog>

@ -56,7 +56,7 @@
<a
color="primary"
mat-flat-button
[routerLink]="['/pricing']"
[routerLink]="routerLinkPricing"
(click)="closeDialog()"
>
<span i18n>Upgrade Plan</span>

@ -4,13 +4,7 @@ import {
Router,
RouterStateSnapshot
} from '@angular/router';
import { routes as aboutRoutes } from '@ghostfolio/client/pages/about/routes';
import { routes as faqRoutes } from '@ghostfolio/client/pages/faq/routes';
import { routes as featuresRoutes } from '@ghostfolio/client/pages/features/routes';
import { routes as marketsRoutes } from '@ghostfolio/client/pages/markets/routes';
import { routes as pricingRoutes } from '@ghostfolio/client/pages/pricing/routes';
import { routes as registerRoutes } from '@ghostfolio/client/pages/register/routes';
import { routes as resourcesRoutes } from '@ghostfolio/client/pages/resources/routes';
import { paths } from '@ghostfolio/client/app-routing.module';
import { DataService } from '@ghostfolio/client/services/data.service';
import { SettingsStorageService } from '@ghostfolio/client/services/settings-storage.service';
import { UserService } from '@ghostfolio/client/services/user/user.service';
@ -20,17 +14,17 @@ import { catchError } from 'rxjs/operators';
@Injectable({ providedIn: 'root' })
export class AuthGuard {
private static PUBLIC_PAGE_ROUTES = [
...aboutRoutes.map((route) => `/${route}`),
`/${paths.about}`,
'/blog',
'/demo',
...faqRoutes.map((route) => `/${route}`),
...featuresRoutes.map((route) => `/${route}`),
...marketsRoutes.map((route) => `/${route}`),
`/${paths.faq}`,
`/${paths.features}`,
`/${paths.markets}`,
'/open',
'/p',
...pricingRoutes.map((route) => `/${route}`),
...registerRoutes.map((route) => `/${route}`),
...resourcesRoutes.map((route) => `/${route}`)
`/${paths.pricing}`,
`/${paths.register}`,
`/${paths.resources}`
];
constructor(
@ -56,7 +50,7 @@ export class AuthGuard {
this.router.navigate(['/demo']);
resolve(false);
} else if (utmSource === 'trusted-web-activity') {
this.router.navigate(['/register']);
this.router.navigate(['/' + $localize`register`]);
resolve(false);
} else if (
AuthGuard.PUBLIC_PAGE_ROUTES.filter((publicPageRoute) =>

@ -77,7 +77,7 @@ export class HttpResponseInterceptor implements HttpInterceptor {
});
this.snackBarRef.onAction().subscribe(() => {
this.router.navigate(['/pricing']);
this.router.navigate(['/' + $localize`pricing`]);
});
}
} else if (error.status === StatusCodes.INTERNAL_SERVER_ERROR) {

@ -3,6 +3,8 @@ import { RouterModule, Routes } from '@angular/router';
import { AuthGuard } from '@ghostfolio/client/core/auth.guard';
import { AboutPageComponent } from './about-page.component';
import { paths } from '@ghostfolio/client/app-routing.module';
import * as path from 'path';
const routes: Routes = [
{
@ -22,22 +24,13 @@ const routes: Routes = [
(m) => m.ChangelogPageModule
)
},
...[
'license',
/////
'licenca',
'licence',
'licencia',
'licentie',
'lizenz',
'licenza'
].map((path) => ({
path,
{
path: paths.license,
loadChildren: () =>
import('./license/license-page.module').then(
(m) => m.LicensePageModule
)
})),
},
{
path: 'oss-friends',
loadChildren: () =>
@ -45,22 +38,13 @@ const routes: Routes = [
(m) => m.OpenSourceSoftwareFriendsPageModule
)
},
...[
'privacy-policy',
/////
'datenschutzbestimmungen',
'informativa-sulla-privacy',
'politique-de-confidentialite',
'politica-de-privacidad',
'politica-de-privacidade',
'privacybeleid'
].map((path) => ({
path,
{
path: paths.privacyPolicy,
loadChildren: () =>
import('./privacy-policy/privacy-policy-page.module').then(
(m) => m.PrivacyPolicyPageModule
)
}))
}
],
component: AboutPageComponent,
path: '',

@ -48,17 +48,17 @@ export class AboutPageComponent implements OnDestroy, OnInit {
{
iconName: 'reader-outline',
label: $localize`About`,
path: ['/about']
path: ['/' + $localize`about`]
},
{
iconName: 'sparkles-outline',
label: $localize`Changelog`,
path: ['/about', 'changelog']
path: ['/' + $localize`about`, 'changelog']
},
{
iconName: 'ribbon-outline',
label: $localize`License`,
path: ['/about', 'license']
path: ['/' + $localize`about`, $localize`license`]
}
];
@ -66,7 +66,7 @@ export class AboutPageComponent implements OnDestroy, OnInit {
this.tabs.push({
iconName: 'shield-checkmark-outline',
label: $localize`Privacy Policy`,
path: ['/about', 'privacy-policy'],
path: ['/' + $localize`about`, $localize`privacy-policy`],
showCondition: this.hasPermissionForSubscription
});
this.user = state.user;
@ -83,7 +83,7 @@ export class AboutPageComponent implements OnDestroy, OnInit {
this.tabs.push({
iconName: 'happy-outline',
label: 'OSS Friends',
path: ['/about', 'oss-friends']
path: ['/' + $localize`about`, 'oss-friends']
});
});
}

@ -6,7 +6,7 @@
><ng-container i18n>Our</ng-container> OSS Friends</span
>
<small class="text-muted" i18n
>Discover more Open Source Software projects</small
>Discover other exciting Open Source Software projects</small
>
</h1>
<div class="row">

@ -18,6 +18,8 @@ export class AboutOverviewPageComponent implements OnDestroy, OnInit {
public hasPermissionForStatistics: boolean;
public hasPermissionForSubscription: boolean;
public isLoggedIn: boolean;
public routerLinkFaq = ['/' + $localize`faq`];
public routerLinkFeatures = ['/' + $localize`features`];
public user: User;
public version = environment.version;

@ -46,7 +46,7 @@
<p>
If you encounter a bug or would like to suggest an improvement or a
new
<a [routerLink]="['/features']">feature</a>, please join the
<a [routerLink]="routerLinkFeatures">feature</a>, please join the
Ghostfolio
<a
href="https://join.slack.com/t/ghostfolio/shared_invite/zt-vsaan64h-F_I0fEo5M0P88lP9ibCxFg"
@ -139,7 +139,7 @@
class="py-4 w-100"
color="primary"
mat-flat-button
[routerLink]="['/faq']"
[routerLink]="routerLinkFaq"
>Frequently Asked Questions (FAQ)</a
>
</div>

@ -1,9 +0,0 @@
export const routes = [
'about',
/////
'a-propos',
'informazioni-su',
'over',
'sobre',
'ueber-uns'
] as const;

@ -9,4 +9,7 @@ import { RouterModule } from '@angular/router';
standalone: true,
templateUrl: './hallo-ghostfolio-page.html'
})
export class HalloGhostfolioPageComponent {}
export class HalloGhostfolioPageComponent {
public routerLinkPricing = ['/' + $localize`pricing`];
public routerLinkResources = ['/' + $localize`resources`];
}

@ -19,7 +19,7 @@
Aufgrund der steigenden Inflation und den Negativzinsen befasse ich
mich seit einiger Zeit, wie ich mein Vermögen möglichst
diversifiziert anlegen kann. Konkret verfolge ich eine
<a [routerLink]="['/resources']">Buy and Hold Strategie</a> mit
<a [routerLink]="routerLinkResources">Buy and Hold Strategie</a> mit
Investitionen in verschiedene Anlageklassen verteilt auf
unterschiedliche Plattformen. Deshalb suchte ich nach einer App, die
mein Portfolio ganzheitlich zusammenfasst. Bei meiner
@ -119,7 +119,7 @@
Anlagestrategie? Ich freue mich über alle, die Ghostfolio
ausprobieren. Bist du überzeugt vom Potential der Software? Jede
Unterstützung für Ghostfolio ist willkommen. Sei es mit einer
<a [routerLink]="['/pricing']">Ghostfolio Premium</a>
<a [routerLink]="routerLinkPricing">Ghostfolio Premium</a>
Subscription zur Finanzierung des Hostings, einem positiven Rating
im
<a

@ -9,4 +9,7 @@ import { RouterModule } from '@angular/router';
standalone: true,
templateUrl: './hello-ghostfolio-page.html'
})
export class HelloGhostfolioPageComponent {}
export class HelloGhostfolioPageComponent {
public routerLinkPricing = ['/' + $localize`pricing`];
public routerLinkResources = ['/' + $localize`resources`];
}

@ -19,7 +19,7 @@
Due to rising inflation and negative interest rates, I have been
looking for some time at how I can invest my assets in the most
diversified way possible. Specifically, I follow a
<a [routerLink]="['/resources']">buy and hold strategy</a> with
<a [routerLink]="routerLinkResources">buy and hold strategy</a> with
investments in different asset classes spread across different
platforms. Therefore, I was looking for an app that would
holistically aggregate my portfolio. During my research on the
@ -115,7 +115,7 @@
strategy? I'm happy for everyone who tries Ghostfolio. Are you
convinced of its potential? Any support for Ghostfolio is welcome.
Be it with a
<a [routerLink]="['/pricing']">Ghostfolio Premium</a>
<a [routerLink]="routerLinkPricing">Ghostfolio Premium</a>
Subscription to finance the hosting, a positive rating in the
<a
href="https://play.google.com/store/apps/details?id=ch.dotsilver.ghostfolio.twa"

@ -9,4 +9,6 @@ import { RouterModule } from '@angular/router';
standalone: true,
templateUrl: './first-months-in-open-source-page.html'
})
export class FirstMonthsInOpenSourcePageComponent {}
export class FirstMonthsInOpenSourcePageComponent {
public routerLinkPricing = ['/' + $localize`pricing`];
}

@ -86,7 +86,7 @@
</p>
<p>
My personal goal is to reach break-even with the Saas offering (<a
[routerLink]="['/pricing']"
[routerLink]="routerLinkPricing"
>Ghostfolio Premium</a
>) and regularly report about the progress and my learnings on this
exciting journey.

@ -9,4 +9,6 @@ import { RouterModule } from '@angular/router';
standalone: true,
templateUrl: './how-do-i-get-my-finances-in-order-page.html'
})
export class HowDoIGetMyFinancesInOrderPageComponent {}
export class HowDoIGetMyFinancesInOrderPageComponent {
public routerLinkResources = ['/' + $localize`resources`];
}

@ -9,9 +9,9 @@
<section class="mb-4">
<p>
Before you can think of
<a [routerLink]="['/resources']">long-term investing</a>, you have
to get your finances in order. Take a look at Peter's journey to see
how you can achieve it, too.
<a [routerLink]="routerLinkResources">long-term investing</a>, you
have to get your finances in order. Take a look at Peter's journey
to see how you can achieve it, too.
</p>
<p>
Peter enjoys life, but sometimes he overspends a bit. He realizes it

@ -9,4 +9,7 @@ import { RouterModule } from '@angular/router';
standalone: true,
templateUrl: './500-stars-on-github-page.html'
})
export class FiveHundredStarsOnGitHubPageComponent {}
export class FiveHundredStarsOnGitHubPageComponent {
public routerLinkMarkets = ['/' + $localize`markets`];
public routerLinkPricing = ['/' + $localize`pricing`];
}

@ -71,10 +71,10 @@
<h2 class="h4">Break-even Point</h2>
<p>
Despite the complicated
<a [routerLink]="['/markets']">economic situation</a> at this time,
the goal set at the beginning of the year to build a sustainable
business and reach break-even with the SaaS offering (<a
[routerLink]="['/pricing']"
<a [routerLink]="routerLinkMarkets">economic situation</a> at this
time, the goal set at the beginning of the year to build a
sustainable business and reach break-even with the SaaS offering (<a
[routerLink]="routerLinkPricing"
>Ghostfolio Premium</a
>) has been achieved. We will continue to leverage the revenue to
further improve the fully managed cloud offering for our paying

@ -11,5 +11,6 @@ import { GfPremiumIndicatorModule } from '@ghostfolio/ui/premium-indicator';
templateUrl: './black-friday-2022-page.html'
})
export class BlackFriday2022PageComponent {
public constructor() {}
public routerLinkFeatures = ['/' + $localize`features`];
public routerLinkPricing = ['/' + $localize`pricing`];
}

@ -35,17 +35,18 @@
software presents the current assets (stocks, ETFs,
cryptocurrencies, commodities etc.) in real time to make solid,
data-driven investment decisions. Check out the numerous
<a [routerLink]="['/features']">features</a> to manage your wealth.
<a [routerLink]="routerLinkFeatures">features</a> to manage your
wealth.
</p>
</section>
<section class="mb-4">
<p>
Snap the limited Black Friday 2022 deal before its gone. For
detailed information on plans and pricing, please visit our
<a [routerLink]="['/pricing']">pricing page</a>.
<a [routerLink]="routerLinkPricing">pricing page</a>.
</p>
<p class="text-center">
<a color="primary" mat-flat-button [routerLink]="['/pricing']"
<a color="primary" mat-flat-button [routerLink]="routerLinkPricing"
>Get the Deal</a
>
</p>

@ -9,4 +9,7 @@ import { RouterModule } from '@angular/router';
standalone: true,
templateUrl: './1000-stars-on-github-page.html'
})
export class ThousandStarsOnGitHubPageComponent {}
export class ThousandStarsOnGitHubPageComponent {
public routerLinkFeatures = ['/' + $localize`features`];
public routerLinkPricing = ['/' + $localize`pricing`];
}

@ -92,7 +92,7 @@
<p>
These self-hosting platforms allow users to run applications on
their own hardware rather than rely on a
<a [routerLink]="['/pricing']">SaaS offering</a>. As a result,
<a [routerLink]="routerLinkPricing">SaaS offering</a>. As a result,
Ghostfolio has become accessible to an even wider range of users who
would like to take control of their wealth management.
</p>
@ -108,9 +108,9 @@
As the project continues to evolve, we can expect to see even more
exciting developments and innovations around Ghostfolio which guides
users through the process of
<a [routerLink]="['/features']">tracking their assets</a>, such as
stocks, ETFs, or cryptocurrencies. Especially in the areas of data
import and portfolio analysis.
<a [routerLink]="routerLinkFeatures">tracking their assets</a>, such
as stocks, ETFs, or cryptocurrencies. Especially in the areas of
data import and portfolio analysis.
</p>
<p>
We are honored to be a part of this vibrant and growing community,

@ -9,4 +9,7 @@ import { RouterModule } from '@angular/router';
standalone: true,
templateUrl: './unlock-your-financial-potential-with-ghostfolio-page.html'
})
export class UnlockYourFinancialPotentialWithGhostfolioPageComponent {}
export class UnlockYourFinancialPotentialWithGhostfolioPageComponent {
public routerLinkFeatures = ['/' + $localize`features`];
public routerLinkResources = ['/' + $localize`resources`];
}

@ -44,13 +44,13 @@
<h2 class="h4">Empowering Buy & Hold Strategies</h2>
<p>
For those committed to a
<a [routerLink]="['/resources']">buy & hold strategy</a>, Ghostfolio
provides an intuitive interface to monitor long-term investments.
Users can track performance over time, gaining insights into
portfolio growth and stability. With strong visualizations and
reporting <a [routerLink]="['/features']">features</a>, Ghostfolio
equips users to make well-informed decisions aligned with their
long-term investment goals.
<a [routerLink]="routerLinkResources">buy & hold strategy</a>,
Ghostfolio provides an intuitive interface to monitor long-term
investments. Users can track performance over time, gaining insights
into portfolio growth and stability. With strong visualizations and
reporting <a [routerLink]="routerLinkFeatures">features</a>,
Ghostfolio equips users to make well-informed decisions aligned with
their long-term investment goals.
</p>
</section>
<section class="mb-4">
@ -91,7 +91,7 @@
<h2 class="h4">Driving Financial Independence (FIRE)</h2>
<p>
Achieving
<a [routerLink]="['/resources']">financial independence</a>
<a [routerLink]="routerLinkResources">financial independence</a>
including early retirement (<a
href="../en/blog/2023/07/exploring-the-path-to-fire"
>FIRE</a

@ -9,4 +9,6 @@ import { RouterModule } from '@angular/router';
standalone: true,
templateUrl: './exploring-the-path-to-fire-page.html'
})
export class ExploringThePathToFirePageComponent {}
export class ExploringThePathToFirePageComponent {
public routerLinkFeatures = ['/' + $localize`features`];
}

@ -135,10 +135,10 @@
track your investments, and make informed decisions to accelerate
your progress towards financial independence. Ghostfolio also
provides a dedicated
<a [routerLink]="['/features']">FIRE calculator</a>, allowing you to
simulate your customized plan to achieve FIRE. You get the tools to
optimize your financial journey and confidently strive for a future
that is both personally fulfilling and financially secure.
<a [routerLink]="routerLinkFeatures">FIRE calculator</a>, allowing
you to simulate your customized plan to achieve FIRE. You get the
tools to optimize your financial journey and confidently strive for
a future that is both personally fulfilling and financially secure.
</p>
</section>
<section class="mb-4 py-3">

@ -10,6 +10,10 @@ import { Subject, takeUntil } from 'rxjs';
templateUrl: './faq-page.html'
})
export class FaqPageComponent implements OnDestroy {
public routerLinkFeatures = ['/' + $localize`features`];
public routerLinkMarkets = ['/' + $localize`markets`];
public routerLinkPricing = ['/' + $localize`pricing`];
public routerLinkRegister = ['/' + $localize`register`];
public user: User;
private unsubscribeSubject = new Subject<void>();

@ -39,7 +39,7 @@
>
<mat-card-content>
Please find a feature overview to manage your wealth
<a [routerLink]="['/features']">here</a>.
<a [routerLink]="routerLinkFeatures">here</a>.
</mat-card-content>
</mat-card>
<mat-card appearance="outlined" class="mb-3">
@ -47,7 +47,7 @@
<mat-card-title>How do I start?</mat-card-title></mat-card-header
>
<mat-card-content>
You can sign up via the “<a [routerLink]="['/register']"
You can sign up via the “<a [routerLink]="routerLinkRegister"
>Get Started</a
>” button at the top of the page. You have multiple options to join
Ghostfolio: Create an account with a security token, using
@ -93,7 +93,7 @@
world. The
<a href="https://github.com/ghostfolio/ghostfolio">source code</a> is
fully available as open source software (OSS). Thanks to our generous
<a [routerLink]="['/pricing']">Ghostfolio Premium</a> users and
<a [routerLink]="routerLinkPricing">Ghostfolio Premium</a> users and
<a href="https://www.buymeacoffee.com/ghostfolio">sponsors</a> we have
the ability to run a free, limited plan for novice
investors.</mat-card-content
@ -105,8 +105,8 @@
>
<mat-card-content
>Yes, it is! Our
<a [routerLink]="['/pricing']">pricing page</a> details everything you
get for free.</mat-card-content
<a [routerLink]="routerLinkPricing">pricing page</a> details
everything you get for free.</mat-card-content
>
</mat-card>
<mat-card appearance="outlined" class="mb-3">
@ -127,7 +127,8 @@
></mat-card-header
>
<mat-card-content
>By offering <a [routerLink]="['/pricing']">Ghostfolio Premium</a>, a
>By offering
<a [routerLink]="routerLinkPricing">Ghostfolio Premium</a>, a
subscription plan with a managed hosting service and enhanced
features, we fund our business while providing added value to our
users.</mat-card-content
@ -140,12 +141,12 @@
></mat-card-header
>
<mat-card-content
><a [routerLink]="['/pricing']">Ghostfolio Premium</a> is a fully
><a [routerLink]="routerLinkPricing">Ghostfolio Premium</a> is a fully
managed Ghostfolio cloud offering for ambitious investors. The revenue
is used to cover the hosting infrastructure and to fund the ongoing
development. It is the Open Source code base with some extras like the
<a [routerLink]="['/markets']">markets overview</a> and a professional
data provider.</mat-card-content
<a [routerLink]="routerLinkMarkets">markets overview</a> and a
professional data provider.</mat-card-content
>
</mat-card>
<mat-card appearance="outlined" class="mb-3">
@ -156,9 +157,9 @@
>
<mat-card-content
>Yes, you can try
<a [routerLink]="['/pricing']">Ghostfolio Premium</a> by signing up
for Ghostfolio and applying for a trial (see “My Ghostfolio”). It is
easy, free and there is no commitment. You can stop using it at any
<a [routerLink]="routerLinkPricing">Ghostfolio Premium</a> by signing
up for Ghostfolio and applying for a trial (see “My Ghostfolio”). It
is easy, free and there is no commitment. You can stop using it at any
time.</mat-card-content
>
</mat-card>
@ -214,8 +215,9 @@
</mat-card-header>
<mat-card-content
>Any support for Ghostfolio is welcome. Be it with a
<a [routerLink]="['/pricing']">Ghostfolio Premium</a> subscription to
finance the hosting infrastructure, a positive rating in the
<a [routerLink]="routerLinkPricing">Ghostfolio Premium</a>
subscription to finance the hosting infrastructure, a positive rating
in the
<a
href="https://play.google.com/store/apps/details?id=ch.dotsilver.ghostfolio.twa"
>Google Play Store</a

@ -1,10 +0,0 @@
export const routes = [
'faq',
/////
'domande-piu-frequenti',
'foire-aux-questions',
'haeufig-gestellte-fragen',
'perguntas-mais-frequentes',
'preguntas-mas-frecuentes',
'vaak-gestelde-vragen'
] as const;

@ -14,6 +14,7 @@ import { Subject, takeUntil } from 'rxjs';
export class FeaturesPageComponent implements OnDestroy {
public hasPermissionForSubscription: boolean;
public info: InfoItem;
public routerLinkRegister = ['/' + $localize`register`];
public user: User;
private unsubscribeSubject = new Subject<void>();

@ -211,7 +211,7 @@
</h4>
<p class="m-0">
Check the current market mood (<a
[routerLink]="['/resources']"
[routerLink]="routerLinkResources"
>Fear & Greed Index</a
>) within the app.
</p>
@ -294,7 +294,7 @@
</div>
<div *ngIf="!user" class="row">
<div class="col mt-3 text-center">
<a color="primary" i18n mat-flat-button [routerLink]="['/register']"
<a color="primary" i18n mat-flat-button [routerLink]="routerLinkRegister"
>Get Started</a
>
</div>

@ -1,8 +0,0 @@
export const routes = [
'features',
/////
'fonctionnalites',
'funcionalidades',
'funzionalita',
'kenmerken'
] as const;

@ -22,6 +22,8 @@ export class LandingPageComponent implements OnDestroy, OnInit {
public hasPermissionForStatistics: boolean;
public hasPermissionForSubscription: boolean;
public hasPermissionToCreateUser: boolean;
public routerLinkAbout = ['/' + $localize`about`];
public routerLinkRegister = ['/' + $localize`register`];
public statistics: Statistics;
public testimonials = [
{

@ -31,7 +31,12 @@
<div class="button-container mb-5 row">
<div class="align-items-center col d-flex justify-content-center">
<ng-container *ngIf="hasPermissionToCreateUser">
<a color="primary" i18n mat-flat-button [routerLink]="['/register']">
<a
color="primary"
i18n
mat-flat-button
[routerLink]="routerLinkRegister"
>
Get Started
</a>
</ng-container>
@ -290,7 +295,7 @@
</li>
</ul>
<div class="mt-4 text-center">
<a i18n mat-stroked-button [routerLink]="['/about']"
<a i18n mat-stroked-button [routerLink]="routerLinkAbout"
>Learn more about Ghostfolio</a
>
</div>
@ -397,7 +402,12 @@
>
</p>
<div class="align-items-center d-flex justify-content-center py-2">
<a color="primary" i18n mat-flat-button [routerLink]="['/register']">
<a
color="primary"
i18n
mat-flat-button
[routerLink]="routerLinkRegister"
>
Get Started
</a>
<ng-container *ngIf="hasPermissionForDemo">

@ -1,9 +0,0 @@
export const routes = [
'markets',
/////
'maerkte',
'marches',
'markten',
'mercados',
'mercati'
] as const;

@ -29,6 +29,8 @@ export class PricingPageComponent implements OnDestroy, OnInit {
public isLoggedIn: boolean;
public price: number;
public priceId: string;
public routerLinkFeatures = ['/' + $localize`features`];
public routerLinkRegister = ['/' + $localize`register`];
public user: User;
private unsubscribeSubject = new Subject<void>();

@ -106,7 +106,7 @@
class="mr-1"
name="checkmark-circle-outline"
></ion-icon>
<a i18n [routerLink]="['/features']"
<a i18n [routerLink]="routerLinkFeatures"
>and more Features...</a
>
</li>
@ -302,7 +302,7 @@
class="mr-1"
name="checkmark-circle-outline"
></ion-icon>
<a i18n [routerLink]="['/features']"
<a i18n [routerLink]="routerLinkFeatures"
>and more Features...</a
>
</li>
@ -360,7 +360,7 @@
</div>
<div *ngIf="!user" class="row">
<div class="col mt-3 text-center">
<a color="primary" i18n mat-flat-button [routerLink]="['/register']">
<a color="primary" i18n mat-flat-button [routerLink]="routerLinkRegister">
Get Started
</a>
<p class="m-0 text-muted"><small i18n>Its free.</small></p>

@ -1,10 +0,0 @@
export const routes = [
'pricing',
/////
'precios',
'precos',
'preise',
'prezzi',
'prijzen',
'prix'
] as const;

@ -1,10 +0,0 @@
export const routes = [
'register',
/////
'enregistrement',
'iscrizione',
'registo',
'registratie',
'registrierung',
'registro'
] as const;

@ -22,7 +22,7 @@ const routes: Routes = [
path: `open-source-alternative-to-${key}`,
loadComponent: () =>
import(`./products/${key}-page.component`).then(() => component),
title: `Open Source Alternative to ${name}`
title: $localize`Open Source Alternative to ${name}`
};
})
];

@ -10,9 +10,11 @@ import { products } from './products';
templateUrl: './personal-finance-tools-page.html'
})
export class PersonalFinanceToolsPageComponent implements OnDestroy {
public pathResources = '/' + $localize`resources`;
public products = products.filter(({ key }) => {
return key !== 'ghostfolio';
});
public routerLinkAbout = ['/' + $localize`about`];
private unsubscribeSubject = new Subject<void>();

@ -5,15 +5,15 @@
Discover Open Source Alternatives for Personal Finance Tools
</h1>
<div class="introduction mb-4">
<p>
<p i18n>
This overview page features a curated collection of personal finance
tools compared to the open source alternative
<a [routerLink]="['/about']">Ghostfolio</a>. If you value
<a [routerLink]="routerLinkAbout">Ghostfolio</a>. If you value
transparency, data privacy, and community collaboration, Ghostfolio
provides an excellent opportunity to take control of your financial
management.
</p>
<p>
<p i18n>
Explore the links below to compare a variety of personal finance tools
with Ghostfolio.
</p>
@ -29,10 +29,10 @@
<a
class="d-flex overflow-hidden w-100"
title="Compare Ghostfolio to {{ product.name }}"
[routerLink]="['/resources', 'personal-finance-tools', 'open-source-alternative-to-' + product.key]"
[routerLink]="[pathResources, 'personal-finance-tools', 'open-source-alternative-to-' + product.key]"
>
<div class="flex-grow-1 overflow-hidden">
<div class="h6 m-0 text-truncate">
<div class="h6 m-0 text-truncate" i18n>
Open Source Alternative to {{ product.name }}
</div>
</div>

@ -4,19 +4,22 @@
<article>
<div class="mb-4 text-center">
<h1 class="mb-1">
<strong>Ghostfolio</strong>: The Open Source Alternative to
<strong>{{ product2.name }}</strong>
<strong>Ghostfolio</strong>:
<ng-container i18n>The Open Source Alternative to</ng-container
>&nbsp;<strong>{{ product2.name }}</strong>
</h1>
</div>
<section class="mb-4">
<p>
Are you looking for an open source alternative to {{ product2.name
}}? <a [routerLink]="['/about']">Ghostfolio</a> is a powerful
}}? <a [routerLink]="routerLinkAbout">Ghostfolio</a> is a powerful
portfolio management tool that provides individuals with a
comprehensive platform to track, analyze, and optimize their
investments. Whether you are an experienced investor or just
starting out, Ghostfolio offers an intuitive user interface and a
<a [routerLink]="['/features']">wide range of functionalities</a>
<a [routerLink]="routerLinkFeatures"
>wide range of functionalities</a
>
to help you make informed decisions and take control of your
financial future.
</p>
@ -280,7 +283,7 @@
<nav aria-label="breadcrumb">
<ol class="breadcrumb">
<li class="breadcrumb-item">
<a i18n [routerLink]="['/resources', 'personal-finance-tools']"
<a i18n [routerLink]="routerLinkResourcesPersonalFinanceTools"
>Personal Finance Tools</a
>
</li>

@ -21,4 +21,11 @@ export class AltooPageComponent {
public product2 = products.find(({ key }) => {
return key === 'altoo';
});
public routerLinkAbout = ['/' + $localize`about`];
public routerLinkFeatures = ['/' + $localize`features`];
public routerLinkResourcesPersonalFinanceTools = [
'/' + $localize`resources`,
'personal-finance-tools'
];
}

@ -21,4 +21,11 @@ export class CopilotMoneyPageComponent {
public product2 = products.find(({ key }) => {
return key === 'copilot-money';
});
public routerLinkAbout = ['/' + $localize`about`];
public routerLinkFeatures = ['/' + $localize`features`];
public routerLinkResourcesPersonalFinanceTools = [
'/' + $localize`resources`,
'personal-finance-tools'
];
}

@ -21,4 +21,11 @@ export class DeltaPageComponent {
public product2 = products.find(({ key }) => {
return key === 'delta';
});
public routerLinkAbout = ['/' + $localize`about`];
public routerLinkFeatures = ['/' + $localize`features`];
public routerLinkResourcesPersonalFinanceTools = [
'/' + $localize`resources`,
'personal-finance-tools'
];
}

@ -21,4 +21,11 @@ export class DivvyDiaryPageComponent {
public product2 = products.find(({ key }) => {
return key === 'divvydiary';
});
public routerLinkAbout = ['/' + $localize`about`];
public routerLinkFeatures = ['/' + $localize`features`];
public routerLinkResourcesPersonalFinanceTools = [
'/' + $localize`resources`,
'personal-finance-tools'
];
}

@ -21,4 +21,11 @@ export class ExirioPageComponent {
public product2 = products.find(({ key }) => {
return key === 'exirio';
});
public routerLinkAbout = ['/' + $localize`about`];
public routerLinkFeatures = ['/' + $localize`features`];
public routerLinkResourcesPersonalFinanceTools = [
'/' + $localize`resources`,
'personal-finance-tools'
];
}

@ -21,4 +21,11 @@ export class FolisharePageComponent {
public product2 = products.find(({ key }) => {
return key === 'folishare';
});
public routerLinkAbout = ['/' + $localize`about`];
public routerLinkFeatures = ['/' + $localize`features`];
public routerLinkResourcesPersonalFinanceTools = [
'/' + $localize`resources`,
'personal-finance-tools'
];
}

@ -21,4 +21,11 @@ export class GetquinPageComponent {
public product2 = products.find(({ key }) => {
return key === 'getquin';
});
public routerLinkAbout = ['/' + $localize`about`];
public routerLinkFeatures = ['/' + $localize`features`];
public routerLinkResourcesPersonalFinanceTools = [
'/' + $localize`resources`,
'personal-finance-tools'
];
}

@ -21,4 +21,11 @@ export class GoSpatzPageComponent {
public product2 = products.find(({ key }) => {
return key === 'gospatz';
});
public routerLinkAbout = ['/' + $localize`about`];
public routerLinkFeatures = ['/' + $localize`features`];
public routerLinkResourcesPersonalFinanceTools = [
'/' + $localize`resources`,
'personal-finance-tools'
];
}

@ -21,4 +21,11 @@ export class JustEtfPageComponent {
public product2 = products.find(({ key }) => {
return key === 'justetf';
});
public routerLinkAbout = ['/' + $localize`about`];
public routerLinkFeatures = ['/' + $localize`features`];
public routerLinkResourcesPersonalFinanceTools = [
'/' + $localize`resources`,
'personal-finance-tools'
];
}

@ -21,4 +21,11 @@ export class KuberaPageComponent {
public product2 = products.find(({ key }) => {
return key === 'kubera';
});
public routerLinkAbout = ['/' + $localize`about`];
public routerLinkFeatures = ['/' + $localize`features`];
public routerLinkResourcesPersonalFinanceTools = [
'/' + $localize`resources`,
'personal-finance-tools'
];
}

@ -21,4 +21,11 @@ export class MarketsShPageComponent {
public product2 = products.find(({ key }) => {
return key === 'markets.sh';
});
public routerLinkAbout = ['/' + $localize`about`];
public routerLinkFeatures = ['/' + $localize`features`];
public routerLinkResourcesPersonalFinanceTools = [
'/' + $localize`resources`,
'personal-finance-tools'
];
}

@ -21,4 +21,11 @@ export class MaybeFinancePageComponent {
public product2 = products.find(({ key }) => {
return key === 'maybe-finance';
});
public routerLinkAbout = ['/' + $localize`about`];
public routerLinkFeatures = ['/' + $localize`features`];
public routerLinkResourcesPersonalFinanceTools = [
'/' + $localize`resources`,
'personal-finance-tools'
];
}

@ -21,4 +21,11 @@ export class MonsePageComponent {
public product2 = products.find(({ key }) => {
return key === 'monse';
});
public routerLinkAbout = ['/' + $localize`about`];
public routerLinkFeatures = ['/' + $localize`features`];
public routerLinkResourcesPersonalFinanceTools = [
'/' + $localize`resources`,
'personal-finance-tools'
];
}

@ -21,4 +21,11 @@ export class ParqetPageComponent {
public product2 = products.find(({ key }) => {
return key === 'parqet';
});
public routerLinkAbout = ['/' + $localize`about`];
public routerLinkFeatures = ['/' + $localize`features`];
public routerLinkResourcesPersonalFinanceTools = [
'/' + $localize`resources`,
'personal-finance-tools'
];
}

@ -21,4 +21,11 @@ export class PlannixPageComponent {
public product2 = products.find(({ key }) => {
return key === 'plannix';
});
public routerLinkAbout = ['/' + $localize`about`];
public routerLinkFeatures = ['/' + $localize`features`];
public routerLinkResourcesPersonalFinanceTools = [
'/' + $localize`resources`,
'personal-finance-tools'
];
}

@ -21,4 +21,11 @@ export class PortfolioDividendTrackerPageComponent {
public product2 = products.find(({ key }) => {
return key === 'portfolio-dividend-tracker';
});
public routerLinkAbout = ['/' + $localize`about`];
public routerLinkFeatures = ['/' + $localize`features`];
public routerLinkResourcesPersonalFinanceTools = [
'/' + $localize`resources`,
'personal-finance-tools'
];
}

@ -21,4 +21,11 @@ export class PortseidoPageComponent {
public product2 = products.find(({ key }) => {
return key === 'portseido';
});
public routerLinkAbout = ['/' + $localize`about`];
public routerLinkFeatures = ['/' + $localize`features`];
public routerLinkResourcesPersonalFinanceTools = [
'/' + $localize`resources`,
'personal-finance-tools'
];
}

@ -21,4 +21,11 @@ export class ProjectionLabPageComponent {
public product2 = products.find(({ key }) => {
return key === 'projectionlab';
});
public routerLinkAbout = ['/' + $localize`about`];
public routerLinkFeatures = ['/' + $localize`features`];
public routerLinkResourcesPersonalFinanceTools = [
'/' + $localize`resources`,
'personal-finance-tools'
];
}

@ -21,4 +21,11 @@ export class SeekingAlphaPageComponent {
public product2 = products.find(({ key }) => {
return key === 'seeking-alpha';
});
public routerLinkAbout = ['/' + $localize`about`];
public routerLinkFeatures = ['/' + $localize`features`];
public routerLinkResourcesPersonalFinanceTools = [
'/' + $localize`resources`,
'personal-finance-tools'
];
}

@ -21,4 +21,11 @@ export class SharesightPageComponent {
public product2 = products.find(({ key }) => {
return key === 'sharesight';
});
public routerLinkAbout = ['/' + $localize`about`];
public routerLinkFeatures = ['/' + $localize`features`];
public routerLinkResourcesPersonalFinanceTools = [
'/' + $localize`resources`,
'personal-finance-tools'
];
}

@ -21,4 +21,11 @@ export class SimplePortfolioPageComponent {
public product2 = products.find(({ key }) => {
return key === 'simple-portfolio';
});
public routerLinkAbout = ['/' + $localize`about`];
public routerLinkFeatures = ['/' + $localize`features`];
public routerLinkResourcesPersonalFinanceTools = [
'/' + $localize`resources`,
'personal-finance-tools'
];
}

@ -21,4 +21,11 @@ export class SnowballAnalyticsPageComponent {
public product2 = products.find(({ key }) => {
return key === 'snowball-analytics';
});
public routerLinkAbout = ['/' + $localize`about`];
public routerLinkFeatures = ['/' + $localize`features`];
public routerLinkResourcesPersonalFinanceTools = [
'/' + $localize`resources`,
'personal-finance-tools'
];
}

@ -21,4 +21,11 @@ export class SumioPageComponent {
public product2 = products.find(({ key }) => {
return key === 'sumio';
});
public routerLinkAbout = ['/' + $localize`about`];
public routerLinkFeatures = ['/' + $localize`features`];
public routerLinkResourcesPersonalFinanceTools = [
'/' + $localize`resources`,
'personal-finance-tools'
];
}

@ -21,4 +21,11 @@ export class UtlunaPageComponent {
public product2 = products.find(({ key }) => {
return key === 'utluna';
});
public routerLinkAbout = ['/' + $localize`about`];
public routerLinkFeatures = ['/' + $localize`features`];
public routerLinkResourcesPersonalFinanceTools = [
'/' + $localize`resources`,
'personal-finance-tools'
];
}

@ -21,4 +21,11 @@ export class YeekateePageComponent {
public product2 = products.find(({ key }) => {
return key === 'yeekatee';
});
public routerLinkAbout = ['/' + $localize`about`];
public routerLinkFeatures = ['/' + $localize`features`];
public routerLinkResourcesPersonalFinanceTools = [
'/' + $localize`resources`,
'personal-finance-tools'
];
}

@ -13,6 +13,10 @@ import { Subject } from 'rxjs';
export class ResourcesPageComponent implements OnInit {
public hasPermissionForSubscription: boolean;
public info: InfoItem;
public routerLinkResourcesPersonalFinanceTools = [
'/' + $localize`resources`,
'personal-finance-tools'
];
private unsubscribeSubject = new Subject<void>();

@ -179,7 +179,7 @@
monitor investments, and make informed financial decisions.
</div>
<div>
<a [routerLink]="['/resources', 'personal-finance-tools']"
<a [routerLink]="routerLinkResourcesPersonalFinanceTools"
>Personal Finance Tools →</a
>
</div>

@ -1,9 +0,0 @@
export const routes = [
'resources',
/////
'bronnen',
'recursos',
'ressourcen',
'ressources',
'risorse'
] as const;

@ -15,7 +15,7 @@
<div class="pr-1 w-50" i18n>Membership</div>
<div class="pl-1 w-50">
<div class="align-items-center d-flex mb-1">
<a [routerLink]="['/pricing']"
<a [routerLink]="routerLinkPricing"
>{{ user?.subscription?.type }}</a
>
<gf-premium-indicator

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff
Loading…
Cancel
Save