From 2d23c566f1aa8e1d274c28e0e85cc5ad5e11f420 Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Sun, 9 Jul 2023 10:42:10 +0200 Subject: [PATCH] Feature/setup personal finance tools pages (#2135) --- ...sonal-finance-tools-page-routing.module.ts | 34 +++ .../personal-finance-tools-page.component.ts | 25 ++ .../personal-finance-tools-page.html | 53 ++++ .../personal-finance-tools-page.module.ts | 13 + .../personal-finance-tools-page.scss | 19 ++ .../product-page-template.html | 263 ++++++++++++++++ .../product-page-template.scss | 17 ++ .../personal-finance-tools/products.ts | 280 +++++++++++++++++ .../products/altoo-page.component.ts | 24 ++ .../products/divvydiary-page.component.ts | 24 ++ .../products/exirio-page.component.ts | 24 ++ .../products/folishare-page.component.ts | 24 ++ .../products/getquin-page.component.ts | 24 ++ .../products/justetf-page.component.ts | 24 ++ .../products/kubera-page.component.ts | 24 ++ .../products/maybe-finance-page.component.ts | 24 ++ .../products/monse-page.component.ts | 24 ++ .../products/parqet-page.component.ts | 24 ++ ...rtfolio-dividend-tracker-page.component.ts | 24 ++ .../products/portseido-page.component.ts | 24 ++ .../products/projectionlab-page.component.ts | 24 ++ .../products/seeking-alpha-page.component.ts | 24 ++ .../products/sharesight-page.component.ts | 24 ++ .../simple-portfolio-page.component.ts | 24 ++ .../snowball-analytics-page.component.ts | 24 ++ .../products/sumio-page.component.ts | 24 ++ .../products/utluna-page.component.ts | 24 ++ .../products/yeekatee-page.component.ts | 24 ++ .../resources-page-routing.module.ts | 9 +- .../app/pages/resources/resources-page.html | 21 +- apps/client/src/assets/sitemap.xml | 282 ++++++++++++------ libs/common/src/lib/interfaces/index.ts | 2 + libs/common/src/lib/interfaces/product.ts | 15 + 33 files changed, 1410 insertions(+), 103 deletions(-) create mode 100644 apps/client/src/app/pages/resources/personal-finance-tools/personal-finance-tools-page-routing.module.ts create mode 100644 apps/client/src/app/pages/resources/personal-finance-tools/personal-finance-tools-page.component.ts create mode 100644 apps/client/src/app/pages/resources/personal-finance-tools/personal-finance-tools-page.html create mode 100644 apps/client/src/app/pages/resources/personal-finance-tools/personal-finance-tools-page.module.ts create mode 100644 apps/client/src/app/pages/resources/personal-finance-tools/personal-finance-tools-page.scss create mode 100644 apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html create mode 100644 apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.scss create mode 100644 apps/client/src/app/pages/resources/personal-finance-tools/products.ts create mode 100644 apps/client/src/app/pages/resources/personal-finance-tools/products/altoo-page.component.ts create mode 100644 apps/client/src/app/pages/resources/personal-finance-tools/products/divvydiary-page.component.ts create mode 100644 apps/client/src/app/pages/resources/personal-finance-tools/products/exirio-page.component.ts create mode 100644 apps/client/src/app/pages/resources/personal-finance-tools/products/folishare-page.component.ts create mode 100644 apps/client/src/app/pages/resources/personal-finance-tools/products/getquin-page.component.ts create mode 100644 apps/client/src/app/pages/resources/personal-finance-tools/products/justetf-page.component.ts create mode 100644 apps/client/src/app/pages/resources/personal-finance-tools/products/kubera-page.component.ts create mode 100644 apps/client/src/app/pages/resources/personal-finance-tools/products/maybe-finance-page.component.ts create mode 100644 apps/client/src/app/pages/resources/personal-finance-tools/products/monse-page.component.ts create mode 100644 apps/client/src/app/pages/resources/personal-finance-tools/products/parqet-page.component.ts create mode 100644 apps/client/src/app/pages/resources/personal-finance-tools/products/portfolio-dividend-tracker-page.component.ts create mode 100644 apps/client/src/app/pages/resources/personal-finance-tools/products/portseido-page.component.ts create mode 100644 apps/client/src/app/pages/resources/personal-finance-tools/products/projectionlab-page.component.ts create mode 100644 apps/client/src/app/pages/resources/personal-finance-tools/products/seeking-alpha-page.component.ts create mode 100644 apps/client/src/app/pages/resources/personal-finance-tools/products/sharesight-page.component.ts create mode 100644 apps/client/src/app/pages/resources/personal-finance-tools/products/simple-portfolio-page.component.ts create mode 100644 apps/client/src/app/pages/resources/personal-finance-tools/products/snowball-analytics-page.component.ts create mode 100644 apps/client/src/app/pages/resources/personal-finance-tools/products/sumio-page.component.ts create mode 100644 apps/client/src/app/pages/resources/personal-finance-tools/products/utluna-page.component.ts create mode 100644 apps/client/src/app/pages/resources/personal-finance-tools/products/yeekatee-page.component.ts create mode 100644 libs/common/src/lib/interfaces/product.ts diff --git a/apps/client/src/app/pages/resources/personal-finance-tools/personal-finance-tools-page-routing.module.ts b/apps/client/src/app/pages/resources/personal-finance-tools/personal-finance-tools-page-routing.module.ts new file mode 100644 index 000000000..ca8e12656 --- /dev/null +++ b/apps/client/src/app/pages/resources/personal-finance-tools/personal-finance-tools-page-routing.module.ts @@ -0,0 +1,34 @@ +import { NgModule } from '@angular/core'; +import { RouterModule, Routes } from '@angular/router'; +import { AuthGuard } from '@ghostfolio/client/core/auth.guard'; + +import { PersonalFinanceToolsPageComponent } from './personal-finance-tools-page.component'; +import { products } from './products'; + +const routes: Routes = [ + { + canActivate: [AuthGuard], + component: PersonalFinanceToolsPageComponent, + path: '', + title: $localize`Personal Finance Tools` + }, + ...products + .filter(({ key }) => { + return key !== 'ghostfolio'; + }) + .map(({ component, key, name }) => { + return { + canActivate: [AuthGuard], + path: `open-source-alternative-to-${key}`, + loadComponent: () => + import(`./products/${key}-page.component`).then(() => component), + title: `Open Source Alternative to ${name}` + }; + }) +]; + +@NgModule({ + imports: [RouterModule.forChild(routes)], + exports: [RouterModule] +}) +export class PersonalFinanceToolsPageRoutingModule {} diff --git a/apps/client/src/app/pages/resources/personal-finance-tools/personal-finance-tools-page.component.ts b/apps/client/src/app/pages/resources/personal-finance-tools/personal-finance-tools-page.component.ts new file mode 100644 index 000000000..a63c307ff --- /dev/null +++ b/apps/client/src/app/pages/resources/personal-finance-tools/personal-finance-tools-page.component.ts @@ -0,0 +1,25 @@ +import { Component, OnDestroy } from '@angular/core'; +import { Subject } from 'rxjs'; + +import { products } from './products'; + +@Component({ + host: { class: 'page' }, + selector: 'gf-personal-finance-tools-page', + styleUrls: ['./personal-finance-tools-page.scss'], + templateUrl: './personal-finance-tools-page.html' +}) +export class PersonalFinanceToolsPageComponent implements OnDestroy { + public products = products.filter(({ key }) => { + return key !== 'ghostfolio'; + }); + + private unsubscribeSubject = new Subject(); + + public constructor() {} + + public ngOnDestroy() { + this.unsubscribeSubject.next(); + this.unsubscribeSubject.complete(); + } +} diff --git a/apps/client/src/app/pages/resources/personal-finance-tools/personal-finance-tools-page.html b/apps/client/src/app/pages/resources/personal-finance-tools/personal-finance-tools-page.html new file mode 100644 index 000000000..736018a91 --- /dev/null +++ b/apps/client/src/app/pages/resources/personal-finance-tools/personal-finance-tools-page.html @@ -0,0 +1,53 @@ +
+
+
+

+ Discover Open Source Alternatives for Personal Finance Tools +

+
+

+ This overview page features a curated collection of personal finance + tools compared to the open source alternative + Ghostfolio. If you value + transparency, data privacy, and community collaboration, Ghostfolio + provides an excellent opportunity to take control of your financial + management. +

+

+ Explore the links below to compare a variety of personal finance tools + with Ghostfolio. +

+
+ + + + + +
+
+
diff --git a/apps/client/src/app/pages/resources/personal-finance-tools/personal-finance-tools-page.module.ts b/apps/client/src/app/pages/resources/personal-finance-tools/personal-finance-tools-page.module.ts new file mode 100644 index 000000000..b8d6c947d --- /dev/null +++ b/apps/client/src/app/pages/resources/personal-finance-tools/personal-finance-tools-page.module.ts @@ -0,0 +1,13 @@ +import { CommonModule } from '@angular/common'; +import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core'; +import { MatCardModule } from '@angular/material/card'; + +import { PersonalFinanceToolsPageRoutingModule } from './personal-finance-tools-page-routing.module'; +import { PersonalFinanceToolsPageComponent } from './personal-finance-tools-page.component'; + +@NgModule({ + declarations: [PersonalFinanceToolsPageComponent], + imports: [CommonModule, MatCardModule, PersonalFinanceToolsPageRoutingModule], + schemas: [CUSTOM_ELEMENTS_SCHEMA] +}) +export class PersonalFinanceToolsPageModule {} diff --git a/apps/client/src/app/pages/resources/personal-finance-tools/personal-finance-tools-page.scss b/apps/client/src/app/pages/resources/personal-finance-tools/personal-finance-tools-page.scss new file mode 100644 index 000000000..8e1e178c7 --- /dev/null +++ b/apps/client/src/app/pages/resources/personal-finance-tools/personal-finance-tools-page.scss @@ -0,0 +1,19 @@ +:host { + color: rgb(var(--dark-primary-text)); + display: block; + + .introduction { + 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)); +} diff --git a/apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html b/apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html new file mode 100644 index 000000000..a2e1b3955 --- /dev/null +++ b/apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html @@ -0,0 +1,263 @@ +
+
+
+
+
+

+ Ghostfolio: The Open Source Alternative to + {{ product2.name }} +

+
+
+

+ Are you looking for an open source alternative to {{ product2.name + }}? Ghostfolio 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 + wide range of functionalities + to help you make informed decisions and take control of your + financial future. +

+

+ Ghostfolio is open source software (OSS) where a community of + developers, contributors, and enthusiasts collaborate to enhance its + capabilities, security, and user experience. +

+

+ Let’s dive deeper into the detailed comparison table below to gain a + thorough understanding of how Ghostfolio positions itself relative + to {{ product2.name }}. We will explore various aspects such as + features, data privacy, pricing, and more, allowing you to make a + well-informed choice for your personal requirements. +

+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Ghostfolio + {{ product2.name }} +
{{ product1.slogan }}{{ product2.slogan }}
Founded{{ product1.founded }}{{ product2.founded }}
Origin{{ product1.origin }}{{ product2.origin }}
Region{{ product1.region }}{{ product2.region }}
+ Available in + {{ product1.languages }}{{ product2.languages }}
+ Open Source Software + + ✅ Yes❌ No + + ✅ Yes❌ No + +
+ Self-Hosting + + ✅ Yes❌ No + + ✅ Yes❌ No +
+ Free Plan + + ✅ Yes❌ No + + ✅ Yes❌ No +
Pricing + Starting from {{ product1.pricingPerYear }} / year + + Starting from {{ product2.pricingPerYear }} / + year +
Notes{{ product1.note }}{{ product2.note }}
+
+
+

+ Ready to take your investments to the + next level? +

+

+ Effortlessly track, analyze, and visualize your wealth with + Ghostfolio. +

+ +
+
+ + Please note that the information provided is based on our + independent research and analysis. This website is not affiliated + with {{ product2.name }} or any other product mentioned in the + comparison. As the landscape of personal finance tools evolves, it + is essential to verify any specific details or changes directly from + the respective product page. Data needs a refresh? Help us maintain + accurate data on + GitHub. + +
+
+
    +
  • + {{ product1.name }} +
  • +
  • + {{ product2.name }} +
  • +
  • + Alternative +
  • +
  • + App +
  • +
  • + Community +
  • +
  • + Fintech +
  • +
  • + Investment +
  • +
  • + Investor +
  • +
  • + Open Source +
  • +
  • + OSS +
  • +
  • + Personal Finance +
  • +
  • + Privacy +
  • +
  • + Portfolio +
  • +
  • + Software +
  • +
  • + Tool +
  • +
  • + User Experience +
  • +
  • + Wealth +
  • +
  • + Wealth Management +
  • +
+
+ +
+
+
+
diff --git a/apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.scss b/apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.scss new file mode 100644 index 000000000..4a8680714 --- /dev/null +++ b/apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.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)); +} diff --git a/apps/client/src/app/pages/resources/personal-finance-tools/products.ts b/apps/client/src/app/pages/resources/personal-finance-tools/products.ts new file mode 100644 index 000000000..715fef21d --- /dev/null +++ b/apps/client/src/app/pages/resources/personal-finance-tools/products.ts @@ -0,0 +1,280 @@ +import { Product } from '@ghostfolio/common/interfaces'; + +import { AltooPageComponent } from './products/altoo-page.component'; +import { DivvyDiaryPageComponent } from './products/divvydiary-page.component'; +import { ExirioPageComponent } from './products/exirio-page.component'; +import { FolisharePageComponent } from './products/folishare-page.component'; +import { GetquinPageComponent } from './products/getquin-page.component'; +import { JustEtfPageComponent } from './products/justetf-page.component'; +import { KuberaPageComponent } from './products/kubera-page.component'; +import { MaybeFinancePageComponent } from './products/maybe-finance-page.component'; +import { MonsePageComponent } from './products/monse-page.component'; +import { ParqetPageComponent } from './products/parqet-page.component'; +import { PortfolioDividendTrackerPageComponent } from './products/portfolio-dividend-tracker-page.component'; +import { PortseidoPageComponent } from './products/portseido-page.component'; +import { SeekingAlphaPageComponent } from './products/seeking-alpha-page.component'; +import { SharesightPageComponent } from './products/sharesight-page.component'; +import { SimplePortfolioPageComponent } from './products/simple-portfolio-page.component'; +import { SnowballAnalyticsPageComponent } from './products/snowball-analytics-page.component'; +import { SumioPageComponent } from './products/sumio-page.component'; +import { UtlunaPageComponent } from './products/utluna-page.component'; +import { YeekateePageComponent } from './products/yeekatee-page.component'; +import { ProjectionLabPageComponent } from './products/projectionlab-page.component'; + +export const products: Product[] = [ + { + component: undefined, + founded: 2021, + hasFreePlan: true, + hasSelfHostingAbility: true, + isOpenSource: true, + key: 'ghostfolio', + languages: 'Dutch, English, French, German, Italian, Portuguese, Spanish', + name: 'Ghostfolio', + origin: 'Switzerland', + pricingPerYear: '$19', + region: 'Global', + slogan: 'Open Source Wealth Management' + }, + { + component: AltooPageComponent, + founded: 2017, + hasSelfHostingAbility: false, + isOpenSource: false, + key: 'altoo', + name: 'Altoo Wealth Platform', + origin: 'Switzerland', + slogan: 'Simplicity for Complex Wealth' + }, + { + component: DivvyDiaryPageComponent, + founded: 2019, + hasFreePlan: true, + hasSelfHostingAbility: false, + isOpenSource: false, + key: 'divvydiary', + languages: 'English, German', + name: 'DivvyDiary', + origin: 'Germany', + pricingPerYear: '€65', + slogan: 'Your personal Dividend Calendar' + }, + { + component: ExirioPageComponent, + founded: 2020, + hasFreePlan: true, + hasSelfHostingAbility: false, + isOpenSource: false, + key: 'exirio', + name: 'Exirio', + origin: 'United States', + pricingPerYear: '$100', + slogan: 'All your wealth, in one place.' + }, + { + component: FolisharePageComponent, + hasFreePlan: true, + hasSelfHostingAbility: false, + isOpenSource: false, + key: 'folishare', + languages: 'English, German', + name: 'folishare', + origin: 'Austria', + pricingPerYear: '$65', + slogan: 'Take control over your investments' + }, + { + component: GetquinPageComponent, + founded: 2020, + hasFreePlan: true, + hasSelfHostingAbility: false, + isOpenSource: false, + key: 'getquin', + languages: 'English, German', + name: 'getquin', + origin: 'Germany', + pricingPerYear: '€48', + slogan: 'Portfolio Tracker, Analysis & Community' + }, + { + component: JustEtfPageComponent, + founded: 2011, + hasFreePlan: true, + hasSelfHostingAbility: false, + isOpenSource: false, + key: 'justetf', + name: 'justETF', + origin: 'Germany', + pricingPerYear: '€119', + slogan: 'ETF portfolios made simple' + }, + { + component: KuberaPageComponent, + founded: 2019, + hasFreePlan: false, + hasSelfHostingAbility: false, + isOpenSource: false, + key: 'kubera', + name: 'Kubera®', + origin: 'United States', + pricingPerYear: '$150', + slogan: 'The Time Machine for your Net Worth' + }, + { + component: MaybeFinancePageComponent, + founded: 2021, + hasSelfHostingAbility: false, + isOpenSource: false, + key: 'maybe-finance', + languages: 'English', + name: 'Maybe Finance', + note: 'Sunset in 2023', + origin: 'United States', + pricingPerYear: '$145', + region: 'United States', + slogan: 'Your financial future, in your control' + }, + { + component: MonsePageComponent, + hasFreePlan: false, + hasSelfHostingAbility: false, + isOpenSource: false, + key: 'monse', + name: 'Monse', + pricingPerYear: '$60', + slogan: 'Gain financial control and keep your data private.' + }, + { + component: ParqetPageComponent, + founded: 2020, + hasSelfHostingAbility: false, + hasFreePlan: true, + isOpenSource: false, + key: 'parqet', + name: 'Parqet', + note: 'Originally named as Tresor One', + origin: 'Germany', + pricingPerYear: '€88', + region: 'Austria, Germany, Switzerland', + slogan: 'Dein Vermögen immer im Blick' + }, + { + component: PortfolioDividendTrackerPageComponent, + hasFreePlan: false, + hasSelfHostingAbility: false, + isOpenSource: false, + key: 'portfolio-dividend-tracker', + languages: 'English, Dutch', + name: 'Portfolio Dividend Tracker', + origin: 'Netherlands', + pricingPerYear: '€60', + slogan: 'Manage all your portfolios' + }, + { + component: PortseidoPageComponent, + founded: 2021, + hasFreePlan: true, + hasSelfHostingAbility: false, + isOpenSource: false, + key: 'portseido', + languages: 'Dutch, English, French, German', + name: 'Portseido', + origin: 'Thailand', + pricingPerYear: '$96', + slogan: 'Portfolio Performance and Dividend Tracker' + }, + { + component: ProjectionLabPageComponent, + founded: 2021, + hasFreePlan: true, + hasSelfHostingAbility: true, + isOpenSource: false, + key: 'projectionlab', + name: 'ProjectionLab', + origin: 'United States', + pricingPerYear: '$108', + slogan: 'Build Financial Plans You Love.' + }, + { + component: SeekingAlphaPageComponent, + founded: 2004, + hasFreePlan: false, + hasSelfHostingAbility: false, + isOpenSource: false, + key: 'seeking-alpha', + name: 'Seeking Alpha', + origin: 'United States', + pricingPerYear: '$239', + slogan: 'Stock Market Analysis & Tools for Investors' + }, + { + component: SharesightPageComponent, + founded: 2007, + hasFreePlan: true, + hasSelfHostingAbility: false, + isOpenSource: false, + key: 'sharesight', + name: 'Sharesight', + origin: 'New Zealand', + pricingPerYear: '$135', + region: 'Global', + slogan: 'Stock Portfolio Tracker' + }, + { + component: SimplePortfolioPageComponent, + hasFreePlan: true, + hasSelfHostingAbility: false, + isOpenSource: false, + key: 'simple-portfolio', + name: 'Simple Portfolio', + origin: 'Czech Republic', + pricingPerYear: '€80', + slogan: 'Stock Portfolio Tracker' + }, + { + component: SnowballAnalyticsPageComponent, + founded: 2021, + hasFreePlan: true, + hasSelfHostingAbility: false, + isOpenSource: false, + key: 'snowball-analytics', + name: 'Snowball Analytics', + origin: 'France', + pricingPerYear: '$80', + slogan: 'Simple and powerful portfolio tracker' + }, + { + component: SumioPageComponent, + hasFreePlan: true, + hasSelfHostingAbility: false, + isOpenSource: false, + key: 'sumio', + name: 'Sumio', + origin: 'Czech Republic', + pricingPerYear: '$20', + slogan: 'Sum up and build your wealth.' + }, + { + component: UtlunaPageComponent, + hasFreePlan: true, + hasSelfHostingAbility: false, + isOpenSource: false, + key: 'utluna', + languages: 'English, French, German', + name: 'Utluna', + origin: 'Switzerland', + pricingPerYear: '$300', + slogan: 'Your Portfolio. Revealed.' + }, + { + component: YeekateePageComponent, + founded: 2021, + hasSelfHostingAbility: false, + isOpenSource: false, + key: 'yeekatee', + name: 'yeekatee', + origin: 'Switzerland', + region: 'Switzerland', + slogan: 'Connect. Share. Invest.' + } +]; diff --git a/apps/client/src/app/pages/resources/personal-finance-tools/products/altoo-page.component.ts b/apps/client/src/app/pages/resources/personal-finance-tools/products/altoo-page.component.ts new file mode 100644 index 000000000..c810298f1 --- /dev/null +++ b/apps/client/src/app/pages/resources/personal-finance-tools/products/altoo-page.component.ts @@ -0,0 +1,24 @@ +import { CommonModule } from '@angular/common'; +import { Component } from '@angular/core'; +import { MatButtonModule } from '@angular/material/button'; +import { RouterModule } from '@angular/router'; + +import { products } from '../products'; + +@Component({ + host: { class: 'page' }, + imports: [CommonModule, MatButtonModule, RouterModule], + selector: 'gf-altoo-page', + standalone: true, + styleUrls: ['../product-page-template.scss'], + templateUrl: '../product-page-template.html' +}) +export class AltooPageComponent { + public product1 = products.find(({ key }) => { + return key === 'ghostfolio'; + }); + + public product2 = products.find(({ key }) => { + return key === 'altoo'; + }); +} diff --git a/apps/client/src/app/pages/resources/personal-finance-tools/products/divvydiary-page.component.ts b/apps/client/src/app/pages/resources/personal-finance-tools/products/divvydiary-page.component.ts new file mode 100644 index 000000000..86d57377b --- /dev/null +++ b/apps/client/src/app/pages/resources/personal-finance-tools/products/divvydiary-page.component.ts @@ -0,0 +1,24 @@ +import { CommonModule } from '@angular/common'; +import { Component } from '@angular/core'; +import { MatButtonModule } from '@angular/material/button'; +import { RouterModule } from '@angular/router'; + +import { products } from '../products'; + +@Component({ + host: { class: 'page' }, + imports: [CommonModule, MatButtonModule, RouterModule], + selector: 'gf-divvy-diary-page', + standalone: true, + styleUrls: ['../product-page-template.scss'], + templateUrl: '../product-page-template.html' +}) +export class DivvyDiaryPageComponent { + public product1 = products.find(({ key }) => { + return key === 'ghostfolio'; + }); + + public product2 = products.find(({ key }) => { + return key === 'divvydiary'; + }); +} diff --git a/apps/client/src/app/pages/resources/personal-finance-tools/products/exirio-page.component.ts b/apps/client/src/app/pages/resources/personal-finance-tools/products/exirio-page.component.ts new file mode 100644 index 000000000..488794e5f --- /dev/null +++ b/apps/client/src/app/pages/resources/personal-finance-tools/products/exirio-page.component.ts @@ -0,0 +1,24 @@ +import { CommonModule } from '@angular/common'; +import { Component } from '@angular/core'; +import { MatButtonModule } from '@angular/material/button'; +import { RouterModule } from '@angular/router'; + +import { products } from '../products'; + +@Component({ + host: { class: 'page' }, + imports: [CommonModule, MatButtonModule, RouterModule], + selector: 'gf-exirio-page', + standalone: true, + styleUrls: ['../product-page-template.scss'], + templateUrl: '../product-page-template.html' +}) +export class ExirioPageComponent { + public product1 = products.find(({ key }) => { + return key === 'ghostfolio'; + }); + + public product2 = products.find(({ key }) => { + return key === 'exirio'; + }); +} diff --git a/apps/client/src/app/pages/resources/personal-finance-tools/products/folishare-page.component.ts b/apps/client/src/app/pages/resources/personal-finance-tools/products/folishare-page.component.ts new file mode 100644 index 000000000..64cd60b31 --- /dev/null +++ b/apps/client/src/app/pages/resources/personal-finance-tools/products/folishare-page.component.ts @@ -0,0 +1,24 @@ +import { CommonModule } from '@angular/common'; +import { Component } from '@angular/core'; +import { MatButtonModule } from '@angular/material/button'; +import { RouterModule } from '@angular/router'; + +import { products } from '../products'; + +@Component({ + host: { class: 'page' }, + imports: [CommonModule, MatButtonModule, RouterModule], + selector: 'gf-folishare-page', + standalone: true, + styleUrls: ['../product-page-template.scss'], + templateUrl: '../product-page-template.html' +}) +export class FolisharePageComponent { + public product1 = products.find(({ key }) => { + return key === 'ghostfolio'; + }); + + public product2 = products.find(({ key }) => { + return key === 'folishare'; + }); +} diff --git a/apps/client/src/app/pages/resources/personal-finance-tools/products/getquin-page.component.ts b/apps/client/src/app/pages/resources/personal-finance-tools/products/getquin-page.component.ts new file mode 100644 index 000000000..dcd7ae402 --- /dev/null +++ b/apps/client/src/app/pages/resources/personal-finance-tools/products/getquin-page.component.ts @@ -0,0 +1,24 @@ +import { CommonModule } from '@angular/common'; +import { Component } from '@angular/core'; +import { MatButtonModule } from '@angular/material/button'; +import { RouterModule } from '@angular/router'; + +import { products } from '../products'; + +@Component({ + host: { class: 'page' }, + imports: [CommonModule, MatButtonModule, RouterModule], + selector: 'gf-getquin-page', + standalone: true, + styleUrls: ['../product-page-template.scss'], + templateUrl: '../product-page-template.html' +}) +export class GetquinPageComponent { + public product1 = products.find(({ key }) => { + return key === 'ghostfolio'; + }); + + public product2 = products.find(({ key }) => { + return key === 'getquin'; + }); +} diff --git a/apps/client/src/app/pages/resources/personal-finance-tools/products/justetf-page.component.ts b/apps/client/src/app/pages/resources/personal-finance-tools/products/justetf-page.component.ts new file mode 100644 index 000000000..f5b282b06 --- /dev/null +++ b/apps/client/src/app/pages/resources/personal-finance-tools/products/justetf-page.component.ts @@ -0,0 +1,24 @@ +import { CommonModule } from '@angular/common'; +import { Component } from '@angular/core'; +import { MatButtonModule } from '@angular/material/button'; +import { RouterModule } from '@angular/router'; + +import { products } from '../products'; + +@Component({ + host: { class: 'page' }, + imports: [CommonModule, MatButtonModule, RouterModule], + selector: 'gf-justetf-page', + standalone: true, + styleUrls: ['../product-page-template.scss'], + templateUrl: '../product-page-template.html' +}) +export class JustEtfPageComponent { + public product1 = products.find(({ key }) => { + return key === 'ghostfolio'; + }); + + public product2 = products.find(({ key }) => { + return key === 'justetf'; + }); +} diff --git a/apps/client/src/app/pages/resources/personal-finance-tools/products/kubera-page.component.ts b/apps/client/src/app/pages/resources/personal-finance-tools/products/kubera-page.component.ts new file mode 100644 index 000000000..0071012c2 --- /dev/null +++ b/apps/client/src/app/pages/resources/personal-finance-tools/products/kubera-page.component.ts @@ -0,0 +1,24 @@ +import { CommonModule } from '@angular/common'; +import { Component } from '@angular/core'; +import { MatButtonModule } from '@angular/material/button'; +import { RouterModule } from '@angular/router'; + +import { products } from '../products'; + +@Component({ + host: { class: 'page' }, + imports: [CommonModule, MatButtonModule, RouterModule], + selector: 'gf-kubera-page', + standalone: true, + styleUrls: ['../product-page-template.scss'], + templateUrl: '../product-page-template.html' +}) +export class KuberaPageComponent { + public product1 = products.find(({ key }) => { + return key === 'ghostfolio'; + }); + + public product2 = products.find(({ key }) => { + return key === 'kubera'; + }); +} diff --git a/apps/client/src/app/pages/resources/personal-finance-tools/products/maybe-finance-page.component.ts b/apps/client/src/app/pages/resources/personal-finance-tools/products/maybe-finance-page.component.ts new file mode 100644 index 000000000..5bda6a813 --- /dev/null +++ b/apps/client/src/app/pages/resources/personal-finance-tools/products/maybe-finance-page.component.ts @@ -0,0 +1,24 @@ +import { CommonModule } from '@angular/common'; +import { Component } from '@angular/core'; +import { MatButtonModule } from '@angular/material/button'; +import { RouterModule } from '@angular/router'; + +import { products } from '../products'; + +@Component({ + host: { class: 'page' }, + imports: [CommonModule, MatButtonModule, RouterModule], + selector: 'gf-maybe-finance-page', + standalone: true, + styleUrls: ['../product-page-template.scss'], + templateUrl: '../product-page-template.html' +}) +export class MaybeFinancePageComponent { + public product1 = products.find(({ key }) => { + return key === 'ghostfolio'; + }); + + public product2 = products.find(({ key }) => { + return key === 'maybe-finance'; + }); +} diff --git a/apps/client/src/app/pages/resources/personal-finance-tools/products/monse-page.component.ts b/apps/client/src/app/pages/resources/personal-finance-tools/products/monse-page.component.ts new file mode 100644 index 000000000..8457d38e6 --- /dev/null +++ b/apps/client/src/app/pages/resources/personal-finance-tools/products/monse-page.component.ts @@ -0,0 +1,24 @@ +import { CommonModule } from '@angular/common'; +import { Component } from '@angular/core'; +import { MatButtonModule } from '@angular/material/button'; +import { RouterModule } from '@angular/router'; + +import { products } from '../products'; + +@Component({ + host: { class: 'page' }, + imports: [CommonModule, MatButtonModule, RouterModule], + selector: 'gf-monse-page', + standalone: true, + styleUrls: ['../product-page-template.scss'], + templateUrl: '../product-page-template.html' +}) +export class MonsePageComponent { + public product1 = products.find(({ key }) => { + return key === 'ghostfolio'; + }); + + public product2 = products.find(({ key }) => { + return key === 'monse'; + }); +} diff --git a/apps/client/src/app/pages/resources/personal-finance-tools/products/parqet-page.component.ts b/apps/client/src/app/pages/resources/personal-finance-tools/products/parqet-page.component.ts new file mode 100644 index 000000000..bdc615951 --- /dev/null +++ b/apps/client/src/app/pages/resources/personal-finance-tools/products/parqet-page.component.ts @@ -0,0 +1,24 @@ +import { CommonModule } from '@angular/common'; +import { Component } from '@angular/core'; +import { MatButtonModule } from '@angular/material/button'; +import { RouterModule } from '@angular/router'; + +import { products } from '../products'; + +@Component({ + host: { class: 'page' }, + imports: [CommonModule, MatButtonModule, RouterModule], + selector: 'gf-parqet-page', + standalone: true, + styleUrls: ['../product-page-template.scss'], + templateUrl: '../product-page-template.html' +}) +export class ParqetPageComponent { + public product1 = products.find(({ key }) => { + return key === 'ghostfolio'; + }); + + public product2 = products.find(({ key }) => { + return key === 'parqet'; + }); +} diff --git a/apps/client/src/app/pages/resources/personal-finance-tools/products/portfolio-dividend-tracker-page.component.ts b/apps/client/src/app/pages/resources/personal-finance-tools/products/portfolio-dividend-tracker-page.component.ts new file mode 100644 index 000000000..9d885f2d8 --- /dev/null +++ b/apps/client/src/app/pages/resources/personal-finance-tools/products/portfolio-dividend-tracker-page.component.ts @@ -0,0 +1,24 @@ +import { CommonModule } from '@angular/common'; +import { Component } from '@angular/core'; +import { MatButtonModule } from '@angular/material/button'; +import { RouterModule } from '@angular/router'; + +import { products } from '../products'; + +@Component({ + host: { class: 'page' }, + imports: [CommonModule, MatButtonModule, RouterModule], + selector: 'gf-portfolio-dividend-tracker-page', + standalone: true, + styleUrls: ['../product-page-template.scss'], + templateUrl: '../product-page-template.html' +}) +export class PortfolioDividendTrackerPageComponent { + public product1 = products.find(({ key }) => { + return key === 'ghostfolio'; + }); + + public product2 = products.find(({ key }) => { + return key === 'portfolio-dividend-tracker'; + }); +} diff --git a/apps/client/src/app/pages/resources/personal-finance-tools/products/portseido-page.component.ts b/apps/client/src/app/pages/resources/personal-finance-tools/products/portseido-page.component.ts new file mode 100644 index 000000000..e0ba2b39b --- /dev/null +++ b/apps/client/src/app/pages/resources/personal-finance-tools/products/portseido-page.component.ts @@ -0,0 +1,24 @@ +import { CommonModule } from '@angular/common'; +import { Component } from '@angular/core'; +import { MatButtonModule } from '@angular/material/button'; +import { RouterModule } from '@angular/router'; + +import { products } from '../products'; + +@Component({ + host: { class: 'page' }, + imports: [CommonModule, MatButtonModule, RouterModule], + selector: 'gf-portseido-page', + standalone: true, + styleUrls: ['../product-page-template.scss'], + templateUrl: '../product-page-template.html' +}) +export class PortseidoPageComponent { + public product1 = products.find(({ key }) => { + return key === 'ghostfolio'; + }); + + public product2 = products.find(({ key }) => { + return key === 'portseido'; + }); +} diff --git a/apps/client/src/app/pages/resources/personal-finance-tools/products/projectionlab-page.component.ts b/apps/client/src/app/pages/resources/personal-finance-tools/products/projectionlab-page.component.ts new file mode 100644 index 000000000..1d3d799fc --- /dev/null +++ b/apps/client/src/app/pages/resources/personal-finance-tools/products/projectionlab-page.component.ts @@ -0,0 +1,24 @@ +import { CommonModule } from '@angular/common'; +import { Component } from '@angular/core'; +import { MatButtonModule } from '@angular/material/button'; +import { RouterModule } from '@angular/router'; + +import { products } from '../products'; + +@Component({ + host: { class: 'page' }, + imports: [CommonModule, MatButtonModule, RouterModule], + selector: 'gf-projection-lab-page', + standalone: true, + styleUrls: ['../product-page-template.scss'], + templateUrl: '../product-page-template.html' +}) +export class ProjectionLabPageComponent { + public product1 = products.find(({ key }) => { + return key === 'ghostfolio'; + }); + + public product2 = products.find(({ key }) => { + return key === 'projectionlab'; + }); +} diff --git a/apps/client/src/app/pages/resources/personal-finance-tools/products/seeking-alpha-page.component.ts b/apps/client/src/app/pages/resources/personal-finance-tools/products/seeking-alpha-page.component.ts new file mode 100644 index 000000000..caee77534 --- /dev/null +++ b/apps/client/src/app/pages/resources/personal-finance-tools/products/seeking-alpha-page.component.ts @@ -0,0 +1,24 @@ +import { CommonModule } from '@angular/common'; +import { Component } from '@angular/core'; +import { MatButtonModule } from '@angular/material/button'; +import { RouterModule } from '@angular/router'; + +import { products } from '../products'; + +@Component({ + host: { class: 'page' }, + imports: [CommonModule, MatButtonModule, RouterModule], + selector: 'gf-seeking-alpha-page', + standalone: true, + styleUrls: ['../product-page-template.scss'], + templateUrl: '../product-page-template.html' +}) +export class SeekingAlphaPageComponent { + public product1 = products.find(({ key }) => { + return key === 'ghostfolio'; + }); + + public product2 = products.find(({ key }) => { + return key === 'seeking-alpha'; + }); +} diff --git a/apps/client/src/app/pages/resources/personal-finance-tools/products/sharesight-page.component.ts b/apps/client/src/app/pages/resources/personal-finance-tools/products/sharesight-page.component.ts new file mode 100644 index 000000000..9ce49a51c --- /dev/null +++ b/apps/client/src/app/pages/resources/personal-finance-tools/products/sharesight-page.component.ts @@ -0,0 +1,24 @@ +import { CommonModule } from '@angular/common'; +import { Component } from '@angular/core'; +import { MatButtonModule } from '@angular/material/button'; +import { RouterModule } from '@angular/router'; + +import { products } from '../products'; + +@Component({ + host: { class: 'page' }, + imports: [CommonModule, MatButtonModule, RouterModule], + selector: 'gf-sharesight-page', + standalone: true, + styleUrls: ['../product-page-template.scss'], + templateUrl: '../product-page-template.html' +}) +export class SharesightPageComponent { + public product1 = products.find(({ key }) => { + return key === 'ghostfolio'; + }); + + public product2 = products.find(({ key }) => { + return key === 'sharesight'; + }); +} diff --git a/apps/client/src/app/pages/resources/personal-finance-tools/products/simple-portfolio-page.component.ts b/apps/client/src/app/pages/resources/personal-finance-tools/products/simple-portfolio-page.component.ts new file mode 100644 index 000000000..f06f3790f --- /dev/null +++ b/apps/client/src/app/pages/resources/personal-finance-tools/products/simple-portfolio-page.component.ts @@ -0,0 +1,24 @@ +import { CommonModule } from '@angular/common'; +import { Component } from '@angular/core'; +import { MatButtonModule } from '@angular/material/button'; +import { RouterModule } from '@angular/router'; + +import { products } from '../products'; + +@Component({ + host: { class: 'page' }, + imports: [CommonModule, MatButtonModule, RouterModule], + selector: 'gf-simple-portfolio-page', + standalone: true, + styleUrls: ['../product-page-template.scss'], + templateUrl: '../product-page-template.html' +}) +export class SimplePortfolioPageComponent { + public product1 = products.find(({ key }) => { + return key === 'ghostfolio'; + }); + + public product2 = products.find(({ key }) => { + return key === 'simple-portfolio'; + }); +} diff --git a/apps/client/src/app/pages/resources/personal-finance-tools/products/snowball-analytics-page.component.ts b/apps/client/src/app/pages/resources/personal-finance-tools/products/snowball-analytics-page.component.ts new file mode 100644 index 000000000..379b6f7f8 --- /dev/null +++ b/apps/client/src/app/pages/resources/personal-finance-tools/products/snowball-analytics-page.component.ts @@ -0,0 +1,24 @@ +import { CommonModule } from '@angular/common'; +import { Component } from '@angular/core'; +import { MatButtonModule } from '@angular/material/button'; +import { RouterModule } from '@angular/router'; + +import { products } from '../products'; + +@Component({ + host: { class: 'page' }, + imports: [CommonModule, MatButtonModule, RouterModule], + selector: 'gf-snowball-analytics-page', + standalone: true, + styleUrls: ['../product-page-template.scss'], + templateUrl: '../product-page-template.html' +}) +export class SnowballAnalyticsPageComponent { + public product1 = products.find(({ key }) => { + return key === 'ghostfolio'; + }); + + public product2 = products.find(({ key }) => { + return key === 'snowball-analytics'; + }); +} diff --git a/apps/client/src/app/pages/resources/personal-finance-tools/products/sumio-page.component.ts b/apps/client/src/app/pages/resources/personal-finance-tools/products/sumio-page.component.ts new file mode 100644 index 000000000..0a27eed49 --- /dev/null +++ b/apps/client/src/app/pages/resources/personal-finance-tools/products/sumio-page.component.ts @@ -0,0 +1,24 @@ +import { CommonModule } from '@angular/common'; +import { Component } from '@angular/core'; +import { MatButtonModule } from '@angular/material/button'; +import { RouterModule } from '@angular/router'; + +import { products } from '../products'; + +@Component({ + host: { class: 'page' }, + imports: [CommonModule, MatButtonModule, RouterModule], + selector: 'gf-sumio-page', + standalone: true, + styleUrls: ['../product-page-template.scss'], + templateUrl: '../product-page-template.html' +}) +export class SumioPageComponent { + public product1 = products.find(({ key }) => { + return key === 'ghostfolio'; + }); + + public product2 = products.find(({ key }) => { + return key === 'sumio'; + }); +} diff --git a/apps/client/src/app/pages/resources/personal-finance-tools/products/utluna-page.component.ts b/apps/client/src/app/pages/resources/personal-finance-tools/products/utluna-page.component.ts new file mode 100644 index 000000000..7c80584b3 --- /dev/null +++ b/apps/client/src/app/pages/resources/personal-finance-tools/products/utluna-page.component.ts @@ -0,0 +1,24 @@ +import { CommonModule } from '@angular/common'; +import { Component } from '@angular/core'; +import { MatButtonModule } from '@angular/material/button'; +import { RouterModule } from '@angular/router'; + +import { products } from '../products'; + +@Component({ + host: { class: 'page' }, + imports: [CommonModule, MatButtonModule, RouterModule], + selector: 'gf-utluna-page', + standalone: true, + styleUrls: ['../product-page-template.scss'], + templateUrl: '../product-page-template.html' +}) +export class UtlunaPageComponent { + public product1 = products.find(({ key }) => { + return key === 'ghostfolio'; + }); + + public product2 = products.find(({ key }) => { + return key === 'utluna'; + }); +} diff --git a/apps/client/src/app/pages/resources/personal-finance-tools/products/yeekatee-page.component.ts b/apps/client/src/app/pages/resources/personal-finance-tools/products/yeekatee-page.component.ts new file mode 100644 index 000000000..c85397808 --- /dev/null +++ b/apps/client/src/app/pages/resources/personal-finance-tools/products/yeekatee-page.component.ts @@ -0,0 +1,24 @@ +import { CommonModule } from '@angular/common'; +import { Component } from '@angular/core'; +import { MatButtonModule } from '@angular/material/button'; +import { RouterModule } from '@angular/router'; + +import { products } from '../products'; + +@Component({ + host: { class: 'page' }, + imports: [CommonModule, MatButtonModule, RouterModule], + selector: 'gf-yeekatee-page', + standalone: true, + styleUrls: ['../product-page-template.scss'], + templateUrl: '../product-page-template.html' +}) +export class YeekateePageComponent { + public product1 = products.find(({ key }) => { + return key === 'ghostfolio'; + }); + + public product2 = products.find(({ key }) => { + return key === 'yeekatee'; + }); +} diff --git a/apps/client/src/app/pages/resources/resources-page-routing.module.ts b/apps/client/src/app/pages/resources/resources-page-routing.module.ts index d0f385e10..7b00fcaae 100644 --- a/apps/client/src/app/pages/resources/resources-page-routing.module.ts +++ b/apps/client/src/app/pages/resources/resources-page-routing.module.ts @@ -10,7 +10,14 @@ const routes: Routes = [ component: ResourcesPageComponent, path: '', title: $localize`Resources` - } + }, + ...['personal-finance-tools'].map((path) => ({ + path, + loadChildren: () => + import( + './personal-finance-tools/personal-finance-tools-page.module' + ).then((m) => m.PersonalFinanceToolsPageModule) + })) ]; @NgModule({ diff --git a/apps/client/src/app/pages/resources/resources-page.html b/apps/client/src/app/pages/resources/resources-page.html index 35e5d5fce..53484b270 100644 --- a/apps/client/src/app/pages/resources/resources-page.html +++ b/apps/client/src/app/pages/resources/resources-page.html @@ -2,7 +2,7 @@

Resources

-

Guides

+

Guides

@@ -36,7 +36,7 @@
-

Market

+

Markets

@@ -72,7 +72,7 @@
-

Glossary

+

Glossary

@@ -170,6 +170,21 @@
+
+
+

Personal Finance Tools

+
+ Personal finance tools are software applications that help + individuals manage their money, track expenses, set budgets, + monitor investments, and make informed financial decisions. +
+ +
+

Stagflation

diff --git a/apps/client/src/assets/sitemap.xml b/apps/client/src/assets/sitemap.xml index 7ab2ba2a7..880509ec8 100644 --- a/apps/client/src/assets/sitemap.xml +++ b/apps/client/src/assets/sitemap.xml @@ -6,410 +6,494 @@ http://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd"> https://ghostfol.io/de - 2023-07-01T00:00:00+00:00 + 2023-07-07T00:00:00+00:00 https://ghostfol.io/de/blog - 2023-07-01T00:00:00+00:00 + 2023-07-07T00:00:00+00:00 https://ghostfol.io/de/blog/2021/07/hallo-ghostfolio - 2023-07-01T00:00:00+00:00 + 2023-07-07T00:00:00+00:00 https://ghostfol.io/de/blog/2023/01/ghostfolio-auf-sackgeld-vorgestellt - 2023-07-01T00:00:00+00:00 + 2023-07-07T00:00:00+00:00 https://ghostfol.io/de/features - 2023-07-01T00:00:00+00:00 + 2023-07-07T00:00:00+00:00 https://ghostfol.io/de/haeufig-gestellte-fragen - 2023-07-01T00:00:00+00:00 + 2023-07-07T00:00:00+00:00 https://ghostfol.io/de/maerkte daily - 2023-07-01T00:00:00+00:00 + 2023-07-07T00:00:00+00:00 https://ghostfol.io/de/open daily - 2023-07-01T00:00:00+00:00 + 2023-07-07T00:00:00+00:00 https://ghostfol.io/de/preise - 2023-07-01T00:00:00+00:00 + 2023-07-07T00:00:00+00:00 https://ghostfol.io/de/registrierung - 2023-07-01T00:00:00+00:00 + 2023-07-07T00:00:00+00:00 https://ghostfol.io/de/ressourcen - 2023-07-01T00:00:00+00:00 + 2023-07-07T00:00:00+00:00 https://ghostfol.io/de/ueber-uns - 2023-07-01T00:00:00+00:00 + 2023-07-07T00:00:00+00:00 https://ghostfol.io/de/ueber-uns/changelog - 2023-07-01T00:00:00+00:00 + 2023-07-07T00:00:00+00:00 https://ghostfol.io/de/ueber-uns/datenschutzbestimmungen - 2023-07-01T00:00:00+00:00 + 2023-07-07T00:00:00+00:00 https://ghostfol.io/de/ueber-uns/lizenz - 2023-07-01T00:00:00+00:00 + 2023-07-07T00:00:00+00:00 https://ghostfol.io/en - 2023-07-01T00:00:00+00:00 + 2023-07-07T00:00:00+00:00 https://ghostfol.io/en/about - 2023-07-01T00:00:00+00:00 + 2023-07-07T00:00:00+00:00 https://ghostfol.io/en/about/changelog - 2023-07-01T00:00:00+00:00 + 2023-07-07T00:00:00+00:00 https://ghostfol.io/en/about/license - 2023-07-01T00:00:00+00:00 + 2023-07-07T00:00:00+00:00 https://ghostfol.io/en/blog - 2023-07-01T00:00:00+00:00 + 2023-07-07T00:00:00+00:00 https://ghostfol.io/en/blog/2021/07/hello-ghostfolio - 2023-07-01T00:00:00+00:00 + 2023-07-07T00:00:00+00:00 https://ghostfol.io/en/blog/2022/01/ghostfolio-first-months-in-open-source - 2023-07-01T00:00:00+00:00 + 2023-07-07T00:00:00+00:00 https://ghostfol.io/en/blog/2022/07/ghostfolio-meets-internet-identity - 2023-07-01T00:00:00+00:00 + 2023-07-07T00:00:00+00:00 https://ghostfol.io/en/blog/2022/07/how-do-i-get-my-finances-in-order - 2023-07-01T00:00:00+00:00 + 2023-07-07T00:00:00+00:00 https://ghostfol.io/en/blog/2022/08/500-stars-on-github - 2023-07-01T00:00:00+00:00 + 2023-07-07T00:00:00+00:00 https://ghostfol.io/en/blog/2022/10/hacktoberfest-2022 - 2023-07-01T00:00:00+00:00 + 2023-07-07T00:00:00+00:00 https://ghostfol.io/en/blog/2022/11/black-friday-2022 - 2023-07-01T00:00:00+00:00 + 2023-07-07T00:00:00+00:00 https://ghostfol.io/en/blog/2022/12/the-importance-of-tracking-your-personal-finances - 2023-07-01T00:00:00+00:00 + 2023-07-07T00:00:00+00:00 https://ghostfol.io/en/blog/2023/02/ghostfolio-meets-umbrel - 2023-07-01T00:00:00+00:00 + 2023-07-07T00:00:00+00:00 https://ghostfol.io/en/blog/2023/03/ghostfolio-reaches-1000-stars-on-github - 2023-07-01T00:00:00+00:00 + 2023-07-07T00:00:00+00:00 https://ghostfol.io/en/blog/2023/05/unlock-your-financial-potential-with-ghostfolio - 2023-07-01T00:00:00+00:00 + 2023-07-07T00:00:00+00:00 https://ghostfol.io/en/blog/2023/07/exploring-the-path-to-fire - 2023-07-01T00:00:00+00:00 + 2023-07-07T00:00:00+00:00 https://ghostfol.io/en/faq - 2023-07-01T00:00:00+00:00 + 2023-07-07T00:00:00+00:00 https://ghostfol.io/en/features - 2023-07-01T00:00:00+00:00 + 2023-07-07T00:00:00+00:00 https://ghostfol.io/en/markets daily - 2023-07-01T00:00:00+00:00 + 2023-07-07T00:00:00+00:00 https://ghostfol.io/en/open daily - 2023-07-01T00:00:00+00:00 + 2023-07-07T00:00:00+00:00 https://ghostfol.io/en/pricing - 2023-07-01T00:00:00+00:00 + 2023-07-07T00:00:00+00:00 https://ghostfol.io/en/register - 2023-07-01T00:00:00+00:00 + 2023-07-07T00:00:00+00:00 https://ghostfol.io/en/resources - 2023-07-01T00:00:00+00:00 + 2023-07-07T00:00:00+00:00 + + + https://ghostfol.io/en/resources/personal-finance-tools + 2023-07-07T00:00:00+00:00 + + + https://ghostfol.io/en/resources/personal-finance-tools/open-source-alternative-to-altoo + 2023-07-07T00:00:00+00:00 + + + https://ghostfol.io/en/resources/personal-finance-tools/open-source-alternative-to-divvydiary + 2023-07-07T00:00:00+00:00 + + + https://ghostfol.io/en/resources/personal-finance-tools/open-source-alternative-to-exirio + 2023-07-07T00:00:00+00:00 + + + https://ghostfol.io/en/resources/personal-finance-tools/open-source-alternative-to-folishare + 2023-07-07T00:00:00+00:00 + + + https://ghostfol.io/en/resources/personal-finance-tools/open-source-alternative-to-getquin + 2023-07-07T00:00:00+00:00 + + + https://ghostfol.io/en/resources/personal-finance-tools/open-source-alternative-to-justetf + 2023-07-07T00:00:00+00:00 + + + https://ghostfol.io/en/resources/personal-finance-tools/open-source-alternative-to-kubera + 2023-07-07T00:00:00+00:00 + + + https://ghostfol.io/en/resources/personal-finance-tools/open-source-alternative-to-maybe-finance + 2023-07-07T00:00:00+00:00 + + + https://ghostfol.io/en/resources/personal-finance-tools/open-source-alternative-to-monse + 2023-07-07T00:00:00+00:00 + + + https://ghostfol.io/en/resources/personal-finance-tools/open-source-alternative-to-parqet + 2023-07-07T00:00:00+00:00 + + + https://ghostfol.io/en/resources/personal-finance-tools/open-source-alternative-to-portfolio-dividend-tracker + 2023-07-07T00:00:00+00:00 + + + https://ghostfol.io/en/resources/personal-finance-tools/open-source-alternative-to-portseido + 2023-07-07T00:00:00+00:00 + + + https://ghostfol.io/en/resources/personal-finance-tools/open-source-alternative-to-projectionlab + 2023-07-07T00:00:00+00:00 + + + https://ghostfol.io/en/resources/personal-finance-tools/open-source-alternative-to-seeking-alpha + 2023-07-07T00:00:00+00:00 + + + https://ghostfol.io/en/resources/personal-finance-tools/open-source-alternative-to-sharesight + 2023-07-07T00:00:00+00:00 + + + https://ghostfol.io/en/resources/personal-finance-tools/open-source-alternative-to-simple-portfolio + 2023-07-07T00:00:00+00:00 + + + https://ghostfol.io/en/resources/personal-finance-tools/open-source-alternative-to-snowball-analytics + 2023-07-07T00:00:00+00:00 + + + https://ghostfol.io/en/resources/personal-finance-tools/open-source-alternative-to-sumio + 2023-07-07T00:00:00+00:00 + + + https://ghostfol.io/en/resources/personal-finance-tools/open-source-alternative-to-utluna + 2023-07-07T00:00:00+00:00 + + + https://ghostfol.io/en/resources/personal-finance-tools/open-source-alternative-to-yeekatee + 2023-07-07T00:00:00+00:00 https://ghostfol.io/es - 2023-07-01T00:00:00+00:00 + 2023-07-07T00:00:00+00:00 https://ghostfol.io/es/funcionalidades - 2023-07-01T00:00:00+00:00 + 2023-07-07T00:00:00+00:00 https://ghostfol.io/es/mercados daily - 2023-07-01T00:00:00+00:00 + 2023-07-07T00:00:00+00:00 https://ghostfol.io/es/open daily - 2023-07-01T00:00:00+00:00 + 2023-07-07T00:00:00+00:00 https://ghostfol.io/es/precios - 2023-07-01T00:00:00+00:00 + 2023-07-07T00:00:00+00:00 https://ghostfol.io/es/preguntas-mas-frecuentes - 2023-07-01T00:00:00+00:00 + 2023-07-07T00:00:00+00:00 https://ghostfol.io/es/recursos - 2023-07-01T00:00:00+00:00 + 2023-07-07T00:00:00+00:00 https://ghostfol.io/es/registro - 2023-07-01T00:00:00+00:00 + 2023-07-07T00:00:00+00:00 https://ghostfol.io/es/sobre - 2023-07-01T00:00:00+00:00 + 2023-07-07T00:00:00+00:00 https://ghostfol.io/es/sobre/changelog - 2023-07-01T00:00:00+00:00 + 2023-07-07T00:00:00+00:00 https://ghostfol.io/es/sobre/licencia - 2023-07-01T00:00:00+00:00 + 2023-07-07T00:00:00+00:00 https://ghostfol.io/es/sobre/politica-de-privacidad - 2023-07-01T00:00:00+00:00 + 2023-07-07T00:00:00+00:00 https://ghostfol.io/fr - 2023-07-01T00:00:00+00:00 + 2023-07-07T00:00:00+00:00 https://ghostfol.io/fr/a-propos - 2023-07-01T00:00:00+00:00 + 2023-07-07T00:00:00+00:00 https://ghostfol.io/fr/a-propos/changelog - 2023-07-01T00:00:00+00:00 + 2023-07-07T00:00:00+00:00 https://ghostfol.io/fr/a-propos/licence - 2023-07-01T00:00:00+00:00 + 2023-07-07T00:00:00+00:00 https://ghostfol.io/fr/a-propos/politique-de-confidentialite - 2023-07-01T00:00:00+00:00 + 2023-07-07T00:00:00+00:00 https://ghostfol.io/fr/enregistrement - 2023-07-01T00:00:00+00:00 + 2023-07-07T00:00:00+00:00 https://ghostfol.io/fr/fonctionnalites - 2023-07-01T00:00:00+00:00 + 2023-07-07T00:00:00+00:00 https://ghostfol.io/fr/foire-aux-questions - 2023-07-01T00:00:00+00:00 + 2023-07-07T00:00:00+00:00 https://ghostfol.io/fr/marches daily - 2023-07-01T00:00:00+00:00 + 2023-07-07T00:00:00+00:00 https://ghostfol.io/fr/open daily - 2023-07-01T00:00:00+00:00 + 2023-07-07T00:00:00+00:00 https://ghostfol.io/fr/prix - 2023-07-01T00:00:00+00:00 + 2023-07-07T00:00:00+00:00 https://ghostfol.io/fr/ressources - 2023-07-01T00:00:00+00:00 + 2023-07-07T00:00:00+00:00 https://ghostfol.io/it - 2023-07-01T00:00:00+00:00 + 2023-07-07T00:00:00+00:00 https://ghostfol.io/it/domande-piu-frequenti - 2023-07-01T00:00:00+00:00 + 2023-07-07T00:00:00+00:00 https://ghostfol.io/it/funzionalita - 2023-07-01T00:00:00+00:00 + 2023-07-07T00:00:00+00:00 https://ghostfol.io/it/informazioni-su - 2023-07-01T00:00:00+00:00 + 2023-07-07T00:00:00+00:00 https://ghostfol.io/it/informazioni-su/changelog - 2023-07-01T00:00:00+00:00 + 2023-07-07T00:00:00+00:00 https://ghostfol.io/it/informazioni-su/licenza - 2023-07-01T00:00:00+00:00 + 2023-07-07T00:00:00+00:00 https://ghostfol.io/it/informazioni-su/informativa-sulla-privacy - 2023-07-01T00:00:00+00:00 + 2023-07-07T00:00:00+00:00 https://ghostfol.io/it/iscrizione - 2023-07-01T00:00:00+00:00 + 2023-07-07T00:00:00+00:00 https://ghostfol.io/it/mercati daily - 2023-07-01T00:00:00+00:00 + 2023-07-07T00:00:00+00:00 https://ghostfol.io/it/open daily - 2023-07-01T00:00:00+00:00 + 2023-07-07T00:00:00+00:00 https://ghostfol.io/it/prezzi - 2023-07-01T00:00:00+00:00 + 2023-07-07T00:00:00+00:00 https://ghostfol.io/it/risorse - 2023-07-01T00:00:00+00:00 + 2023-07-07T00:00:00+00:00 https://ghostfol.io/nl - 2023-07-01T00:00:00+00:00 + 2023-07-07T00:00:00+00:00 https://ghostfol.io/nl/bronnen - 2023-07-01T00:00:00+00:00 + 2023-07-07T00:00:00+00:00 https://ghostfol.io/nl/kenmerken - 2023-07-01T00:00:00+00:00 + 2023-07-07T00:00:00+00:00 https://ghostfol.io/nl/markten daily - 2023-07-01T00:00:00+00:00 + 2023-07-07T00:00:00+00:00 https://ghostfol.io/nl/open daily - 2023-07-01T00:00:00+00:00 + 2023-07-07T00:00:00+00:00 https://ghostfol.io/nl/over - 2023-07-01T00:00:00+00:00 + 2023-07-07T00:00:00+00:00 https://ghostfol.io/nl/over/changelog - 2023-07-01T00:00:00+00:00 + 2023-07-07T00:00:00+00:00 https://ghostfol.io/nl/over/licentie - 2023-07-01T00:00:00+00:00 + 2023-07-07T00:00:00+00:00 https://ghostfol.io/nl/over/privacybeleid - 2023-07-01T00:00:00+00:00 + 2023-07-07T00:00:00+00:00 https://ghostfol.io/nl/prijzen - 2023-07-01T00:00:00+00:00 + 2023-07-07T00:00:00+00:00 https://ghostfol.io/nl/registratie - 2023-07-01T00:00:00+00:00 + 2023-07-07T00:00:00+00:00 https://ghostfol.io/nl/vaak-gestelde-vragen - 2023-07-01T00:00:00+00:00 + 2023-07-07T00:00:00+00:00 https://ghostfol.io/pt/blog - 2023-07-01T00:00:00+00:00 + 2023-07-07T00:00:00+00:00 https://ghostfol.io/pt/funcionalidades - 2023-07-01T00:00:00+00:00 + 2023-07-07T00:00:00+00:00 https://ghostfol.io/pt/mercados - 2023-07-01T00:00:00+00:00 + 2023-07-07T00:00:00+00:00 https://ghostfol.io/pt/open - 2023-07-01T00:00:00+00:00 + 2023-07-07T00:00:00+00:00 https://ghostfol.io/pt/perguntas-mais-frequentes - 2023-07-01T00:00:00+00:00 + 2023-07-07T00:00:00+00:00 https://ghostfol.io/pt/precos - 2023-07-01T00:00:00+00:00 + 2023-07-07T00:00:00+00:00 https://ghostfol.io/pt/recursos - 2023-07-01T00:00:00+00:00 + 2023-07-07T00:00:00+00:00 https://ghostfol.io/pt/registo - 2023-07-01T00:00:00+00:00 + 2023-07-07T00:00:00+00:00 https://ghostfol.io/pt/sobre - 2023-07-01T00:00:00+00:00 + 2023-07-07T00:00:00+00:00 https://ghostfol.io/pt/sobre/changelog - 2023-07-01T00:00:00+00:00 + 2023-07-07T00:00:00+00:00 https://ghostfol.io/pt/sobre/licenca - 2023-07-01T00:00:00+00:00 + 2023-07-07T00:00:00+00:00 https://ghostfol.io/pt/sobre/politica-de-privacidade - 2023-07-01T00:00:00+00:00 + 2023-07-07T00:00:00+00:00 diff --git a/libs/common/src/lib/interfaces/index.ts b/libs/common/src/lib/interfaces/index.ts index 6eebc0de2..e33b6b55f 100644 --- a/libs/common/src/lib/interfaces/index.ts +++ b/libs/common/src/lib/interfaces/index.ts @@ -32,6 +32,7 @@ import type { PortfolioReportRule } from './portfolio-report-rule.interface'; import type { PortfolioReport } from './portfolio-report.interface'; import type { PortfolioSummary } from './portfolio-summary.interface'; import type { Position } from './position.interface'; +import type { Product } from './product'; import type { BenchmarkResponse } from './responses/benchmark-response.interface'; import type { ResponseError } from './responses/errors.interface'; import type { ImportResponse } from './responses/import-response.interface'; @@ -83,6 +84,7 @@ export { PortfolioReportRule, PortfolioSummary, Position, + Product, ResponseError, ScraperConfiguration, Statistics, diff --git a/libs/common/src/lib/interfaces/product.ts b/libs/common/src/lib/interfaces/product.ts new file mode 100644 index 000000000..22067b7b7 --- /dev/null +++ b/libs/common/src/lib/interfaces/product.ts @@ -0,0 +1,15 @@ +export interface Product { + component: any; + founded?: number; + hasFreePlan?: boolean; + hasSelfHostingAbility?: boolean; + isOpenSource: boolean; + key: string; + languages?: string; + name: string; + note?: string; + origin?: string; + pricingPerYear?: string; + region?: string; + slogan?: string; +}